diff options
| author | Christoph Paasch <cpaasch@apple.com> | 2017-10-23 16:22:23 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2017-10-24 05:48:08 -0400 |
| commit | 71c02379c762cb616c00fd5c4ed253fbf6bbe11b (patch) | |
| tree | 516606a09f6d284d35d2d510fe23b11bf9e69f2a /net/ipv4/tcp_fastopen.c | |
| parent | b6f4f8484d88b69f700907200a9a9ec73806355f (diff) | |
tcp: Configure TFO without cookie per socket and/or per route
We already allow to enable TFO without a cookie by using the
fastopen-sysctl and setting it to TFO_SERVER_COOKIE_NOT_REQD (or
TFO_CLIENT_NO_COOKIE).
This is safe to do in certain environments where we know that there
isn't a malicous host (aka., data-centers) or when the
application-protocol already provides an authentication mechanism in the
first flight of data.
A server however might be providing multiple services or talking to both
sides (public Internet and data-center). So, this server would want to
enable cookie-less TFO for certain services and/or for connections that
go to the data-center.
This patch exposes a socket-option and a per-route attribute to enable such
fine-grained configurations.
Signed-off-by: Christoph Paasch <cpaasch@apple.com>
Reviewed-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_fastopen.c')
| -rw-r--r-- | net/ipv4/tcp_fastopen.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index 21075ce19cb6..e0a4b56644aa 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c | |||
| @@ -310,13 +310,23 @@ static bool tcp_fastopen_queue_check(struct sock *sk) | |||
| 310 | return true; | 310 | return true; |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | static bool tcp_fastopen_no_cookie(const struct sock *sk, | ||
| 314 | const struct dst_entry *dst, | ||
| 315 | int flag) | ||
| 316 | { | ||
| 317 | return (sock_net(sk)->ipv4.sysctl_tcp_fastopen & flag) || | ||
| 318 | tcp_sk(sk)->fastopen_no_cookie || | ||
| 319 | (dst && dst_metric(dst, RTAX_FASTOPEN_NO_COOKIE)); | ||
| 320 | } | ||
| 321 | |||
| 313 | /* Returns true if we should perform Fast Open on the SYN. The cookie (foc) | 322 | /* Returns true if we should perform Fast Open on the SYN. The cookie (foc) |
| 314 | * may be updated and return the client in the SYN-ACK later. E.g., Fast Open | 323 | * may be updated and return the client in the SYN-ACK later. E.g., Fast Open |
| 315 | * cookie request (foc->len == 0). | 324 | * cookie request (foc->len == 0). |
| 316 | */ | 325 | */ |
| 317 | struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, | 326 | struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, |
| 318 | struct request_sock *req, | 327 | struct request_sock *req, |
| 319 | struct tcp_fastopen_cookie *foc) | 328 | struct tcp_fastopen_cookie *foc, |
| 329 | const struct dst_entry *dst) | ||
| 320 | { | 330 | { |
| 321 | bool syn_data = TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1; | 331 | bool syn_data = TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1; |
| 322 | int tcp_fastopen = sock_net(sk)->ipv4.sysctl_tcp_fastopen; | 332 | int tcp_fastopen = sock_net(sk)->ipv4.sysctl_tcp_fastopen; |
| @@ -333,7 +343,8 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, | |||
| 333 | return NULL; | 343 | return NULL; |
| 334 | } | 344 | } |
| 335 | 345 | ||
| 336 | if (syn_data && (tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD)) | 346 | if (syn_data && |
| 347 | tcp_fastopen_no_cookie(sk, dst, TFO_SERVER_COOKIE_NOT_REQD)) | ||
| 337 | goto fastopen; | 348 | goto fastopen; |
| 338 | 349 | ||
| 339 | if (foc->len >= 0 && /* Client presents or requests a cookie */ | 350 | if (foc->len >= 0 && /* Client presents or requests a cookie */ |
| @@ -370,6 +381,7 @@ bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss, | |||
| 370 | struct tcp_fastopen_cookie *cookie) | 381 | struct tcp_fastopen_cookie *cookie) |
| 371 | { | 382 | { |
| 372 | unsigned long last_syn_loss = 0; | 383 | unsigned long last_syn_loss = 0; |
| 384 | const struct dst_entry *dst; | ||
| 373 | int syn_loss = 0; | 385 | int syn_loss = 0; |
| 374 | 386 | ||
| 375 | tcp_fastopen_cache_get(sk, mss, cookie, &syn_loss, &last_syn_loss); | 387 | tcp_fastopen_cache_get(sk, mss, cookie, &syn_loss, &last_syn_loss); |
| @@ -387,7 +399,9 @@ bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss, | |||
| 387 | return false; | 399 | return false; |
| 388 | } | 400 | } |
| 389 | 401 | ||
| 390 | if (sock_net(sk)->ipv4.sysctl_tcp_fastopen & TFO_CLIENT_NO_COOKIE) { | 402 | dst = __sk_dst_get(sk); |
| 403 | |||
| 404 | if (tcp_fastopen_no_cookie(sk, dst, TFO_CLIENT_NO_COOKIE)) { | ||
| 391 | cookie->len = -1; | 405 | cookie->len = -1; |
| 392 | return true; | 406 | return true; |
| 393 | } | 407 | } |
