Commit df8aee6d authored by Yonglong Li's avatar Yonglong Li Committed by David S. Miller
Browse files

selftests: mptcp: add a test case for MSG_PEEK



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: default avatarPaolo Abeni <pabeni@redhat.com>
Co-developed-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarYonglong Li <liyonglong@chinatelecom.cn>
Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ca4fb892
Loading
Loading
Loading
Loading
+46 −2
Original line number Diff line number Diff line
@@ -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;
		}
	}

+23 −6
Original line number Diff line number Diff line
@@ -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))