|
@@ -3603,6 +3603,23 @@ old_ack:
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void tcp_parse_fastopen_option(int len, const unsigned char *cookie,
|
|
|
|
+ bool syn, struct tcp_fastopen_cookie *foc,
|
|
|
|
+ bool exp_opt)
|
|
|
|
+{
|
|
|
|
+ /* Valid only in SYN or SYN-ACK with an even length. */
|
|
|
|
+ if (!foc || !syn || len < 0 || (len & 1))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ if (len >= TCP_FASTOPEN_COOKIE_MIN &&
|
|
|
|
+ len <= TCP_FASTOPEN_COOKIE_MAX)
|
|
|
|
+ memcpy(foc->val, cookie, len);
|
|
|
|
+ else if (len != 0)
|
|
|
|
+ len = -1;
|
|
|
|
+ foc->len = len;
|
|
|
|
+ foc->exp = exp_opt;
|
|
|
|
+}
|
|
|
|
+
|
|
/* Look for tcp options. Normally only called on SYN and SYNACK packets.
|
|
/* Look for tcp options. Normally only called on SYN and SYNACK packets.
|
|
* But, this can also be called on packets in the established flow when
|
|
* But, this can also be called on packets in the established flow when
|
|
* the fast version below fails.
|
|
* the fast version below fails.
|
|
@@ -3692,21 +3709,22 @@ void tcp_parse_options(const struct sk_buff *skb,
|
|
*/
|
|
*/
|
|
break;
|
|
break;
|
|
#endif
|
|
#endif
|
|
|
|
+ case TCPOPT_FASTOPEN:
|
|
|
|
+ tcp_parse_fastopen_option(
|
|
|
|
+ opsize - TCPOLEN_FASTOPEN_BASE,
|
|
|
|
+ ptr, th->syn, foc, false);
|
|
|
|
+ break;
|
|
|
|
+
|
|
case TCPOPT_EXP:
|
|
case TCPOPT_EXP:
|
|
/* Fast Open option shares code 254 using a
|
|
/* Fast Open option shares code 254 using a
|
|
- * 16 bits magic number. It's valid only in
|
|
|
|
- * SYN or SYN-ACK with an even size.
|
|
|
|
|
|
+ * 16 bits magic number.
|
|
*/
|
|
*/
|
|
- if (opsize < TCPOLEN_EXP_FASTOPEN_BASE ||
|
|
|
|
- get_unaligned_be16(ptr) != TCPOPT_FASTOPEN_MAGIC ||
|
|
|
|
- !foc || !th->syn || (opsize & 1))
|
|
|
|
- break;
|
|
|
|
- foc->len = opsize - TCPOLEN_EXP_FASTOPEN_BASE;
|
|
|
|
- if (foc->len >= TCP_FASTOPEN_COOKIE_MIN &&
|
|
|
|
- foc->len <= TCP_FASTOPEN_COOKIE_MAX)
|
|
|
|
- memcpy(foc->val, ptr + 2, foc->len);
|
|
|
|
- else if (foc->len != 0)
|
|
|
|
- foc->len = -1;
|
|
|
|
|
|
+ if (opsize >= TCPOLEN_EXP_FASTOPEN_BASE &&
|
|
|
|
+ get_unaligned_be16(ptr) ==
|
|
|
|
+ TCPOPT_FASTOPEN_MAGIC)
|
|
|
|
+ tcp_parse_fastopen_option(opsize -
|
|
|
|
+ TCPOLEN_EXP_FASTOPEN_BASE,
|
|
|
|
+ ptr + 2, th->syn, foc, true);
|
|
break;
|
|
break;
|
|
|
|
|
|
}
|
|
}
|