Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tcp: Remove TCPCT

TCPCT uses option-number 253, reserved for experimental use and should
not be used in production environments.
Further, TCPCT does not fully implement RFC 6013.

As a nice side-effect, removing TCPCT increases TCP's performance for
very short flows:

Doing an apache-benchmark with -c 100 -n 100000, sending HTTP-requests
for files of 1KB size.

before this patch:
average (among 7 runs) of 20845.5 Requests/Second
after:
average (among 7 runs) of 21403.6 Requests/Second

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Christoph Paasch and committed by
David S. Miller
1a2c6181 94d8f2b1

+37 -840
-8
Documentation/networking/ip-sysctl.txt
··· 175 175 is inherited. 176 176 [see setsockopt(listenfd, SOL_TCP, TCP_CONGESTION, "name" ...) ] 177 177 178 - tcp_cookie_size - INTEGER 179 - Default size of TCP Cookie Transactions (TCPCT) option, that may be 180 - overridden on a per socket basis by the TCPCT socket option. 181 - Values greater than the maximum (16) are interpreted as the maximum. 182 - Values greater than zero and less than the minimum (8) are interpreted 183 - as the minimum. Odd values are interpreted as the next even value. 184 - Default: 0 (off). 185 - 186 178 tcp_dsack - BOOLEAN 187 179 Allows TCP to send "duplicate" SACKs. 188 180
+1 -1
drivers/infiniband/hw/cxgb4/cm.c
··· 2915 2915 */ 2916 2916 memset(&tmp_opt, 0, sizeof(tmp_opt)); 2917 2917 tcp_clear_options(&tmp_opt); 2918 - tcp_parse_options(skb, &tmp_opt, NULL, 0, NULL); 2918 + tcp_parse_options(skb, &tmp_opt, 0, NULL); 2919 2919 2920 2920 req = (struct cpl_pass_accept_req *)__skb_push(skb, sizeof(*req)); 2921 2921 memset(req, 0, sizeof(*req));
-10
include/linux/tcp.h
··· 90 90 sack_ok : 4, /* SACK seen on SYN packet */ 91 91 snd_wscale : 4, /* Window scaling received from sender */ 92 92 rcv_wscale : 4; /* Window scaling to send to receiver */ 93 - u8 cookie_plus:6, /* bytes in authenticator/cookie option */ 94 - cookie_out_never:1, 95 - cookie_in_always:1; 96 93 u8 num_sacks; /* Number of SACK blocks */ 97 94 u16 user_mss; /* mss requested by user in ioctl */ 98 95 u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ ··· 99 102 { 100 103 rx_opt->tstamp_ok = rx_opt->sack_ok = 0; 101 104 rx_opt->wscale_ok = rx_opt->snd_wscale = 0; 102 - rx_opt->cookie_plus = 0; 103 105 } 104 106 105 107 /* This is the max number of SACKS that we'll generate and process. It's safe ··· 315 319 /* TCP MD5 Signature Option information */ 316 320 struct tcp_md5sig_info __rcu *md5sig_info; 317 321 #endif 318 - 319 - /* When the cookie options are generated and exchanged, then this 320 - * object holds a reference to them (cookie_values->kref). Also 321 - * contains related tcp_cookie_transactions fields. 322 - */ 323 - struct tcp_cookie_values *cookie_values; 324 322 325 323 /* TCP fastopen related information */ 326 324 struct tcp_fastopen_request *fastopen_req;
+1 -7
include/net/request_sock.h
··· 27 27 struct dst_entry; 28 28 struct proto; 29 29 30 - /* empty to "strongly type" an otherwise void parameter. 31 - */ 32 - struct request_values { 33 - }; 34 - 35 30 struct request_sock_ops { 36 31 int family; 37 32 int obj_size; 38 33 struct kmem_cache *slab; 39 34 char *slab_name; 40 35 int (*rtx_syn_ack)(struct sock *sk, 41 - struct request_sock *req, 42 - struct request_values *rvp); 36 + struct request_sock *req); 43 37 void (*send_ack)(struct sock *sk, struct sk_buff *skb, 44 38 struct request_sock *req); 45 39 void (*send_reset)(struct sock *sk,
+1 -88
include/net/tcp.h
··· 179 179 #define TCPOPT_SACK 5 /* SACK Block */ 180 180 #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ 181 181 #define TCPOPT_MD5SIG 19 /* MD5 Signature (RFC2385) */ 182 - #define TCPOPT_COOKIE 253 /* Cookie extension (experimental) */ 183 182 #define TCPOPT_EXP 254 /* Experimental */ 184 183 /* Magic number to be after the option value for sharing TCP 185 184 * experimental options. See draft-ietf-tcpm-experimental-options-00.txt ··· 453 454 extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 454 455 size_t len, int nonblock, int flags, int *addr_len); 455 456 extern void tcp_parse_options(const struct sk_buff *skb, 456 - struct tcp_options_received *opt_rx, const u8 **hvpp, 457 + struct tcp_options_received *opt_rx, 457 458 int estab, struct tcp_fastopen_cookie *foc); 458 459 extern const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); 459 460 ··· 475 476 extern int tcp_connect(struct sock *sk); 476 477 extern struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, 477 478 struct request_sock *req, 478 - struct request_values *rvp, 479 479 struct tcp_fastopen_cookie *foc); 480 480 extern int tcp_disconnect(struct sock *sk, int flags); 481 481 ··· 1586 1588 const struct sk_buff *skb); 1587 1589 #endif 1588 1590 }; 1589 - 1590 - /* Using SHA1 for now, define some constants. 1591 - */ 1592 - #define COOKIE_DIGEST_WORDS (SHA_DIGEST_WORDS) 1593 - #define COOKIE_MESSAGE_WORDS (SHA_MESSAGE_BYTES / 4) 1594 - #define COOKIE_WORKSPACE_WORDS (COOKIE_DIGEST_WORDS + COOKIE_MESSAGE_WORDS) 1595 - 1596 - extern int tcp_cookie_generator(u32 *bakery); 1597 - 1598 - /** 1599 - * struct tcp_cookie_values - each socket needs extra space for the 1600 - * cookies, together with (optional) space for any SYN data. 1601 - * 1602 - * A tcp_sock contains a pointer to the current value, and this is 1603 - * cloned to the tcp_timewait_sock. 1604 - * 1605 - * @cookie_pair: variable data from the option exchange. 1606 - * 1607 - * @cookie_desired: user specified tcpct_cookie_desired. Zero 1608 - * indicates default (sysctl_tcp_cookie_size). 1609 - * After cookie sent, remembers size of cookie. 1610 - * Range 0, TCP_COOKIE_MIN to TCP_COOKIE_MAX. 1611 - * 1612 - * @s_data_desired: user specified tcpct_s_data_desired. When the 1613 - * constant payload is specified (@s_data_constant), 1614 - * holds its length instead. 1615 - * Range 0 to TCP_MSS_DESIRED. 1616 - * 1617 - * @s_data_payload: constant data that is to be included in the 1618 - * payload of SYN or SYNACK segments when the 1619 - * cookie option is present. 1620 - */ 1621 - struct tcp_cookie_values { 1622 - struct kref kref; 1623 - u8 cookie_pair[TCP_COOKIE_PAIR_SIZE]; 1624 - u8 cookie_pair_size; 1625 - u8 cookie_desired; 1626 - u16 s_data_desired:11, 1627 - s_data_constant:1, 1628 - s_data_in:1, 1629 - s_data_out:1, 1630 - s_data_unused:2; 1631 - u8 s_data_payload[0]; 1632 - }; 1633 - 1634 - static inline void tcp_cookie_values_release(struct kref *kref) 1635 - { 1636 - kfree(container_of(kref, struct tcp_cookie_values, kref)); 1637 - } 1638 - 1639 - /* The length of constant payload data. Note that s_data_desired is 1640 - * overloaded, depending on s_data_constant: either the length of constant 1641 - * data (returned here) or the limit on variable data. 1642 - */ 1643 - static inline int tcp_s_data_size(const struct tcp_sock *tp) 1644 - { 1645 - return (tp->cookie_values != NULL && tp->cookie_values->s_data_constant) 1646 - ? tp->cookie_values->s_data_desired 1647 - : 0; 1648 - } 1649 - 1650 - /** 1651 - * struct tcp_extend_values - tcp_ipv?.c to tcp_output.c workspace. 1652 - * 1653 - * As tcp_request_sock has already been extended in other places, the 1654 - * only remaining method is to pass stack values along as function 1655 - * parameters. These parameters are not needed after sending SYNACK. 1656 - * 1657 - * @cookie_bakery: cryptographic secret and message workspace. 1658 - * 1659 - * @cookie_plus: bytes in authenticator/cookie option, copied from 1660 - * struct tcp_options_received (above). 1661 - */ 1662 - struct tcp_extend_values { 1663 - struct request_values rv; 1664 - u32 cookie_bakery[COOKIE_WORKSPACE_WORDS]; 1665 - u8 cookie_plus:6, 1666 - cookie_out_never:1, 1667 - cookie_in_always:1; 1668 - }; 1669 - 1670 - static inline struct tcp_extend_values *tcp_xv(struct request_values *rvp) 1671 - { 1672 - return (struct tcp_extend_values *)rvp; 1673 - } 1674 1591 1675 1592 extern void tcp_v4_init(void); 1676 1593 extern void tcp_init(void);
-26
include/uapi/linux/tcp.h
··· 102 102 #define TCP_QUICKACK 12 /* Block/reenable quick acks */ 103 103 #define TCP_CONGESTION 13 /* Congestion control algorithm */ 104 104 #define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */ 105 - #define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */ 106 105 #define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/ 107 106 #define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */ 108 107 #define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */ ··· 197 198 __u32 __tcpm_pad2; /* zero */ 198 199 __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */ 199 200 }; 200 - 201 - /* for TCP_COOKIE_TRANSACTIONS (TCPCT) socket option */ 202 - #define TCP_COOKIE_MIN 8 /* 64-bits */ 203 - #define TCP_COOKIE_MAX 16 /* 128-bits */ 204 - #define TCP_COOKIE_PAIR_SIZE (2*TCP_COOKIE_MAX) 205 - 206 - /* Flags for both getsockopt and setsockopt */ 207 - #define TCP_COOKIE_IN_ALWAYS (1 << 0) /* Discard SYN without cookie */ 208 - #define TCP_COOKIE_OUT_NEVER (1 << 1) /* Prohibit outgoing cookies, 209 - * supercedes everything. */ 210 - 211 - /* Flags for getsockopt */ 212 - #define TCP_S_DATA_IN (1 << 2) /* Was data received? */ 213 - #define TCP_S_DATA_OUT (1 << 3) /* Was data sent? */ 214 - 215 - /* TCP_COOKIE_TRANSACTIONS data */ 216 - struct tcp_cookie_transactions { 217 - __u16 tcpct_flags; /* see above */ 218 - __u8 __tcpct_pad1; /* zero */ 219 - __u8 tcpct_cookie_desired; /* bytes */ 220 - __u16 tcpct_s_data_desired; /* bytes of variable data */ 221 - __u16 tcpct_used; /* bytes in value */ 222 - __u8 tcpct_value[TCP_MSS_DEFAULT]; 223 - }; 224 - 225 201 226 202 #endif /* _UAPI_LINUX_TCP_H */
+2 -3
net/dccp/ipv4.c
··· 500 500 return &rt->dst; 501 501 } 502 502 503 - static int dccp_v4_send_response(struct sock *sk, struct request_sock *req, 504 - struct request_values *rv_unused) 503 + static int dccp_v4_send_response(struct sock *sk, struct request_sock *req) 505 504 { 506 505 int err = -1; 507 506 struct sk_buff *skb; ··· 657 658 dreq->dreq_gss = dreq->dreq_iss; 658 659 dreq->dreq_service = service; 659 660 660 - if (dccp_v4_send_response(sk, req, NULL)) 661 + if (dccp_v4_send_response(sk, req)) 661 662 goto drop_and_free; 662 663 663 664 inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
+2 -3
net/dccp/ipv6.c
··· 213 213 } 214 214 215 215 216 - static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, 217 - struct request_values *rv_unused) 216 + static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) 218 217 { 219 218 struct inet6_request_sock *ireq6 = inet6_rsk(req); 220 219 struct ipv6_pinfo *np = inet6_sk(sk); ··· 427 428 dreq->dreq_gss = dreq->dreq_iss; 428 429 dreq->dreq_service = service; 429 430 430 - if (dccp_v6_send_response(sk, req, NULL)) 431 + if (dccp_v6_send_response(sk, req)) 431 432 goto drop_and_free; 432 433 433 434 inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
+1 -1
net/ipv4/inet_connection_sock.c
··· 559 559 560 560 int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req) 561 561 { 562 - int err = req->rsk_ops->rtx_syn_ack(parent, req, NULL); 562 + int err = req->rsk_ops->rtx_syn_ack(parent, req); 563 563 564 564 if (!err) 565 565 req->num_retrans++;
+1 -2
net/ipv4/syncookies.c
··· 267 267 struct ip_options *opt) 268 268 { 269 269 struct tcp_options_received tcp_opt; 270 - const u8 *hash_location; 271 270 struct inet_request_sock *ireq; 272 271 struct tcp_request_sock *treq; 273 272 struct tcp_sock *tp = tcp_sk(sk); ··· 293 294 294 295 /* check for timestamp cookie support */ 295 296 memset(&tcp_opt, 0, sizeof(tcp_opt)); 296 - tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL); 297 + tcp_parse_options(skb, &tcp_opt, 0, NULL); 297 298 298 299 if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok)) 299 300 goto out;
-7
net/ipv4/sysctl_net_ipv4.c
··· 733 733 .proc_handler = proc_dointvec, 734 734 }, 735 735 { 736 - .procname = "tcp_cookie_size", 737 - .data = &sysctl_tcp_cookie_size, 738 - .maxlen = sizeof(int), 739 - .mode = 0644, 740 - .proc_handler = proc_dointvec 741 - }, 742 - { 743 736 .procname = "tcp_thin_linear_timeouts", 744 737 .data = &sysctl_tcp_thin_linear_timeouts, 745 738 .maxlen = sizeof(int),
-267
net/ipv4/tcp.c
··· 409 409 410 410 icsk->icsk_sync_mss = tcp_sync_mss; 411 411 412 - /* TCP Cookie Transactions */ 413 - if (sysctl_tcp_cookie_size > 0) { 414 - /* Default, cookies without s_data_payload. */ 415 - tp->cookie_values = 416 - kzalloc(sizeof(*tp->cookie_values), 417 - sk->sk_allocation); 418 - if (tp->cookie_values != NULL) 419 - kref_init(&tp->cookie_values->kref); 420 - } 421 412 /* Presumed zeroed, in order of appearance: 422 413 * cookie_in_always, cookie_out_never, 423 414 * s_data_constant, s_data_in, s_data_out ··· 2388 2397 release_sock(sk); 2389 2398 return err; 2390 2399 } 2391 - case TCP_COOKIE_TRANSACTIONS: { 2392 - struct tcp_cookie_transactions ctd; 2393 - struct tcp_cookie_values *cvp = NULL; 2394 - 2395 - if (sizeof(ctd) > optlen) 2396 - return -EINVAL; 2397 - if (copy_from_user(&ctd, optval, sizeof(ctd))) 2398 - return -EFAULT; 2399 - 2400 - if (ctd.tcpct_used > sizeof(ctd.tcpct_value) || 2401 - ctd.tcpct_s_data_desired > TCP_MSS_DESIRED) 2402 - return -EINVAL; 2403 - 2404 - if (ctd.tcpct_cookie_desired == 0) { 2405 - /* default to global value */ 2406 - } else if ((0x1 & ctd.tcpct_cookie_desired) || 2407 - ctd.tcpct_cookie_desired > TCP_COOKIE_MAX || 2408 - ctd.tcpct_cookie_desired < TCP_COOKIE_MIN) { 2409 - return -EINVAL; 2410 - } 2411 - 2412 - if (TCP_COOKIE_OUT_NEVER & ctd.tcpct_flags) { 2413 - /* Supercedes all other values */ 2414 - lock_sock(sk); 2415 - if (tp->cookie_values != NULL) { 2416 - kref_put(&tp->cookie_values->kref, 2417 - tcp_cookie_values_release); 2418 - tp->cookie_values = NULL; 2419 - } 2420 - tp->rx_opt.cookie_in_always = 0; /* false */ 2421 - tp->rx_opt.cookie_out_never = 1; /* true */ 2422 - release_sock(sk); 2423 - return err; 2424 - } 2425 - 2426 - /* Allocate ancillary memory before locking. 2427 - */ 2428 - if (ctd.tcpct_used > 0 || 2429 - (tp->cookie_values == NULL && 2430 - (sysctl_tcp_cookie_size > 0 || 2431 - ctd.tcpct_cookie_desired > 0 || 2432 - ctd.tcpct_s_data_desired > 0))) { 2433 - cvp = kzalloc(sizeof(*cvp) + ctd.tcpct_used, 2434 - GFP_KERNEL); 2435 - if (cvp == NULL) 2436 - return -ENOMEM; 2437 - 2438 - kref_init(&cvp->kref); 2439 - } 2440 - lock_sock(sk); 2441 - tp->rx_opt.cookie_in_always = 2442 - (TCP_COOKIE_IN_ALWAYS & ctd.tcpct_flags); 2443 - tp->rx_opt.cookie_out_never = 0; /* false */ 2444 - 2445 - if (tp->cookie_values != NULL) { 2446 - if (cvp != NULL) { 2447 - /* Changed values are recorded by a changed 2448 - * pointer, ensuring the cookie will differ, 2449 - * without separately hashing each value later. 2450 - */ 2451 - kref_put(&tp->cookie_values->kref, 2452 - tcp_cookie_values_release); 2453 - } else { 2454 - cvp = tp->cookie_values; 2455 - } 2456 - } 2457 - 2458 - if (cvp != NULL) { 2459 - cvp->cookie_desired = ctd.tcpct_cookie_desired; 2460 - 2461 - if (ctd.tcpct_used > 0) { 2462 - memcpy(cvp->s_data_payload, ctd.tcpct_value, 2463 - ctd.tcpct_used); 2464 - cvp->s_data_desired = ctd.tcpct_used; 2465 - cvp->s_data_constant = 1; /* true */ 2466 - } else { 2467 - /* No constant payload data. */ 2468 - cvp->s_data_desired = ctd.tcpct_s_data_desired; 2469 - cvp->s_data_constant = 0; /* false */ 2470 - } 2471 - 2472 - tp->cookie_values = cvp; 2473 - } 2474 - release_sock(sk); 2475 - return err; 2476 - } 2477 2400 default: 2478 2401 /* fallthru */ 2479 2402 break; ··· 2807 2902 return -EFAULT; 2808 2903 return 0; 2809 2904 2810 - case TCP_COOKIE_TRANSACTIONS: { 2811 - struct tcp_cookie_transactions ctd; 2812 - struct tcp_cookie_values *cvp = tp->cookie_values; 2813 - 2814 - if (get_user(len, optlen)) 2815 - return -EFAULT; 2816 - if (len < sizeof(ctd)) 2817 - return -EINVAL; 2818 - 2819 - memset(&ctd, 0, sizeof(ctd)); 2820 - ctd.tcpct_flags = (tp->rx_opt.cookie_in_always ? 2821 - TCP_COOKIE_IN_ALWAYS : 0) 2822 - | (tp->rx_opt.cookie_out_never ? 2823 - TCP_COOKIE_OUT_NEVER : 0); 2824 - 2825 - if (cvp != NULL) { 2826 - ctd.tcpct_flags |= (cvp->s_data_in ? 2827 - TCP_S_DATA_IN : 0) 2828 - | (cvp->s_data_out ? 2829 - TCP_S_DATA_OUT : 0); 2830 - 2831 - ctd.tcpct_cookie_desired = cvp->cookie_desired; 2832 - ctd.tcpct_s_data_desired = cvp->s_data_desired; 2833 - 2834 - memcpy(&ctd.tcpct_value[0], &cvp->cookie_pair[0], 2835 - cvp->cookie_pair_size); 2836 - ctd.tcpct_used = cvp->cookie_pair_size; 2837 - } 2838 - 2839 - if (put_user(sizeof(ctd), optlen)) 2840 - return -EFAULT; 2841 - if (copy_to_user(optval, &ctd, sizeof(ctd))) 2842 - return -EFAULT; 2843 - return 0; 2844 - } 2845 2905 case TCP_THIN_LINEAR_TIMEOUTS: 2846 2906 val = tp->thin_lto; 2847 2907 break; ··· 3279 3409 3280 3410 #endif 3281 3411 3282 - /* Each Responder maintains up to two secret values concurrently for 3283 - * efficient secret rollover. Each secret value has 4 states: 3284 - * 3285 - * Generating. (tcp_secret_generating != tcp_secret_primary) 3286 - * Generates new Responder-Cookies, but not yet used for primary 3287 - * verification. This is a short-term state, typically lasting only 3288 - * one round trip time (RTT). 3289 - * 3290 - * Primary. (tcp_secret_generating == tcp_secret_primary) 3291 - * Used both for generation and primary verification. 3292 - * 3293 - * Retiring. (tcp_secret_retiring != tcp_secret_secondary) 3294 - * Used for verification, until the first failure that can be 3295 - * verified by the newer Generating secret. At that time, this 3296 - * cookie's state is changed to Secondary, and the Generating 3297 - * cookie's state is changed to Primary. This is a short-term state, 3298 - * typically lasting only one round trip time (RTT). 3299 - * 3300 - * Secondary. (tcp_secret_retiring == tcp_secret_secondary) 3301 - * Used for secondary verification, after primary verification 3302 - * failures. This state lasts no more than twice the Maximum Segment 3303 - * Lifetime (2MSL). Then, the secret is discarded. 3304 - */ 3305 - struct tcp_cookie_secret { 3306 - /* The secret is divided into two parts. The digest part is the 3307 - * equivalent of previously hashing a secret and saving the state, 3308 - * and serves as an initialization vector (IV). The message part 3309 - * serves as the trailing secret. 3310 - */ 3311 - u32 secrets[COOKIE_WORKSPACE_WORDS]; 3312 - unsigned long expires; 3313 - }; 3314 - 3315 - #define TCP_SECRET_1MSL (HZ * TCP_PAWS_MSL) 3316 - #define TCP_SECRET_2MSL (HZ * TCP_PAWS_MSL * 2) 3317 - #define TCP_SECRET_LIFE (HZ * 600) 3318 - 3319 - static struct tcp_cookie_secret tcp_secret_one; 3320 - static struct tcp_cookie_secret tcp_secret_two; 3321 - 3322 - /* Essentially a circular list, without dynamic allocation. */ 3323 - static struct tcp_cookie_secret *tcp_secret_generating; 3324 - static struct tcp_cookie_secret *tcp_secret_primary; 3325 - static struct tcp_cookie_secret *tcp_secret_retiring; 3326 - static struct tcp_cookie_secret *tcp_secret_secondary; 3327 - 3328 - static DEFINE_SPINLOCK(tcp_secret_locker); 3329 - 3330 - /* Select a pseudo-random word in the cookie workspace. 3331 - */ 3332 - static inline u32 tcp_cookie_work(const u32 *ws, const int n) 3333 - { 3334 - return ws[COOKIE_DIGEST_WORDS + ((COOKIE_MESSAGE_WORDS-1) & ws[n])]; 3335 - } 3336 - 3337 - /* Fill bakery[COOKIE_WORKSPACE_WORDS] with generator, updating as needed. 3338 - * Called in softirq context. 3339 - * Returns: 0 for success. 3340 - */ 3341 - int tcp_cookie_generator(u32 *bakery) 3342 - { 3343 - unsigned long jiffy = jiffies; 3344 - 3345 - if (unlikely(time_after_eq(jiffy, tcp_secret_generating->expires))) { 3346 - spin_lock_bh(&tcp_secret_locker); 3347 - if (!time_after_eq(jiffy, tcp_secret_generating->expires)) { 3348 - /* refreshed by another */ 3349 - memcpy(bakery, 3350 - &tcp_secret_generating->secrets[0], 3351 - COOKIE_WORKSPACE_WORDS); 3352 - } else { 3353 - /* still needs refreshing */ 3354 - get_random_bytes(bakery, COOKIE_WORKSPACE_WORDS); 3355 - 3356 - /* The first time, paranoia assumes that the 3357 - * randomization function isn't as strong. But, 3358 - * this secret initialization is delayed until 3359 - * the last possible moment (packet arrival). 3360 - * Although that time is observable, it is 3361 - * unpredictably variable. Mash in the most 3362 - * volatile clock bits available, and expire the 3363 - * secret extra quickly. 3364 - */ 3365 - if (unlikely(tcp_secret_primary->expires == 3366 - tcp_secret_secondary->expires)) { 3367 - struct timespec tv; 3368 - 3369 - getnstimeofday(&tv); 3370 - bakery[COOKIE_DIGEST_WORDS+0] ^= 3371 - (u32)tv.tv_nsec; 3372 - 3373 - tcp_secret_secondary->expires = jiffy 3374 - + TCP_SECRET_1MSL 3375 - + (0x0f & tcp_cookie_work(bakery, 0)); 3376 - } else { 3377 - tcp_secret_secondary->expires = jiffy 3378 - + TCP_SECRET_LIFE 3379 - + (0xff & tcp_cookie_work(bakery, 1)); 3380 - tcp_secret_primary->expires = jiffy 3381 - + TCP_SECRET_2MSL 3382 - + (0x1f & tcp_cookie_work(bakery, 2)); 3383 - } 3384 - memcpy(&tcp_secret_secondary->secrets[0], 3385 - bakery, COOKIE_WORKSPACE_WORDS); 3386 - 3387 - rcu_assign_pointer(tcp_secret_generating, 3388 - tcp_secret_secondary); 3389 - rcu_assign_pointer(tcp_secret_retiring, 3390 - tcp_secret_primary); 3391 - /* 3392 - * Neither call_rcu() nor synchronize_rcu() needed. 3393 - * Retiring data is not freed. It is replaced after 3394 - * further (locked) pointer updates, and a quiet time 3395 - * (minimum 1MSL, maximum LIFE - 2MSL). 3396 - */ 3397 - } 3398 - spin_unlock_bh(&tcp_secret_locker); 3399 - } else { 3400 - rcu_read_lock_bh(); 3401 - memcpy(bakery, 3402 - &rcu_dereference(tcp_secret_generating)->secrets[0], 3403 - COOKIE_WORKSPACE_WORDS); 3404 - rcu_read_unlock_bh(); 3405 - } 3406 - return 0; 3407 - } 3408 - EXPORT_SYMBOL(tcp_cookie_generator); 3409 - 3410 3412 void tcp_done(struct sock *sk) 3411 3413 { 3412 3414 struct request_sock *req = tcp_sk(sk)->fastopen_rsk; ··· 3333 3591 unsigned long limit; 3334 3592 int max_rshare, max_wshare, cnt; 3335 3593 unsigned int i; 3336 - unsigned long jiffy = jiffies; 3337 3594 3338 3595 BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); 3339 3596 ··· 3408 3667 3409 3668 tcp_register_congestion_control(&tcp_reno); 3410 3669 3411 - memset(&tcp_secret_one.secrets[0], 0, sizeof(tcp_secret_one.secrets)); 3412 - memset(&tcp_secret_two.secrets[0], 0, sizeof(tcp_secret_two.secrets)); 3413 - tcp_secret_one.expires = jiffy; /* past due */ 3414 - tcp_secret_two.expires = jiffy; /* past due */ 3415 - tcp_secret_generating = &tcp_secret_one; 3416 - tcp_secret_primary = &tcp_secret_one; 3417 - tcp_secret_retiring = &tcp_secret_two; 3418 - tcp_secret_secondary = &tcp_secret_two; 3419 3670 tcp_tasklet_init(); 3420 3671 }
+7 -62
net/ipv4/tcp_input.c
··· 3760 3760 * But, this can also be called on packets in the established flow when 3761 3761 * the fast version below fails. 3762 3762 */ 3763 - void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *opt_rx, 3764 - const u8 **hvpp, int estab, 3763 + void tcp_parse_options(const struct sk_buff *skb, 3764 + struct tcp_options_received *opt_rx, int estab, 3765 3765 struct tcp_fastopen_cookie *foc) 3766 3766 { 3767 3767 const unsigned char *ptr; ··· 3845 3845 */ 3846 3846 break; 3847 3847 #endif 3848 - case TCPOPT_COOKIE: 3849 - /* This option is variable length. 3850 - */ 3851 - switch (opsize) { 3852 - case TCPOLEN_COOKIE_BASE: 3853 - /* not yet implemented */ 3854 - break; 3855 - case TCPOLEN_COOKIE_PAIR: 3856 - /* not yet implemented */ 3857 - break; 3858 - case TCPOLEN_COOKIE_MIN+0: 3859 - case TCPOLEN_COOKIE_MIN+2: 3860 - case TCPOLEN_COOKIE_MIN+4: 3861 - case TCPOLEN_COOKIE_MIN+6: 3862 - case TCPOLEN_COOKIE_MAX: 3863 - /* 16-bit multiple */ 3864 - opt_rx->cookie_plus = opsize; 3865 - *hvpp = ptr; 3866 - break; 3867 - default: 3868 - /* ignore option */ 3869 - break; 3870 - } 3871 - break; 3872 - 3873 3848 case TCPOPT_EXP: 3874 3849 /* Fast Open option shares code 254 using a 3875 3850 * 16 bits magic number. It's valid only in ··· 3890 3915 * If it is wrong it falls back on tcp_parse_options(). 3891 3916 */ 3892 3917 static bool tcp_fast_parse_options(const struct sk_buff *skb, 3893 - const struct tcphdr *th, 3894 - struct tcp_sock *tp, const u8 **hvpp) 3918 + const struct tcphdr *th, struct tcp_sock *tp) 3895 3919 { 3896 3920 /* In the spirit of fast parsing, compare doff directly to constant 3897 3921 * values. Because equality is used, short doff can be ignored here. ··· 3904 3930 return true; 3905 3931 } 3906 3932 3907 - tcp_parse_options(skb, &tp->rx_opt, hvpp, 1, NULL); 3933 + tcp_parse_options(skb, &tp->rx_opt, 1, NULL); 3908 3934 if (tp->rx_opt.saw_tstamp) 3909 3935 tp->rx_opt.rcv_tsecr -= tp->tsoffset; 3910 3936 ··· 5285 5311 static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, 5286 5312 const struct tcphdr *th, int syn_inerr) 5287 5313 { 5288 - const u8 *hash_location; 5289 5314 struct tcp_sock *tp = tcp_sk(sk); 5290 5315 5291 5316 /* RFC1323: H1. Apply PAWS check first. */ 5292 - if (tcp_fast_parse_options(skb, th, tp, &hash_location) && 5293 - tp->rx_opt.saw_tstamp && 5317 + if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp && 5294 5318 tcp_paws_discard(sk, skb)) { 5295 5319 if (!th->rst) { 5296 5320 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED); ··· 5642 5670 5643 5671 if (mss == tp->rx_opt.user_mss) { 5644 5672 struct tcp_options_received opt; 5645 - const u8 *hash_location; 5646 5673 5647 5674 /* Get original SYNACK MSS value if user MSS sets mss_clamp */ 5648 5675 tcp_clear_options(&opt); 5649 5676 opt.user_mss = opt.mss_clamp = 0; 5650 - tcp_parse_options(synack, &opt, &hash_location, 0, NULL); 5677 + tcp_parse_options(synack, &opt, 0, NULL); 5651 5678 mss = opt.mss_clamp; 5652 5679 } 5653 5680 ··· 5677 5706 static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, 5678 5707 const struct tcphdr *th, unsigned int len) 5679 5708 { 5680 - const u8 *hash_location; 5681 5709 struct inet_connection_sock *icsk = inet_csk(sk); 5682 5710 struct tcp_sock *tp = tcp_sk(sk); 5683 - struct tcp_cookie_values *cvp = tp->cookie_values; 5684 5711 struct tcp_fastopen_cookie foc = { .len = -1 }; 5685 5712 int saved_clamp = tp->rx_opt.mss_clamp; 5686 5713 5687 - tcp_parse_options(skb, &tp->rx_opt, &hash_location, 0, &foc); 5714 + tcp_parse_options(skb, &tp->rx_opt, 0, &foc); 5688 5715 if (tp->rx_opt.saw_tstamp) 5689 5716 tp->rx_opt.rcv_tsecr -= tp->tsoffset; 5690 5717 ··· 5778 5809 * Change state from SYN-SENT only after copied_seq 5779 5810 * is initialized. */ 5780 5811 tp->copied_seq = tp->rcv_nxt; 5781 - 5782 - if (cvp != NULL && 5783 - cvp->cookie_pair_size > 0 && 5784 - tp->rx_opt.cookie_plus > 0) { 5785 - int cookie_size = tp->rx_opt.cookie_plus 5786 - - TCPOLEN_COOKIE_BASE; 5787 - int cookie_pair_size = cookie_size 5788 - + cvp->cookie_desired; 5789 - 5790 - /* A cookie extension option was sent and returned. 5791 - * Note that each incoming SYNACK replaces the 5792 - * Responder cookie. The initial exchange is most 5793 - * fragile, as protection against spoofing relies 5794 - * entirely upon the sequence and timestamp (above). 5795 - * This replacement strategy allows the correct pair to 5796 - * pass through, while any others will be filtered via 5797 - * Responder verification later. 5798 - */ 5799 - if (sizeof(cvp->cookie_pair) >= cookie_pair_size) { 5800 - memcpy(&cvp->cookie_pair[cvp->cookie_desired], 5801 - hash_location, cookie_size); 5802 - cvp->cookie_pair_size = cookie_pair_size; 5803 - } 5804 - } 5805 5812 5806 5813 smp_mb(); 5807 5814
+6 -54
net/ipv4/tcp_ipv4.c
··· 838 838 */ 839 839 static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, 840 840 struct request_sock *req, 841 - struct request_values *rvp, 842 841 u16 queue_mapping, 843 842 bool nocache) 844 843 { ··· 850 851 if (!dst && (dst = inet_csk_route_req(sk, &fl4, req)) == NULL) 851 852 return -1; 852 853 853 - skb = tcp_make_synack(sk, dst, req, rvp, NULL); 854 + skb = tcp_make_synack(sk, dst, req, NULL); 854 855 855 856 if (skb) { 856 857 __tcp_v4_send_check(skb, ireq->loc_addr, ireq->rmt_addr); ··· 867 868 return err; 868 869 } 869 870 870 - static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req, 871 - struct request_values *rvp) 871 + static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req) 872 872 { 873 - int res = tcp_v4_send_synack(sk, NULL, req, rvp, 0, false); 873 + int res = tcp_v4_send_synack(sk, NULL, req, 0, false); 874 874 875 875 if (!res) 876 876 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); ··· 1369 1371 static int tcp_v4_conn_req_fastopen(struct sock *sk, 1370 1372 struct sk_buff *skb, 1371 1373 struct sk_buff *skb_synack, 1372 - struct request_sock *req, 1373 - struct request_values *rvp) 1374 + struct request_sock *req) 1374 1375 { 1375 1376 struct tcp_sock *tp = tcp_sk(sk); 1376 1377 struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; ··· 1464 1467 1465 1468 int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) 1466 1469 { 1467 - struct tcp_extend_values tmp_ext; 1468 1470 struct tcp_options_received tmp_opt; 1469 - const u8 *hash_location; 1470 1471 struct request_sock *req; 1471 1472 struct inet_request_sock *ireq; 1472 1473 struct tcp_sock *tp = tcp_sk(sk); ··· 1514 1519 tcp_clear_options(&tmp_opt); 1515 1520 tmp_opt.mss_clamp = TCP_MSS_DEFAULT; 1516 1521 tmp_opt.user_mss = tp->rx_opt.user_mss; 1517 - tcp_parse_options(skb, &tmp_opt, &hash_location, 0, 1518 - want_cookie ? NULL : &foc); 1519 - 1520 - if (tmp_opt.cookie_plus > 0 && 1521 - tmp_opt.saw_tstamp && 1522 - !tp->rx_opt.cookie_out_never && 1523 - (sysctl_tcp_cookie_size > 0 || 1524 - (tp->cookie_values != NULL && 1525 - tp->cookie_values->cookie_desired > 0))) { 1526 - u8 *c; 1527 - u32 *mess = &tmp_ext.cookie_bakery[COOKIE_DIGEST_WORDS]; 1528 - int l = tmp_opt.cookie_plus - TCPOLEN_COOKIE_BASE; 1529 - 1530 - if (tcp_cookie_generator(&tmp_ext.cookie_bakery[0]) != 0) 1531 - goto drop_and_release; 1532 - 1533 - /* Secret recipe starts with IP addresses */ 1534 - *mess++ ^= (__force u32)daddr; 1535 - *mess++ ^= (__force u32)saddr; 1536 - 1537 - /* plus variable length Initiator Cookie */ 1538 - c = (u8 *)mess; 1539 - while (l-- > 0) 1540 - *c++ ^= *hash_location++; 1541 - 1542 - want_cookie = false; /* not our kind of cookie */ 1543 - tmp_ext.cookie_out_never = 0; /* false */ 1544 - tmp_ext.cookie_plus = tmp_opt.cookie_plus; 1545 - } else if (!tp->rx_opt.cookie_in_always) { 1546 - /* redundant indications, but ensure initialization. */ 1547 - tmp_ext.cookie_out_never = 1; /* true */ 1548 - tmp_ext.cookie_plus = 0; 1549 - } else { 1550 - goto drop_and_release; 1551 - } 1552 - tmp_ext.cookie_in_always = tp->rx_opt.cookie_in_always; 1522 + tcp_parse_options(skb, &tmp_opt, 0, want_cookie ? NULL : &foc); 1553 1523 1554 1524 if (want_cookie && !tmp_opt.saw_tstamp) 1555 1525 tcp_clear_options(&tmp_opt); ··· 1596 1636 * of tcp_v4_send_synack()->tcp_select_initial_window(). 1597 1637 */ 1598 1638 skb_synack = tcp_make_synack(sk, dst, req, 1599 - (struct request_values *)&tmp_ext, 1600 1639 fastopen_cookie_present(&valid_foc) ? &valid_foc : NULL); 1601 1640 1602 1641 if (skb_synack) { ··· 1619 1660 if (fastopen_cookie_present(&foc) && foc.len != 0) 1620 1661 NET_INC_STATS_BH(sock_net(sk), 1621 1662 LINUX_MIB_TCPFASTOPENPASSIVEFAIL); 1622 - } else if (tcp_v4_conn_req_fastopen(sk, skb, skb_synack, req, 1623 - (struct request_values *)&tmp_ext)) 1663 + } else if (tcp_v4_conn_req_fastopen(sk, skb, skb_synack, req)) 1624 1664 goto drop_and_free; 1625 1665 1626 1666 return 0; ··· 2199 2241 if (inet_csk(sk)->icsk_bind_hash) 2200 2242 inet_put_port(sk); 2201 2243 2202 - /* TCP Cookie Transactions */ 2203 - if (tp->cookie_values != NULL) { 2204 - kref_put(&tp->cookie_values->kref, 2205 - tcp_cookie_values_release); 2206 - tp->cookie_values = NULL; 2207 - } 2208 2244 BUG_ON(tp->fastopen_rsk != NULL); 2209 2245 2210 2246 /* If socket is aborted during connect operation */
+5 -35
net/ipv4/tcp_minisocks.c
··· 93 93 const struct tcphdr *th) 94 94 { 95 95 struct tcp_options_received tmp_opt; 96 - const u8 *hash_location; 97 96 struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); 98 97 bool paws_reject = false; 99 98 100 99 tmp_opt.saw_tstamp = 0; 101 100 if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { 102 - tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL); 101 + tcp_parse_options(skb, &tmp_opt, 0, NULL); 103 102 104 103 if (tmp_opt.saw_tstamp) { 105 104 tmp_opt.rcv_tsecr -= tcptw->tw_ts_offset; ··· 387 388 struct tcp_request_sock *treq = tcp_rsk(req); 388 389 struct inet_connection_sock *newicsk = inet_csk(newsk); 389 390 struct tcp_sock *newtp = tcp_sk(newsk); 390 - struct tcp_sock *oldtp = tcp_sk(sk); 391 - struct tcp_cookie_values *oldcvp = oldtp->cookie_values; 392 - 393 - /* TCP Cookie Transactions require space for the cookie pair, 394 - * as it differs for each connection. There is no need to 395 - * copy any s_data_payload stored at the original socket. 396 - * Failure will prevent resuming the connection. 397 - * 398 - * Presumed copied, in order of appearance: 399 - * cookie_in_always, cookie_out_never 400 - */ 401 - if (oldcvp != NULL) { 402 - struct tcp_cookie_values *newcvp = 403 - kzalloc(sizeof(*newtp->cookie_values), 404 - GFP_ATOMIC); 405 - 406 - if (newcvp != NULL) { 407 - kref_init(&newcvp->kref); 408 - newcvp->cookie_desired = 409 - oldcvp->cookie_desired; 410 - newtp->cookie_values = newcvp; 411 - } else { 412 - /* Not Yet Implemented */ 413 - newtp->cookie_values = NULL; 414 - } 415 - } 416 391 417 392 /* Now setup tcp_sock */ 418 393 newtp->pred_flags = 0; ··· 395 422 newtp->rcv_nxt = treq->rcv_isn + 1; 396 423 397 424 newtp->snd_sml = newtp->snd_una = 398 - newtp->snd_nxt = newtp->snd_up = 399 - treq->snt_isn + 1 + tcp_s_data_size(oldtp); 425 + newtp->snd_nxt = newtp->snd_up = treq->snt_isn + 1; 400 426 401 427 tcp_prequeue_init(newtp); 402 428 INIT_LIST_HEAD(&newtp->tsq_node); ··· 432 460 tcp_set_ca_state(newsk, TCP_CA_Open); 433 461 tcp_init_xmit_timers(newsk); 434 462 skb_queue_head_init(&newtp->out_of_order_queue); 435 - newtp->write_seq = newtp->pushed_seq = 436 - treq->snt_isn + 1 + tcp_s_data_size(oldtp); 463 + newtp->write_seq = newtp->pushed_seq = treq->snt_isn + 1; 437 464 438 465 newtp->rx_opt.saw_tstamp = 0; 439 466 ··· 509 538 bool fastopen) 510 539 { 511 540 struct tcp_options_received tmp_opt; 512 - const u8 *hash_location; 513 541 struct sock *child; 514 542 const struct tcphdr *th = tcp_hdr(skb); 515 543 __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); ··· 518 548 519 549 tmp_opt.saw_tstamp = 0; 520 550 if (th->doff > (sizeof(struct tcphdr)>>2)) { 521 - tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL); 551 + tcp_parse_options(skb, &tmp_opt, 0, NULL); 522 552 523 553 if (tmp_opt.saw_tstamp) { 524 554 tmp_opt.ts_recent = req->ts_recent; ··· 618 648 */ 619 649 if ((flg & TCP_FLAG_ACK) && !fastopen && 620 650 (TCP_SKB_CB(skb)->ack_seq != 621 - tcp_rsk(req)->snt_isn + 1 + tcp_s_data_size(tcp_sk(sk)))) 651 + tcp_rsk(req)->snt_isn + 1)) 622 652 return sk; 623 653 624 654 /* Also, it would be not so bad idea to check rcv_tsecr, which
+5 -212
net/ipv4/tcp_output.c
··· 65 65 /* By default, RFC2861 behavior. */ 66 66 int sysctl_tcp_slow_start_after_idle __read_mostly = 1; 67 67 68 - int sysctl_tcp_cookie_size __read_mostly = 0; /* TCP_COOKIE_MAX */ 69 - EXPORT_SYMBOL_GPL(sysctl_tcp_cookie_size); 70 - 71 68 static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, 72 69 int push_one, gfp_t gfp); 73 70 ··· 383 386 #define OPTION_TS (1 << 1) 384 387 #define OPTION_MD5 (1 << 2) 385 388 #define OPTION_WSCALE (1 << 3) 386 - #define OPTION_COOKIE_EXTENSION (1 << 4) 387 389 #define OPTION_FAST_OPEN_COOKIE (1 << 8) 388 390 389 391 struct tcp_out_options { ··· 395 399 __u32 tsval, tsecr; /* need to include OPTION_TS */ 396 400 struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ 397 401 }; 398 - 399 - /* The sysctl int routines are generic, so check consistency here. 400 - */ 401 - static u8 tcp_cookie_size_check(u8 desired) 402 - { 403 - int cookie_size; 404 - 405 - if (desired > 0) 406 - /* previously specified */ 407 - return desired; 408 - 409 - cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size); 410 - if (cookie_size <= 0) 411 - /* no default specified */ 412 - return 0; 413 - 414 - if (cookie_size <= TCP_COOKIE_MIN) 415 - /* value too small, specify minimum */ 416 - return TCP_COOKIE_MIN; 417 - 418 - if (cookie_size >= TCP_COOKIE_MAX) 419 - /* value too large, specify maximum */ 420 - return TCP_COOKIE_MAX; 421 - 422 - if (cookie_size & 1) 423 - /* 8-bit multiple, illegal, fix it */ 424 - cookie_size++; 425 - 426 - return (u8)cookie_size; 427 - } 428 402 429 403 /* Write previously computed TCP options to the packet. 430 404 * ··· 414 448 { 415 449 u16 options = opts->options; /* mungable copy */ 416 450 417 - /* Having both authentication and cookies for security is redundant, 418 - * and there's certainly not enough room. Instead, the cookie-less 419 - * extension variant is proposed. 420 - * 421 - * Consider the pessimal case with authentication. The options 422 - * could look like: 423 - * COOKIE|MD5(20) + MSS(4) + SACK|TS(12) + WSCALE(4) == 40 424 - */ 425 451 if (unlikely(OPTION_MD5 & options)) { 426 - if (unlikely(OPTION_COOKIE_EXTENSION & options)) { 427 - *ptr++ = htonl((TCPOPT_COOKIE << 24) | 428 - (TCPOLEN_COOKIE_BASE << 16) | 429 - (TCPOPT_MD5SIG << 8) | 430 - TCPOLEN_MD5SIG); 431 - } else { 432 - *ptr++ = htonl((TCPOPT_NOP << 24) | 433 - (TCPOPT_NOP << 16) | 434 - (TCPOPT_MD5SIG << 8) | 435 - TCPOLEN_MD5SIG); 436 - } 437 - options &= ~OPTION_COOKIE_EXTENSION; 452 + *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | 453 + (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG); 438 454 /* overload cookie hash location */ 439 455 opts->hash_location = (__u8 *)ptr; 440 456 ptr += 4; ··· 443 495 } 444 496 *ptr++ = htonl(opts->tsval); 445 497 *ptr++ = htonl(opts->tsecr); 446 - } 447 - 448 - /* Specification requires after timestamp, so do it now. 449 - * 450 - * Consider the pessimal case without authentication. The options 451 - * could look like: 452 - * MSS(4) + SACK|TS(12) + COOKIE(20) + WSCALE(4) == 40 453 - */ 454 - if (unlikely(OPTION_COOKIE_EXTENSION & options)) { 455 - __u8 *cookie_copy = opts->hash_location; 456 - u8 cookie_size = opts->hash_size; 457 - 458 - /* 8-bit multiple handled in tcp_cookie_size_check() above, 459 - * and elsewhere. 460 - */ 461 - if (0x2 & cookie_size) { 462 - __u8 *p = (__u8 *)ptr; 463 - 464 - /* 16-bit multiple */ 465 - *p++ = TCPOPT_COOKIE; 466 - *p++ = TCPOLEN_COOKIE_BASE + cookie_size; 467 - *p++ = *cookie_copy++; 468 - *p++ = *cookie_copy++; 469 - ptr++; 470 - cookie_size -= 2; 471 - } else { 472 - /* 32-bit multiple */ 473 - *ptr++ = htonl(((TCPOPT_NOP << 24) | 474 - (TCPOPT_NOP << 16) | 475 - (TCPOPT_COOKIE << 8) | 476 - TCPOLEN_COOKIE_BASE) + 477 - cookie_size); 478 - } 479 - 480 - if (cookie_size > 0) { 481 - memcpy(ptr, cookie_copy, cookie_size); 482 - ptr += (cookie_size / 4); 483 - } 484 498 } 485 499 486 500 if (unlikely(OPTION_SACK_ADVERTISE & options)) { ··· 503 593 struct tcp_md5sig_key **md5) 504 594 { 505 595 struct tcp_sock *tp = tcp_sk(sk); 506 - struct tcp_cookie_values *cvp = tp->cookie_values; 507 596 unsigned int remaining = MAX_TCP_OPTION_SPACE; 508 - u8 cookie_size = (!tp->rx_opt.cookie_out_never && cvp != NULL) ? 509 - tcp_cookie_size_check(cvp->cookie_desired) : 510 - 0; 511 597 struct tcp_fastopen_request *fastopen = tp->fastopen_req; 512 598 513 599 #ifdef CONFIG_TCP_MD5SIG ··· 555 649 tp->syn_fastopen = 1; 556 650 } 557 651 } 558 - /* Note that timestamps are required by the specification. 559 - * 560 - * Odd numbers of bytes are prohibited by the specification, ensuring 561 - * that the cookie is 16-bit aligned, and the resulting cookie pair is 562 - * 32-bit aligned. 563 - */ 564 - if (*md5 == NULL && 565 - (OPTION_TS & opts->options) && 566 - cookie_size > 0) { 567 - int need = TCPOLEN_COOKIE_BASE + cookie_size; 568 652 569 - if (0x2 & need) { 570 - /* 32-bit multiple */ 571 - need += 2; /* NOPs */ 572 - 573 - if (need > remaining) { 574 - /* try shrinking cookie to fit */ 575 - cookie_size -= 2; 576 - need -= 4; 577 - } 578 - } 579 - while (need > remaining && TCP_COOKIE_MIN <= cookie_size) { 580 - cookie_size -= 4; 581 - need -= 4; 582 - } 583 - if (TCP_COOKIE_MIN <= cookie_size) { 584 - opts->options |= OPTION_COOKIE_EXTENSION; 585 - opts->hash_location = (__u8 *)&cvp->cookie_pair[0]; 586 - opts->hash_size = cookie_size; 587 - 588 - /* Remember for future incarnations. */ 589 - cvp->cookie_desired = cookie_size; 590 - 591 - if (cvp->cookie_desired != cvp->cookie_pair_size) { 592 - /* Currently use random bytes as a nonce, 593 - * assuming these are completely unpredictable 594 - * by hostile users of the same system. 595 - */ 596 - get_random_bytes(&cvp->cookie_pair[0], 597 - cookie_size); 598 - cvp->cookie_pair_size = cookie_size; 599 - } 600 - 601 - remaining -= need; 602 - } 603 - } 604 653 return MAX_TCP_OPTION_SPACE - remaining; 605 654 } 606 655 ··· 565 704 unsigned int mss, struct sk_buff *skb, 566 705 struct tcp_out_options *opts, 567 706 struct tcp_md5sig_key **md5, 568 - struct tcp_extend_values *xvp, 569 707 struct tcp_fastopen_cookie *foc) 570 708 { 571 709 struct inet_request_sock *ireq = inet_rsk(req); 572 710 unsigned int remaining = MAX_TCP_OPTION_SPACE; 573 - u8 cookie_plus = (xvp != NULL && !xvp->cookie_out_never) ? 574 - xvp->cookie_plus : 575 - 0; 576 711 577 712 #ifdef CONFIG_TCP_MD5SIG 578 713 *md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req); ··· 616 759 remaining -= need; 617 760 } 618 761 } 619 - /* Similar rationale to tcp_syn_options() applies here, too. 620 - * If the <SYN> options fit, the same options should fit now! 621 - */ 622 - if (*md5 == NULL && 623 - ireq->tstamp_ok && 624 - cookie_plus > TCPOLEN_COOKIE_BASE) { 625 - int need = cookie_plus; /* has TCPOLEN_COOKIE_BASE */ 626 762 627 - if (0x2 & need) { 628 - /* 32-bit multiple */ 629 - need += 2; /* NOPs */ 630 - } 631 - if (need <= remaining) { 632 - opts->options |= OPTION_COOKIE_EXTENSION; 633 - opts->hash_size = cookie_plus - TCPOLEN_COOKIE_BASE; 634 - remaining -= need; 635 - } else { 636 - /* There's no error return, so flag it. */ 637 - xvp->cookie_out_never = 1; /* true */ 638 - opts->hash_size = 0; 639 - } 640 - } 641 763 return MAX_TCP_OPTION_SPACE - remaining; 642 764 } 643 765 ··· 2638 2802 * sk: listener socket 2639 2803 * dst: dst entry attached to the SYNACK 2640 2804 * req: request_sock pointer 2641 - * rvp: request_values pointer 2642 2805 * 2643 2806 * Allocate one skb and build a SYNACK packet. 2644 2807 * @dst is consumed : Caller should not use it again. 2645 2808 */ 2646 2809 struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, 2647 2810 struct request_sock *req, 2648 - struct request_values *rvp, 2649 2811 struct tcp_fastopen_cookie *foc) 2650 2812 { 2651 2813 struct tcp_out_options opts; 2652 - struct tcp_extend_values *xvp = tcp_xv(rvp); 2653 2814 struct inet_request_sock *ireq = inet_rsk(req); 2654 2815 struct tcp_sock *tp = tcp_sk(sk); 2655 - const struct tcp_cookie_values *cvp = tp->cookie_values; 2656 2816 struct tcphdr *th; 2657 2817 struct sk_buff *skb; 2658 2818 struct tcp_md5sig_key *md5; 2659 2819 int tcp_header_size; 2660 2820 int mss; 2661 - int s_data_desired = 0; 2662 2821 2663 - if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired) 2664 - s_data_desired = cvp->s_data_desired; 2665 - skb = alloc_skb(MAX_TCP_HEADER + 15 + s_data_desired, 2666 - sk_gfp_atomic(sk, GFP_ATOMIC)); 2822 + skb = alloc_skb(MAX_TCP_HEADER + 15, sk_gfp_atomic(sk, GFP_ATOMIC)); 2667 2823 if (unlikely(!skb)) { 2668 2824 dst_release(dst); 2669 2825 return NULL; ··· 2697 2869 else 2698 2870 #endif 2699 2871 TCP_SKB_CB(skb)->when = tcp_time_stamp; 2700 - tcp_header_size = tcp_synack_options(sk, req, mss, 2701 - skb, &opts, &md5, xvp, foc) 2702 - + sizeof(*th); 2872 + tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, &md5, 2873 + foc) + sizeof(*th); 2703 2874 2704 2875 skb_push(skb, tcp_header_size); 2705 2876 skb_reset_transport_header(skb); ··· 2715 2888 */ 2716 2889 tcp_init_nondata_skb(skb, tcp_rsk(req)->snt_isn, 2717 2890 TCPHDR_SYN | TCPHDR_ACK); 2718 - 2719 - if (OPTION_COOKIE_EXTENSION & opts.options) { 2720 - if (s_data_desired) { 2721 - u8 *buf = skb_put(skb, s_data_desired); 2722 - 2723 - /* copy data directly from the listening socket. */ 2724 - memcpy(buf, cvp->s_data_payload, s_data_desired); 2725 - TCP_SKB_CB(skb)->end_seq += s_data_desired; 2726 - } 2727 - 2728 - if (opts.hash_size > 0) { 2729 - __u32 workspace[SHA_WORKSPACE_WORDS]; 2730 - u32 *mess = &xvp->cookie_bakery[COOKIE_DIGEST_WORDS]; 2731 - u32 *tail = &mess[COOKIE_MESSAGE_WORDS-1]; 2732 - 2733 - /* Secret recipe depends on the Timestamp, (future) 2734 - * Sequence and Acknowledgment Numbers, Initiator 2735 - * Cookie, and others handled by IP variant caller. 2736 - */ 2737 - *tail-- ^= opts.tsval; 2738 - *tail-- ^= tcp_rsk(req)->rcv_isn + 1; 2739 - *tail-- ^= TCP_SKB_CB(skb)->seq + 1; 2740 - 2741 - /* recommended */ 2742 - *tail-- ^= (((__force u32)th->dest << 16) | (__force u32)th->source); 2743 - *tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */ 2744 - 2745 - sha_transform((__u32 *)&xvp->cookie_bakery[0], 2746 - (char *)mess, 2747 - &workspace[0]); 2748 - opts.hash_location = 2749 - (__u8 *)&xvp->cookie_bakery[0]; 2750 - } 2751 - } 2752 2891 2753 2892 th->seq = htonl(TCP_SKB_CB(skb)->seq); 2754 2893 /* XXX data is queued and acked as is. No buffer/window check */
+1 -2
net/ipv6/syncookies.c
··· 149 149 struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) 150 150 { 151 151 struct tcp_options_received tcp_opt; 152 - const u8 *hash_location; 153 152 struct inet_request_sock *ireq; 154 153 struct inet6_request_sock *ireq6; 155 154 struct tcp_request_sock *treq; ··· 176 177 177 178 /* check for timestamp cookie support */ 178 179 memset(&tcp_opt, 0, sizeof(tcp_opt)); 179 - tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL); 180 + tcp_parse_options(skb, &tcp_opt, 0, NULL); 180 181 181 182 if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok)) 182 183 goto out;
+4 -52
net/ipv6/tcp_ipv6.c
··· 454 454 static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, 455 455 struct flowi6 *fl6, 456 456 struct request_sock *req, 457 - struct request_values *rvp, 458 457 u16 queue_mapping) 459 458 { 460 459 struct inet6_request_sock *treq = inet6_rsk(req); ··· 465 466 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL) 466 467 goto done; 467 468 468 - skb = tcp_make_synack(sk, dst, req, rvp, NULL); 469 + skb = tcp_make_synack(sk, dst, req, NULL); 469 470 470 471 if (skb) { 471 472 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); ··· 480 481 return err; 481 482 } 482 483 483 - static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, 484 - struct request_values *rvp) 484 + static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req) 485 485 { 486 486 struct flowi6 fl6; 487 487 int res; 488 488 489 - res = tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0); 489 + res = tcp_v6_send_synack(sk, NULL, &fl6, req, 0); 490 490 if (!res) 491 491 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); 492 492 return res; ··· 938 940 */ 939 941 static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) 940 942 { 941 - struct tcp_extend_values tmp_ext; 942 943 struct tcp_options_received tmp_opt; 943 - const u8 *hash_location; 944 944 struct request_sock *req; 945 945 struct inet6_request_sock *treq; 946 946 struct ipv6_pinfo *np = inet6_sk(sk); ··· 976 980 tcp_clear_options(&tmp_opt); 977 981 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); 978 982 tmp_opt.user_mss = tp->rx_opt.user_mss; 979 - tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL); 980 - 981 - if (tmp_opt.cookie_plus > 0 && 982 - tmp_opt.saw_tstamp && 983 - !tp->rx_opt.cookie_out_never && 984 - (sysctl_tcp_cookie_size > 0 || 985 - (tp->cookie_values != NULL && 986 - tp->cookie_values->cookie_desired > 0))) { 987 - u8 *c; 988 - u32 *d; 989 - u32 *mess = &tmp_ext.cookie_bakery[COOKIE_DIGEST_WORDS]; 990 - int l = tmp_opt.cookie_plus - TCPOLEN_COOKIE_BASE; 991 - 992 - if (tcp_cookie_generator(&tmp_ext.cookie_bakery[0]) != 0) 993 - goto drop_and_free; 994 - 995 - /* Secret recipe starts with IP addresses */ 996 - d = (__force u32 *)&ipv6_hdr(skb)->daddr.s6_addr32[0]; 997 - *mess++ ^= *d++; 998 - *mess++ ^= *d++; 999 - *mess++ ^= *d++; 1000 - *mess++ ^= *d++; 1001 - d = (__force u32 *)&ipv6_hdr(skb)->saddr.s6_addr32[0]; 1002 - *mess++ ^= *d++; 1003 - *mess++ ^= *d++; 1004 - *mess++ ^= *d++; 1005 - *mess++ ^= *d++; 1006 - 1007 - /* plus variable length Initiator Cookie */ 1008 - c = (u8 *)mess; 1009 - while (l-- > 0) 1010 - *c++ ^= *hash_location++; 1011 - 1012 - want_cookie = false; /* not our kind of cookie */ 1013 - tmp_ext.cookie_out_never = 0; /* false */ 1014 - tmp_ext.cookie_plus = tmp_opt.cookie_plus; 1015 - } else if (!tp->rx_opt.cookie_in_always) { 1016 - /* redundant indications, but ensure initialization. */ 1017 - tmp_ext.cookie_out_never = 1; /* true */ 1018 - tmp_ext.cookie_plus = 0; 1019 - } else { 1020 - goto drop_and_free; 1021 - } 1022 - tmp_ext.cookie_in_always = tp->rx_opt.cookie_in_always; 983 + tcp_parse_options(skb, &tmp_opt, 0, NULL); 1023 984 1024 985 if (want_cookie && !tmp_opt.saw_tstamp) 1025 986 tcp_clear_options(&tmp_opt); ··· 1054 1101 goto drop_and_release; 1055 1102 1056 1103 if (tcp_v6_send_synack(sk, dst, &fl6, req, 1057 - (struct request_values *)&tmp_ext, 1058 1104 skb_get_queue_mapping(skb)) || 1059 1105 want_cookie) 1060 1106 goto drop_and_free;