TCPCT part 1g: Responder Cookie => Initiator
Parse incoming TCP_COOKIE option(s). Calculate <SYN,ACK> TCP_COOKIE option. Send optional <SYN,ACK> data. This is a significantly revised implementation of an earlier (year-old) patch that no longer applies cleanly, with permission of the original author (Adam Langley): http://thread.gmane.org/gmane.linux.network/102586 Requires: TCPCT part 1a: add request_values parameter for sending SYNACK TCPCT part 1b: generate Responder Cookie secret TCPCT part 1c: sysctl_tcp_cookie_size, socket option TCP_COOKIE_TRANSACTIONS TCPCT part 1d: define TCP cookie option, extend existing struct's TCPCT part 1e: implement socket option TCP_COOKIE_TRANSACTIONS TCPCT part 1f: Initiator Cookie => Responder Signed-off-by: William.Allen.Simpson@gmail.com Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
bd0388ae77
commit
4957faade1
@ -1162,7 +1162,9 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
|
||||
*/
|
||||
static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct tcp_extend_values tmp_ext;
|
||||
struct tcp_options_received tmp_opt;
|
||||
u8 *hash_location;
|
||||
struct request_sock *req;
|
||||
struct inet6_request_sock *treq;
|
||||
struct ipv6_pinfo *np = inet6_sk(sk);
|
||||
@ -1206,8 +1208,52 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
|
||||
tcp_clear_options(&tmp_opt);
|
||||
tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
|
||||
tmp_opt.user_mss = tp->rx_opt.user_mss;
|
||||
tcp_parse_options(skb, &tmp_opt, &hash_location, 0, dst);
|
||||
|
||||
tcp_parse_options(skb, &tmp_opt, 0, dst);
|
||||
if (tmp_opt.cookie_plus > 0 &&
|
||||
tmp_opt.saw_tstamp &&
|
||||
!tp->rx_opt.cookie_out_never &&
|
||||
(sysctl_tcp_cookie_size > 0 ||
|
||||
(tp->cookie_values != NULL &&
|
||||
tp->cookie_values->cookie_desired > 0))) {
|
||||
u8 *c;
|
||||
u32 *d;
|
||||
u32 *mess = &tmp_ext.cookie_bakery[COOKIE_DIGEST_WORDS];
|
||||
int l = tmp_opt.cookie_plus - TCPOLEN_COOKIE_BASE;
|
||||
|
||||
if (tcp_cookie_generator(&tmp_ext.cookie_bakery[0]) != 0)
|
||||
goto drop_and_free;
|
||||
|
||||
/* Secret recipe starts with IP addresses */
|
||||
d = &ipv6_hdr(skb)->daddr.s6_addr32[0];
|
||||
*mess++ ^= *d++;
|
||||
*mess++ ^= *d++;
|
||||
*mess++ ^= *d++;
|
||||
*mess++ ^= *d++;
|
||||
d = &ipv6_hdr(skb)->saddr.s6_addr32[0];
|
||||
*mess++ ^= *d++;
|
||||
*mess++ ^= *d++;
|
||||
*mess++ ^= *d++;
|
||||
*mess++ ^= *d++;
|
||||
|
||||
/* plus variable length Initiator Cookie */
|
||||
c = (u8 *)mess;
|
||||
while (l-- > 0)
|
||||
*c++ ^= *hash_location++;
|
||||
|
||||
#ifdef CONFIG_SYN_COOKIES
|
||||
want_cookie = 0; /* not our kind of cookie */
|
||||
#endif
|
||||
tmp_ext.cookie_out_never = 0; /* false */
|
||||
tmp_ext.cookie_plus = tmp_opt.cookie_plus;
|
||||
} else if (!tp->rx_opt.cookie_in_always) {
|
||||
/* redundant indications, but ensure initialization. */
|
||||
tmp_ext.cookie_out_never = 1; /* true */
|
||||
tmp_ext.cookie_plus = 0;
|
||||
} else {
|
||||
goto drop_and_free;
|
||||
}
|
||||
tmp_ext.cookie_in_always = tp->rx_opt.cookie_in_always;
|
||||
|
||||
if (want_cookie && !tmp_opt.saw_tstamp)
|
||||
tcp_clear_options(&tmp_opt);
|
||||
@ -1244,7 +1290,9 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
|
||||
|
||||
security_inet_conn_request(sk, skb, req);
|
||||
|
||||
if (tcp_v6_send_synack(sk, req, NULL) || want_cookie)
|
||||
if (tcp_v6_send_synack(sk, req,
|
||||
(struct request_values *)&tmp_ext) ||
|
||||
want_cookie)
|
||||
goto drop_and_free;
|
||||
|
||||
inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
|
||||
|
Reference in New Issue
Block a user