OSDN Git Service

selftests: mptcp: add a test case for MSG_PEEK
authorYonglong Li <liyonglong@chinatelecom.cn>
Fri, 23 Apr 2021 18:17:09 +0000 (11:17 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 23 Apr 2021 21:06:32 +0000 (14:06 -0700)
Extend mptcp_connect tool with MSG_PEEK support and add a test case in
mptcp_connect.sh that checks the data received from/after recv() with
MSG_PEEK.

Acked-by: Paolo Abeni <pabeni@redhat.com>
Co-developed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Yonglong Li <liyonglong@chinatelecom.cn>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
tools/testing/selftests/net/mptcp/mptcp_connect.c
tools/testing/selftests/net/mptcp/mptcp_connect.sh

index 2f207cf..d88e1fd 100644 (file)
@@ -45,7 +45,14 @@ enum cfg_mode {
        CFG_MODE_SENDFILE,
 };
 
+enum cfg_peek {
+       CFG_NONE_PEEK,
+       CFG_WITH_PEEK,
+       CFG_AFTER_PEEK,
+};
+
 static enum cfg_mode cfg_mode = CFG_MODE_POLL;
+static enum cfg_peek cfg_peek = CFG_NONE_PEEK;
 static const char *cfg_host;
 static const char *cfg_port    = "12000";
 static int cfg_sock_proto      = IPPROTO_MPTCP;
@@ -73,6 +80,8 @@ static void die_usage(void)
        fprintf(stderr, "\t-M mark -- set socket packet mark\n");
        fprintf(stderr, "\t-u -- check mptcp ulp\n");
        fprintf(stderr, "\t-w num -- wait num sec before closing the socket\n");
+       fprintf(stderr,
+               "\t-P [saveWithPeek|saveAfterPeek] -- save data with/after MSG_PEEK form tcp socket\n");
        exit(1);
 }
 
@@ -331,6 +340,8 @@ static size_t do_write(const int fd, char *buf, const size_t len)
 
 static ssize_t do_rnd_read(const int fd, char *buf, const size_t len)
 {
+       int ret = 0;
+       char tmp[16384];
        size_t cap = rand();
 
        cap &= 0xffff;
@@ -340,7 +351,17 @@ static ssize_t do_rnd_read(const int fd, char *buf, const size_t len)
        else if (cap > len)
                cap = len;
 
-       return read(fd, buf, cap);
+       if (cfg_peek == CFG_WITH_PEEK) {
+               ret = recv(fd, buf, cap, MSG_PEEK);
+               ret = (ret < 0) ? ret : read(fd, tmp, ret);
+       } else if (cfg_peek == CFG_AFTER_PEEK) {
+               ret = recv(fd, buf, cap, MSG_PEEK);
+               ret = (ret < 0) ? ret : read(fd, buf, cap);
+       } else {
+               ret = read(fd, buf, cap);
+       }
+
+       return ret;
 }
 
 static void set_nonblock(int fd)
@@ -819,6 +840,26 @@ int parse_mode(const char *mode)
        return 0;
 }
 
+int parse_peek(const char *mode)
+{
+       if (!strcasecmp(mode, "saveWithPeek"))
+               return CFG_WITH_PEEK;
+       if (!strcasecmp(mode, "saveAfterPeek"))
+               return CFG_AFTER_PEEK;
+
+       fprintf(stderr, "Unknown: %s\n", mode);
+       fprintf(stderr, "Supported MSG_PEEK mode are:\n");
+       fprintf(stderr,
+               "\t\t\"saveWithPeek\" - recv data with flags 'MSG_PEEK' and save the peek data into file\n");
+       fprintf(stderr,
+               "\t\t\"saveAfterPeek\" - read and save data into file after recv with flags 'MSG_PEEK'\n");
+
+       die_usage();
+
+       /* silence compiler warning */
+       return 0;
+}
+
 static int parse_int(const char *size)
 {
        unsigned long s;
@@ -846,7 +887,7 @@ static void parse_opts(int argc, char **argv)
 {
        int c;
 
-       while ((c = getopt(argc, argv, "6jr:lp:s:hut:m:S:R:w:M:")) != -1) {
+       while ((c = getopt(argc, argv, "6jr:lp:s:hut:m:S:R:w:M:P:")) != -1) {
                switch (c) {
                case 'j':
                        cfg_join = true;
@@ -899,6 +940,9 @@ static void parse_opts(int argc, char **argv)
                case 'M':
                        cfg_mark = strtol(optarg, NULL, 0);
                        break;
+               case 'P':
+                       cfg_peek = parse_peek(optarg);
+                       break;
                }
        }
 
index 385cdc9..9236609 100755 (executable)
@@ -375,7 +375,7 @@ do_transfer()
        local srv_proto="$4"
        local connect_addr="$5"
        local local_addr="$6"
-       local extra_args=""
+       local extra_args="$7"
 
        local port
        port=$((10000+$TEST_COUNT))
@@ -394,9 +394,9 @@ do_transfer()
        fi
 
        if [ -n "$extra_args" ] && $options_log; then
-               options_log=false
                echo "INFO: extra options: $extra_args"
        fi
+       options_log=false
 
        :> "$cout"
        :> "$sout"
@@ -589,6 +589,7 @@ run_tests_lo()
        local connector_ns="$2"
        local connect_addr="$3"
        local loopback="$4"
+       local extra_args="$5"
        local lret=0
 
        # skip if test programs are running inside same netns for subsequent runs.
@@ -608,7 +609,8 @@ run_tests_lo()
                local_addr="0.0.0.0"
        fi
 
-       do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr} ${local_addr}
+       do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP \
+                   ${connect_addr} ${local_addr} "${extra_args}"
        lret=$?
        if [ $lret -ne 0 ]; then
                ret=$lret
@@ -622,14 +624,16 @@ run_tests_lo()
                fi
        fi
 
-       do_transfer ${listener_ns} ${connector_ns} MPTCP TCP ${connect_addr} ${local_addr}
+       do_transfer ${listener_ns} ${connector_ns} MPTCP TCP \
+                   ${connect_addr} ${local_addr} "${extra_args}"
        lret=$?
        if [ $lret -ne 0 ]; then
                ret=$lret
                return 1
        fi
 
-       do_transfer ${listener_ns} ${connector_ns} TCP MPTCP ${connect_addr} ${local_addr}
+       do_transfer ${listener_ns} ${connector_ns} TCP MPTCP \
+                   ${connect_addr} ${local_addr} "${extra_args}"
        lret=$?
        if [ $lret -ne 0 ]; then
                ret=$lret
@@ -637,7 +641,8 @@ run_tests_lo()
        fi
 
        if [ $do_tcp -gt 1 ] ;then
-               do_transfer ${listener_ns} ${connector_ns} TCP TCP ${connect_addr} ${local_addr}
+               do_transfer ${listener_ns} ${connector_ns} TCP TCP \
+                           ${connect_addr} ${local_addr} "${extra_args}"
                lret=$?
                if [ $lret -ne 0 ]; then
                        ret=$lret
@@ -653,6 +658,15 @@ run_tests()
        run_tests_lo $1 $2 $3 0
 }
 
+run_tests_peekmode()
+{
+       local peekmode="$1"
+
+       echo "INFO: with peek mode: ${peekmode}"
+       run_tests_lo "$ns1" "$ns1" 10.0.1.1 1 "-P ${peekmode}"
+       run_tests_lo "$ns1" "$ns1" dead:beef:1::1 1 "-P ${peekmode}"
+}
+
 make_file "$cin" "client"
 make_file "$sin" "server"
 
@@ -732,6 +746,9 @@ for sender in $ns1 $ns2 $ns3 $ns4;do
        run_tests "$ns4" $sender dead:beef:3::1
 done
 
+run_tests_peekmode "saveWithPeek"
+run_tests_peekmode "saveAfterPeek"
+
 time_end=$(date +%s)
 time_run=$((time_end-time_start))