| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tcp_input.c,v 1.386 2018/03/22 21:19:28 maxv Exp $ */ | | 1 | /* $NetBSD: tcp_input.c,v 1.387 2018/03/23 08:57:40 maxv Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | | 4 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -138,27 +138,27 @@ | | | @@ -138,27 +138,27 @@ |
138 | */ | | 138 | */ |
139 | | | 139 | |
140 | /* | | 140 | /* |
141 | * TODO list for SYN cache stuff: | | 141 | * TODO list for SYN cache stuff: |
142 | * | | 142 | * |
143 | * Find room for a "state" field, which is needed to keep a | | 143 | * Find room for a "state" field, which is needed to keep a |
144 | * compressed state for TIME_WAIT TCBs. It's been noted already | | 144 | * compressed state for TIME_WAIT TCBs. It's been noted already |
145 | * that this is fairly important for very high-volume web and | | 145 | * that this is fairly important for very high-volume web and |
146 | * mail servers, which use a large number of short-lived | | 146 | * mail servers, which use a large number of short-lived |
147 | * connections. | | 147 | * connections. |
148 | */ | | 148 | */ |
149 | | | 149 | |
150 | #include <sys/cdefs.h> | | 150 | #include <sys/cdefs.h> |
151 | __KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.386 2018/03/22 21:19:28 maxv Exp $"); | | 151 | __KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.387 2018/03/23 08:57:40 maxv Exp $"); |
152 | | | 152 | |
153 | #ifdef _KERNEL_OPT | | 153 | #ifdef _KERNEL_OPT |
154 | #include "opt_inet.h" | | 154 | #include "opt_inet.h" |
155 | #include "opt_ipsec.h" | | 155 | #include "opt_ipsec.h" |
156 | #include "opt_inet_csum.h" | | 156 | #include "opt_inet_csum.h" |
157 | #include "opt_tcp_debug.h" | | 157 | #include "opt_tcp_debug.h" |
158 | #endif | | 158 | #endif |
159 | | | 159 | |
160 | #include <sys/param.h> | | 160 | #include <sys/param.h> |
161 | #include <sys/systm.h> | | 161 | #include <sys/systm.h> |
162 | #include <sys/malloc.h> | | 162 | #include <sys/malloc.h> |
163 | #include <sys/mbuf.h> | | 163 | #include <sys/mbuf.h> |
164 | #include <sys/protosw.h> | | 164 | #include <sys/protosw.h> |
| @@ -1371,38 +1371,40 @@ tcp_input(struct mbuf *m, ...) | | | @@ -1371,38 +1371,40 @@ tcp_input(struct mbuf *m, ...) |
1371 | goto drop; | | 1371 | goto drop; |
1372 | } | | 1372 | } |
1373 | tlen -= off; | | 1373 | tlen -= off; |
1374 | | | 1374 | |
1375 | if (off > sizeof(struct tcphdr)) { | | 1375 | if (off > sizeof(struct tcphdr)) { |
1376 | IP6_EXTHDR_GET(th, struct tcphdr *, m, toff, off); | | 1376 | IP6_EXTHDR_GET(th, struct tcphdr *, m, toff, off); |
1377 | if (th == NULL) { | | 1377 | if (th == NULL) { |
1378 | TCP_STATINC(TCP_STAT_RCVSHORT); | | 1378 | TCP_STATINC(TCP_STAT_RCVSHORT); |
1379 | return; | | 1379 | return; |
1380 | } | | 1380 | } |
1381 | KASSERT(TCP_HDR_ALIGNED_P(th)); | | 1381 | KASSERT(TCP_HDR_ALIGNED_P(th)); |
1382 | optlen = off - sizeof(struct tcphdr); | | 1382 | optlen = off - sizeof(struct tcphdr); |
1383 | optp = ((u_int8_t *)th) + sizeof(struct tcphdr); | | 1383 | optp = ((u_int8_t *)th) + sizeof(struct tcphdr); |
| | | 1384 | |
1384 | /* | | 1385 | /* |
1385 | * Do quick retrieval of timestamp options ("options | | 1386 | * Do quick retrieval of timestamp options. |
1386 | * prediction?"). If timestamp is the only option and it's | | 1387 | * |
1387 | * formatted as recommended in RFC 1323 appendix A, we | | 1388 | * If timestamp is the only option and it's formatted as |
1388 | * quickly get the values now and not bother calling | | 1389 | * recommended in RFC 1323 appendix A, we quickly get the |
1389 | * tcp_dooptions(), etc. | | 1390 | * values now and don't bother calling tcp_dooptions(), |
| | | 1391 | * etc. |
1390 | */ | | 1392 | */ |
1391 | if ((optlen == TCPOLEN_TSTAMP_APPA || | | 1393 | if ((optlen == TCPOLEN_TSTAMP_APPA || |
1392 | (optlen > TCPOLEN_TSTAMP_APPA && | | 1394 | (optlen > TCPOLEN_TSTAMP_APPA && |
1393 | optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) && | | 1395 | optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) && |
1394 | *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) && | | 1396 | *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) && |
1395 | (th->th_flags & TH_SYN) == 0) { | | 1397 | (th->th_flags & TH_SYN) == 0) { |
1396 | opti.ts_present = 1; | | 1398 | opti.ts_present = 1; |
1397 | opti.ts_val = ntohl(*(u_int32_t *)(optp + 4)); | | 1399 | opti.ts_val = ntohl(*(u_int32_t *)(optp + 4)); |
1398 | opti.ts_ecr = ntohl(*(u_int32_t *)(optp + 8)); | | 1400 | opti.ts_ecr = ntohl(*(u_int32_t *)(optp + 8)); |
1399 | optp = NULL; /* we've parsed the options */ | | 1401 | optp = NULL; /* we've parsed the options */ |
1400 | } | | 1402 | } |
1401 | } | | 1403 | } |
1402 | tiflags = th->th_flags; | | 1404 | tiflags = th->th_flags; |
1403 | | | 1405 | |
1404 | /* | | 1406 | /* |
1405 | * Checksum extended TCP header and data | | 1407 | * Checksum extended TCP header and data |
1406 | */ | | 1408 | */ |
1407 | if (tcp_input_checksum(af, m, th, toff, off, tlen)) | | 1409 | if (tcp_input_checksum(af, m, th, toff, off, tlen)) |
1408 | goto badcsum; | | 1410 | goto badcsum; |
| @@ -2333,71 +2335,75 @@ after_listen: | | | @@ -2333,71 +2335,75 @@ after_listen: |
2333 | * user processes are gone, then RST the other end. | | 2335 | * user processes are gone, then RST the other end. |
2334 | */ | | 2336 | */ |
2335 | if ((so->so_state & SS_NOFDREF) && | | 2337 | if ((so->so_state & SS_NOFDREF) && |
2336 | tp->t_state > TCPS_CLOSE_WAIT && tlen) { | | 2338 | tp->t_state > TCPS_CLOSE_WAIT && tlen) { |
2337 | tp = tcp_close(tp); | | 2339 | tp = tcp_close(tp); |
2338 | TCP_STATINC(TCP_STAT_RCVAFTERCLOSE); | | 2340 | TCP_STATINC(TCP_STAT_RCVAFTERCLOSE); |
2339 | goto dropwithreset; | | 2341 | goto dropwithreset; |
2340 | } | | 2342 | } |
2341 | | | 2343 | |
2342 | /* | | 2344 | /* |
2343 | * If segment ends after window, drop trailing data | | 2345 | * If segment ends after window, drop trailing data |
2344 | * (and PUSH and FIN); if nothing left, just ACK. | | 2346 | * (and PUSH and FIN); if nothing left, just ACK. |
2345 | */ | | 2347 | */ |
2346 | todrop = (th->th_seq + tlen) - (tp->rcv_nxt+tp->rcv_wnd); | | 2348 | todrop = (th->th_seq + tlen) - (tp->rcv_nxt + tp->rcv_wnd); |
2347 | if (todrop > 0) { | | 2349 | if (todrop > 0) { |
2348 | TCP_STATINC(TCP_STAT_RCVPACKAFTERWIN); | | 2350 | TCP_STATINC(TCP_STAT_RCVPACKAFTERWIN); |
2349 | if (todrop >= tlen) { | | 2351 | if (todrop >= tlen) { |
2350 | /* | | 2352 | /* |
2351 | * The segment actually starts after the window. | | 2353 | * The segment actually starts after the window. |
2352 | * th->th_seq + tlen - tp->rcv_nxt - tp->rcv_wnd >= tlen | | 2354 | * th->th_seq + tlen - tp->rcv_nxt - tp->rcv_wnd >= tlen |
2353 | * th->th_seq - tp->rcv_nxt - tp->rcv_wnd >= 0 | | 2355 | * th->th_seq - tp->rcv_nxt - tp->rcv_wnd >= 0 |
2354 | * th->th_seq >= tp->rcv_nxt + tp->rcv_wnd | | 2356 | * th->th_seq >= tp->rcv_nxt + tp->rcv_wnd |
2355 | */ | | 2357 | */ |
2356 | TCP_STATADD(TCP_STAT_RCVBYTEAFTERWIN, tlen); | | 2358 | TCP_STATADD(TCP_STAT_RCVBYTEAFTERWIN, tlen); |
| | | 2359 | |
2357 | /* | | 2360 | /* |
2358 | * If a new connection request is received | | 2361 | * If a new connection request is received while in |
2359 | * while in TIME_WAIT, drop the old connection | | 2362 | * TIME_WAIT, drop the old connection and start over |
2360 | * and start over if the sequence numbers | | 2363 | * if the sequence numbers are above the previous |
2361 | * are above the previous ones. | | 2364 | * ones. |
| | | 2365 | * |
| | | 2366 | * NOTE: We need to put the header fields back into |
| | | 2367 | * network order. |
2362 | * | | 2368 | * |
2363 | * NOTE: We will checksum the packet again, and | | | |
2364 | * so we need to put the header fields back into | | | |
2365 | * network order! | | | |
2366 | * XXX This kind of sucks, but we don't expect | | 2369 | * XXX This kind of sucks, but we don't expect |
2367 | * XXX this to happen very often, so maybe it | | 2370 | * XXX this to happen very often, so maybe it |
2368 | * XXX doesn't matter so much. | | 2371 | * XXX doesn't matter so much. |
2369 | */ | | 2372 | */ |
2370 | if (tiflags & TH_SYN && | | 2373 | if ((tiflags & TH_SYN) && |
2371 | tp->t_state == TCPS_TIME_WAIT && | | 2374 | tp->t_state == TCPS_TIME_WAIT && |
2372 | SEQ_GT(th->th_seq, tp->rcv_nxt)) { | | 2375 | SEQ_GT(th->th_seq, tp->rcv_nxt)) { |
2373 | tp = tcp_close(tp); | | 2376 | tp = tcp_close(tp); |
2374 | tcp_fields_to_net(th); | | 2377 | tcp_fields_to_net(th); |
2375 | goto findpcb; | | 2378 | goto findpcb; |
2376 | } | | 2379 | } |
| | | 2380 | |
2377 | /* | | 2381 | /* |
2378 | * If window is closed can only take segments at | | 2382 | * If window is closed can only take segments at |
2379 | * window edge, and have to drop data and PUSH from | | 2383 | * window edge, and have to drop data and PUSH from |
2380 | * incoming segments. Continue processing, but | | 2384 | * incoming segments. Continue processing, but |
2381 | * remember to ack. Otherwise, drop segment | | 2385 | * remember to ack. Otherwise, drop segment |
2382 | * and (if not RST) ack. | | 2386 | * and (if not RST) ack. |
2383 | */ | | 2387 | */ |
2384 | if (tp->rcv_wnd == 0 && th->th_seq == tp->rcv_nxt) { | | 2388 | if (tp->rcv_wnd == 0 && th->th_seq == tp->rcv_nxt) { |
2385 | tp->t_flags |= TF_ACKNOW; | | 2389 | tp->t_flags |= TF_ACKNOW; |
2386 | TCP_STATINC(TCP_STAT_RCVWINPROBE); | | 2390 | TCP_STATINC(TCP_STAT_RCVWINPROBE); |
2387 | } else | | 2391 | } else { |
2388 | goto dropafterack; | | 2392 | goto dropafterack; |
2389 | } else | | 2393 | } |
| | | 2394 | } else { |
2390 | TCP_STATADD(TCP_STAT_RCVBYTEAFTERWIN, todrop); | | 2395 | TCP_STATADD(TCP_STAT_RCVBYTEAFTERWIN, todrop); |
| | | 2396 | } |
2391 | m_adj(m, -todrop); | | 2397 | m_adj(m, -todrop); |
2392 | tlen -= todrop; | | 2398 | tlen -= todrop; |
2393 | tiflags &= ~(TH_PUSH|TH_FIN); | | 2399 | tiflags &= ~(TH_PUSH|TH_FIN); |
2394 | } | | 2400 | } |
2395 | | | 2401 | |
2396 | /* | | 2402 | /* |
2397 | * If last ACK falls within this segment's sequence numbers, | | 2403 | * If last ACK falls within this segment's sequence numbers, |
2398 | * record the timestamp. | | 2404 | * record the timestamp. |
2399 | * NOTE: | | 2405 | * NOTE: |
2400 | * 1) That the test incorporates suggestions from the latest | | 2406 | * 1) That the test incorporates suggestions from the latest |
2401 | * proposal of the tcplw@cray.com list (Braden 1993/04/26). | | 2407 | * proposal of the tcplw@cray.com list (Braden 1993/04/26). |
2402 | * 2) That updating only on newer timestamps interferes with | | 2408 | * 2) That updating only on newer timestamps interferes with |
2403 | * our earlier PAWS tests, so this check should be solely | | 2409 | * our earlier PAWS tests, so this check should be solely |
| @@ -3189,27 +3195,27 @@ tcp_dooptions(struct tcpcb *tp, const u_ | | | @@ -3189,27 +3195,27 @@ tcp_dooptions(struct tcpcb *tp, const u_ |
3189 | } | | 3195 | } |
3190 | switch (opt) { | | 3196 | switch (opt) { |
3191 | | | 3197 | |
3192 | default: | | 3198 | default: |
3193 | continue; | | 3199 | continue; |
3194 | | | 3200 | |
3195 | case TCPOPT_MAXSEG: | | 3201 | case TCPOPT_MAXSEG: |
3196 | if (optlen != TCPOLEN_MAXSEG) | | 3202 | if (optlen != TCPOLEN_MAXSEG) |
3197 | continue; | | 3203 | continue; |
3198 | if (!(th->th_flags & TH_SYN)) | | 3204 | if (!(th->th_flags & TH_SYN)) |
3199 | continue; | | 3205 | continue; |
3200 | if (TCPS_HAVERCVDSYN(tp->t_state)) | | 3206 | if (TCPS_HAVERCVDSYN(tp->t_state)) |
3201 | continue; | | 3207 | continue; |
3202 | bcopy(cp + 2, &mss, sizeof(mss)); | | 3208 | memcpy(&mss, cp + 2, sizeof(mss)); |
3203 | oi->maxseg = ntohs(mss); | | 3209 | oi->maxseg = ntohs(mss); |
3204 | break; | | 3210 | break; |
3205 | | | 3211 | |
3206 | case TCPOPT_WINDOW: | | 3212 | case TCPOPT_WINDOW: |
3207 | if (optlen != TCPOLEN_WINDOW) | | 3213 | if (optlen != TCPOLEN_WINDOW) |
3208 | continue; | | 3214 | continue; |
3209 | if (!(th->th_flags & TH_SYN)) | | 3215 | if (!(th->th_flags & TH_SYN)) |
3210 | continue; | | 3216 | continue; |
3211 | if (TCPS_HAVERCVDSYN(tp->t_state)) | | 3217 | if (TCPS_HAVERCVDSYN(tp->t_state)) |
3212 | continue; | | 3218 | continue; |
3213 | tp->t_flags |= TF_RCVD_SCALE; | | 3219 | tp->t_flags |= TF_RCVD_SCALE; |
3214 | tp->requested_s_scale = cp[2]; | | 3220 | tp->requested_s_scale = cp[2]; |
3215 | if (tp->requested_s_scale > TCP_MAX_WINSHIFT) { | | 3221 | if (tp->requested_s_scale > TCP_MAX_WINSHIFT) { |
| @@ -3230,29 +3236,29 @@ tcp_dooptions(struct tcpcb *tp, const u_ | | | @@ -3230,29 +3236,29 @@ tcp_dooptions(struct tcpcb *tp, const u_ |
3230 | strlcpy(buf, "(unknown)", sizeof(buf)); | | 3236 | strlcpy(buf, "(unknown)", sizeof(buf)); |
3231 | log(LOG_ERR, "TCP: invalid wscale %d from %s, " | | 3237 | log(LOG_ERR, "TCP: invalid wscale %d from %s, " |
3232 | "assuming %d\n", | | 3238 | "assuming %d\n", |
3233 | tp->requested_s_scale, buf, | | 3239 | tp->requested_s_scale, buf, |
3234 | TCP_MAX_WINSHIFT); | | 3240 | TCP_MAX_WINSHIFT); |
3235 | tp->requested_s_scale = TCP_MAX_WINSHIFT; | | 3241 | tp->requested_s_scale = TCP_MAX_WINSHIFT; |
3236 | } | | 3242 | } |
3237 | break; | | 3243 | break; |
3238 | | | 3244 | |
3239 | case TCPOPT_TIMESTAMP: | | 3245 | case TCPOPT_TIMESTAMP: |
3240 | if (optlen != TCPOLEN_TIMESTAMP) | | 3246 | if (optlen != TCPOLEN_TIMESTAMP) |
3241 | continue; | | 3247 | continue; |
3242 | oi->ts_present = 1; | | 3248 | oi->ts_present = 1; |
3243 | bcopy(cp + 2, &oi->ts_val, sizeof(oi->ts_val)); | | 3249 | memcpy(&oi->ts_val, cp + 2, sizeof(oi->ts_val)); |
3244 | NTOHL(oi->ts_val); | | 3250 | NTOHL(oi->ts_val); |
3245 | bcopy(cp + 6, &oi->ts_ecr, sizeof(oi->ts_ecr)); | | 3251 | memcpy(&oi->ts_ecr, cp + 6, sizeof(oi->ts_ecr)); |
3246 | NTOHL(oi->ts_ecr); | | 3252 | NTOHL(oi->ts_ecr); |
3247 | | | 3253 | |
3248 | if (!(th->th_flags & TH_SYN)) | | 3254 | if (!(th->th_flags & TH_SYN)) |
3249 | continue; | | 3255 | continue; |
3250 | if (TCPS_HAVERCVDSYN(tp->t_state)) | | 3256 | if (TCPS_HAVERCVDSYN(tp->t_state)) |
3251 | continue; | | 3257 | continue; |
3252 | /* | | 3258 | /* |
3253 | * A timestamp received in a SYN makes | | 3259 | * A timestamp received in a SYN makes |
3254 | * it ok to send timestamp requests and replies. | | 3260 | * it ok to send timestamp requests and replies. |
3255 | */ | | 3261 | */ |
3256 | tp->t_flags |= TF_RCVD_TSTMP; | | 3262 | tp->t_flags |= TF_RCVD_TSTMP; |
3257 | tp->ts_recent = oi->ts_val; | | 3263 | tp->ts_recent = oi->ts_val; |
3258 | tp->ts_recent_age = tcp_now; | | 3264 | tp->ts_recent_age = tcp_now; |
| @@ -3337,33 +3343,33 @@ out: | | | @@ -3337,33 +3343,33 @@ out: |
3337 | void | | 3343 | void |
3338 | tcp_pulloutofband(struct socket *so, struct tcphdr *th, | | 3344 | tcp_pulloutofband(struct socket *so, struct tcphdr *th, |
3339 | struct mbuf *m, int off) | | 3345 | struct mbuf *m, int off) |
3340 | { | | 3346 | { |
3341 | int cnt = off + th->th_urp - 1; | | 3347 | int cnt = off + th->th_urp - 1; |
3342 | | | 3348 | |
3343 | while (cnt >= 0) { | | 3349 | while (cnt >= 0) { |
3344 | if (m->m_len > cnt) { | | 3350 | if (m->m_len > cnt) { |
3345 | char *cp = mtod(m, char *) + cnt; | | 3351 | char *cp = mtod(m, char *) + cnt; |
3346 | struct tcpcb *tp = sototcpcb(so); | | 3352 | struct tcpcb *tp = sototcpcb(so); |
3347 | | | 3353 | |
3348 | tp->t_iobc = *cp; | | 3354 | tp->t_iobc = *cp; |
3349 | tp->t_oobflags |= TCPOOB_HAVEDATA; | | 3355 | tp->t_oobflags |= TCPOOB_HAVEDATA; |
3350 | bcopy(cp+1, cp, (unsigned)(m->m_len - cnt - 1)); | | 3356 | memmove(cp, cp + 1, (unsigned)(m->m_len - cnt - 1)); |
3351 | m->m_len--; | | 3357 | m->m_len--; |
3352 | return; | | 3358 | return; |
3353 | } | | 3359 | } |
3354 | cnt -= m->m_len; | | 3360 | cnt -= m->m_len; |
3355 | m = m->m_next; | | 3361 | m = m->m_next; |
3356 | if (m == 0) | | 3362 | if (m == NULL) |
3357 | break; | | 3363 | break; |
3358 | } | | 3364 | } |
3359 | panic("tcp_pulloutofband"); | | 3365 | panic("tcp_pulloutofband"); |
3360 | } | | 3366 | } |
3361 | | | 3367 | |
3362 | /* | | 3368 | /* |
3363 | * Collect new round-trip time estimate | | 3369 | * Collect new round-trip time estimate |
3364 | * and update averages and current timeout. | | 3370 | * and update averages and current timeout. |
3365 | * | | 3371 | * |
3366 | * rtt is in units of slow ticks (typically 500 ms) -- essentially the | | 3372 | * rtt is in units of slow ticks (typically 500 ms) -- essentially the |
3367 | * difference of two timestamps. | | 3373 | * difference of two timestamps. |
3368 | */ | | 3374 | */ |
3369 | void | | 3375 | void |
| @@ -4218,29 +4224,27 @@ syn_cache_add(struct sockaddr *src, stru | | | @@ -4218,29 +4224,27 @@ syn_cache_add(struct sockaddr *src, stru |
4218 | #ifdef TCP_SIGNATURE | | 4224 | #ifdef TCP_SIGNATURE |
4219 | tb.t_flags |= (tp->t_flags & TF_SIGNATURE); | | 4225 | tb.t_flags |= (tp->t_flags & TF_SIGNATURE); |
4220 | #endif | | 4226 | #endif |
4221 | tb.t_state = TCPS_LISTEN; | | 4227 | tb.t_state = TCPS_LISTEN; |
4222 | if (tcp_dooptions(&tb, optp, optlen, th, m, m->m_pkthdr.len - | | 4228 | if (tcp_dooptions(&tb, optp, optlen, th, m, m->m_pkthdr.len - |
4223 | sizeof(struct tcphdr) - optlen - hlen, oi) < 0) | | 4229 | sizeof(struct tcphdr) - optlen - hlen, oi) < 0) |
4224 | return 0; | | 4230 | return 0; |
4225 | } else | | 4231 | } else |
4226 | tb.t_flags = 0; | | 4232 | tb.t_flags = 0; |
4227 | | | 4233 | |
4228 | switch (src->sa_family) { | | 4234 | switch (src->sa_family) { |
4229 | #ifdef INET | | 4235 | #ifdef INET |
4230 | case AF_INET: | | 4236 | case AF_INET: |
4231 | /* | | 4237 | /* Remember the IP options, if any. */ |
4232 | * Remember the IP options, if any. | | | |
4233 | */ | | | |
4234 | ipopts = ip_srcroute(m); | | 4238 | ipopts = ip_srcroute(m); |
4235 | break; | | 4239 | break; |
4236 | #endif | | 4240 | #endif |
4237 | default: | | 4241 | default: |
4238 | ipopts = NULL; | | 4242 | ipopts = NULL; |
4239 | } | | 4243 | } |
4240 | | | 4244 | |
4241 | /* | | 4245 | /* |
4242 | * See if we already have an entry for this connection. | | 4246 | * See if we already have an entry for this connection. |
4243 | * If we do, resend the SYN,ACK. We do not count this | | 4247 | * If we do, resend the SYN,ACK. We do not count this |
4244 | * as a retransmission (XXX though maybe we should). | | 4248 | * as a retransmission (XXX though maybe we should). |
4245 | */ | | 4249 | */ |
4246 | if ((sc = syn_cache_lookup(src, dst, &scp)) != NULL) { | | 4250 | if ((sc = syn_cache_lookup(src, dst, &scp)) != NULL) { |
| @@ -4270,28 +4274,28 @@ syn_cache_add(struct sockaddr *src, stru | | | @@ -4270,28 +4274,28 @@ syn_cache_add(struct sockaddr *src, stru |
4270 | splx(s); | | 4274 | splx(s); |
4271 | if (sc == NULL) { | | 4275 | if (sc == NULL) { |
4272 | if (ipopts) | | 4276 | if (ipopts) |
4273 | (void)m_free(ipopts); | | 4277 | (void)m_free(ipopts); |
4274 | return 0; | | 4278 | return 0; |
4275 | } | | 4279 | } |
4276 | | | 4280 | |
4277 | /* | | 4281 | /* |
4278 | * Fill in the cache, and put the necessary IP and TCP | | 4282 | * Fill in the cache, and put the necessary IP and TCP |
4279 | * options into the reply. | | 4283 | * options into the reply. |
4280 | */ | | 4284 | */ |
4281 | memset(sc, 0, sizeof(struct syn_cache)); | | 4285 | memset(sc, 0, sizeof(struct syn_cache)); |
4282 | callout_init(&sc->sc_timer, CALLOUT_MPSAFE); | | 4286 | callout_init(&sc->sc_timer, CALLOUT_MPSAFE); |
4283 | bcopy(src, &sc->sc_src, src->sa_len); | | 4287 | memcpy(&sc->sc_src, src, src->sa_len); |
4284 | bcopy(dst, &sc->sc_dst, dst->sa_len); | | 4288 | memcpy(&sc->sc_dst, dst, dst->sa_len); |
4285 | sc->sc_flags = 0; | | 4289 | sc->sc_flags = 0; |
4286 | sc->sc_ipopts = ipopts; | | 4290 | sc->sc_ipopts = ipopts; |
4287 | sc->sc_irs = th->th_seq; | | 4291 | sc->sc_irs = th->th_seq; |
4288 | switch (src->sa_family) { | | 4292 | switch (src->sa_family) { |
4289 | #ifdef INET | | 4293 | #ifdef INET |
4290 | case AF_INET: | | 4294 | case AF_INET: |
4291 | { | | 4295 | { |
4292 | struct sockaddr_in *srcin = (void *)src; | | 4296 | struct sockaddr_in *srcin = (void *)src; |
4293 | struct sockaddr_in *dstin = (void *)dst; | | 4297 | struct sockaddr_in *dstin = (void *)dst; |
4294 | | | 4298 | |
4295 | sc->sc_iss = tcp_new_iss1(&dstin->sin_addr, | | 4299 | sc->sc_iss = tcp_new_iss1(&dstin->sin_addr, |
4296 | &srcin->sin_addr, dstin->sin_port, | | 4300 | &srcin->sin_addr, dstin->sin_port, |
4297 | srcin->sin_port, sizeof(dstin->sin_addr), 0); | | 4301 | srcin->sin_port, sizeof(dstin->sin_addr), 0); |