From: Dmytro Shytyi <dmytro@shytyi.net>
To: Matthieu Baerts <matthieu.baerts@tessares.net>, mptcp@lists.linux.dev
Subject: Re: [RFC PATCH mptcp-next v15 5/5] selftests: mptcp: mptfo Initiator/Listener
Date: Sun, 6 Nov 2022 21:50:09 +0100 [thread overview]
Message-ID: <5ea8631f-c975-35a9-d717-b6ea3991f952@shytyi.net> (raw)
In-Reply-To: <20221106152411.655-6-dmytro@shytyi.net>
Hello all,
@Matthieu Baerts,
Please find the first packetdrill test in this github repo:
https://github.com/dmytroshytyi/MPTFO
Precisely,
*.pkt:
https://github.com/dmytroshytyi/MPTFO/blob/main/client-MSG_FASTOPEN.pkt
and result of test execution:
https://github.com/dmytroshytyi/MPTFO/blob/main/packetdrill-sender-test-result.png
Also I created a pull request in multipath-tcp/packetdrill:
https://github.com/multipath-tcp/packetdrill/pull/99
Best regards,
Dmytro SHYTYI.
On 11/6/2022 4:24 PM, Dmytro Shytyi wrote:
> This patch adds the selftests support for mptfo in mptcp_connect.c
> We introduce mptfo option, that sets "TCP_FASTOPEN" + "MSG_FASTOPEN"
> We call sendto() instead of connect().
>
> Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
> ---
> .../selftests/net/mptcp/mptcp_connect.c | 121 +++++++++++++-----
> .../selftests/net/mptcp/mptcp_connect.sh | 21 +++
> 2 files changed, 113 insertions(+), 29 deletions(-)
>
> diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
> index e54653ea2ed4..4bc855159c52 100644
> --- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
> +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
> @@ -26,11 +26,13 @@
>
> #include <netdb.h>
> #include <netinet/in.h>
> +#include <netinet/tcp.h>
>
> -#include <linux/tcp.h>
> #include <linux/time_types.h>
> #include <linux/sockios.h>
>
> +
> +
> extern int optind;
>
> #ifndef IPPROTO_MPTCP
> @@ -83,6 +85,7 @@ struct cfg_cmsg_types {
>
> struct cfg_sockopt_types {
> unsigned int transparent:1;
> + unsigned int mptfo:1;
> };
>
> struct tcp_inq_state {
> @@ -232,6 +235,14 @@ static void set_transparent(int fd, int pf)
> }
> }
>
> +static void set_mptfo(int fd, int pf)
> +{
> + int qlen = 25;
> +
> + if (setsockopt(fd, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)) == -1)
> + perror("TCP_FASTOPEN");
> +}
> +
> static int do_ulp_so(int sock, const char *name)
> {
> return setsockopt(sock, IPPROTO_TCP, TCP_ULP, name, strlen(name));
> @@ -300,6 +311,9 @@ static int sock_listen_mptcp(const char * const listenaddr,
> if (cfg_sockopt_types.transparent)
> set_transparent(sock, pf);
>
> + if (cfg_sockopt_types.mptfo)
> + set_mptfo(sock, pf);
> +
> if (bind(sock, a->ai_addr, a->ai_addrlen) == 0)
> break; /* success */
>
> @@ -330,13 +344,18 @@ static int sock_listen_mptcp(const char * const listenaddr,
>
> static int sock_connect_mptcp(const char * const remoteaddr,
> const char * const port, int proto,
> - struct addrinfo **peer)
> + struct addrinfo **peer,
> + int infd,
> + unsigned int *woff)
> {
> struct addrinfo hints = {
> .ai_protocol = IPPROTO_TCP,
> .ai_socktype = SOCK_STREAM,
> };
> struct addrinfo *a, *addr;
> + unsigned int wlen = 0;
> + int syn_copied = 0;
> + char wbuf[8192];
> int sock = -1;
>
> hints.ai_family = pf;
> @@ -354,14 +373,33 @@ static int sock_connect_mptcp(const char * const remoteaddr,
> if (cfg_mark)
> set_mark(sock, cfg_mark);
>
> - if (connect(sock, a->ai_addr, a->ai_addrlen) == 0) {
> - *peer = a;
> - break; /* success */
> - }
> + if (cfg_sockopt_types.mptfo) {
> + if (wlen == 0)
> + wlen = read(infd, wbuf, sizeof(wbuf));
>
> - perror("connect()");
> - close(sock);
> - sock = -1;
> + syn_copied = sendto(sock, wbuf, wlen, MSG_FASTOPEN,
> + a->ai_addr, a->ai_addrlen);
> + if (syn_copied) {
> + *woff = wlen;
> + *peer = a;
> + break; /* success */
> + }
> + } else {
> + if (connect(sock, a->ai_addr, a->ai_addrlen) == 0) {
> + *peer = a;
> + break; /* success */
> + }
> + }
> + if (cfg_sockopt_types.mptfo) {
> + perror("sendto()");
> + close(sock);
> + sock = -1;
> + } else {
> +
> + perror("connect()");
> + close(sock);
> + sock = -1;
> + }
> }
>
> freeaddrinfo(addr);
> @@ -571,13 +609,14 @@ static void shut_wr(int fd)
> shutdown(fd, SHUT_WR);
> }
>
> -static int copyfd_io_poll(int infd, int peerfd, int outfd, bool *in_closed_after_out)
> +static int copyfd_io_poll(int infd, int peerfd, int outfd,
> + bool *in_closed_after_out, unsigned int woff)
> {
> struct pollfd fds = {
> .fd = peerfd,
> .events = POLLIN | POLLOUT,
> };
> - unsigned int woff = 0, wlen = 0, total_wlen = 0, total_rlen = 0;
> + unsigned int wlen = 0, total_wlen = 0, total_rlen = 0;
> char wbuf[8192];
>
> set_nonblock(peerfd, true);
> @@ -839,7 +878,7 @@ static int copyfd_io_sendfile(int infd, int peerfd, int outfd,
> return err;
> }
>
> -static int copyfd_io(int infd, int peerfd, int outfd, bool close_peerfd)
> +static int copyfd_io(int infd, int peerfd, int outfd, bool close_peerfd, unsigned int woff)
> {
> bool in_closed_after_out = false;
> struct timespec start, end;
> @@ -851,7 +890,7 @@ static int copyfd_io(int infd, int peerfd, int outfd, bool close_peerfd)
>
> switch (cfg_mode) {
> case CFG_MODE_POLL:
> - ret = copyfd_io_poll(infd, peerfd, outfd, &in_closed_after_out);
> + ret = copyfd_io_poll(infd, peerfd, outfd, &in_closed_after_out, woff);
> break;
>
> case CFG_MODE_MMAP:
> @@ -1033,7 +1072,7 @@ int main_loop_s(int listensock)
>
> SOCK_TEST_TCPULP(remotesock, 0);
>
> - copyfd_io(fd, remotesock, 1, true);
> + copyfd_io(fd, remotesock, 1, true, 0);
> } else {
> perror("accept");
> return 1;
> @@ -1130,6 +1169,11 @@ static void parse_setsock_options(const char *name)
> return;
> }
>
> + if (strncmp(name, "MPTFO", len) == 0) {
> + cfg_sockopt_types.mptfo = 1;
> + return;
> + }
> +
> fprintf(stderr, "Unrecognized setsockopt option %s\n", name);
> exit(1);
> }
> @@ -1168,23 +1212,25 @@ int main_loop(void)
> {
> int fd, ret, fd_in = 0;
> struct addrinfo *peer;
> + unsigned int woff = 0;
>
> - /* listener is ready. */
> - fd = sock_connect_mptcp(cfg_host, cfg_port, cfg_sock_proto, &peer);
> - if (fd < 0)
> - return 2;
> -
> + if (!cfg_sockopt_types.mptfo) {
> + /* listener is ready. */
> + fd = sock_connect_mptcp(cfg_host, cfg_port, cfg_sock_proto, &peer, 0, 0);
> + if (fd < 0)
> + return 2;
> again:
> - check_getpeername_connect(fd);
> + check_getpeername_connect(fd);
>
> - SOCK_TEST_TCPULP(fd, cfg_sock_proto);
> + SOCK_TEST_TCPULP(fd, cfg_sock_proto);
>
> - if (cfg_rcvbuf)
> - set_rcvbuf(fd, cfg_rcvbuf);
> - if (cfg_sndbuf)
> - set_sndbuf(fd, cfg_sndbuf);
> - if (cfg_cmsg_types.cmsg_enabled)
> - apply_cmsg_types(fd, &cfg_cmsg_types);
> + if (cfg_rcvbuf)
> + set_rcvbuf(fd, cfg_rcvbuf);
> + if (cfg_sndbuf)
> + set_sndbuf(fd, cfg_sndbuf);
> + if (cfg_cmsg_types.cmsg_enabled)
> + apply_cmsg_types(fd, &cfg_cmsg_types);
> + }
>
> if (cfg_input) {
> fd_in = open(cfg_input, O_RDONLY);
> @@ -1192,8 +1238,25 @@ int main_loop(void)
> xerror("can't open %s:%d", cfg_input, errno);
> }
>
> - /* close the client socket open only if we are not going to reconnect */
> - ret = copyfd_io(fd_in, fd, 1, 0);
> + if (cfg_sockopt_types.mptfo) {
> + /* sendto() instead of connect */
> + fd = sock_connect_mptcp(cfg_host, cfg_port, cfg_sock_proto, &peer, fd_in, &woff);
> + if (fd < 0)
> + return 2;
> +
> + check_getpeername_connect(fd);
> +
> + SOCK_TEST_TCPULP(fd, cfg_sock_proto);
> +
> + if (cfg_rcvbuf)
> + set_rcvbuf(fd, cfg_rcvbuf);
> + if (cfg_sndbuf)
> + set_sndbuf(fd, cfg_sndbuf);
> + if (cfg_cmsg_types.cmsg_enabled)
> + apply_cmsg_types(fd, &cfg_cmsg_types);
> + }
> +
> + ret = copyfd_io(fd_in, fd, 1, 0, 0);
> if (ret)
> return ret;
>
> diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
> index 621af6895f4d..60198b91a530 100755
> --- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
> +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
> @@ -762,6 +762,23 @@ run_tests_peekmode()
> run_tests_lo "$ns1" "$ns1" dead:beef:1::1 1 "-P ${peekmode}"
> }
>
> +run_tests_mptfo()
> +{
> + echo "INFO: with MPTFO start"
> + ip netns exec "$ns1" sysctl -q net.ipv4.tcp_fastopen=2
> + ip netns exec "$ns2" sysctl -q net.ipv4.tcp_fastopen=1
> +
> + run_tests_lo "$ns1" "$ns2" 10.0.1.1 0 "-o MPTFO"
> + run_tests_lo "$ns1" "$ns2" 10.0.1.1 0 "-o MPTFO"
> +
> + run_tests_lo "$ns1" "$ns2" dead:beef:1::1 0 "-o MPTFO"
> + run_tests_lo "$ns1" "$ns2" dead:beef:1::1 0 "-o MPTFO"
> +
> + ip netns exec "$ns1" sysctl -q net.ipv4.tcp_fastopen=0
> + ip netns exec "$ns2" sysctl -q net.ipv4.tcp_fastopen=0
> + echo "INFO: with MPTFO end"
> +}
> +
> run_tests_disconnect()
> {
> local peekmode="$1"
> @@ -901,6 +918,10 @@ run_tests_peekmode "saveWithPeek"
> run_tests_peekmode "saveAfterPeek"
> stop_if_error "Tests with peek mode have failed"
>
> +# MPTFO (MultiPath TCP Fatopen tests)
> +run_tests_mptfo
> +stop_if_error "Tests with MPTFO have failed"
> +
> # connect to ns4 ip address, ns2 should intercept/proxy
> run_test_transparent 10.0.3.1 "tproxy ipv4"
> run_test_transparent dead:beef:3::1 "tproxy ipv6"
next prev parent reply other threads:[~2022-11-06 20:50 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-06 15:24 [RFC PATCH mptcp-next v15 0/5] mptcp: Fast Open Mechanism Dmytro Shytyi
2022-11-06 15:24 ` [RFC PATCH mptcp-next v15 1/5] mptcp: introduce MSG_FASTOPEN flag Dmytro Shytyi
2022-11-06 15:24 ` [RFC PATCH mptcp-next v15 2/5] mptcp: implement delayed seq generation for passive fastopen Dmytro Shytyi
2022-11-06 15:24 ` [RFC PATCH mptcp-next v15 3/5] mptcp: add subflow_v(4,6)_send_synack() Dmytro Shytyi
2022-11-06 15:24 ` [RFC PATCH mptcp-next v15 4/5] mptcp: add TCP_FASTOPEN sock option Dmytro Shytyi
2022-11-06 15:24 ` [RFC PATCH mptcp-next v15 5/5] selftests: mptcp: mptfo Initiator/Listener Dmytro Shytyi
2022-11-06 17:10 ` selftests: mptcp: mptfo Initiator/Listener: Tests Results MPTCP CI
2022-11-06 20:50 ` Dmytro Shytyi [this message]
2022-11-07 15:47 ` [RFC PATCH mptcp-next v15 5/5] selftests: mptcp: mptfo Initiator/Listener Paolo Abeni
2022-11-10 18:58 ` [RFC PATCH mptcp-next v15 0/5] mptcp: Fast Open Mechanism Matthieu Baerts
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5ea8631f-c975-35a9-d717-b6ea3991f952@shytyi.net \
--to=dmytro@shytyi.net \
--cc=matthieu.baerts@tessares.net \
--cc=mptcp@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).