aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c47
1 files changed, 43 insertions, 4 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index a2bcac9b388e..59c911f3889d 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1213,9 +1213,12 @@ static struct timewait_sock_ops tcp_timewait_sock_ops = {
1213 1213
1214int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) 1214int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1215{ 1215{
1216 struct tcp_extend_values tmp_ext;
1216 struct tcp_options_received tmp_opt; 1217 struct tcp_options_received tmp_opt;
1218 u8 *hash_location;
1217 struct request_sock *req; 1219 struct request_sock *req;
1218 struct inet_request_sock *ireq; 1220 struct inet_request_sock *ireq;
1221 struct tcp_sock *tp = tcp_sk(sk);
1219 struct dst_entry *dst = NULL; 1222 struct dst_entry *dst = NULL;
1220 __be32 saddr = ip_hdr(skb)->saddr; 1223 __be32 saddr = ip_hdr(skb)->saddr;
1221 __be32 daddr = ip_hdr(skb)->daddr; 1224 __be32 daddr = ip_hdr(skb)->daddr;
@@ -1271,15 +1274,49 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1271 1274
1272 tcp_clear_options(&tmp_opt); 1275 tcp_clear_options(&tmp_opt);
1273 tmp_opt.mss_clamp = TCP_MSS_DEFAULT; 1276 tmp_opt.mss_clamp = TCP_MSS_DEFAULT;
1274 tmp_opt.user_mss = tcp_sk(sk)->rx_opt.user_mss; 1277 tmp_opt.user_mss = tp->rx_opt.user_mss;
1278 tcp_parse_options(skb, &tmp_opt, &hash_location, 0, dst);
1279
1280 if (tmp_opt.cookie_plus > 0 &&
1281 tmp_opt.saw_tstamp &&
1282 !tp->rx_opt.cookie_out_never &&
1283 (sysctl_tcp_cookie_size > 0 ||
1284 (tp->cookie_values != NULL &&
1285 tp->cookie_values->cookie_desired > 0))) {
1286 u8 *c;
1287 u32 *mess = &tmp_ext.cookie_bakery[COOKIE_DIGEST_WORDS];
1288 int l = tmp_opt.cookie_plus - TCPOLEN_COOKIE_BASE;
1289
1290 if (tcp_cookie_generator(&tmp_ext.cookie_bakery[0]) != 0)
1291 goto drop_and_release;
1292
1293 /* Secret recipe starts with IP addresses */
1294 *mess++ ^= daddr;
1295 *mess++ ^= saddr;
1275 1296
1276 tcp_parse_options(skb, &tmp_opt, 0, dst); 1297 /* plus variable length Initiator Cookie */
1298 c = (u8 *)mess;
1299 while (l-- > 0)
1300 *c++ ^= *hash_location++;
1301
1302#ifdef CONFIG_SYN_COOKIES
1303 want_cookie = 0; /* not our kind of cookie */
1304#endif
1305 tmp_ext.cookie_out_never = 0; /* false */
1306 tmp_ext.cookie_plus = tmp_opt.cookie_plus;
1307 } else if (!tp->rx_opt.cookie_in_always) {
1308 /* redundant indications, but ensure initialization. */
1309 tmp_ext.cookie_out_never = 1; /* true */
1310 tmp_ext.cookie_plus = 0;
1311 } else {
1312 goto drop_and_release;
1313 }
1314 tmp_ext.cookie_in_always = tp->rx_opt.cookie_in_always;
1277 1315
1278 if (want_cookie && !tmp_opt.saw_tstamp) 1316 if (want_cookie && !tmp_opt.saw_tstamp)
1279 tcp_clear_options(&tmp_opt); 1317 tcp_clear_options(&tmp_opt);
1280 1318
1281 tmp_opt.tstamp_ok = tmp_opt.saw_tstamp; 1319 tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
1282
1283 tcp_openreq_init(req, &tmp_opt, skb); 1320 tcp_openreq_init(req, &tmp_opt, skb);
1284 1321
1285 if (security_inet_conn_request(sk, skb, req)) 1322 if (security_inet_conn_request(sk, skb, req))
@@ -1339,7 +1376,9 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1339 } 1376 }
1340 tcp_rsk(req)->snt_isn = isn; 1377 tcp_rsk(req)->snt_isn = isn;
1341 1378
1342 if (__tcp_v4_send_synack(sk, dst, req, NULL) || want_cookie) 1379 if (__tcp_v4_send_synack(sk, dst, req,
1380 (struct request_values *)&tmp_ext) ||
1381 want_cookie)
1343 goto drop_and_free; 1382 goto drop_and_free;
1344 1383
1345 inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); 1384 inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);