Merge branch 'mptcp-selftests'
Mat Martineau says: ==================== mptcp: Some selftest improvements Here are a couple of selftest changes for MPTCP. Patch 1 fixes a mistake where the wrong protocol (TCP vs MPTCP) could be requested on the listening socket in some link failure tests. Patch 2 refactors the simulataneous flow tests to improve timing accuracy and give more consistent results. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
986d2e3da7
|
@ -14,6 +14,7 @@
|
|||
#include <strings.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/poll.h>
|
||||
#include <sys/sendfile.h>
|
||||
|
@ -64,6 +65,7 @@ static int cfg_sndbuf;
|
|||
static int cfg_rcvbuf;
|
||||
static bool cfg_join;
|
||||
static bool cfg_remove;
|
||||
static unsigned int cfg_time;
|
||||
static unsigned int cfg_do_w;
|
||||
static int cfg_wait;
|
||||
static uint32_t cfg_mark;
|
||||
|
@ -78,9 +80,10 @@ static struct cfg_cmsg_types cfg_cmsg_types;
|
|||
static void die_usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: mptcp_connect [-6] [-u] [-s MPTCP|TCP] [-p port] [-m mode]"
|
||||
"[-l] [-w sec] connect_address\n");
|
||||
"[-l] [-w sec] [-t num] [-T num] connect_address\n");
|
||||
fprintf(stderr, "\t-6 use ipv6\n");
|
||||
fprintf(stderr, "\t-t num -- set poll timeout to num\n");
|
||||
fprintf(stderr, "\t-T num -- set expected runtime to num ms\n");
|
||||
fprintf(stderr, "\t-S num -- set SO_SNDBUF to num\n");
|
||||
fprintf(stderr, "\t-R num -- set SO_RCVBUF to num\n");
|
||||
fprintf(stderr, "\t-p num -- use port num\n");
|
||||
|
@ -448,7 +451,7 @@ static void set_nonblock(int fd)
|
|||
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
|
||||
static int copyfd_io_poll(int infd, int peerfd, int outfd)
|
||||
static int copyfd_io_poll(int infd, int peerfd, int outfd, bool *in_closed_after_out)
|
||||
{
|
||||
struct pollfd fds = {
|
||||
.fd = peerfd,
|
||||
|
@ -487,9 +490,11 @@ static int copyfd_io_poll(int infd, int peerfd, int outfd)
|
|||
*/
|
||||
fds.events &= ~POLLIN;
|
||||
|
||||
if ((fds.events & POLLOUT) == 0)
|
||||
if ((fds.events & POLLOUT) == 0) {
|
||||
*in_closed_after_out = true;
|
||||
/* and nothing more to send */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Else, still have data to transmit */
|
||||
} else if (len < 0) {
|
||||
|
@ -547,7 +552,7 @@ static int copyfd_io_poll(int infd, int peerfd, int outfd)
|
|||
}
|
||||
|
||||
/* leave some time for late join/announce */
|
||||
if (cfg_join || cfg_remove)
|
||||
if (cfg_remove)
|
||||
usleep(cfg_wait);
|
||||
|
||||
close(peerfd);
|
||||
|
@ -646,7 +651,7 @@ static int do_sendfile(int infd, int outfd, unsigned int count)
|
|||
}
|
||||
|
||||
static int copyfd_io_mmap(int infd, int peerfd, int outfd,
|
||||
unsigned int size)
|
||||
unsigned int size, bool *in_closed_after_out)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -664,13 +669,14 @@ static int copyfd_io_mmap(int infd, int peerfd, int outfd,
|
|||
shutdown(peerfd, SHUT_WR);
|
||||
|
||||
err = do_recvfile(peerfd, outfd);
|
||||
*in_closed_after_out = true;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int copyfd_io_sendfile(int infd, int peerfd, int outfd,
|
||||
unsigned int size)
|
||||
unsigned int size, bool *in_closed_after_out)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -685,6 +691,7 @@ static int copyfd_io_sendfile(int infd, int peerfd, int outfd,
|
|||
if (err)
|
||||
return err;
|
||||
err = do_recvfile(peerfd, outfd);
|
||||
*in_closed_after_out = true;
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -692,27 +699,62 @@ static int copyfd_io_sendfile(int infd, int peerfd, int outfd,
|
|||
|
||||
static int copyfd_io(int infd, int peerfd, int outfd)
|
||||
{
|
||||
bool in_closed_after_out = false;
|
||||
struct timespec start, end;
|
||||
int file_size;
|
||||
int ret;
|
||||
|
||||
if (cfg_time && (clock_gettime(CLOCK_MONOTONIC, &start) < 0))
|
||||
xerror("can not fetch start time %d", errno);
|
||||
|
||||
switch (cfg_mode) {
|
||||
case CFG_MODE_POLL:
|
||||
return copyfd_io_poll(infd, peerfd, outfd);
|
||||
ret = copyfd_io_poll(infd, peerfd, outfd, &in_closed_after_out);
|
||||
break;
|
||||
|
||||
case CFG_MODE_MMAP:
|
||||
file_size = get_infd_size(infd);
|
||||
if (file_size < 0)
|
||||
return file_size;
|
||||
return copyfd_io_mmap(infd, peerfd, outfd, file_size);
|
||||
ret = copyfd_io_mmap(infd, peerfd, outfd, file_size, &in_closed_after_out);
|
||||
break;
|
||||
|
||||
case CFG_MODE_SENDFILE:
|
||||
file_size = get_infd_size(infd);
|
||||
if (file_size < 0)
|
||||
return file_size;
|
||||
return copyfd_io_sendfile(infd, peerfd, outfd, file_size);
|
||||
ret = copyfd_io_sendfile(infd, peerfd, outfd, file_size, &in_closed_after_out);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Invalid mode %d\n", cfg_mode);
|
||||
|
||||
die_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Invalid mode %d\n", cfg_mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
die_usage();
|
||||
return 1;
|
||||
if (cfg_time) {
|
||||
unsigned int delta_ms;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &end) < 0)
|
||||
xerror("can not fetch end time %d", errno);
|
||||
delta_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000;
|
||||
if (delta_ms > cfg_time) {
|
||||
xerror("transfer slower than expected! runtime %d ms, expected %d ms",
|
||||
delta_ms, cfg_time);
|
||||
}
|
||||
|
||||
/* show the runtime only if this end shutdown(wr) before receiving the EOF,
|
||||
* (that is, if this end got the longer runtime)
|
||||
*/
|
||||
if (in_closed_after_out)
|
||||
fprintf(stderr, "%d", delta_ms);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void check_sockaddr(int pf, struct sockaddr_storage *ss,
|
||||
|
@ -1005,12 +1047,11 @@ static void parse_opts(int argc, char **argv)
|
|||
{
|
||||
int c;
|
||||
|
||||
while ((c = getopt(argc, argv, "6jr:lp:s:hut:m:S:R:w:M:P:c:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "6jr:lp:s:hut:T:m:S:R:w:M:P:c:")) != -1) {
|
||||
switch (c) {
|
||||
case 'j':
|
||||
cfg_join = true;
|
||||
cfg_mode = CFG_MODE_POLL;
|
||||
cfg_wait = 400000;
|
||||
break;
|
||||
case 'r':
|
||||
cfg_remove = true;
|
||||
|
@ -1043,6 +1084,9 @@ static void parse_opts(int argc, char **argv)
|
|||
if (poll_timeout <= 0)
|
||||
poll_timeout = -1;
|
||||
break;
|
||||
case 'T':
|
||||
cfg_time = atoi(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
cfg_mode = parse_mode(optarg);
|
||||
break;
|
||||
|
|
|
@ -297,7 +297,7 @@ do_transfer()
|
|||
if [ "$test_link_fail" -eq 2 ];then
|
||||
timeout ${timeout_test} \
|
||||
ip netns exec ${listener_ns} \
|
||||
$mptcp_connect -t ${timeout_poll} -l -p $port -s ${cl_proto} \
|
||||
$mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
|
||||
${local_addr} < "$sinfail" > "$sout" &
|
||||
else
|
||||
timeout ${timeout_test} \
|
||||
|
|
|
@ -51,7 +51,7 @@ setup()
|
|||
sout=$(mktemp)
|
||||
cout=$(mktemp)
|
||||
capout=$(mktemp)
|
||||
size=$((2048 * 4096))
|
||||
size=$((2 * 2048 * 4096))
|
||||
dd if=/dev/zero of=$small bs=4096 count=20 >/dev/null 2>&1
|
||||
dd if=/dev/zero of=$large bs=4096 count=$((size / 4096)) >/dev/null 2>&1
|
||||
|
||||
|
@ -161,17 +161,15 @@ do_transfer()
|
|||
|
||||
timeout ${timeout_test} \
|
||||
ip netns exec ${ns3} \
|
||||
./mptcp_connect -jt ${timeout_poll} -l -p $port \
|
||||
./mptcp_connect -jt ${timeout_poll} -l -p $port -T $time \
|
||||
0.0.0.0 < "$sin" > "$sout" &
|
||||
local spid=$!
|
||||
|
||||
wait_local_port_listen "${ns3}" "${port}"
|
||||
|
||||
local start
|
||||
start=$(date +%s%3N)
|
||||
timeout ${timeout_test} \
|
||||
ip netns exec ${ns1} \
|
||||
./mptcp_connect -jt ${timeout_poll} -p $port \
|
||||
./mptcp_connect -jt ${timeout_poll} -p $port -T $time \
|
||||
10.0.3.3 < "$cin" > "$cout" &
|
||||
local cpid=$!
|
||||
|
||||
|
@ -180,27 +178,20 @@ do_transfer()
|
|||
wait $spid
|
||||
local rets=$?
|
||||
|
||||
local stop
|
||||
stop=$(date +%s%3N)
|
||||
|
||||
if $capture; then
|
||||
sleep 1
|
||||
kill ${cappid_listener}
|
||||
kill ${cappid_connector}
|
||||
fi
|
||||
|
||||
local duration
|
||||
duration=$((stop-start))
|
||||
|
||||
cmp $sin $cout > /dev/null 2>&1
|
||||
local cmps=$?
|
||||
cmp $cin $sout > /dev/null 2>&1
|
||||
local cmpc=$?
|
||||
|
||||
printf "%16s" "$duration max $max_time "
|
||||
printf "%-16s" " max $max_time "
|
||||
if [ $retc -eq 0 ] && [ $rets -eq 0 ] && \
|
||||
[ $cmpc -eq 0 ] && [ $cmps -eq 0 ] && \
|
||||
[ $duration -lt $max_time ]; then
|
||||
[ $cmpc -eq 0 ] && [ $cmps -eq 0 ]; then
|
||||
echo "[ OK ]"
|
||||
cat "$capout"
|
||||
return 0
|
||||
|
@ -244,23 +235,24 @@ run_test()
|
|||
tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1
|
||||
tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2
|
||||
|
||||
# time is measure in ms
|
||||
local time=$((size * 8 * 1000 / (( $rate1 + $rate2) * 1024 *1024) ))
|
||||
# time is measured in ms, account for transfer size, affegated link speed
|
||||
# and header overhead (10%)
|
||||
local time=$((size * 8 * 1000 * 10 / (( $rate1 + $rate2) * 1024 *1024 * 9) ))
|
||||
|
||||
# mptcp_connect will do some sleeps to allow the mp_join handshake
|
||||
# completion
|
||||
time=$((time + 1350))
|
||||
# completion (see mptcp_connect): 200ms on each side, add some slack
|
||||
time=$((time + 450))
|
||||
|
||||
printf "%-50s" "$msg"
|
||||
do_transfer $small $large $((time * 11 / 10))
|
||||
printf "%-60s" "$msg"
|
||||
do_transfer $small $large $time
|
||||
lret=$?
|
||||
if [ $lret -ne 0 ]; then
|
||||
ret=$lret
|
||||
[ $bail -eq 0 ] || exit $ret
|
||||
fi
|
||||
|
||||
printf "%-50s" "$msg - reverse direction"
|
||||
do_transfer $large $small $((time * 11 / 10))
|
||||
printf "%-60s" "$msg - reverse direction"
|
||||
do_transfer $large $small $time
|
||||
lret=$?
|
||||
if [ $lret -ne 0 ]; then
|
||||
ret=$lret
|
||||
|
|
Загрузка…
Ссылка в новой задаче