aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
authorDaniel Lee <Longinus00@gmail.com>2015-04-06 17:37:26 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-07 18:36:39 -0400
commit7f9b838b71eb78a27de27a12ca5de8542fac3115 (patch)
tree05567522b8a365930815675c5961c608f9157940 /net/ipv4/tcp_output.c
parent812034f11628aaaab0e2d7af1d3bc50a49eb396b (diff)
tcp: RFC7413 option support for Fast Open server
Fast Open has been using the experimental option with a magic number (RFC6994) to request and grant Fast Open cookies. This patch enables the server to support the official IANA option 34 in RFC7413 in addition. The change has passed all existing Fast Open tests with both old and new options at Google. Signed-off-by: Daniel Lee <Longinus00@gmail.com> Signed-off-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: Neal Cardwell <ncardwell@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r--net/ipv4/tcp_output.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 7404e5238e00..464bd8c5de69 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -518,17 +518,26 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
518 518
519 if (unlikely(OPTION_FAST_OPEN_COOKIE & options)) { 519 if (unlikely(OPTION_FAST_OPEN_COOKIE & options)) {
520 struct tcp_fastopen_cookie *foc = opts->fastopen_cookie; 520 struct tcp_fastopen_cookie *foc = opts->fastopen_cookie;
521 u8 *p = (u8 *)ptr;
522 u32 len; /* Fast Open option length */
523
524 if (foc->exp) {
525 len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len;
526 *ptr = htonl((TCPOPT_EXP << 24) | (len << 16) |
527 TCPOPT_FASTOPEN_MAGIC);
528 p += TCPOLEN_EXP_FASTOPEN_BASE;
529 } else {
530 len = TCPOLEN_FASTOPEN_BASE + foc->len;
531 *p++ = TCPOPT_FASTOPEN;
532 *p++ = len;
533 }
521 534
522 *ptr++ = htonl((TCPOPT_EXP << 24) | 535 memcpy(p, foc->val, foc->len);
523 ((TCPOLEN_EXP_FASTOPEN_BASE + foc->len) << 16) | 536 if ((len & 3) == 2) {
524 TCPOPT_FASTOPEN_MAGIC); 537 p[foc->len] = TCPOPT_NOP;
525 538 p[foc->len + 1] = TCPOPT_NOP;
526 memcpy(ptr, foc->val, foc->len);
527 if ((foc->len & 3) == 2) {
528 u8 *align = ((u8 *)ptr) + foc->len;
529 align[0] = align[1] = TCPOPT_NOP;
530 } 539 }
531 ptr += (foc->len + 3) >> 2; 540 ptr += (len + 3) >> 2;
532 } 541 }
533} 542}
534 543
@@ -641,8 +650,11 @@ static unsigned int tcp_synack_options(struct sock *sk,
641 if (unlikely(!ireq->tstamp_ok)) 650 if (unlikely(!ireq->tstamp_ok))
642 remaining -= TCPOLEN_SACKPERM_ALIGNED; 651 remaining -= TCPOLEN_SACKPERM_ALIGNED;
643 } 652 }
644 if (foc && foc->len >= 0) { 653 if (foc != NULL && foc->len >= 0) {
645 u32 need = TCPOLEN_EXP_FASTOPEN_BASE + foc->len; 654 u32 need = foc->len;
655
656 need += foc->exp ? TCPOLEN_EXP_FASTOPEN_BASE :
657 TCPOLEN_FASTOPEN_BASE;
646 need = (need + 3) & ~3U; /* Align to 32 bits */ 658 need = (need + 3) & ~3U; /* Align to 32 bits */
647 if (remaining >= need) { 659 if (remaining >= need) {
648 opts->options |= OPTION_FAST_OPEN_COOKIE; 660 opts->options |= OPTION_FAST_OPEN_COOKIE;