|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ ! 26: /* ! 27: * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995 ! 28: * The Regents of the University of California. All rights reserved. ! 29: * ! 30: * Redistribution and use in source and binary forms, with or without ! 31: * modification, are permitted provided that the following conditions ! 32: * are met: ! 33: * 1. Redistributions of source code must retain the above copyright ! 34: * notice, this list of conditions and the following disclaimer. ! 35: * 2. Redistributions in binary form must reproduce the above copyright ! 36: * notice, this list of conditions and the following disclaimer in the ! 37: * documentation and/or other materials provided with the distribution. ! 38: * 3. All advertising materials mentioning features or use of this software ! 39: * must display the following acknowledgement: ! 40: * This product includes software developed by the University of ! 41: * California, Berkeley and its contributors. ! 42: * 4. Neither the name of the University nor the names of its contributors ! 43: * may be used to endorse or promote products derived from this software ! 44: * without specific prior written permission. ! 45: * ! 46: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 47: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 48: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 49: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 50: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 51: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 52: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 53: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 54: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 55: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 56: * SUCH DAMAGE. ! 57: * ! 58: * @(#)tcp_input.c 8.5 (Berkeley) 4/10/94 ! 59: */ ! 60: ! 61: #ifndef TUBA_INCLUDE ! 62: #include <sys/param.h> ! 63: #include <sys/systm.h> ! 64: #include <sys/malloc.h> ! 65: #include <sys/mbuf.h> ! 66: #include <sys/protosw.h> ! 67: #include <sys/socket.h> ! 68: #include <sys/socketvar.h> ! 69: #include <sys/errno.h> ! 70: #include <sys/ev.h> ! 71: ! 72: #include <net/if.h> ! 73: #include <net/route.h> ! 74: ! 75: #include <netinet/in.h> ! 76: #include <netinet/in_systm.h> ! 77: #include <netinet/ip.h> ! 78: #include <netinet/in_pcb.h> ! 79: #include <netinet/ip_var.h> ! 80: #include <netinet/tcp.h> ! 81: #include <netinet/tcp_fsm.h> ! 82: #include <netinet/tcp_seq.h> ! 83: #include <netinet/tcp_timer.h> ! 84: #include <netinet/tcp_var.h> ! 85: #include <netinet/tcpip.h> ! 86: #include <netinet/tcp_debug.h> ! 87: #include <sys/ev.h> ! 88: ! 89: ! 90: #import <kern/kdebug.h> ! 91: ! 92: #if KDEBUG ! 93: ! 94: #define DBG_LAYER_BEG NETDBG_CODE(DBG_NETTCP, 0) ! 95: #define DBG_LAYER_END NETDBG_CODE(DBG_NETTCP, 2) ! 96: #define DBG_FNC_TCP_INPUT NETDBG_CODE(DBG_NETTCP, (3 << 8)) ! 97: ! 98: #endif ! 99: ! 100: extern struct inpcb_hash_str tcp_hash_str; ! 101: extern struct inpcb_hash_str tcp_lport_hash_str; ! 102: ! 103: #if DELACK_BITMASK_ON ! 104: extern u_long current_active_connections; ! 105: extern u_long last_active_conn_count; ! 106: ! 107: extern u_long delack_bitmask[]; ! 108: #endif ! 109: ! 110: int tcprexmtthresh = 3; ! 111: struct tcpiphdr tcp_saveti; ! 112: ! 113: extern u_long sb_max; ! 114: ! 115: #endif /* TUBA_INCLUDE */ ! 116: #define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ) ! 117: ! 118: /* for modulo comparisons of timestamps */ ! 119: #define TSTMP_LT(a,b) ((int)((a)-(b)) < 0) ! 120: #define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0) ! 121: ! 122: ! 123: ! 124: /* ! 125: * Insert segment ti into reassembly queue of tcp with ! 126: * control block tp. Return TH_FIN if reassembly now includes ! 127: * a segment with FIN. The macro form does the common case inline ! 128: * (segment is the next to be received on an established connection, ! 129: * and the queue is empty), avoiding linkage into and removal ! 130: * from the queue and repetition of various conversions. ! 131: * Set DELACK for segments received in order, but ack immediately ! 132: * when segments are out of order (so fast retransmit can work). ! 133: */ ! 134: #if DELACK_BITMASK_ON ! 135: #define TCP_REASS(tp, ti, m, so, flags) { \ ! 136: if ((ti)->ti_seq == (tp)->rcv_nxt && \ ! 137: (tp)->seg_next == (struct tcpiphdr *)(tp) && \ ! 138: (tp)->t_state == TCPS_ESTABLISHED) { \ ! 139: if (last_active_conn_count > DELACK_BITMASK_THRESH) \ ! 140: TCP_DELACK_BITSET(tp->t_inpcb->hash_element); \ ! 141: tp->t_flags |= TF_DELACK; \ ! 142: (tp)->rcv_nxt += (ti)->ti_len; \ ! 143: flags = (ti)->ti_flags & TH_FIN; \ ! 144: tcpstat.tcps_rcvpack++;\ ! 145: tcpstat.tcps_rcvbyte += (ti)->ti_len;\ ! 146: sbappend(&(so)->so_rcv, (m)); \ ! 147: sorwakeup(so); \ ! 148: } else { \ ! 149: (flags) = tcp_reass((tp), (ti), (m)); \ ! 150: tp->t_flags |= TF_ACKNOW; \ ! 151: } \ ! 152: } ! 153: #else ! 154: #define TCP_REASS(tp, ti, m, so, flags) { \ ! 155: if ((ti)->ti_seq == (tp)->rcv_nxt && \ ! 156: (tp)->seg_next == (struct tcpiphdr *)(tp) && \ ! 157: (tp)->t_state == TCPS_ESTABLISHED) { \ ! 158: tp->t_flags |= TF_DELACK; \ ! 159: (tp)->rcv_nxt += (ti)->ti_len; \ ! 160: flags = (ti)->ti_flags & TH_FIN; \ ! 161: tcpstat.tcps_rcvpack++;\ ! 162: tcpstat.tcps_rcvbyte += (ti)->ti_len;\ ! 163: sbappend(&(so)->so_rcv, (m)); \ ! 164: sorwakeup(so); \ ! 165: } else { \ ! 166: (flags) = tcp_reass((tp), (ti), (m)); \ ! 167: tp->t_flags |= TF_ACKNOW; \ ! 168: } \ ! 169: } ! 170: ! 171: #endif ! 172: ! 173: ! 174: ! 175: #ifndef TUBA_INCLUDE ! 176: ! 177: int ! 178: tcp_reass(tp, ti, m) ! 179: register struct tcpcb *tp; ! 180: register struct tcpiphdr *ti; ! 181: struct mbuf *m; ! 182: { ! 183: register struct tcpiphdr *q; ! 184: struct socket *so = tp->t_inpcb->inp_socket; ! 185: int flags; ! 186: ! 187: /* ! 188: * Call with ti==0 after become established to ! 189: * force pre-ESTABLISHED data up to user socket. ! 190: */ ! 191: if (ti == 0) ! 192: goto present; ! 193: ! 194: /* ! 195: * Find a segment which begins after this one does. ! 196: */ ! 197: for (q = tp->seg_next; q != (struct tcpiphdr *)tp; ! 198: q = (struct tcpiphdr *)q->ti_next) ! 199: if (SEQ_GT(q->ti_seq, ti->ti_seq)) ! 200: break; ! 201: ! 202: /* ! 203: * If there is a preceding segment, it may provide some of ! 204: * our data already. If so, drop the data from the incoming ! 205: * segment. If it provides all of our data, drop us. ! 206: */ ! 207: if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) { ! 208: register int i; ! 209: q = (struct tcpiphdr *)q->ti_prev; ! 210: /* conversion to int (in i) handles seq wraparound */ ! 211: i = q->ti_seq + q->ti_len - ti->ti_seq; ! 212: if (i > 0) { ! 213: if (i >= ti->ti_len) { ! 214: tcpstat.tcps_rcvduppack++; ! 215: tcpstat.tcps_rcvdupbyte += ti->ti_len; ! 216: m_freem(m); ! 217: return (0); ! 218: } ! 219: m_adj(m, i); ! 220: ti->ti_len -= i; ! 221: ti->ti_seq += i; ! 222: } ! 223: q = (struct tcpiphdr *)(q->ti_next); ! 224: } ! 225: tcpstat.tcps_rcvoopack++; ! 226: tcpstat.tcps_rcvoobyte += ti->ti_len; ! 227: REASS_MBUF(ti) = m; /* XXX */ ! 228: ! 229: /* ! 230: * While we overlap succeeding segments trim them or, ! 231: * if they are completely covered, dequeue them. ! 232: */ ! 233: while (q != (struct tcpiphdr *)tp) { ! 234: register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; ! 235: if (i <= 0) ! 236: break; ! 237: if (i < q->ti_len) { ! 238: q->ti_seq += i; ! 239: q->ti_len -= i; ! 240: m_adj(REASS_MBUF(q), i); ! 241: break; ! 242: } ! 243: q = (struct tcpiphdr *)q->ti_next; ! 244: m = REASS_MBUF((struct tcpiphdr *)q->ti_prev); ! 245: remque((queue_t) q->ti_prev); ! 246: m_freem(m); ! 247: } ! 248: ! 249: /* ! 250: * Stick new segment in its place. ! 251: */ ! 252: insque((queue_t) ti, (queue_t) q->ti_prev); ! 253: ! 254: present: ! 255: /* ! 256: * Present data to user, advancing rcv_nxt through ! 257: * completed sequence space. ! 258: */ ! 259: if (TCPS_HAVERCVDSYN(tp->t_state) == 0) ! 260: return (0); ! 261: ti = tp->seg_next; ! 262: if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt) ! 263: return (0); ! 264: if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len) ! 265: return (0); ! 266: do { ! 267: tp->rcv_nxt += ti->ti_len; ! 268: flags = ti->ti_flags & TH_FIN; ! 269: remque((queue_t) ti); ! 270: m = REASS_MBUF(ti); ! 271: ti = (struct tcpiphdr *)ti->ti_next; ! 272: if (so->so_state & SS_CANTRCVMORE) ! 273: m_freem(m); ! 274: else ! 275: sbappend(&so->so_rcv, m); ! 276: } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt); ! 277: ! 278: KERNEL_DEBUG(DBG_LAYER_END, ((ti->ti_dport << 16) | ti->ti_sport), ! 279: (((ti->ti_src.s_addr & 0xffff) << 16) | (ti->ti_dst.s_addr & 0xffff)), ! 280: ti->ti_seq, ti->ti_ack, ti->ti_win); ! 281: ! 282: sorwakeup(so); ! 283: return (flags); ! 284: } ! 285: ! 286: /* ! 287: * TCP input routine, follows pages 65-76 of the ! 288: * protocol specification dated September, 1981 very closely. ! 289: */ ! 290: void ! 291: tcp_input(m, iphlen) ! 292: register struct mbuf *m; ! 293: int iphlen; ! 294: { ! 295: register struct tcpiphdr *ti; ! 296: register struct inpcb *inp; ! 297: u_char *optp = NULL; ! 298: int optlen; ! 299: int len, tlen, off; ! 300: register struct tcpcb *tp = 0; ! 301: register int tiflags; ! 302: struct socket *so; ! 303: int todrop, acked, ourfinisacked, needoutput = 0; ! 304: short ostate; ! 305: struct in_addr laddr; ! 306: int dropsocket = 0; ! 307: int iss = 0; ! 308: u_long tiwin, ts_val, ts_ecr; ! 309: int ts_present = 0; ! 310: ! 311: ! 312: KERNEL_DEBUG(DBG_FNC_TCP_INPUT | DBG_FUNC_START,0,0,0,0,0); ! 313: ! 314: tcpstat.tcps_rcvtotal++; ! 315: /* ! 316: * Get IP and TCP header together in first mbuf. ! 317: * Note: IP leaves IP header in first mbuf. ! 318: */ ! 319: ti = mtod(m, struct tcpiphdr *); ! 320: ! 321: ! 322: KERNEL_DEBUG(DBG_LAYER_BEG, ((ti->ti_dport << 16) | ti->ti_sport), ! 323: (((ti->ti_src.s_addr & 0xffff) << 16) | (ti->ti_dst.s_addr & 0xffff)), ! 324: ti->ti_seq, ti->ti_ack, ti->ti_win); ! 325: ! 326: if (iphlen > sizeof (struct ip)) ! 327: ip_stripoptions(m, (struct mbuf *)0); ! 328: if (m->m_len < sizeof (struct tcpiphdr)) { ! 329: if ((m = m_pullup(m, sizeof (struct tcpiphdr))) == 0) { ! 330: tcpstat.tcps_rcvshort++; ! 331: KERNEL_DEBUG(DBG_FNC_TCP_INPUT | DBG_FUNC_END,0,0,0,0,0); ! 332: return; ! 333: } ! 334: ti = mtod(m, struct tcpiphdr *); ! 335: } ! 336: ! 337: /* ! 338: * Checksum extended TCP header and data. ! 339: */ ! 340: tlen = ((struct ip *)ti)->ip_len; ! 341: len = sizeof (struct ip) + tlen; ! 342: ti->ti_next = ti->ti_prev = 0; ! 343: ti->ti_x1 = 0; ! 344: ti->ti_len = (u_short)tlen; ! 345: HTONS(ti->ti_len); ! 346: if (ti->ti_sum = in_cksum(m, len)) { ! 347: tcpstat.tcps_rcvbadsum++; ! 348: goto drop; ! 349: } ! 350: #endif /* TUBA_INCLUDE */ ! 351: ! 352: /* ! 353: * Check that TCP offset makes sense, ! 354: * pull out TCP options and adjust length. XXX ! 355: */ ! 356: off = ti->ti_off << 2; ! 357: if (off < sizeof (struct tcphdr) || off > tlen) { ! 358: tcpstat.tcps_rcvbadoff++; ! 359: goto drop; ! 360: } ! 361: tlen -= off; ! 362: ti->ti_len = tlen; ! 363: if (off > sizeof (struct tcphdr)) { ! 364: if (m->m_len < sizeof(struct ip) + off) { ! 365: if ((m = m_pullup(m, sizeof (struct ip) + off)) == 0) { ! 366: tcpstat.tcps_rcvshort++; ! 367: KERNEL_DEBUG(DBG_FNC_TCP_INPUT | DBG_FUNC_END,0,0,0,0,0); ! 368: return; ! 369: } ! 370: ti = mtod(m, struct tcpiphdr *); ! 371: } ! 372: optlen = off - sizeof (struct tcphdr); ! 373: optp = mtod(m, u_char *) + sizeof (struct tcpiphdr); ! 374: /* ! 375: * Do quick retrieval of timestamp options ("options ! 376: * prediction?"). If timestamp is the only option and it's ! 377: * formatted as recommended in RFC 1323 appendix A, we ! 378: * quickly get the values now and not bother calling ! 379: * tcp_dooptions(), etc. ! 380: */ ! 381: if ((optlen == TCPOLEN_TSTAMP_APPA || ! 382: (optlen > TCPOLEN_TSTAMP_APPA && ! 383: optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) && ! 384: *(u_long *)optp == htonl(TCPOPT_TSTAMP_HDR) && ! 385: (ti->ti_flags & TH_SYN) == 0) { ! 386: ts_present = 1; ! 387: ts_val = ntohl(*(u_long *)(optp + 4)); ! 388: ts_ecr = ntohl(*(u_long *)(optp + 8)); ! 389: optp = NULL; /* we've parsed the options */ ! 390: } ! 391: } ! 392: tiflags = ti->ti_flags; ! 393: ! 394: /* ! 395: * Convert TCP protocol specific fields to host format. ! 396: */ ! 397: NTOHL(ti->ti_seq); ! 398: NTOHL(ti->ti_ack); ! 399: NTOHS(ti->ti_win); ! 400: NTOHS(ti->ti_urp); ! 401: ! 402: /* ! 403: * Locate pcb for segment. ! 404: */ ! 405: findpcb: ! 406: inp = inet_hash1(&tcp_hash_str, ti->ti_dst.s_addr, ti->ti_dport, ! 407: ti->ti_src.s_addr, ti->ti_sport); ! 408: inp = hash_in_pcblookup(inp, ti->ti_src, ti->ti_sport, ! 409: ti->ti_dst, ti->ti_dport); ! 410: if (inp == 0) { ! 411: findpcb_nolookup: ! 412: inp = inet_hash1(&tcp_hash_str, 0, ti->ti_dport,0,0); ! 413: inp = hash_in_pcbwild(inp, ! 414: ti->ti_src, ti->ti_sport, ! 415: ti->ti_dst, ti->ti_dport, INPLOOKUP_WILDCARD); ! 416: /* ! 417: if (inp == 0) ! 418: inp = in_pcblookup(&tcb, ti->ti_src, ti->ti_sport, ! 419: ti->ti_dst, ti->ti_dport, INPLOOKUP_WILDCARD); ! 420: */ ! 421: } ! 422: /* ! 423: * If the state is CLOSED (i.e., TCB does not exist) then ! 424: * all data in the incoming segment is discarded. ! 425: * If the TCB exists but is in CLOSED state, it is embryonic, ! 426: * but should either do a listen or a connect soon. ! 427: */ ! 428: if (inp == 0) ! 429: goto dropwithreset; ! 430: tp = intotcpcb(inp); ! 431: if (tp == 0) ! 432: goto dropwithreset; ! 433: if (tp->t_state == TCPS_CLOSED) ! 434: goto drop; ! 435: ! 436: /* Unscale the window into a 32-bit value. */ ! 437: if ((tiflags & TH_SYN) == 0) ! 438: tiwin = ti->ti_win << tp->snd_scale; ! 439: else ! 440: tiwin = ti->ti_win; ! 441: ! 442: so = inp->inp_socket; ! 443: if (so->so_options & (SO_DEBUG|SO_ACCEPTCONN)) { ! 444: if (so->so_options & SO_DEBUG) { ! 445: ostate = tp->t_state; ! 446: tcp_saveti = *ti; ! 447: } ! 448: if (so->so_options & SO_ACCEPTCONN) { ! 449: if ((tiflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) { ! 450: /* ! 451: * Note: dropwithreset makes sure we don't ! 452: * send a reset in response to a RST. ! 453: */ ! 454: if (tiflags & TH_ACK) { ! 455: tcpstat.tcps_badsyn++; ! 456: goto dropwithreset; ! 457: } ! 458: goto drop; ! 459: } ! 460: so = sonewconn(so, 0); ! 461: if (so == 0) ! 462: goto drop; ! 463: /* ! 464: * This is ugly, but .... ! 465: * ! 466: * Mark socket as temporary until we're ! 467: * committed to keeping it. The code at ! 468: * ``drop'' and ``dropwithreset'' check the ! 469: * flag dropsocket to see if the temporary ! 470: * socket created here should be discarded. ! 471: * We mark the socket as discardable until ! 472: * we're committed to it below in TCPS_LISTEN. ! 473: */ ! 474: dropsocket++; ! 475: inp = (struct inpcb *)so->so_pcb; ! 476: inp->inp_laddr = ti->ti_dst; ! 477: inp->inp_lport = ti->ti_dport; ! 478: lport_hash_insert(inp); ! 479: /* kprintf("TCP - lport hash element = %d\n", inp->lport_hash_element); */ ! 480: #if BSD>=43 ! 481: inp->inp_options = ip_srcroute(); ! 482: #endif ! 483: inp->inp_flags |= INP_NOLOOKUP; ! 484: ! 485: tp = intotcpcb(inp); ! 486: tp->t_state = TCPS_LISTEN; ! 487: ! 488: /* Compute proper scaling value from buffer space ! 489: */ ! 490: while (tp->request_r_scale < TCP_MAX_WINSHIFT && ! 491: TCP_MAXWIN << tp->request_r_scale < so->so_rcv.sb_hiwat) ! 492: tp->request_r_scale++; ! 493: } ! 494: } ! 495: ! 496: /* ! 497: * Segment received on connection. ! 498: * Reset idle time and keep-alive timer. ! 499: */ ! 500: tp->t_idle = 0; ! 501: tp->t_timer[TCPT_KEEP] = tcp_keepidle; ! 502: ! 503: /* ! 504: * Process options if not in LISTEN state, ! 505: * else do it below (after getting remote address). ! 506: */ ! 507: if (optp && tp->t_state != TCPS_LISTEN) ! 508: tcp_dooptions(tp, optp, optlen, ti, ! 509: &ts_present, &ts_val, &ts_ecr); ! 510: ! 511: /* ! 512: * Header prediction: check for the two common cases ! 513: * of a uni-directional data xfer. If the packet has ! 514: * no control flags, is in-sequence, the window didn't ! 515: * change and we're not retransmitting, it's a ! 516: * candidate. If the length is zero and the ack moved ! 517: * forward, we're the sender side of the xfer. Just ! 518: * free the data acked & wake any higher level process ! 519: * that was blocked waiting for space. If the length ! 520: * is non-zero and the ack didn't move, we're the ! 521: * receiver side. If we're getting packets in-order ! 522: * (the reassembly queue is empty), add the data to ! 523: * the socket buffer and note that we need a delayed ack. ! 524: */ ! 525: if (tp->t_state == TCPS_ESTABLISHED && ! 526: (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK && ! 527: (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) && ! 528: ti->ti_seq == tp->rcv_nxt && ! 529: tiwin && tiwin == tp->snd_wnd && ! 530: tp->snd_nxt == tp->snd_max) { ! 531: ! 532: /* ! 533: * If last ACK falls within this segment's sequence numbers, ! 534: * record the timestamp. ! 535: */ ! 536: if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && ! 537: SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len)) { ! 538: tp->ts_recent_age = tcp_now; ! 539: tp->ts_recent = ts_val; ! 540: } ! 541: ! 542: if (ti->ti_len == 0) { ! 543: if (SEQ_GT(ti->ti_ack, tp->snd_una) && ! 544: SEQ_LEQ(ti->ti_ack, tp->snd_max) && ! 545: tp->snd_cwnd >= tp->snd_wnd) { ! 546: /* ! 547: * this is a pure ack for outstanding data. ! 548: */ ! 549: ++tcpstat.tcps_predack; ! 550: if (ts_present) ! 551: tcp_xmit_timer(tp, tcp_now-ts_ecr+1); ! 552: else if (tp->t_rtt && ! 553: SEQ_GT(ti->ti_ack, tp->t_rtseq)) ! 554: tcp_xmit_timer(tp, tp->t_rtt); ! 555: acked = ti->ti_ack - tp->snd_una; ! 556: tcpstat.tcps_rcvackpack++; ! 557: tcpstat.tcps_rcvackbyte += acked; ! 558: sbdrop(&so->so_snd, acked); ! 559: tp->snd_una = ti->ti_ack; ! 560: m_freem(m); ! 561: ! 562: /* ! 563: * If all outstanding data are acked, stop ! 564: * retransmit timer, otherwise restart timer ! 565: * using current (possibly backed-off) value. ! 566: * If process is waiting for space, ! 567: * wakeup/selwakeup/signal. If data ! 568: * are ready to send, let tcp_output ! 569: * decide between more output or persist. ! 570: */ ! 571: if (tp->snd_una == tp->snd_max) ! 572: tp->t_timer[TCPT_REXMT] = 0; ! 573: else if (tp->t_timer[TCPT_PERSIST] == 0) ! 574: tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; ! 575: ! 576: if (so->so_snd.sb_flags & SB_NOTIFY) ! 577: sowwakeup(so); ! 578: if (so->so_snd.sb_cc) ! 579: (void) tcp_output(tp); ! 580: ! 581: KERNEL_DEBUG(DBG_FNC_TCP_INPUT | DBG_FUNC_END,0,0,0,0,0); ! 582: return; ! 583: } ! 584: } else if (ti->ti_ack == tp->snd_una && ! 585: tp->seg_next == (struct tcpiphdr *)tp && ! 586: ti->ti_len <= sbspace(&so->so_rcv)) { ! 587: /* ! 588: * this is a pure, in-sequence data packet ! 589: * with nothing on the reassembly queue and ! 590: * we have enough buffer space to take it. ! 591: */ ! 592: ++tcpstat.tcps_preddat; ! 593: tp->rcv_nxt += ti->ti_len; ! 594: tcpstat.tcps_rcvpack++; ! 595: tcpstat.tcps_rcvbyte += ti->ti_len; ! 596: /* ! 597: * Drop TCP, IP headers and TCP options then add data ! 598: * to socket buffer. ! 599: */ ! 600: m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); ! 601: m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); ! 602: sbappend(&so->so_rcv, m); ! 603: ! 604: KERNEL_DEBUG(DBG_LAYER_END, ((ti->ti_dport << 16) | ti->ti_sport), ! 605: (((ti->ti_src.s_addr & 0xffff) << 16) | (ti->ti_dst.s_addr & 0xffff)), ! 606: ti->ti_seq, ti->ti_ack, ti->ti_win); ! 607: ! 608: sorwakeup(so); ! 609: #if DELACK_BITMASK_ON ! 610: if (last_active_conn_count > DELACK_BITMASK_THRESH) ! 611: TCP_DELACK_BITSET(tp->t_inpcb->hash_element); ! 612: #endif ! 613: tp->t_flags |= TF_DELACK; ! 614: KERNEL_DEBUG(DBG_FNC_TCP_INPUT | DBG_FUNC_END,0,0,0,0,0); ! 615: return; ! 616: } ! 617: } ! 618: ! 619: /* ! 620: * Drop TCP, IP headers and TCP options. ! 621: */ ! 622: m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); ! 623: m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); ! 624: ! 625: /* ! 626: * Calculate amount of space in receive window, ! 627: * and then do TCP input processing. ! 628: * Receive window is amount of space in rcv queue, ! 629: * but not less than advertised window. ! 630: */ ! 631: { int win; ! 632: ! 633: win = sbspace(&so->so_rcv); ! 634: if (win < 0) ! 635: win = 0; ! 636: tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt)); ! 637: } ! 638: ! 639: switch (tp->t_state) { ! 640: ! 641: /* ! 642: * If the state is LISTEN then ignore segment if it contains an RST. ! 643: * If the segment contains an ACK then it is bad and send a RST. ! 644: * If it does not contain a SYN then it is not interesting; drop it. ! 645: * Don't bother responding if the destination was a broadcast. ! 646: * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial ! 647: * tp->iss, and send a segment: ! 648: * <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK> ! 649: * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. ! 650: * Fill in remote peer address fields if not previously specified. ! 651: * Enter SYN_RECEIVED state, and process any other fields of this ! 652: * segment in this state. ! 653: */ ! 654: case TCPS_LISTEN: { ! 655: struct mbuf *am; ! 656: register struct sockaddr_in *sin; ! 657: ! 658: #ifdef already_done ! 659: if (tiflags & TH_RST) ! 660: goto drop; ! 661: if (tiflags & TH_ACK) ! 662: goto dropwithreset; ! 663: if ((tiflags & TH_SYN) == 0) ! 664: goto drop; ! 665: #endif ! 666: ! 667: if ((ti->ti_dport == ti->ti_sport) && ! 668: (ti->ti_dst.s_addr == ti->ti_src.s_addr)) ! 669: goto drop; ! 670: /* ! 671: * RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN ! 672: * in_broadcast() should never return true on a received ! 673: * packet with M_BCAST not set. ! 674: */ ! 675: if (m->m_flags & (M_BCAST|M_MCAST) || ! 676: IN_MULTICAST(ntohl(ti->ti_dst.s_addr))) ! 677: goto drop; ! 678: am = m_get(M_DONTWAIT, MT_SONAME); /* XXX */ ! 679: if (am == NULL) ! 680: goto drop; ! 681: am->m_len = sizeof (struct sockaddr_in); ! 682: sin = mtod(am, struct sockaddr_in *); ! 683: sin->sin_family = AF_INET; ! 684: sin->sin_len = sizeof(*sin); ! 685: sin->sin_addr = ti->ti_src; ! 686: sin->sin_port = ti->ti_sport; ! 687: bzero((caddr_t)sin->sin_zero, sizeof(sin->sin_zero)); ! 688: laddr = inp->inp_laddr; ! 689: if (inp->inp_laddr.s_addr == INADDR_ANY) ! 690: inp->inp_laddr = ti->ti_dst; ! 691: ! 692: if (in_pcbconnect(inp, am)) { ! 693: inp->inp_laddr = laddr; ! 694: (void) m_free(am); ! 695: goto drop; ! 696: } ! 697: inp->inp_flags &= ~INP_NOLOOKUP; ! 698: ! 699: (void) m_free(am); ! 700: tp->t_template = tcp_template(tp); ! 701: if (tp->t_template == 0) { ! 702: tp = tcp_drop(tp, ENOBUFS); ! 703: dropsocket = 0; /* socket is already gone */ ! 704: goto drop; ! 705: } ! 706: if (optp) ! 707: tcp_dooptions(tp, optp, optlen, ti, ! 708: &ts_present, &ts_val, &ts_ecr); ! 709: if (iss) ! 710: tp->iss = iss; ! 711: else ! 712: tp->iss = tcp_iss; ! 713: tcp_iss += TCP_ISSINCR/4; ! 714: tp->irs = ti->ti_seq; ! 715: tcp_sendseqinit(tp); ! 716: tcp_rcvseqinit(tp); ! 717: tp->t_flags |= TF_ACKNOW; ! 718: tp->t_state = TCPS_SYN_RECEIVED; ! 719: tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; ! 720: dropsocket = 0; /* committed to socket */ ! 721: tcpstat.tcps_accepts++; ! 722: goto trimthenstep6; ! 723: } ! 724: ! 725: /* ! 726: * If the state is SYN_RECEIVED: ! 727: * if seg contains SYN/ACK, send a RST. ! 728: * if seg contains an ACK, but not for our SYN/ACK, send a RST. ! 729: */ ! 730: case TCPS_SYN_RECEIVED: ! 731: if (tiflags & TH_ACK) { ! 732: if (tiflags & TH_SYN) { ! 733: tcpstat.tcps_badsyn++; ! 734: goto dropwithreset; ! 735: } ! 736: if (SEQ_LEQ(ti->ti_ack, tp->snd_una) || ! 737: SEQ_GT(ti->ti_ack, tp->snd_max)) ! 738: goto dropwithreset; ! 739: } ! 740: break; ! 741: ! 742: /* ! 743: * If the state is SYN_SENT: ! 744: * if seg contains an ACK, but not for our SYN, drop the input. ! 745: * if seg contains a RST, then drop the connection. ! 746: * if seg does not contain SYN, then drop it. ! 747: * Otherwise this is an acceptable SYN segment ! 748: * initialize tp->rcv_nxt and tp->irs ! 749: * if seg contains ack then advance tp->snd_una ! 750: * if SYN has been acked change to ESTABLISHED else SYN_RCVD state ! 751: * arrange for segment to be acked (eventually) ! 752: * continue processing rest of data/controls, beginning with URG ! 753: */ ! 754: case TCPS_SYN_SENT: ! 755: if ((tiflags & TH_ACK) && ! 756: (SEQ_LEQ(ti->ti_ack, tp->iss) || ! 757: SEQ_GT(ti->ti_ack, tp->snd_max))) ! 758: goto dropwithreset; ! 759: if (tiflags & TH_RST) { ! 760: if (tiflags & TH_ACK) ! 761: tp = tcp_drop(tp, ECONNREFUSED); ! 762: goto drop; ! 763: } ! 764: if ((tiflags & TH_SYN) == 0) ! 765: goto drop; ! 766: if (tiflags & TH_ACK) { ! 767: tp->snd_una = ti->ti_ack; ! 768: if (SEQ_LT(tp->snd_nxt, tp->snd_una)) ! 769: tp->snd_nxt = tp->snd_una; ! 770: } ! 771: tp->t_timer[TCPT_REXMT] = 0; ! 772: tp->irs = ti->ti_seq; ! 773: tcp_rcvseqinit(tp); ! 774: tp->t_flags |= TF_ACKNOW; ! 775: if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) { ! 776: tcpstat.tcps_connects++; ! 777: soisconnected(so); ! 778: #if DELACK_BITMASK_ON ! 779: current_active_connections++; ! 780: #endif ! 781: tp->t_state = TCPS_ESTABLISHED; ! 782: /* Do window scaling on this connection? */ ! 783: if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == ! 784: (TF_RCVD_SCALE|TF_REQ_SCALE)) { ! 785: tp->snd_scale = tp->requested_s_scale; ! 786: tp->rcv_scale = tp->request_r_scale; ! 787: } ! 788: (void) tcp_reass(tp, (struct tcpiphdr *)0, ! 789: (struct mbuf *)0); ! 790: /* ! 791: * if we didn't have to retransmit the SYN, ! 792: * use its rtt as our initial srtt & rtt var. ! 793: */ ! 794: if (tp->t_rtt) ! 795: tcp_xmit_timer(tp, tp->t_rtt); ! 796: } else ! 797: tp->t_state = TCPS_SYN_RECEIVED; ! 798: ! 799: trimthenstep6: ! 800: /* ! 801: * Advance ti->ti_seq to correspond to first data byte. ! 802: * If data, trim to stay within window, ! 803: * dropping FIN if necessary. ! 804: */ ! 805: ti->ti_seq++; ! 806: if (ti->ti_len > tp->rcv_wnd) { ! 807: todrop = ti->ti_len - tp->rcv_wnd; ! 808: m_adj(m, -todrop); ! 809: ti->ti_len = tp->rcv_wnd; ! 810: tiflags &= ~TH_FIN; ! 811: tcpstat.tcps_rcvpackafterwin++; ! 812: tcpstat.tcps_rcvbyteafterwin += todrop; ! 813: } ! 814: tp->snd_wl1 = ti->ti_seq - 1; ! 815: tp->rcv_up = ti->ti_seq; ! 816: goto step6; ! 817: } ! 818: ! 819: /* ! 820: * States other than LISTEN or SYN_SENT. ! 821: * First check the RST flag and sequence number since reset segments ! 822: * are exempt from the timestamp and connection count tests. This ! 823: * fixes a bug introduced by the Stevens, vol. 2, p. 960 bugfix ! 824: * below which allowed reset segments in half the sequence space ! 825: * to fall though and be processed (which gives forged reset ! 826: * segments with a random sequence number a 50 percent chance of ! 827: * killing a connection). ! 828: * Then check timestamp, if present. ! 829: * Then check the connection count, if present. ! 830: * Then check that at least some bytes of segment are within ! 831: * receive window. If segment begins before rcv_nxt, ! 832: * drop leading data (and SYN); if nothing left, just ack. ! 833: * ! 834: * If the RST bit is set, check the sequence number to see ! 835: * if this is a valid reset segment. ! 836: * RFC 793 page 37: ! 837: * In all states except SYN-SENT, all reset (RST) segments ! 838: * are validated by checking their SEQ-fields. A reset is ! 839: * valid if its sequence number is in the window. ! 840: * Note: this does not take into account delayed ACKs, so ! 841: * we should test against last_ack_sent instead of rcv_nxt. ! 842: * Also, it does not make sense to allow reset segments with ! 843: * sequence numbers greater than last_ack_sent to be processed ! 844: * since these sequence numbers are just the acknowledgement ! 845: * numbers in our outgoing packets being echoed back at us, ! 846: * and these acknowledgement numbers are monotonically ! 847: * increasing. ! 848: * If we have multiple segments in flight, the intial reset ! 849: * segment sequence numbers will be to the left of last_ack_sent, ! 850: * but they will eventually catch up. ! 851: * In any case, it never made sense to trim reset segments to ! 852: * fit the receive window since RFC 1122 says: ! 853: * 4.2.2.12 RST Segment: RFC-793 Section 3.4 ! 854: * ! 855: * A TCP SHOULD allow a received RST segment to include data. ! 856: * ! 857: * DISCUSSION ! 858: * It has been suggested that a RST segment could contain ! 859: * ASCII text that encoded and explained the cause of the ! 860: * RST. No standard has yet been established for such ! 861: * data. ! 862: * ! 863: * If the reset segment passes the sequence number test examine ! 864: * the state: ! 865: * SYN_RECEIVED STATE: ! 866: * If passive open, return to LISTEN state. ! 867: * If active open, inform user that connection was refused. ! 868: * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: ! 869: * Inform user that connection was reset, and close tcb. ! 870: * CLOSING, LAST_ACK, TIME_WAIT STATES ! 871: * Close the tcb. ! 872: * TIME_WAIT state: ! 873: * Drop the segment - see Stevens, vol. 2, p. 964 and ! 874: * RFC 1337. ! 875: */ ! 876: if (tiflags & TH_RST) { ! 877: if (tp->last_ack_sent == ti->ti_seq) { ! 878: switch (tp->t_state) { ! 879: ! 880: case TCPS_SYN_RECEIVED: ! 881: so->so_error = ECONNREFUSED; ! 882: goto close; ! 883: ! 884: case TCPS_ESTABLISHED: ! 885: case TCPS_FIN_WAIT_1: ! 886: case TCPS_FIN_WAIT_2: ! 887: case TCPS_CLOSE_WAIT: ! 888: so->so_error = ECONNRESET; ! 889: close: ! 890: postevent(so, 0, EV_RESET); ! 891: tp->t_state = TCPS_CLOSED; ! 892: tcpstat.tcps_drops++; ! 893: tp = tcp_close(tp); ! 894: break; ! 895: ! 896: case TCPS_CLOSING: ! 897: case TCPS_LAST_ACK: ! 898: tp = tcp_close(tp); ! 899: break; ! 900: ! 901: case TCPS_TIME_WAIT: ! 902: break; ! 903: } ! 904: } ! 905: goto drop; ! 906: } ! 907: ! 908: /* ! 909: * RFC 1323 PAWS: If we have a timestamp reply on this segment ! 910: * and it's less than ts_recent, drop it. ! 911: */ ! 912: ! 913: if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent && ! 914: TSTMP_LT(ts_val, tp->ts_recent)) { ! 915: ! 916: /* Check to see if ts_recent is over 24 days old. */ ! 917: if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) { ! 918: /* ! 919: * Invalidate ts_recent. If this segment updates ! 920: * ts_recent, the age will be reset later and ts_recent ! 921: * will get a valid value. If it does not, setting ! 922: * ts_recent to zero will at least satisfy the ! 923: * requirement that zero be placed in the timestamp ! 924: * echo reply when ts_recent isn't valid. The ! 925: * age isn't reset until we get a valid ts_recent ! 926: * because we don't want out-of-order segments to be ! 927: * dropped when ts_recent is old. ! 928: */ ! 929: tp->ts_recent = 0; ! 930: } else { ! 931: tcpstat.tcps_rcvduppack++; ! 932: tcpstat.tcps_rcvdupbyte += ti->ti_len; ! 933: tcpstat.tcps_pawsdrop++; ! 934: goto dropafterack; ! 935: } ! 936: } ! 937: ! 938: ! 939: /* ! 940: * In the SYN-RECEIVED state, validate that the packet belongs to ! 941: * this connection before trimming the data to fit the receive ! 942: * window. Check the sequence number versus IRS since we know ! 943: * the sequence numbers haven't wrapped. This is a partial fix ! 944: * for the "LAND" DoS attack. ! 945: */ ! 946: if (tp->t_state == TCPS_SYN_RECEIVED && SEQ_LT(ti->ti_seq, tp->irs)) ! 947: goto dropwithreset; ! 948: ! 949: todrop = tp->rcv_nxt - ti->ti_seq; ! 950: if (todrop > 0) { ! 951: if (tiflags & TH_SYN) { ! 952: tiflags &= ~TH_SYN; ! 953: ti->ti_seq++; ! 954: if (ti->ti_urp > 1) ! 955: ti->ti_urp--; ! 956: else ! 957: tiflags &= ~TH_URG; ! 958: todrop--; ! 959: } ! 960: if (todrop >= ti->ti_len) { ! 961: tcpstat.tcps_rcvduppack++; ! 962: tcpstat.tcps_rcvdupbyte += ti->ti_len; ! 963: /* ! 964: * If segment is just one to the left of the window, ! 965: * check two special cases: ! 966: * 1. Don't toss RST in response to 4.2-style keepalive. ! 967: * 2. If the only thing to drop is a FIN, we can drop ! 968: * it, but check the ACK or we will get into FIN ! 969: * wars if our FINs crossed (both CLOSING). ! 970: * In either case, send ACK to resynchronize, ! 971: * but keep on processing for RST or ACK. ! 972: */ ! 973: if ((tiflags & TH_FIN && todrop == ti->ti_len + 1) ! 974: #ifdef TCP_COMPAT_42 ! 975: || (tiflags & TH_RST && ti->ti_seq == tp->rcv_nxt - 1) ! 976: #endif ! 977: ) { ! 978: todrop = ti->ti_len; ! 979: tiflags &= ~TH_FIN; ! 980: } else { ! 981: /* ! 982: * Handle the case when a bound socket connects ! 983: * to itself. Allow packets with a SYN and ! 984: * an ACK to continue with the processing. ! 985: */ ! 986: if (todrop != 0 || (tiflags & TH_ACK) == 0) ! 987: goto dropafterack; ! 988: } ! 989: tp->t_flags |= TF_ACKNOW; ! 990: } else { ! 991: tcpstat.tcps_rcvpartduppack++; ! 992: tcpstat.tcps_rcvpartdupbyte += todrop; ! 993: } ! 994: m_adj(m, todrop); ! 995: ti->ti_seq += todrop; ! 996: ti->ti_len -= todrop; ! 997: if (ti->ti_urp > todrop) ! 998: ti->ti_urp -= todrop; ! 999: else { ! 1000: tiflags &= ~TH_URG; ! 1001: ti->ti_urp = 0; ! 1002: } ! 1003: } ! 1004: ! 1005: /* ! 1006: * If new data are received on a connection after the ! 1007: * user processes are gone, then RST the other end. ! 1008: */ ! 1009: if ((so->so_state & SS_NOFDREF) && ! 1010: tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) { ! 1011: tp = tcp_close(tp); ! 1012: tcpstat.tcps_rcvafterclose++; ! 1013: goto dropwithreset; ! 1014: } ! 1015: ! 1016: /* ! 1017: * If segment ends after window, drop trailing data ! 1018: * (and PUSH and FIN); if nothing left, just ACK. ! 1019: */ ! 1020: todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd); ! 1021: if (todrop > 0) { ! 1022: tcpstat.tcps_rcvpackafterwin++; ! 1023: if (todrop >= ti->ti_len) { ! 1024: tcpstat.tcps_rcvbyteafterwin += ti->ti_len; ! 1025: /* ! 1026: * If a new connection request is received ! 1027: * while in TIME_WAIT, drop the old connection ! 1028: * and start over if the sequence numbers ! 1029: * are above the previous ones. ! 1030: */ ! 1031: if (tiflags & TH_SYN && ! 1032: tp->t_state == TCPS_TIME_WAIT && ! 1033: SEQ_GT(ti->ti_seq, tp->rcv_nxt)) { ! 1034: iss = tp->snd_nxt + TCP_ISSINCR; ! 1035: tp = tcp_close(tp); ! 1036: goto findpcb_nolookup; ! 1037: } ! 1038: /* ! 1039: * If window is closed can only take segments at ! 1040: * window edge, and have to drop data and PUSH from ! 1041: * incoming segments. Continue processing, but ! 1042: * remember to ack. Otherwise, drop segment ! 1043: * and ack. ! 1044: */ ! 1045: if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) { ! 1046: tp->t_flags |= TF_ACKNOW; ! 1047: tcpstat.tcps_rcvwinprobe++; ! 1048: } else ! 1049: goto dropafterack; ! 1050: } else ! 1051: tcpstat.tcps_rcvbyteafterwin += todrop; ! 1052: m_adj(m, -todrop); ! 1053: ti->ti_len -= todrop; ! 1054: tiflags &= ~(TH_PUSH|TH_FIN); ! 1055: } ! 1056: ! 1057: /* ! 1058: * If last ACK falls within this segment's sequence numbers, ! 1059: * record its timestamp. ! 1060: */ ! 1061: if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && ! 1062: SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len + ! 1063: ((tiflags & (TH_SYN|TH_FIN)) != 0))) { ! 1064: tp->ts_recent_age = tcp_now; ! 1065: tp->ts_recent = ts_val; ! 1066: } ! 1067: ! 1068: /* ! 1069: * If a SYN is in the window, then this is an ! 1070: * error and we send an RST and drop the connection. ! 1071: */ ! 1072: if (tiflags & TH_SYN) { ! 1073: tp = tcp_drop(tp, ECONNRESET); ! 1074: goto dropwithreset; ! 1075: } ! 1076: ! 1077: /* ! 1078: * If the ACK bit is off we drop the segment and return. ! 1079: */ ! 1080: if ((tiflags & TH_ACK) == 0) ! 1081: goto drop; ! 1082: ! 1083: /* ! 1084: * Ack processing. ! 1085: */ ! 1086: switch (tp->t_state) { ! 1087: ! 1088: /* ! 1089: * In SYN_RECEIVED state, the ack ACKs our SYN, so enter ! 1090: * ESTABLISHED state and continue processing. ! 1091: * The ACK was checked above. ! 1092: */ ! 1093: case TCPS_SYN_RECEIVED: ! 1094: ! 1095: tcpstat.tcps_connects++; ! 1096: soisconnected(so); ! 1097: #if DELACK_BITMASK_ON ! 1098: current_active_connections++; ! 1099: #endif ! 1100: tp->t_state = TCPS_ESTABLISHED; ! 1101: /* Do window scaling? */ ! 1102: if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == ! 1103: (TF_RCVD_SCALE|TF_REQ_SCALE)) { ! 1104: tp->snd_scale = tp->requested_s_scale; ! 1105: tp->rcv_scale = tp->request_r_scale; ! 1106: } ! 1107: (void) tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0); ! 1108: tp->snd_wl1 = ti->ti_seq - 1; ! 1109: /* fall into ... */ ! 1110: ! 1111: /* ! 1112: * In ESTABLISHED state: drop duplicate ACKs; ACK out of range ! 1113: * ACKs. If the ack is in the range ! 1114: * tp->snd_una < ti->ti_ack <= tp->snd_max ! 1115: * then advance tp->snd_una to ti->ti_ack and drop ! 1116: * data from the retransmission queue. If this ACK reflects ! 1117: * more up to date window information we update our window information. ! 1118: */ ! 1119: case TCPS_ESTABLISHED: ! 1120: case TCPS_FIN_WAIT_1: ! 1121: case TCPS_FIN_WAIT_2: ! 1122: case TCPS_CLOSE_WAIT: ! 1123: case TCPS_CLOSING: ! 1124: case TCPS_LAST_ACK: ! 1125: case TCPS_TIME_WAIT: ! 1126: ! 1127: if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { ! 1128: if (ti->ti_len == 0 && tiwin == tp->snd_wnd) { ! 1129: tcpstat.tcps_rcvdupack++; ! 1130: /* ! 1131: * If we have outstanding data (other than ! 1132: * a window probe), this is a completely ! 1133: * duplicate ack (ie, window info didn't ! 1134: * change), the ack is the biggest we've ! 1135: * seen and we've seen exactly our rexmt ! 1136: * threshhold of them, assume a packet ! 1137: * has been dropped and retransmit it. ! 1138: * Kludge snd_nxt & the congestion ! 1139: * window so we send only this one ! 1140: * packet. ! 1141: * ! 1142: * We know we're losing at the current ! 1143: * window size so do congestion avoidance ! 1144: * (set ssthresh to half the current window ! 1145: * and pull our congestion window back to ! 1146: * the new ssthresh). ! 1147: * ! 1148: * Dup acks mean that packets have left the ! 1149: * network (they're now cached at the receiver) ! 1150: * so bump cwnd by the amount in the receiver ! 1151: * to keep a constant cwnd packets in the ! 1152: * network. ! 1153: */ ! 1154: if (tp->t_timer[TCPT_REXMT] == 0 || ! 1155: ti->ti_ack != tp->snd_una) ! 1156: tp->t_dupacks = 0; ! 1157: else if (++tp->t_dupacks == tcprexmtthresh) { ! 1158: tcp_seq onxt = tp->snd_nxt; ! 1159: u_int win = ! 1160: min(tp->snd_wnd, tp->snd_cwnd) / 2 / ! 1161: tp->t_maxseg; ! 1162: ! 1163: if (win < 2) ! 1164: win = 2; ! 1165: tp->snd_ssthresh = win * tp->t_maxseg; ! 1166: tp->t_timer[TCPT_REXMT] = 0; ! 1167: tp->t_rtt = 0; ! 1168: tp->snd_nxt = ti->ti_ack; ! 1169: tp->snd_cwnd = tp->t_maxseg; ! 1170: (void) tcp_output(tp); ! 1171: tp->snd_cwnd = tp->snd_ssthresh + ! 1172: tp->t_maxseg * tp->t_dupacks; ! 1173: if (SEQ_GT(onxt, tp->snd_nxt)) ! 1174: tp->snd_nxt = onxt; ! 1175: goto drop; ! 1176: } else if (tp->t_dupacks > tcprexmtthresh) { ! 1177: tp->snd_cwnd += tp->t_maxseg; ! 1178: (void) tcp_output(tp); ! 1179: goto drop; ! 1180: } ! 1181: } else ! 1182: tp->t_dupacks = 0; ! 1183: break; ! 1184: } ! 1185: /* ! 1186: * If the congestion window was inflated to account ! 1187: * for the other side's cached packets, retract it. ! 1188: */ ! 1189: if (tp->t_dupacks > tcprexmtthresh && ! 1190: tp->snd_cwnd > tp->snd_ssthresh) ! 1191: tp->snd_cwnd = tp->snd_ssthresh; ! 1192: tp->t_dupacks = 0; ! 1193: if (SEQ_GT(ti->ti_ack, tp->snd_max)) { ! 1194: tcpstat.tcps_rcvacktoomuch++; ! 1195: goto dropafterack; ! 1196: } ! 1197: acked = ti->ti_ack - tp->snd_una; ! 1198: tcpstat.tcps_rcvackpack++; ! 1199: tcpstat.tcps_rcvackbyte += acked; ! 1200: ! 1201: /* ! 1202: * If we have a timestamp reply, update smoothed ! 1203: * round trip time. If no timestamp is present but ! 1204: * transmit timer is running and timed sequence ! 1205: * number was acked, update smoothed round trip time. ! 1206: * Since we now have an rtt measurement, cancel the ! 1207: * timer backoff (cf., Phil Karn's retransmit alg.). ! 1208: * Recompute the initial retransmit timer. ! 1209: */ ! 1210: if (ts_present) ! 1211: tcp_xmit_timer(tp, tcp_now-ts_ecr+1); ! 1212: else if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) ! 1213: tcp_xmit_timer(tp,tp->t_rtt); ! 1214: ! 1215: /* ! 1216: * If all outstanding data is acked, stop retransmit ! 1217: * timer and remember to restart (more output or persist). ! 1218: * If there is more data to be acked, restart retransmit ! 1219: * timer, using current (possibly backed-off) value. ! 1220: */ ! 1221: if (ti->ti_ack == tp->snd_max) { ! 1222: tp->t_timer[TCPT_REXMT] = 0; ! 1223: needoutput = 1; ! 1224: } else if (tp->t_timer[TCPT_PERSIST] == 0) ! 1225: tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; ! 1226: /* ! 1227: * When new data is acked, open the congestion window. ! 1228: * If the window gives us less than ssthresh packets ! 1229: * in flight, open exponentially (maxseg per packet). ! 1230: * Otherwise open linearly: maxseg per window ! 1231: * (maxseg * (maxseg / cwnd) per packet). ! 1232: */ ! 1233: { ! 1234: register u_int cw = tp->snd_cwnd; ! 1235: register u_int incr = tp->t_maxseg; ! 1236: ! 1237: if (cw > tp->snd_ssthresh) ! 1238: incr = incr * incr / cw; ! 1239: tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<<tp->snd_scale); ! 1240: } ! 1241: if (acked > so->so_snd.sb_cc) { ! 1242: tp->snd_wnd -= so->so_snd.sb_cc; ! 1243: sbdrop(&so->so_snd, (int)so->so_snd.sb_cc); ! 1244: ourfinisacked = 1; ! 1245: } else { ! 1246: sbdrop(&so->so_snd, acked); ! 1247: tp->snd_wnd -= acked; ! 1248: ourfinisacked = 0; ! 1249: } ! 1250: if (so->so_snd.sb_flags & SB_NOTIFY) ! 1251: sowwakeup(so); ! 1252: tp->snd_una = ti->ti_ack; ! 1253: if (SEQ_LT(tp->snd_nxt, tp->snd_una)) ! 1254: tp->snd_nxt = tp->snd_una; ! 1255: ! 1256: switch (tp->t_state) { ! 1257: ! 1258: /* ! 1259: * In FIN_WAIT_1 STATE in addition to the processing ! 1260: * for the ESTABLISHED state if our FIN is now acknowledged ! 1261: * then enter FIN_WAIT_2. ! 1262: */ ! 1263: case TCPS_FIN_WAIT_1: ! 1264: if (ourfinisacked) { ! 1265: /* ! 1266: * If we can't receive any more ! 1267: * data, then closing user can proceed. ! 1268: * Starting the timer is contrary to the ! 1269: * specification, but if we don't get a FIN ! 1270: * we'll hang forever. ! 1271: */ ! 1272: if (so->so_state & SS_CANTRCVMORE) { ! 1273: soisdisconnected(so); ! 1274: tp->t_timer[TCPT_2MSL] = tcp_maxidle; ! 1275: add_to_time_wait(tp); ! 1276: } ! 1277: tp->t_state = TCPS_FIN_WAIT_2; ! 1278: } ! 1279: break; ! 1280: ! 1281: /* ! 1282: * In CLOSING STATE in addition to the processing for ! 1283: * the ESTABLISHED state if the ACK acknowledges our FIN ! 1284: * then enter the TIME-WAIT state, otherwise ignore ! 1285: * the segment. ! 1286: */ ! 1287: case TCPS_CLOSING: ! 1288: if (ourfinisacked) { ! 1289: tp->t_state = TCPS_TIME_WAIT; ! 1290: tcp_canceltimers(tp); ! 1291: tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; ! 1292: add_to_time_wait(tp); ! 1293: soisdisconnected(so); ! 1294: } ! 1295: break; ! 1296: ! 1297: /* ! 1298: * In LAST_ACK, we may still be waiting for data to drain ! 1299: * and/or to be acked, as well as for the ack of our FIN. ! 1300: * If our FIN is now acknowledged, delete the TCB, ! 1301: * enter the closed state and return. ! 1302: */ ! 1303: case TCPS_LAST_ACK: ! 1304: if (ourfinisacked) { ! 1305: tp = tcp_close(tp); ! 1306: goto drop; ! 1307: } ! 1308: break; ! 1309: ! 1310: /* ! 1311: * In TIME_WAIT state the only thing that should arrive ! 1312: * is a retransmission of the remote FIN. Acknowledge ! 1313: * it and restart the finack timer. ! 1314: */ ! 1315: case TCPS_TIME_WAIT: ! 1316: tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; ! 1317: ! 1318: add_to_time_wait(tp); ! 1319: goto dropafterack; ! 1320: } ! 1321: } ! 1322: ! 1323: step6: ! 1324: /* ! 1325: * Update window information. ! 1326: * Don't look at window if no ACK: TAC's send garbage on first SYN. ! 1327: */ ! 1328: if ((tiflags & TH_ACK) && ! 1329: (SEQ_LT(tp->snd_wl1, ti->ti_seq) || tp->snd_wl1 == ti->ti_seq && ! 1330: (SEQ_LT(tp->snd_wl2, ti->ti_ack) || ! 1331: tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))) { ! 1332: /* keep track of pure window updates */ ! 1333: if (ti->ti_len == 0 && ! 1334: tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd) ! 1335: tcpstat.tcps_rcvwinupd++; ! 1336: tp->snd_wnd = tiwin; ! 1337: tp->snd_wl1 = ti->ti_seq; ! 1338: tp->snd_wl2 = ti->ti_ack; ! 1339: if (tp->snd_wnd > tp->max_sndwnd) ! 1340: tp->max_sndwnd = tp->snd_wnd; ! 1341: needoutput = 1; ! 1342: } ! 1343: ! 1344: /* ! 1345: * Process segments with URG. ! 1346: */ ! 1347: if ((tiflags & TH_URG) && ti->ti_urp && ! 1348: TCPS_HAVERCVDFIN(tp->t_state) == 0) { ! 1349: /* ! 1350: * This is a kludge, but if we receive and accept ! 1351: * random urgent pointers, we'll crash in ! 1352: * soreceive. It's hard to imagine someone ! 1353: * actually wanting to send this much urgent data. ! 1354: */ ! 1355: if (ti->ti_urp + so->so_rcv.sb_cc > sb_max) { ! 1356: ti->ti_urp = 0; /* XXX */ ! 1357: tiflags &= ~TH_URG; /* XXX */ ! 1358: goto dodata; /* XXX */ ! 1359: } ! 1360: /* ! 1361: * If this segment advances the known urgent pointer, ! 1362: * then mark the data stream. This should not happen ! 1363: * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since ! 1364: * a FIN has been received from the remote side. ! 1365: * In these states we ignore the URG. ! 1366: * ! 1367: * According to RFC961 (Assigned Protocols), ! 1368: * the urgent pointer points to the last octet ! 1369: * of urgent data. We continue, however, ! 1370: * to consider it to indicate the first octet ! 1371: * of data past the urgent section as the original ! 1372: * spec states (in one of two places). ! 1373: */ ! 1374: if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) { ! 1375: tp->rcv_up = ti->ti_seq + ti->ti_urp; ! 1376: so->so_oobmark = so->so_rcv.sb_cc + ! 1377: (tp->rcv_up - tp->rcv_nxt) - 1; ! 1378: ! 1379: if (so->so_oobmark == 0) { ! 1380: so->so_state |= SS_RCVATMARK; ! 1381: postevent(so, 0, EV_OOB); ! 1382: } ! 1383: ! 1384: sohasoutofband(so); ! 1385: tp->t_oobflags &= ~(TCPOOB_HAVEDATA | TCPOOB_HADDATA); ! 1386: } ! 1387: /* ! 1388: * Remove out of band data so doesn't get presented to user. ! 1389: * This can happen independent of advancing the URG pointer, ! 1390: * but if two URG's are pending at once, some out-of-band ! 1391: * data may creep in... ick. ! 1392: */ ! 1393: if (ti->ti_urp <= ti->ti_len ! 1394: #ifdef SO_OOBINLINE ! 1395: && (so->so_options & SO_OOBINLINE) == 0 ! 1396: #endif ! 1397: ) ! 1398: tcp_pulloutofband(so, ti, m); ! 1399: } else ! 1400: /* ! 1401: * If no out of band data is expected, ! 1402: * pull receive urgent pointer along ! 1403: * with the receive window. ! 1404: */ ! 1405: if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) ! 1406: tp->rcv_up = tp->rcv_nxt; ! 1407: dodata: /* XXX */ ! 1408: ! 1409: /* ! 1410: * Process the segment text, merging it into the TCP sequencing queue, ! 1411: * and arranging for acknowledgment of receipt if necessary. ! 1412: * This process logically involves adjusting tp->rcv_wnd as data ! 1413: * is presented to the user (this happens in tcp_usrreq.c, ! 1414: * case PRU_RCVD). If a FIN has already been received on this ! 1415: * connection then we just ignore the text. ! 1416: */ ! 1417: if ((ti->ti_len || (tiflags&TH_FIN)) && ! 1418: TCPS_HAVERCVDFIN(tp->t_state) == 0) { ! 1419: TCP_REASS(tp, ti, m, so, tiflags); ! 1420: if (tp->t_flags & TF_DELACK) ! 1421: { ! 1422: KERNEL_DEBUG(DBG_LAYER_END, ((ti->ti_dport << 16) | ti->ti_sport), ! 1423: (((ti->ti_src.s_addr & 0xffff) << 16) | (ti->ti_dst.s_addr & 0xffff)), ! 1424: ti->ti_seq, ti->ti_ack, ti->ti_win); ! 1425: } ! 1426: ! 1427: /* ! 1428: * Note the amount of data that peer has sent into ! 1429: * our window, in order to estimate the sender's ! 1430: * buffer size. ! 1431: */ ! 1432: len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt); ! 1433: } else { ! 1434: m_freem(m); ! 1435: tiflags &= ~TH_FIN; ! 1436: } ! 1437: ! 1438: /* ! 1439: * If FIN is received ACK the FIN and let the user know ! 1440: * that the connection is closing. ! 1441: */ ! 1442: if (tiflags & TH_FIN) { ! 1443: if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { ! 1444: socantrcvmore(so); ! 1445: postevent(so, 0, EV_FIN); ! 1446: tp->t_flags |= TF_ACKNOW; ! 1447: tp->rcv_nxt++; ! 1448: } ! 1449: switch (tp->t_state) { ! 1450: ! 1451: /* ! 1452: * In SYN_RECEIVED and ESTABLISHED STATES ! 1453: * enter the CLOSE_WAIT state. ! 1454: */ ! 1455: case TCPS_SYN_RECEIVED: ! 1456: case TCPS_ESTABLISHED: ! 1457: #if DELACK_BITMASK_ON ! 1458: current_active_connections--; ! 1459: #endif ! 1460: tp->t_state = TCPS_CLOSE_WAIT; ! 1461: break; ! 1462: ! 1463: /* ! 1464: * If still in FIN_WAIT_1 STATE FIN has not been acked so ! 1465: * enter the CLOSING state. ! 1466: */ ! 1467: case TCPS_FIN_WAIT_1: ! 1468: tp->t_state = TCPS_CLOSING; ! 1469: break; ! 1470: ! 1471: /* ! 1472: * In FIN_WAIT_2 state enter the TIME_WAIT state, ! 1473: * starting the time-wait timer, turning off the other ! 1474: * standard timers. ! 1475: */ ! 1476: case TCPS_FIN_WAIT_2: ! 1477: tp->t_state = TCPS_TIME_WAIT; ! 1478: tcp_canceltimers(tp); ! 1479: tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; ! 1480: add_to_time_wait(tp); ! 1481: soisdisconnected(so); ! 1482: break; ! 1483: ! 1484: /* ! 1485: * In TIME_WAIT state restart the 2 MSL time_wait timer. ! 1486: */ ! 1487: case TCPS_TIME_WAIT: ! 1488: tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; ! 1489: add_to_time_wait(tp); ! 1490: break; ! 1491: } ! 1492: } ! 1493: if (so->so_options & SO_DEBUG) ! 1494: tcp_trace(TA_INPUT, ostate, tp, &tcp_saveti, 0); ! 1495: ! 1496: /* ! 1497: * Return any desired output. ! 1498: */ ! 1499: if (needoutput || (tp->t_flags & TF_ACKNOW)) ! 1500: (void) tcp_output(tp); ! 1501: ! 1502: KERNEL_DEBUG(DBG_FNC_TCP_INPUT | DBG_FUNC_END,0,0,0,0,0); ! 1503: return; ! 1504: ! 1505: dropafterack: ! 1506: /* ! 1507: * Generate an ACK dropping incoming segment if it occupies ! 1508: * sequence space, where the ACK reflects our state. ! 1509: * ! 1510: * We can now skip the test for the RST flag since all ! 1511: * paths to this code happen after packets containing ! 1512: * RST have been dropped. ! 1513: * ! 1514: * In the SYN-RECEIVED state, don't send an ACK unless the ! 1515: * segment we received passes the SYN-RECEIVED ACK test. ! 1516: * If it fails send a RST. This breaks the loop in the ! 1517: * "LAND" DoS attack, and also prevents an ACK storm ! 1518: * between two listening ports that have been sent forged ! 1519: * SYN segments, each with the source address of the other. ! 1520: */ ! 1521: if (tp->t_state == TCPS_SYN_RECEIVED && (tiflags & TH_ACK) && ! 1522: (SEQ_GT(tp->snd_una, ti->ti_ack) || ! 1523: SEQ_GT(ti->ti_ack, tp->snd_max)) ) ! 1524: goto dropwithreset; ! 1525: ! 1526: m_freem(m); ! 1527: tp->t_flags |= TF_ACKNOW; ! 1528: (void) tcp_output(tp); ! 1529: KERNEL_DEBUG(DBG_FNC_TCP_INPUT | DBG_FUNC_END,0,0,0,0,0); ! 1530: return; ! 1531: ! 1532: dropwithreset: ! 1533: /* ! 1534: * Generate a RST, dropping incoming segment. ! 1535: * Make ACK acceptable to originator of segment. ! 1536: * Don't bother to respond if destination was broadcast/multicast. ! 1537: */ ! 1538: if ((tiflags & TH_RST) || m->m_flags & (M_BCAST|M_MCAST) || ! 1539: IN_MULTICAST(ntohl(ti->ti_dst.s_addr))) ! 1540: goto drop; ! 1541: if (tiflags & TH_ACK) ! 1542: tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST); ! 1543: else { ! 1544: if (tiflags & TH_SYN) ! 1545: ti->ti_len++; ! 1546: tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0, ! 1547: TH_RST|TH_ACK); ! 1548: } ! 1549: /* destroy temporarily created socket */ ! 1550: if (dropsocket) ! 1551: (void) soabort(so); ! 1552: KERNEL_DEBUG(DBG_FNC_TCP_INPUT | DBG_FUNC_END,0,0,0,0,0); ! 1553: return; ! 1554: ! 1555: drop: ! 1556: /* ! 1557: * Drop space held by incoming segment and return. ! 1558: */ ! 1559: if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) ! 1560: tcp_trace(TA_DROP, ostate, tp, &tcp_saveti, 0); ! 1561: m_freem(m); ! 1562: /* destroy temporarily created socket */ ! 1563: if (dropsocket) ! 1564: (void) soabort(so); ! 1565: KERNEL_DEBUG(DBG_FNC_TCP_INPUT | DBG_FUNC_END,0,0,0,0,0); ! 1566: return; ! 1567: #ifndef TUBA_INCLUDE ! 1568: } ! 1569: ! 1570: void ! 1571: tcp_dooptions(tp, cp, cnt, ti, ts_present, ts_val, ts_ecr) ! 1572: struct tcpcb *tp; ! 1573: u_char *cp; ! 1574: int cnt; ! 1575: struct tcpiphdr *ti; ! 1576: int *ts_present; ! 1577: u_long *ts_val, *ts_ecr; ! 1578: { ! 1579: u_short mss; ! 1580: int opt, optlen; ! 1581: ! 1582: for (; cnt > 0; cnt -= optlen, cp += optlen) { ! 1583: opt = cp[0]; ! 1584: if (opt == TCPOPT_EOL) ! 1585: break; ! 1586: if (opt == TCPOPT_NOP) ! 1587: optlen = 1; ! 1588: else { ! 1589: optlen = cp[1]; ! 1590: if (optlen <= 0) ! 1591: break; ! 1592: } ! 1593: switch (opt) { ! 1594: ! 1595: default: ! 1596: continue; ! 1597: ! 1598: case TCPOPT_MAXSEG: ! 1599: if (optlen != TCPOLEN_MAXSEG) ! 1600: continue; ! 1601: if (!(ti->ti_flags & TH_SYN)) ! 1602: continue; ! 1603: bcopy((char *) cp + 2, (char *) &mss, sizeof(mss)); ! 1604: NTOHS(mss); ! 1605: (void) tcp_mss(tp, mss); /* sets t_maxseg */ ! 1606: break; ! 1607: ! 1608: case TCPOPT_WINDOW: ! 1609: if (optlen != TCPOLEN_WINDOW) ! 1610: continue; ! 1611: if (!(ti->ti_flags & TH_SYN)) ! 1612: continue; ! 1613: tp->t_flags |= TF_RCVD_SCALE; ! 1614: tp->requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT); ! 1615: break; ! 1616: ! 1617: case TCPOPT_TIMESTAMP: ! 1618: if (optlen != TCPOLEN_TIMESTAMP) ! 1619: continue; ! 1620: *ts_present = 1; ! 1621: bcopy((char *)cp + 2, (char *) ts_val, sizeof(*ts_val)); ! 1622: NTOHL(*ts_val); ! 1623: bcopy((char *)cp + 6, (char *) ts_ecr, sizeof(*ts_ecr)); ! 1624: NTOHL(*ts_ecr); ! 1625: ! 1626: /* ! 1627: * A timestamp received in a SYN makes ! 1628: * it ok to send timestamp requests and replies. ! 1629: */ ! 1630: if (ti->ti_flags & TH_SYN) { ! 1631: tp->t_flags |= TF_RCVD_TSTMP; ! 1632: tp->ts_recent = *ts_val; ! 1633: tp->ts_recent_age = tcp_now; ! 1634: } ! 1635: break; ! 1636: } ! 1637: } ! 1638: } ! 1639: ! 1640: /* ! 1641: * Pull out of band byte out of a segment so ! 1642: * it doesn't appear in the user's data queue. ! 1643: * It is still reflected in the segment length for ! 1644: * sequencing purposes. ! 1645: */ ! 1646: void ! 1647: tcp_pulloutofband(so, ti, m) ! 1648: struct socket *so; ! 1649: struct tcpiphdr *ti; ! 1650: register struct mbuf *m; ! 1651: { ! 1652: int cnt = ti->ti_urp - 1; ! 1653: ! 1654: while (cnt >= 0) { ! 1655: if (m->m_len > cnt) { ! 1656: char *cp = mtod(m, caddr_t) + cnt; ! 1657: struct tcpcb *tp = sototcpcb(so); ! 1658: ! 1659: tp->t_iobc = *cp; ! 1660: tp->t_oobflags |= TCPOOB_HAVEDATA; ! 1661: bcopy(cp+1, cp, (unsigned)(m->m_len - cnt - 1)); ! 1662: m->m_len--; ! 1663: return; ! 1664: } ! 1665: cnt -= m->m_len; ! 1666: m = m->m_next; ! 1667: if (m == 0) ! 1668: break; ! 1669: } ! 1670: panic("tcp_pulloutofband"); ! 1671: } ! 1672: ! 1673: /* ! 1674: * Collect new round-trip time estimate ! 1675: * and update averages and current timeout. ! 1676: */ ! 1677: void ! 1678: tcp_xmit_timer(tp, rtt) ! 1679: register struct tcpcb *tp; ! 1680: short rtt; ! 1681: { ! 1682: register short delta; ! 1683: ! 1684: tcpstat.tcps_rttupdated++; ! 1685: if (tp->t_srtt != 0) { ! 1686: /* ! 1687: * srtt is stored as fixed point with 3 bits after the ! 1688: * binary point (i.e., scaled by 8). The following magic ! 1689: * is equivalent to the smoothing algorithm in rfc793 with ! 1690: * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed ! 1691: * point). Adjust rtt to origin 0. ! 1692: */ ! 1693: delta = rtt - 1 - (tp->t_srtt >> TCP_RTT_SHIFT); ! 1694: if ((tp->t_srtt += delta) <= 0) ! 1695: tp->t_srtt = 1; ! 1696: /* ! 1697: * We accumulate a smoothed rtt variance (actually, a ! 1698: * smoothed mean difference), then set the retransmit ! 1699: * timer to smoothed rtt + 4 times the smoothed variance. ! 1700: * rttvar is stored as fixed point with 2 bits after the ! 1701: * binary point (scaled by 4). The following is ! 1702: * equivalent to rfc793 smoothing with an alpha of .75 ! 1703: * (rttvar = rttvar*3/4 + |delta| / 4). This replaces ! 1704: * rfc793's wired-in beta. ! 1705: */ ! 1706: if (delta < 0) ! 1707: delta = -delta; ! 1708: delta -= (tp->t_rttvar >> TCP_RTTVAR_SHIFT); ! 1709: if ((tp->t_rttvar += delta) <= 0) ! 1710: tp->t_rttvar = 1; ! 1711: } else { ! 1712: /* ! 1713: * No rtt measurement yet - use the unsmoothed rtt. ! 1714: * Set the variance to half the rtt (so our first ! 1715: * retransmit happens at 3*rtt). ! 1716: */ ! 1717: tp->t_srtt = rtt << TCP_RTT_SHIFT; ! 1718: tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1); ! 1719: } ! 1720: tp->t_rtt = 0; ! 1721: tp->t_rxtshift = 0; ! 1722: ! 1723: /* ! 1724: * the retransmit should happen at rtt + 4 * rttvar. ! 1725: * Because of the way we do the smoothing, srtt and rttvar ! 1726: * will each average +1/2 tick of bias. When we compute ! 1727: * the retransmit timer, we want 1/2 tick of rounding and ! 1728: * 1 extra tick because of +-1/2 tick uncertainty in the ! 1729: * firing of the timer. The bias will give us exactly the ! 1730: * 1.5 tick we need. But, because the bias is ! 1731: * statistical, we have to test that we don't drop below ! 1732: * the minimum feasible timer (which is 2 ticks). ! 1733: */ ! 1734: TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), ! 1735: tp->t_rttmin, TCPTV_REXMTMAX); ! 1736: ! 1737: /* ! 1738: * We received an ack for a packet that wasn't retransmitted; ! 1739: * it is probably safe to discard any error indications we've ! 1740: * received recently. This isn't quite right, but close enough ! 1741: * for now (a route might have failed after we sent a segment, ! 1742: * and the return path might not be symmetrical). ! 1743: */ ! 1744: tp->t_softerror = 0; ! 1745: } ! 1746: ! 1747: /* ! 1748: * Determine a reasonable value for maxseg size. ! 1749: * If the route is known, check route for mtu. ! 1750: * If none, use an mss that can be handled on the outgoing ! 1751: * interface without forcing IP to fragment; if bigger than ! 1752: * an mbuf cluster (MCLBYTES), round down to nearest multiple of MCLBYTES ! 1753: * to utilize large mbufs. If no route is found, route has no mtu, ! 1754: * or the destination isn't local, use a default, hopefully conservative ! 1755: * size (usually 512 or the default IP max size, but no more than the mtu ! 1756: * of the interface), as we can't discover anything about intervening ! 1757: * gateways or networks. We also initialize the congestion/slow start ! 1758: * window to be a single segment if the destination isn't local. ! 1759: * While looking at the routing entry, we also initialize other path-dependent ! 1760: * parameters from pre-set or cached values in the routing entry. ! 1761: */ ! 1762: int ! 1763: tcp_mss(tp, offer) ! 1764: register struct tcpcb *tp; ! 1765: u_int offer; ! 1766: { ! 1767: struct route *ro; ! 1768: register struct rtentry *rt; ! 1769: struct ifnet *ifp; ! 1770: register int rtt, mss; ! 1771: u_long bufsize; ! 1772: struct inpcb *inp; ! 1773: struct socket *so; ! 1774: extern int tcp_mssdflt; ! 1775: ! 1776: inp = tp->t_inpcb; ! 1777: ro = &inp->inp_route; ! 1778: ! 1779: if ((rt = ro->ro_rt) == (struct rtentry *)0) { ! 1780: /* No route yet, so try to acquire one */ ! 1781: if (inp->inp_faddr.s_addr != INADDR_ANY) { ! 1782: ro->ro_dst.sa_family = AF_INET; ! 1783: ro->ro_dst.sa_len = sizeof(ro->ro_dst); ! 1784: ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = ! 1785: inp->inp_faddr; ! 1786: rtalloc(ro); ! 1787: } ! 1788: if ((rt = ro->ro_rt) == (struct rtentry *)0) ! 1789: return (tcp_mssdflt); ! 1790: } ! 1791: ifp = rt->rt_ifp; ! 1792: so = inp->inp_socket; ! 1793: ! 1794: #ifdef RTV_MTU /* if route characteristics exist ... */ ! 1795: /* ! 1796: * While we're here, check if there's an initial rtt ! 1797: * or rttvar. Convert from the route-table units ! 1798: * to scaled multiples of the slow timeout timer. ! 1799: */ ! 1800: if (tp->t_srtt == 0 && (rtt = rt->rt_rmx.rmx_rtt)) { ! 1801: /* ! 1802: * XXX the lock bit for MTU indicates that the value ! 1803: * is also a minimum value; this is subject to time. ! 1804: */ ! 1805: if (rt->rt_rmx.rmx_locks & RTV_RTT) ! 1806: tp->t_rttmin = rtt / (RTM_RTTUNIT / PR_SLOWHZ); ! 1807: tp->t_srtt = rtt / (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTT_SCALE)); ! 1808: if (rt->rt_rmx.rmx_rttvar) ! 1809: tp->t_rttvar = rt->rt_rmx.rmx_rttvar / ! 1810: (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTTVAR_SCALE)); ! 1811: else ! 1812: /* default variation is +- 1 rtt */ ! 1813: tp->t_rttvar = ! 1814: tp->t_srtt * TCP_RTTVAR_SCALE / TCP_RTT_SCALE; ! 1815: TCPT_RANGESET(tp->t_rxtcur, ! 1816: ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1, ! 1817: tp->t_rttmin, TCPTV_REXMTMAX); ! 1818: } ! 1819: /* ! 1820: * if there's an mtu associated with the route, use it ! 1821: */ ! 1822: if (rt->rt_rmx.rmx_mtu) ! 1823: mss = rt->rt_rmx.rmx_mtu - sizeof(struct tcpiphdr); ! 1824: else ! 1825: #endif /* RTV_MTU */ ! 1826: { ! 1827: mss = ifp->if_mtu - sizeof(struct tcpiphdr); ! 1828: #if (MCLBYTES & (MCLBYTES - 1)) == 0 ! 1829: if (mss > MCLBYTES) ! 1830: mss &= ~(MCLBYTES-1); ! 1831: #else ! 1832: if (mss > MCLBYTES) ! 1833: mss = mss / MCLBYTES * MCLBYTES; ! 1834: #endif ! 1835: if (!in_localaddr(inp->inp_faddr)) ! 1836: mss = min(mss, tcp_mssdflt); ! 1837: } ! 1838: /* ! 1839: * The current mss, t_maxseg, is initialized to the default value. ! 1840: * If we compute a smaller value, reduce the current mss. ! 1841: * If we compute a larger value, return it for use in sending ! 1842: * a max seg size option, but don't store it for use ! 1843: * unless we received an offer at least that large from peer. ! 1844: * However, do not accept offers under 32 bytes. ! 1845: */ ! 1846: if (offer) ! 1847: mss = min(mss, offer); ! 1848: mss = max(mss, 32); /* sanity */ ! 1849: if (mss < tp->t_maxseg || offer != 0) { ! 1850: /* ! 1851: * If there's a pipesize, change the socket buffer ! 1852: * to that size. Make the socket buffers an integral ! 1853: * number of mss units; if the mss is larger than ! 1854: * the socket buffer, decrease the mss. ! 1855: */ ! 1856: #ifdef RTV_SPIPE ! 1857: if ((bufsize = rt->rt_rmx.rmx_sendpipe) == 0) ! 1858: #endif ! 1859: bufsize = so->so_snd.sb_hiwat; ! 1860: if (bufsize < mss) ! 1861: mss = bufsize; ! 1862: else { ! 1863: bufsize = roundup(bufsize, mss); ! 1864: if (bufsize > sb_max) ! 1865: bufsize = sb_max; ! 1866: (void)sbreserve(&so->so_snd, bufsize); ! 1867: } ! 1868: tp->t_maxseg = mss; ! 1869: ! 1870: #ifdef RTV_RPIPE ! 1871: if ((bufsize = rt->rt_rmx.rmx_recvpipe) == 0) ! 1872: #endif ! 1873: bufsize = so->so_rcv.sb_hiwat; ! 1874: if (bufsize > mss) { ! 1875: bufsize = roundup(bufsize, mss); ! 1876: if (bufsize > sb_max) ! 1877: bufsize = sb_max; ! 1878: (void)sbreserve(&so->so_rcv, bufsize); ! 1879: } ! 1880: } ! 1881: tp->snd_cwnd = mss; ! 1882: ! 1883: #ifdef RTV_SSTHRESH ! 1884: if (rt->rt_rmx.rmx_ssthresh) { ! 1885: /* ! 1886: * There's some sort of gateway or interface ! 1887: * buffer limit on the path. Use this to set ! 1888: * the slow start threshhold, but set the ! 1889: * threshold to no less than 2*mss. ! 1890: */ ! 1891: tp->snd_ssthresh = max(2 * mss, rt->rt_rmx.rmx_ssthresh); ! 1892: } ! 1893: #endif /* RTV_MTU */ ! 1894: return (mss); ! 1895: } ! 1896: #endif /* TUBA_INCLUDE */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.