diff mbox series

[net-next,v1] net: mptcp, Fast Open Mechanism

Message ID 17ca66cd439.10a0a3ce11621928.1543611905599720914@shytyi.net (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series [net-next,v1] net: mptcp, Fast Open Mechanism | expand

Checks

Context Check Description
netdev/apply fail Patch does not apply to net-next
netdev/tree_selection success Clearly marked for net-next

Commit Message

Dmytro Shytyi Oct. 22, 2021, 5:15 a.m. UTC
This set of patches will bring "Fast Open" Option support to MPTCP.
The aim of Fast Open Mechanism is to eliminate one round trip 
time from a TCP conversation by allowing data to be included as 
part of the SYN segment that initiates the connection. 

IETF RFC 8684: Appendix B.  TCP Fast Open and MPTCP.

[PATCH v1] includes "client" partial support for :
1. send request for cookie;
2. send syn+data+cookie.

Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---

Comments

Matthieu Baerts Oct. 22, 2021, 7:22 a.m. UTC | #1
Hi Dmytro,

On 22/10/2021 07:15, Dmytro Shytyi wrote:
> This set of patches will bring "Fast Open" Option support to MPTCP.
> The aim of Fast Open Mechanism is to eliminate one round trip 
> time from a TCP conversation by allowing data to be included as 
> part of the SYN segment that initiates the connection. 
> 
> IETF RFC 8684: Appendix B.  TCP Fast Open and MPTCP.
> 
> [PATCH v1] includes "client" partial support for :
> 1. send request for cookie;
> 2. send syn+data+cookie.

Thank you for working on that and sharing this patch with us!

It looks like some modifications are going to be needed, e.g. after a
very quick look, it seems all tabs have been converted to spaces causing
the patch not being applicable on git[1]: did you not use git
format-patch to generate it? Also, some issues will be reported by
checkpatch.pl, the "reversed XMas tree" order is not respected for
variables declaration, etc.

Do you mind if we continue the discussion on MPTCP mailing list only? In
other words, without Netdev mailing list and Net maintainers, not to
bother everybody for MPTCP specific stuff?

Our usual way of working for MPTCP patches is to have the code review on
MPTCP ML only, then apply accepted patches in our tree first and once a
validation has been done, send patches later to Netdev ML for inclusion
in the -net or net-next tree.

Cheers,
Matt

[1]
https://patchew.org/logs/17ca66cd439.10a0a3ce11621928.1543611905599720914@shytyi.net/git/
diff mbox series

Patch

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index cd6b11c9b54d..1f9ef060e980 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1686,6 +1686,68 @@  static void mptcp_set_nospace(struct sock *sk)
        set_bit(MPTCP_NOSPACE, &mptcp_sk(sk)->flags);
 }

+static int mptcp_sendmsg_fastopen_cookie_req(struct sock *sk, struct msghdr *msg,
+                                            size_t *copied, size_t size,
+                                            struct ubuf_info *uarg)
+{
+       struct mptcp_sock *msk = mptcp_sk(sk);
+       struct socket *ssk = __mptcp_nmpc_socket(msk);
+       struct tcp_sock *tp = tcp_sk(ssk->sk);
+       struct sockaddr *uaddr = msg->msg_name;
+       struct tcp_fastopen_context *ctx;
+       const struct iphdr *iph;
+       struct sk_buff *skb;
+       int err;
+
+       skb = sk_stream_alloc_skb(ssk->sk, 0, ssk->sk->sk_allocation, true);
+       iph = ip_hdr(skb);
+       tcp_fastopen_init_key_once(sock_net(ssk->sk));
+       ctx = tcp_fastopen_get_ctx(ssk->sk);
+       tp->fastopen_req = kzalloc(sizeof(*tp->fatopen_req),
+                                  ssk->sk->sk_allocation);
+       tp->fastopen_req->data = msg;
+       tp->fastopen_req->size = size;
+       tp->fastopen_req->uarg = uarg;
+       err = mptcp_stream_connect(sk->sk_socket, uaddr, msg->msg_namelen, msg->msg_flags);
+       return err;
+}
+
+static int mptcp_sendmsg_fastopen_cookie_send(struct sock *sk, struct msghdr *msg,
+                                             size_t *copied, size_t size,
+                                             struct ubuf_info *uarg)
+{
+       struct tcp_fastopen_cookie *fastopen_cookie = kmalloc(sizeof(*fastopen_cookie),
+                                                             GFP_KERNEL);
+       struct mptcp_sock *msk = mptcp_sk(sk);
+       struct socket *ssk = __mptcp_nmpc_socket(msk);
+       struct tcp_sock *tp = tcp_sk(ssk->sk);
+       struct sockaddr *uaddr = msg->msg_name;
+       struct tcp_fastopen_context *ctx;
+       const struct iphdr *iph;
+       struct sk_buff *skb;
+       int err;
+
+       skb = sk_stream_alloc_skb(ssk->sk, 0, ssk->sk->sk_allocation, true);
+       iph = ip_hdr(skb);
+       tcp_fastopen_init_key_once(sock_net(ssk->sk));
+       ctx = tcp_fastopen_get_ctx(ssk->sk);
+
+       fastopen_cookie->val[0] = cpu_to_le64(siphash(&iph->saddr,
+                                             sizeof(iph->saddr) +
+                                             sizeof(iph->daddr),
+                                             &ctx->key[0]));
+       fastopen_cookie->len = TCP_FASTOPEN_COOKIE_SIZE;
+
+       tp->fastopen_req = kzalloc(sizeof(*tp->fastopen_req),
+                                  ssk->sk->sk_allocation);
+       tp->fastopen_req->data = msg;
+       tp->fastopen_req->size = size;
+       tp->fastopen_req->uarg = uarg;
+       memcpy(&tp->fastopen_req->cookie, fastopen_cookie, sizeof(tp->fastopen_req->cookie));
+       err = mptcp_stream_connect(sk->sk_socket, uaddr, msg->msg_namelen, msg->msg_flags);
+       return err;
+}
+
 static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 {
        struct mptcp_sock *msk = mptcp_sk(sk);
@@ -1694,9 +1756,22 @@  static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
        int ret = 0;
        long timeo;

-       /* we don't support FASTOPEN yet */
-       if (msg->msg_flags & MSG_FASTOPEN)
-               return -EOPNOTSUPP;
+       /* we don't fully support FASTOPEN yet */
+
+       if (msg->msg_flags & MSG_FASTOPEN) {
+               struct socket *ssk = __mptcp_nmpc_socket(msk);
+               struct tcp_sock *tp = tcp_sk(ssk->sk);
+
+               if (tp && tp->fastopen_req && tp->fastopen_req->cookie.len != 0) {
+                       // send cookie
+                       ret = mptcp_sendmsg_fastopen_cookie_send(sk, msg, &copied, len, uarg);
+               } else {
+                       struct tcp_fastopen_request *fastopen = tp->fastopen_req;
+                       //requests a cookie
+                       ret = mptcp_sendmsg_fastopen_cookie_req(sk, msg, &copied, len, uarg);
+               }
+       return ret;
+       }

        /* silently ignore everything else */
        msg->msg_flags &= MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL;