Skip to content
This repository has been archived by the owner on Apr 18, 2024. It is now read-only.

Commit

Permalink
mptcp: New MP_CAPABLE receiver side
Browse files Browse the repository at this point in the history
Keys are now sent by the client after the 3-way handshake. Thus, we need
to delay some parts of the state initialization to that moment.

Signed-off-by: Christoph Paasch <cpaasch@apple.com>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
  • Loading branch information
cpaasch authored and matttbe committed May 15, 2020
1 parent 3f1f512 commit 0a0abb2
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 52 deletions.
10 changes: 8 additions & 2 deletions include/net/mptcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ struct mptcp_request_sock {

u8 loc_id;
u8 rem_id; /* Address-id in the MP_JOIN */
u8 dss_csum:1,
u16 dss_csum:1,
rem_key_set:1,
is_sub:1, /* Is this a new subflow? */
low_prio:1, /* Interface set to low-prio? */
rcv_low_prio:1,
Expand Down Expand Up @@ -272,6 +273,7 @@ struct mptcp_cb {

u16 send_infinite_mapping:1,
send_mptcpv1_mpcapable:1,
rem_key_set:1,
in_time_wait:1,
list_rcvd:1, /* XXX TO REMOVE */
addr_signal:1, /* Path-manager wants us to call addr_signal */
Expand Down Expand Up @@ -811,10 +813,11 @@ void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp,
void mptcp_close(struct sock *meta_sk, long timeout);
bool mptcp_doit(struct sock *sk);
int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key,
__u8 mptcp_ver, u32 window);
int rem_key_set, __u8 mptcp_ver, u32 window);
int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req);
int mptcp_check_req_master(struct sock *sk, struct sock *child,
struct request_sock *req, const struct sk_buff *skb,
const struct mptcp_options_received *mopt,
int drop, u32 tsoff);
struct sock *mptcp_check_req_child(struct sock *meta_sk,
struct sock *child,
Expand All @@ -838,6 +841,8 @@ void mptcp_sub_close_wq(struct work_struct *work);
void mptcp_sub_close(struct sock *sk, unsigned long delay);
struct sock *mptcp_select_ack_sock(const struct sock *meta_sk);
void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb);
void mptcp_initialize_recv_vars(struct tcp_sock *meta_tp, struct mptcp_cb *mpcb,
__u64 remote_key);
int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb);
void mptcp_ack_handler(struct timer_list *t);
bool mptcp_check_rtt(const struct tcp_sock *tp, int time);
Expand Down Expand Up @@ -1415,6 +1420,7 @@ static inline int mptcp_check_req_master(const struct sock *sk,
const struct sock *child,
const struct request_sock *req,
const struct sk_buff *skb,
const struct mptcp_options_received *mopt,
int drop,
u32 tsoff)
{
Expand Down
1 change: 1 addition & 0 deletions include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb);
/* From syncookies.c */
struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
const struct mptcp_options_received *mopt,
struct dst_entry *dst, u32 tsoff);
int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th,
u32 cookie);
Expand Down
5 changes: 3 additions & 2 deletions net/ipv4/syncookies.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ EXPORT_SYMBOL_GPL(__cookie_v4_check);

struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
const struct mptcp_options_received *mopt,
struct dst_entry *dst, u32 tsoff)
{
struct inet_connection_sock *icsk = inet_csk(sk);
Expand All @@ -219,7 +220,7 @@ struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb,
if (!child)
goto listen_overflow;

ret = mptcp_check_req_master(sk, child, req, skb, 0, tsoff);
ret = mptcp_check_req_master(sk, child, req, skb, mopt, 0, tsoff);
if (ret < 0)
return NULL;

Expand Down Expand Up @@ -428,7 +429,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
ireq->rcv_wscale = rcv_wscale;
ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst);

ret = tcp_get_cookie_sock(sk, skb, req, &rt->dst, tsoff);
ret = tcp_get_cookie_sock(sk, skb, req, &mopt, &rt->dst, tsoff);
/* ip_queue_xmit() depends on our flow being setup
* Normal sockets get it right from inet_csk_route_child_sock()
*/
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/tcp_minisocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
goto listen_overflow;

if (own_req && !is_meta_sk(sk)) {
int ret = mptcp_check_req_master(sk, child, req, skb, 1, 0);
int ret = mptcp_check_req_master(sk, child, req, skb, &mopt, 1, 0);
if (ret < 0)
goto listen_overflow;

Expand Down
2 changes: 1 addition & 1 deletion net/ipv6/syncookies.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
ireq->rcv_wscale = rcv_wscale;
ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), dst);

ret = tcp_get_cookie_sock(sk, skb, req, dst, tsoff);
ret = tcp_get_cookie_sock(sk, skb, req, &mopt, dst, tsoff);
out:
return ret;
out_free:
Expand Down
70 changes: 50 additions & 20 deletions net/mptcp/mptcp_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,11 @@ static void mptcp_reqsk_new_mptcp(struct request_sock *req,
spin_unlock(&mptcp_tk_hashlock);
local_bh_enable();
rcu_read_unlock();
mtreq->mptcp_rem_key = mopt->mptcp_sender_key;

if (mtreq->mptcp_ver == MPTCP_VERSION_0) {
mtreq->mptcp_rem_key = mopt->mptcp_sender_key;
mtreq->rem_key_set = 1;
}
}

static int mptcp_reqsk_new_cookie(struct request_sock *req,
Expand Down Expand Up @@ -357,7 +361,10 @@ static int mptcp_reqsk_new_cookie(struct request_sock *req,
local_bh_enable();
rcu_read_unlock();

mtreq->mptcp_rem_key = mopt->mptcp_sender_key;
if (mtreq->mptcp_ver == MPTCP_VERSION_0) {
mtreq->mptcp_rem_key = mopt->mptcp_sender_key;
mtreq->rem_key_set = 1;
}

return true;
}
Expand Down Expand Up @@ -1236,14 +1243,33 @@ static const struct tcp_sock_ops mptcp_sub_specific = {
.set_cong_ctrl = __tcp_set_congestion_control,
};

void mptcp_initialize_recv_vars(struct tcp_sock *meta_tp, struct mptcp_cb *mpcb,
__u64 remote_key)
{
u64 idsn;

mpcb->mptcp_rem_key = remote_key;
mpcb->rem_key_set = 1;
mptcp_key_sha1(mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &idsn);

idsn++;
mpcb->rcv_high_order[0] = idsn >> 32;
mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1;
meta_tp->copied_seq = (u32)idsn;
meta_tp->rcv_nxt = (u32)idsn;
meta_tp->rcv_wup = (u32)idsn;

meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1;
}

static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key,
__u8 mptcp_ver, u32 window)
int rem_key_set, __u8 mptcp_ver, u32 window)
{
struct mptcp_cb *mpcb;
struct sock *master_sk;
struct inet_connection_sock *meta_icsk = inet_csk(meta_sk);
struct tcp_sock *master_tp, *meta_tp = tcp_sk(meta_sk);
u64 snd_idsn, rcv_idsn;
u64 snd_idsn;

dst_release(meta_sk->sk_rx_dst);
meta_sk->sk_rx_dst = NULL;
Expand Down Expand Up @@ -1276,12 +1302,6 @@ static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key,
mpcb->snd_high_order[0] = snd_idsn >> 32;
mpcb->snd_high_order[1] = mpcb->snd_high_order[0] - 1;

mpcb->mptcp_rem_key = remote_key;
mptcp_key_sha1(mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &rcv_idsn);
rcv_idsn++;
mpcb->rcv_high_order[0] = rcv_idsn >> 32;
mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1;

mpcb->meta_sk = meta_sk;
mpcb->master_sk = master_sk;

Expand Down Expand Up @@ -1393,11 +1413,9 @@ static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key,
meta_tp->pushed_seq = meta_tp->write_seq;
meta_tp->snd_up = meta_tp->write_seq;

meta_tp->copied_seq = (u32)rcv_idsn;
meta_tp->rcv_nxt = (u32)rcv_idsn;
meta_tp->rcv_wup = (u32)rcv_idsn;
if (rem_key_set)
mptcp_initialize_recv_vars(meta_tp, mpcb, remote_key);

meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1;
meta_tp->snd_wnd = window;
meta_tp->retrans_stamp = 0; /* Set in tcp_connect() */

Expand Down Expand Up @@ -2144,12 +2162,12 @@ bool mptcp_doit(struct sock *sk)
}

int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key,
__u8 mptcp_ver, u32 window)
int rem_key_set, __u8 mptcp_ver, u32 window)
{
struct tcp_sock *master_tp;
struct sock *master_sk;

if (mptcp_alloc_mpcb(meta_sk, remote_key, mptcp_ver, window))
if (mptcp_alloc_mpcb(meta_sk, remote_key, rem_key_set, mptcp_ver, window))
goto err_alloc_mpcb;

master_sk = tcp_sk(meta_sk)->mpcb->master_sk;
Expand Down Expand Up @@ -2177,6 +2195,7 @@ int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key,
}

static int __mptcp_check_req_master(struct sock *child,
const struct mptcp_options_received *mopt,
struct request_sock *req)
{
struct tcp_sock *child_tp = tcp_sk(child);
Expand All @@ -2188,6 +2207,8 @@ static int __mptcp_check_req_master(struct sock *child,
if (!inet_rsk(req)->mptcp_rqsk)
return 1;

mtreq = mptcp_rsk(req);

if (!inet_rsk(req)->saw_mpc) {
/* Fallback to regular TCP, because we saw one SYN without
* MP_CAPABLE. In tcp_check_req we continue the regular path.
Expand All @@ -2199,15 +2220,21 @@ static int __mptcp_check_req_master(struct sock *child,
return 1;
}

/* mopt can be NULL when coming from FAST-OPEN */
if (mopt && mopt->saw_mpc && mtreq->mptcp_ver == MPTCP_VERSION_1) {
mtreq->mptcp_rem_key = mopt->mptcp_sender_key;
mtreq->rem_key_set = 1;
}

MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEACK);

/* Just set this values to pass them to mptcp_alloc_mpcb */
mtreq = mptcp_rsk(req);
child_tp->mptcp_loc_key = mtreq->mptcp_loc_key;
child_tp->mptcp_loc_token = mtreq->mptcp_loc_token;

if (mptcp_create_master_sk(meta_sk, mtreq->mptcp_rem_key,
mtreq->mptcp_ver, child_tp->snd_wnd)) {
mtreq->rem_key_set, mtreq->mptcp_ver,
child_tp->snd_wnd)) {
inet_csk_prepare_forced_close(meta_sk);
tcp_done(meta_sk);

Expand Down Expand Up @@ -2242,7 +2269,7 @@ int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req)
u32 new_mapping;
int ret;

ret = __mptcp_check_req_master(child, req);
ret = __mptcp_check_req_master(child, NULL, req);
if (ret)
return ret;

Expand Down Expand Up @@ -2285,12 +2312,13 @@ int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req)

int mptcp_check_req_master(struct sock *sk, struct sock *child,
struct request_sock *req, const struct sk_buff *skb,
const struct mptcp_options_received *mopt,
int drop, u32 tsoff)
{
struct sock *meta_sk = child;
int ret;

ret = __mptcp_check_req_master(child, req);
ret = __mptcp_check_req_master(child, mopt, req);
if (ret)
return ret;
child = tcp_sk(child)->mpcb->master_sk;
Expand Down Expand Up @@ -2658,8 +2686,10 @@ void mptcp_cookies_reqsk_init(struct request_sock *req,
/* Absolutely need to always initialize this. */
mtreq->hash_entry.pprev = NULL;

mtreq->mptcp_ver = mopt->mptcp_ver;
mtreq->mptcp_rem_key = mopt->mptcp_sender_key;
mtreq->mptcp_loc_key = mopt->mptcp_receiver_key;
mtreq->rem_key_set = 1;

/* Generate the token */
mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL);
Expand Down
Loading

0 comments on commit 0a0abb2

Please sign in to comment.