Thread (2 messages) flat view 2 messages, 2 authors, 2021-10-22
STALE1686d

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

From: Dmytro Shytyi <hidden>
Date: 2021-10-22 05:15:54
Also in: mptcp
Subsystem: networking [general], networking [mptcp], the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthieu Baerts, Mat Martineau, Linus Torvalds

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 <redacted>
---
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;
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help