1: /*
   2:  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
   3:  * All rights reserved.
   4:  *
   5:  * Redistribution and use in source and binary forms are permitted
   6:  * provided that this notice is preserved and that due credit is given
   7:  * to the University of California at Berkeley. The name of the University
   8:  * may not be used to endorse or promote products derived from this
   9:  * software without specific prior written permission. This software
  10:  * is provided ``as is'' without express or implied warranty.
  11:  *
  12:  *	@(#)tcp_input.c	7.15.1.2 (Berkeley) 3/16/88
  13:  */
  14: 
  15: #include "param.h"
  16: #include "systm.h"
  17: #include "mbuf.h"
  18: #include "protosw.h"
  19: #include "socket.h"
  20: #include "socketvar.h"
  21: #include "errno.h"
  22: 
  23: #include "../net/if.h"
  24: #include "../net/route.h"
  25: 
  26: #include "domain.h"
  27: #include "in.h"
  28: #include "in_pcb.h"
  29: #include "in_systm.h"
  30: #include "ip.h"
  31: #include "ip_var.h"
  32: #include "tcp.h"
  33: #include "tcp_fsm.h"
  34: #include "tcp_seq.h"
  35: #include "tcp_timer.h"
  36: #include "tcp_var.h"
  37: #include "tcpip.h"
  38: #include "tcp_debug.h"
  39: 
  40: int tcpprintfs = 0;
  41: int tcpcksum = 1;
  42: int tcprexmtthresh = 3;
  43: struct  tcpiphdr tcp_saveti;
  44: extern  tcpnodelack;
  45: 
  46: struct  tcpcb *tcp_newtcpcb();
  47: 
  48: /*
  49:  * Insert segment ti into reassembly queue of tcp with
  50:  * control block tp.  Return TH_FIN if reassembly now includes
  51:  * a segment with FIN.  The macro form does the common case inline
  52:  * (segment is the next to be received on an established connection,
  53:  * and the queue is empty), avoiding linkage into and removal
  54:  * from the queue and repetition of various conversions.
  55:  */
  56: #define TCP_REASS(tp, ti, m, so, flags) { \
  57:     if ((ti)->ti_seq == (tp)->rcv_nxt && \
  58:         (tp)->seg_next == (struct tcpiphdr *)(tp) && \
  59:         (tp)->t_state == TCPS_ESTABLISHED) { \
  60:         (tp)->rcv_nxt += (ti)->ti_len; \
  61:         flags = (ti)->ti_flags & TH_FIN; \
  62:         tcpstat.tcps_rcvpack++;\
  63:         tcpstat.tcps_rcvbyte += (ti)->ti_len;\
  64:         sbappend(&(so)->so_rcv, (m)); \
  65:         sorwakeup(so); \
  66:     } else \
  67:         (flags) = tcp_reass((tp), (ti)); \
  68: }
  69: 
  70: tcp_reass(tp, ti)
  71:     register struct tcpcb *tp;
  72:     register struct tcpiphdr *ti;
  73: {
  74:     register struct tcpiphdr *q;
  75:     struct socket *so = tp->t_inpcb->inp_socket;
  76:     struct mbuf *m;
  77:     int flags;
  78: 
  79:     /*
  80: 	 * Call with ti==0 after become established to
  81: 	 * force pre-ESTABLISHED data up to user socket.
  82: 	 */
  83:     if (ti == 0)
  84:         goto present;
  85: 
  86:     /*
  87: 	 * Find a segment which begins after this one does.
  88: 	 */
  89:     for (q = tp->seg_next; q != (struct tcpiphdr *)tp;
  90:         q = (struct tcpiphdr *)q->ti_next)
  91:         if (SEQ_GT(q->ti_seq, ti->ti_seq))
  92:             break;
  93: 
  94:     /*
  95: 	 * If there is a preceding segment, it may provide some of
  96: 	 * our data already.  If so, drop the data from the incoming
  97: 	 * segment.  If it provides all of our data, drop us.
  98: 	 */
  99:     if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) {
 100:         register int i;
 101:         q = (struct tcpiphdr *)q->ti_prev;
 102:         /* conversion to int (in i) handles seq wraparound */
 103:         i = q->ti_seq + q->ti_len - ti->ti_seq;
 104:         if (i > 0) {
 105:             if (i >= ti->ti_len) {
 106:                 tcpstat.tcps_rcvduppack++;
 107:                 tcpstat.tcps_rcvdupbyte += ti->ti_len;
 108:                 goto drop;
 109:             }
 110:             m_adj(dtom(ti), i);
 111:             ti->ti_len -= i;
 112:             ti->ti_seq += i;
 113:         }
 114:         q = (struct tcpiphdr *)(q->ti_next);
 115:     }
 116:     tcpstat.tcps_rcvoopack++;
 117:     tcpstat.tcps_rcvoobyte += ti->ti_len;
 118: 
 119:     /*
 120: 	 * While we overlap succeeding segments trim them or,
 121: 	 * if they are completely covered, dequeue them.
 122: 	 */
 123:     while (q != (struct tcpiphdr *)tp) {
 124:         register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;
 125:         if (i <= 0)
 126:             break;
 127:         if (i < q->ti_len) {
 128:             q->ti_seq += i;
 129:             q->ti_len -= i;
 130:             m_adj(dtom(q), i);
 131:             break;
 132:         }
 133:         q = (struct tcpiphdr *)q->ti_next;
 134:         m = dtom(q->ti_prev);
 135:         remque(q->ti_prev);
 136:         m_freem(m);
 137:     }
 138: 
 139:     /*
 140: 	 * Stick new segment in its place.
 141: 	 */
 142:     insque(ti, q->ti_prev);
 143: 
 144: present:
 145:     /*
 146: 	 * Present data to user, advancing rcv_nxt through
 147: 	 * completed sequence space.
 148: 	 */
 149:     if (TCPS_HAVERCVDSYN(tp->t_state) == 0)
 150:         return (0);
 151:     ti = tp->seg_next;
 152:     if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt)
 153:         return (0);
 154:     if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)
 155:         return (0);
 156:     do {
 157:         tp->rcv_nxt += ti->ti_len;
 158:         flags = ti->ti_flags & TH_FIN;
 159:         remque(ti);
 160:         m = dtom(ti);
 161:         ti = (struct tcpiphdr *)ti->ti_next;
 162:         if (so->so_state & SS_CANTRCVMORE)
 163:             m_freem(m);
 164:         else
 165:             sbappend(&so->so_rcv, m);
 166:     } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt);
 167:     sorwakeup(so);
 168:     return (flags);
 169: drop:
 170:     m_freem(dtom(ti));
 171:     return (0);
 172: }
 173: 
 174: /*
 175:  * TCP input routine, follows pages 65-76 of the
 176:  * protocol specification dated September, 1981 very closely.
 177:  */
 178: tcp_input(m0)
 179:     struct mbuf *m0;
 180: {
 181:     register struct tcpiphdr *ti;
 182:     struct inpcb *inp;
 183:     register struct mbuf *m;
 184:     struct mbuf *om = 0;
 185:     int len, tlen, off;
 186:     register struct tcpcb *tp = 0;
 187:     register int tiflags;
 188:     struct socket *so;
 189:     int todrop, acked, ourfinisacked, needoutput = 0;
 190:     short ostate;
 191:     struct in_addr laddr;
 192:     int dropsocket = 0;
 193:     long iss = 0;
 194: 
 195:     tcpstat.tcps_rcvtotal++;
 196:     /*
 197: 	 * Get IP and TCP header together in first mbuf.
 198: 	 * Note: IP leaves IP header in first mbuf.
 199: 	 */
 200:     m = m0;
 201:     ti = mtod(m, struct tcpiphdr *);
 202:     if (((struct ip *)ti)->ip_hl > (sizeof (struct ip) >> 2))
 203:         ip_stripoptions((struct ip *)ti, (struct mbuf *)0);
 204:     if (m->m_off > MMAXOFF || m->m_len < sizeof (struct tcpiphdr)) {
 205:         if ((m = m_pullup(m, sizeof (struct tcpiphdr))) == 0) {
 206:             tcpstat.tcps_rcvshort++;
 207:             return;
 208:         }
 209:         ti = mtod(m, struct tcpiphdr *);
 210:     }
 211: 
 212:     /*
 213: 	 * Checksum extended TCP header and data.
 214: 	 */
 215:     tlen = ((struct ip *)ti)->ip_len;
 216:     len = sizeof (struct ip) + tlen;
 217:     if (tcpcksum) {
 218:         ti->ti_next = ti->ti_prev = 0;
 219:         ti->ti_x1 = 0;
 220:         ti->ti_pad = 0;
 221:         ti->ti_len = (u_short)tlen;
 222:         ti->ti_len = htons((u_short)ti->ti_len);
 223:         if (ti->ti_sum = in_cksum(m, len)) {
 224:             if (tcpprintfs)
 225:                 printf("tcp sum: src %x\n", ti->ti_src);
 226:             tcpstat.tcps_rcvbadsum++;
 227:             goto drop;
 228:         }
 229:     }
 230: 
 231:     /*
 232: 	 * Check that TCP offset makes sense,
 233: 	 * pull out TCP options and adjust length.
 234: 	 */
 235:     off = ti->ti_off << 2;
 236:     if (off < sizeof (struct tcphdr) || off > tlen) {
 237:         if (tcpprintfs)
 238:             printf("tcp off: src %x off %d\n", ti->ti_src, off);
 239:         tcpstat.tcps_rcvbadoff++;
 240:         goto drop;
 241:     }
 242:     tlen -= off;
 243:     ti->ti_len = tlen;
 244:     if (off > sizeof (struct tcphdr)) {
 245:         if (m->m_len < sizeof(struct ip) + off) {
 246:             if ((m = m_pullup(m, sizeof (struct ip) + off)) == 0) {
 247:                 tcpstat.tcps_rcvshort++;
 248:                 return;
 249:             }
 250:             ti = mtod(m, struct tcpiphdr *);
 251:         }
 252:         om = m_get(M_DONTWAIT, MT_DATA);
 253:         if (om == 0)
 254:             goto drop;
 255:         om->m_len = off - sizeof (struct tcphdr);
 256:         { caddr_t op = mtod(m, caddr_t) + sizeof (struct tcpiphdr);
 257:           bcopy(op, mtod(om, caddr_t), (unsigned)om->m_len);
 258:           m->m_len -= om->m_len;
 259:           bcopy(op+om->m_len, op,
 260:            (unsigned)(m->m_len-sizeof (struct tcpiphdr)));
 261:         }
 262:     }
 263:     tiflags = ti->ti_flags;
 264: 
 265:     /*
 266: 	 * Drop TCP and IP headers; TCP options were dropped above.
 267: 	 */
 268:     m->m_off += sizeof(struct tcpiphdr);
 269:     m->m_len -= sizeof(struct tcpiphdr);
 270: 
 271:     /*
 272: 	 * Convert TCP protocol specific fields to host format.
 273: 	 */
 274:     ti->ti_seq = ntohl(ti->ti_seq);
 275:     ti->ti_ack = ntohl(ti->ti_ack);
 276:     ti->ti_win = ntohs(ti->ti_win);
 277:     ti->ti_urp = ntohs(ti->ti_urp);
 278: 
 279:     /*
 280: 	 * Locate pcb for segment.
 281: 	 */
 282: findpcb:
 283:     inp = in_pcblookup
 284:         (&tcb, ti->ti_src, ti->ti_sport, ti->ti_dst, ti->ti_dport,
 285:         INPLOOKUP_WILDCARD);
 286: 
 287:     /*
 288: 	 * If the state is CLOSED (i.e., TCB does not exist) then
 289: 	 * all data in the incoming segment is discarded.
 290: 	 * If the TCB exists but is in CLOSED state, it is embryonic,
 291: 	 * but should either do a listen or a connect soon.
 292: 	 */
 293:     if (inp == 0)
 294:         goto dropwithreset;
 295:     tp = intotcpcb(inp);
 296:     if (tp == 0)
 297:         goto dropwithreset;
 298:     if (tp->t_state == TCPS_CLOSED)
 299:         goto drop;
 300:     so = inp->inp_socket;
 301:     if (so->so_options & SO_DEBUG) {
 302:         ostate = tp->t_state;
 303:         tcp_saveti = *ti;
 304:     }
 305:     if (so->so_options & SO_ACCEPTCONN) {
 306:         so = sonewconn(so);
 307:         if (so == 0)
 308:             goto drop;
 309:         /*
 310: 		 * This is ugly, but ....
 311: 		 *
 312: 		 * Mark socket as temporary until we're
 313: 		 * committed to keeping it.  The code at
 314: 		 * ``drop'' and ``dropwithreset'' check the
 315: 		 * flag dropsocket to see if the temporary
 316: 		 * socket created here should be discarded.
 317: 		 * We mark the socket as discardable until
 318: 		 * we're committed to it below in TCPS_LISTEN.
 319: 		 */
 320:         dropsocket++;
 321:         inp = (struct inpcb *)so->so_pcb;
 322:         inp->inp_laddr = ti->ti_dst;
 323:         inp->inp_lport = ti->ti_dport;
 324: #if BSD>=43
 325:         inp->inp_options = ip_srcroute();
 326: #endif
 327:         tp = intotcpcb(inp);
 328:         tp->t_state = TCPS_LISTEN;
 329:     }
 330: 
 331:     /*
 332: 	 * Segment received on connection.
 333: 	 * Reset idle time and keep-alive timer.
 334: 	 */
 335:     tp->t_idle = 0;
 336:     tp->t_timer[TCPT_KEEP] = tcp_keepidle;
 337: 
 338:     /*
 339: 	 * Process options if not in LISTEN state,
 340: 	 * else do it below (after getting remote address).
 341: 	 */
 342:     if (om && tp->t_state != TCPS_LISTEN) {
 343:         tcp_dooptions(tp, om, ti);
 344:         om = 0;
 345:     }
 346: 
 347:     /*
 348: 	 * Calculate amount of space in receive window,
 349: 	 * and then do TCP input processing.
 350: 	 * Receive window is amount of space in rcv queue,
 351: 	 * but not less than advertised window.
 352: 	 */
 353:     { int win;
 354: 
 355:     win = sbspace(&so->so_rcv);
 356:     if (win < 0)
 357:         win = 0;
 358:     tp->rcv_wnd = MAX(win, (int)(tp->rcv_adv - tp->rcv_nxt));
 359:     }
 360: 
 361:     switch (tp->t_state) {
 362: 
 363:     /*
 364: 	 * If the state is LISTEN then ignore segment if it contains an RST.
 365: 	 * If the segment contains an ACK then it is bad and send a RST.
 366: 	 * If it does not contain a SYN then it is not interesting; drop it.
 367: 	 * Don't bother responding if the destination was a broadcast.
 368: 	 * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
 369: 	 * tp->iss, and send a segment:
 370: 	 *     <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK>
 371: 	 * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss.
 372: 	 * Fill in remote peer address fields if not previously specified.
 373: 	 * Enter SYN_RECEIVED state, and process any other fields of this
 374: 	 * segment in this state.
 375: 	 */
 376:     case TCPS_LISTEN: {
 377:         struct mbuf *am;
 378:         register struct sockaddr_in *sin;
 379: 
 380:         if (tiflags & TH_RST)
 381:             goto drop;
 382:         if (tiflags & TH_ACK)
 383:             goto dropwithreset;
 384:         if ((tiflags & TH_SYN) == 0)
 385:             goto drop;
 386:         if (in_broadcast(ti->ti_dst))
 387:             goto drop;
 388:         am = m_get(M_DONTWAIT, MT_SONAME);
 389:         if (am == NULL)
 390:             goto drop;
 391:         am->m_len = sizeof (struct sockaddr_in);
 392:         sin = mtod(am, struct sockaddr_in *);
 393:         sin->sin_family = AF_INET;
 394:         sin->sin_addr = ti->ti_src;
 395:         sin->sin_port = ti->ti_sport;
 396:         laddr = inp->inp_laddr;
 397:         if (inp->inp_laddr.s_addr == INADDR_ANY)
 398:             inp->inp_laddr = ti->ti_dst;
 399:         if (in_pcbconnect(inp, am)) {
 400:             inp->inp_laddr = laddr;
 401:             (void) m_free(am);
 402:             goto drop;
 403:         }
 404:         (void) m_free(am);
 405:         tp->t_template = tcp_template(tp);
 406:         if (tp->t_template == 0) {
 407:             tp = tcp_drop(tp, ENOBUFS);
 408:             dropsocket = 0;     /* socket is already gone */
 409:             goto drop;
 410:         }
 411:         if (om) {
 412:             tcp_dooptions(tp, om, ti);
 413:             om = 0;
 414:         }
 415:         if (iss)
 416:             tp->iss = iss;
 417:         else
 418:             tp->iss = tcp_iss;
 419:         tcp_iss += TCP_ISSINCR/2;
 420:         tp->irs = ti->ti_seq;
 421:         tcp_sendseqinit(tp);
 422:         tcp_rcvseqinit(tp);
 423:         tp->t_flags |= TF_ACKNOW;
 424:         tp->t_state = TCPS_SYN_RECEIVED;
 425:         tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
 426:         dropsocket = 0;     /* committed to socket */
 427:         tcpstat.tcps_accepts++;
 428:         goto trimthenstep6;
 429:         }
 430: 
 431:     /*
 432: 	 * If the state is SYN_SENT:
 433: 	 *	if seg contains an ACK, but not for our SYN, drop the input.
 434: 	 *	if seg contains a RST, then drop the connection.
 435: 	 *	if seg does not contain SYN, then drop it.
 436: 	 * Otherwise this is an acceptable SYN segment
 437: 	 *	initialize tp->rcv_nxt and tp->irs
 438: 	 *	if seg contains ack then advance tp->snd_una
 439: 	 *	if SYN has been acked change to ESTABLISHED else SYN_RCVD state
 440: 	 *	arrange for segment to be acked (eventually)
 441: 	 *	continue processing rest of data/controls, beginning with URG
 442: 	 */
 443:     case TCPS_SYN_SENT:
 444:         if ((tiflags & TH_ACK) &&
 445:             (SEQ_LEQ(ti->ti_ack, tp->iss) ||
 446:              SEQ_GT(ti->ti_ack, tp->snd_max)))
 447:             goto dropwithreset;
 448:         if (tiflags & TH_RST) {
 449:             if (tiflags & TH_ACK)
 450:                 tp = tcp_drop(tp, ECONNREFUSED);
 451:             goto drop;
 452:         }
 453:         if ((tiflags & TH_SYN) == 0)
 454:             goto drop;
 455:         if (tiflags & TH_ACK) {
 456:             tp->snd_una = ti->ti_ack;
 457:             if (SEQ_LT(tp->snd_nxt, tp->snd_una))
 458:                 tp->snd_nxt = tp->snd_una;
 459:         }
 460:         tp->t_timer[TCPT_REXMT] = 0;
 461:         tp->irs = ti->ti_seq;
 462:         tcp_rcvseqinit(tp);
 463:         tp->t_flags |= TF_ACKNOW;
 464:         if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) {
 465:             tcpstat.tcps_connects++;
 466:             soisconnected(so);
 467:             tp->t_state = TCPS_ESTABLISHED;
 468:             tp->t_maxseg = MIN(tp->t_maxseg, tcp_mss(tp));
 469:             (void) tcp_reass(tp, (struct tcpiphdr *)0);
 470:             /*
 471: 			 * if we didn't have to retransmit the SYN,
 472: 			 * use its rtt as our initial srtt & rtt var.
 473: 			 */
 474:             if (tp->t_rtt) {
 475:                 tp->t_srtt = tp->t_rtt << 3;
 476:                 tp->t_rttvar = tp->t_rtt << 1;
 477:                 TCPT_RANGESET(tp->t_rxtcur,
 478:                     ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1,
 479:                     TCPTV_MIN, TCPTV_REXMTMAX);
 480:                 tp->t_rtt = 0;
 481:             }
 482:         } else
 483:             tp->t_state = TCPS_SYN_RECEIVED;
 484: 
 485: trimthenstep6:
 486:         /*
 487: 		 * Advance ti->ti_seq to correspond to first data byte.
 488: 		 * If data, trim to stay within window,
 489: 		 * dropping FIN if necessary.
 490: 		 */
 491:         ti->ti_seq++;
 492:         if (ti->ti_len > tp->rcv_wnd) {
 493:             todrop = ti->ti_len - tp->rcv_wnd;
 494: #if BSD>=43
 495:             m_adj(m, -todrop);
 496: #else
 497:             /* XXX work around 4.2 m_adj bug */
 498:             if (m->m_len) {
 499:                 m_adj(m, -todrop);
 500:             } else {
 501:                 /* skip tcp/ip header in first mbuf */
 502:                 m_adj(m->m_next, -todrop);
 503:             }
 504: #endif
 505:             ti->ti_len = tp->rcv_wnd;
 506:             tiflags &= ~TH_FIN;
 507:             tcpstat.tcps_rcvpackafterwin++;
 508:             tcpstat.tcps_rcvbyteafterwin += todrop;
 509:         }
 510:         tp->snd_wl1 = ti->ti_seq - 1;
 511:         tp->rcv_up = ti->ti_seq;
 512:         goto step6;
 513:     }
 514: 
 515:     /*
 516: 	 * States other than LISTEN or SYN_SENT.
 517: 	 * First check that at least some bytes of segment are within
 518: 	 * receive window.  If segment begins before rcv_nxt,
 519: 	 * drop leading data (and SYN); if nothing left, just ack.
 520: 	 */
 521:     todrop = tp->rcv_nxt - ti->ti_seq;
 522:     if (todrop > 0) {
 523:         if (tiflags & TH_SYN) {
 524:             tiflags &= ~TH_SYN;
 525:             ti->ti_seq++;
 526:             if (ti->ti_urp > 1)
 527:                 ti->ti_urp--;
 528:             else
 529:                 tiflags &= ~TH_URG;
 530:             todrop--;
 531:         }
 532:         if (todrop > ti->ti_len ||
 533:             todrop == ti->ti_len && (tiflags&TH_FIN) == 0) {
 534:             tcpstat.tcps_rcvduppack++;
 535:             tcpstat.tcps_rcvdupbyte += ti->ti_len;
 536:             /*
 537: 			 * If segment is just one to the left of the window,
 538: 			 * check two special cases:
 539: 			 * 1. Don't toss RST in response to 4.2-style keepalive.
 540: 			 * 2. If the only thing to drop is a FIN, we can drop
 541: 			 *    it, but check the ACK or we will get into FIN
 542: 			 *    wars if our FINs crossed (both CLOSING).
 543: 			 * In either case, send ACK to resynchronize,
 544: 			 * but keep on processing for RST or ACK.
 545: 			 */
 546:             if ((tiflags & TH_FIN && todrop == ti->ti_len + 1)
 547: #ifdef TCP_COMPAT_42
 548:               || (tiflags & TH_RST && ti->ti_seq == tp->rcv_nxt - 1)
 549: #endif
 550:                ) {
 551:                 todrop = ti->ti_len;
 552:                 tiflags &= ~TH_FIN;
 553:                 tp->t_flags |= TF_ACKNOW;
 554:             } else
 555:                 goto dropafterack;
 556:         } else {
 557:             tcpstat.tcps_rcvpartduppack++;
 558:             tcpstat.tcps_rcvpartdupbyte += todrop;
 559:         }
 560:         m_adj(m, todrop);
 561:         ti->ti_seq += todrop;
 562:         ti->ti_len -= todrop;
 563:         if (ti->ti_urp > todrop)
 564:             ti->ti_urp -= todrop;
 565:         else {
 566:             tiflags &= ~TH_URG;
 567:             ti->ti_urp = 0;
 568:         }
 569:     }
 570: 
 571:     /*
 572: 	 * If new data are received on a connection after the
 573: 	 * user processes are gone, then RST the other end.
 574: 	 */
 575:     if ((so->so_state & SS_NOFDREF) &&
 576:         tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) {
 577:         tp = tcp_close(tp);
 578:         tcpstat.tcps_rcvafterclose++;
 579:         goto dropwithreset;
 580:     }
 581: 
 582:     /*
 583: 	 * If segment ends after window, drop trailing data
 584: 	 * (and PUSH and FIN); if nothing left, just ACK.
 585: 	 */
 586:     todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd);
 587:     if (todrop > 0) {
 588:         tcpstat.tcps_rcvpackafterwin++;
 589:         if (todrop >= ti->ti_len) {
 590:             tcpstat.tcps_rcvbyteafterwin += ti->ti_len;
 591:             /*
 592: 			 * If a new connection request is received
 593: 			 * while in TIME_WAIT, drop the old connection
 594: 			 * and start over if the sequence numbers
 595: 			 * are above the previous ones.
 596: 			 */
 597:             if (tiflags & TH_SYN &&
 598:                 tp->t_state == TCPS_TIME_WAIT &&
 599:                 SEQ_GT(ti->ti_seq, tp->rcv_nxt)) {
 600:                 iss = tp->rcv_nxt + TCP_ISSINCR;
 601:                 (void) tcp_close(tp);
 602:                 goto findpcb;
 603:             }
 604:             /*
 605: 			 * If window is closed can only take segments at
 606: 			 * window edge, and have to drop data and PUSH from
 607: 			 * incoming segments.  Continue processing, but
 608: 			 * remember to ack.  Otherwise, drop segment
 609: 			 * and ack.
 610: 			 */
 611:             if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) {
 612:                 tp->t_flags |= TF_ACKNOW;
 613:                 tcpstat.tcps_rcvwinprobe++;
 614:             } else
 615:                 goto dropafterack;
 616:         } else
 617:             tcpstat.tcps_rcvbyteafterwin += todrop;
 618: #if BSD>=43
 619:         m_adj(m, -todrop);
 620: #else
 621:         /* XXX work around m_adj bug */
 622:         if (m->m_len) {
 623:             m_adj(m, -todrop);
 624:         } else {
 625:             /* skip tcp/ip header in first mbuf */
 626:             m_adj(m->m_next, -todrop);
 627:         }
 628: #endif
 629:         ti->ti_len -= todrop;
 630:         tiflags &= ~(TH_PUSH|TH_FIN);
 631:     }
 632: 
 633:     /*
 634: 	 * If the RST bit is set examine the state:
 635: 	 *    SYN_RECEIVED STATE:
 636: 	 *	If passive open, return to LISTEN state.
 637: 	 *	If active open, inform user that connection was refused.
 638: 	 *    ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES:
 639: 	 *	Inform user that connection was reset, and close tcb.
 640: 	 *    CLOSING, LAST_ACK, TIME_WAIT STATES
 641: 	 *	Close the tcb.
 642: 	 */
 643:     if (tiflags&TH_RST) switch (tp->t_state) {
 644: 
 645:     case TCPS_SYN_RECEIVED:
 646:         so->so_error = ECONNREFUSED;
 647:         goto close;
 648: 
 649:     case TCPS_ESTABLISHED:
 650:     case TCPS_FIN_WAIT_1:
 651:     case TCPS_FIN_WAIT_2:
 652:     case TCPS_CLOSE_WAIT:
 653:         so->so_error = ECONNRESET;
 654:     close:
 655:         tp->t_state = TCPS_CLOSED;
 656:         tcpstat.tcps_drops++;
 657:         tp = tcp_close(tp);
 658:         goto drop;
 659: 
 660:     case TCPS_CLOSING:
 661:     case TCPS_LAST_ACK:
 662:     case TCPS_TIME_WAIT:
 663:         tp = tcp_close(tp);
 664:         goto drop;
 665:     }
 666: 
 667:     /*
 668: 	 * If a SYN is in the window, then this is an
 669: 	 * error and we send an RST and drop the connection.
 670: 	 */
 671:     if (tiflags & TH_SYN) {
 672:         tp = tcp_drop(tp, ECONNRESET);
 673:         goto dropwithreset;
 674:     }
 675: 
 676:     /*
 677: 	 * If the ACK bit is off we drop the segment and return.
 678: 	 */
 679:     if ((tiflags & TH_ACK) == 0)
 680:         goto drop;
 681: 
 682:     /*
 683: 	 * Ack processing.
 684: 	 */
 685:     switch (tp->t_state) {
 686: 
 687:     /*
 688: 	 * In SYN_RECEIVED state if the ack ACKs our SYN then enter
 689: 	 * ESTABLISHED state and continue processing, otherwise
 690: 	 * send an RST.
 691: 	 */
 692:     case TCPS_SYN_RECEIVED:
 693:         if (SEQ_GT(tp->snd_una, ti->ti_ack) ||
 694:             SEQ_GT(ti->ti_ack, tp->snd_max))
 695:             goto dropwithreset;
 696:         tcpstat.tcps_connects++;
 697:         soisconnected(so);
 698:         tp->t_state = TCPS_ESTABLISHED;
 699:         tp->t_maxseg = MIN(tp->t_maxseg, tcp_mss(tp));
 700:         (void) tcp_reass(tp, (struct tcpiphdr *)0);
 701:         tp->snd_wl1 = ti->ti_seq - 1;
 702:         /* fall into ... */
 703: 
 704:     /*
 705: 	 * In ESTABLISHED state: drop duplicate ACKs; ACK out of range
 706: 	 * ACKs.  If the ack is in the range
 707: 	 *	tp->snd_una < ti->ti_ack <= tp->snd_max
 708: 	 * then advance tp->snd_una to ti->ti_ack and drop
 709: 	 * data from the retransmission queue.  If this ACK reflects
 710: 	 * more up to date window information we update our window information.
 711: 	 */
 712:     case TCPS_ESTABLISHED:
 713:     case TCPS_FIN_WAIT_1:
 714:     case TCPS_FIN_WAIT_2:
 715:     case TCPS_CLOSE_WAIT:
 716:     case TCPS_CLOSING:
 717:     case TCPS_LAST_ACK:
 718:     case TCPS_TIME_WAIT:
 719: 
 720:         if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) {
 721:             if (ti->ti_len == 0 && ti->ti_win == tp->snd_wnd) {
 722:                 tcpstat.tcps_rcvdupack++;
 723:                 /*
 724: 				 * If we have outstanding data (not a
 725: 				 * window probe), this is a completely
 726: 				 * duplicate ack (ie, window info didn't
 727: 				 * change), the ack is the biggest we've
 728: 				 * seen and we've seen exactly our rexmt
 729: 				 * threshhold of them, assume a packet
 730: 				 * has been dropped and retransmit it.
 731: 				 * Kludge snd_nxt & the congestion
 732: 				 * window so we send only this one
 733: 				 * packet.  If this packet fills the
 734: 				 * only hole in the receiver's seq.
 735: 				 * space, the next real ack will fully
 736: 				 * open our window.  This means we
 737: 				 * have to do the usual slow-start to
 738: 				 * not overwhelm an intermediate gateway
 739: 				 * with a burst of packets.  Leave
 740: 				 * here with the congestion window set
 741: 				 * to allow 2 packets on the next real
 742: 				 * ack and the exp-to-linear thresh
 743: 				 * set for half the current window
 744: 				 * size (since we know we're losing at
 745: 				 * the current window size).
 746: 				 */
 747:                 if (tp->t_timer[TCPT_REXMT] == 0 ||
 748:                     ti->ti_ack != tp->snd_una)
 749:                     tp->t_dupacks = 0;
 750:                 else if (++tp->t_dupacks == tcprexmtthresh) {
 751:                     tcp_seq onxt = tp->snd_nxt;
 752:                     u_int win =
 753:                         MIN(tp->snd_wnd, tp->snd_cwnd) / 2 /
 754:                         tp->t_maxseg;
 755: 
 756:                     if (win < 2)
 757:                         win = 2;
 758:                     tp->snd_ssthresh = win * tp->t_maxseg;
 759: 
 760:                     tp->t_timer[TCPT_REXMT] = 0;
 761:                     tp->t_rtt = 0;
 762:                     tp->snd_nxt = ti->ti_ack;
 763:                     tp->snd_cwnd = tp->t_maxseg;
 764:                     (void) tcp_output(tp);
 765: 
 766:                     if (SEQ_GT(onxt, tp->snd_nxt))
 767:                         tp->snd_nxt = onxt;
 768:                     goto drop;
 769:                 }
 770:             } else
 771:                 tp->t_dupacks = 0;
 772:             break;
 773:         }
 774:         tp->t_dupacks = 0;
 775:         if (SEQ_GT(ti->ti_ack, tp->snd_max)) {
 776:             tcpstat.tcps_rcvacktoomuch++;
 777:             goto dropafterack;
 778:         }
 779:         acked = ti->ti_ack - tp->snd_una;
 780:         tcpstat.tcps_rcvackpack++;
 781:         tcpstat.tcps_rcvackbyte += acked;
 782: 
 783:         /*
 784: 		 * If transmit timer is running and timed sequence
 785: 		 * number was acked, update smoothed round trip time.
 786: 		 * Since we now have an rtt measurement, cancel the
 787: 		 * timer backoff (cf., Phil Karn's retransmit alg.).
 788: 		 * Recompute the initial retransmit timer.
 789: 		 */
 790:         if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) {
 791:             tcpstat.tcps_rttupdated++;
 792:             if (tp->t_srtt != 0) {
 793:                 register short delta;
 794: 
 795:                 /*
 796: 				 * srtt is stored as fixed point with 3 bits
 797: 				 * after the binary point (i.e., scaled by 8).
 798: 				 * The following magic is equivalent
 799: 				 * to the smoothing algorithm in rfc793
 800: 				 * with an alpha of .875
 801: 				 * (srtt = rtt/8 + srtt*7/8 in fixed point).
 802: 				 * Adjust t_rtt to origin 0.
 803: 				 */
 804:                 delta = tp->t_rtt - 1 - (tp->t_srtt >> 3);
 805:                 if ((tp->t_srtt += delta) <= 0)
 806:                     tp->t_srtt = 1;
 807:                 /*
 808: 				 * We accumulate a smoothed rtt variance
 809: 				 * (actually, a smoothed mean difference),
 810: 				 * then set the retransmit timer to smoothed
 811: 				 * rtt + 2 times the smoothed variance.
 812: 				 * rttvar is stored as fixed point
 813: 				 * with 2 bits after the binary point
 814: 				 * (scaled by 4).  The following is equivalent
 815: 				 * to rfc793 smoothing with an alpha of .75
 816: 				 * (rttvar = rttvar*3/4 + |delta| / 4).
 817: 				 * This replaces rfc793's wired-in beta.
 818: 				 */
 819:                 if (delta < 0)
 820:                     delta = -delta;
 821:                 delta -= (tp->t_rttvar >> 2);
 822:                 if ((tp->t_rttvar += delta) <= 0)
 823:                     tp->t_rttvar = 1;
 824:             } else {
 825:                 /*
 826: 				 * No rtt measurement yet - use the
 827: 				 * unsmoothed rtt.  Set the variance
 828: 				 * to half the rtt (so our first
 829: 				 * retransmit happens at 2*rtt)
 830: 				 */
 831:                 tp->t_srtt = tp->t_rtt << 3;
 832:                 tp->t_rttvar = tp->t_rtt << 1;
 833:             }
 834:             tp->t_rtt = 0;
 835:             tp->t_rxtshift = 0;
 836:             TCPT_RANGESET(tp->t_rxtcur,
 837:                 ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1,
 838:                 TCPTV_MIN, TCPTV_REXMTMAX);
 839:         }
 840: 
 841:         /*
 842: 		 * If all outstanding data is acked, stop retransmit
 843: 		 * timer and remember to restart (more output or persist).
 844: 		 * If there is more data to be acked, restart retransmit
 845: 		 * timer, using current (possibly backed-off) value.
 846: 		 */
 847:         if (ti->ti_ack == tp->snd_max) {
 848:             tp->t_timer[TCPT_REXMT] = 0;
 849:             needoutput = 1;
 850:         } else if (tp->t_timer[TCPT_PERSIST] == 0)
 851:             tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
 852:         /*
 853: 		 * When new data is acked, open the congestion window.
 854: 		 * If the window gives us less than ssthresh packets
 855: 		 * in flight, open exponentially (maxseg per packet).
 856: 		 * Otherwise open linearly (maxseg per window,
 857: 		 * or maxseg^2 / cwnd per packet).
 858: 		 */
 859:         {
 860:         u_long incr = tp->t_maxseg;
 861: 
 862:         if (tp->snd_cwnd > tp->snd_ssthresh)
 863:             incr = MAX((long)(incr * incr / tp->snd_cwnd), 1L);
 864: 
 865:         tp->snd_cwnd = MIN((long)(tp->snd_cwnd + incr), IP_MAXPACKET); /* XXX */
 866:         }
 867:         if (acked > so->so_snd.sb_cc) {
 868:             tp->snd_wnd -= so->so_snd.sb_cc;
 869:             sbdrop(&so->so_snd, (int)so->so_snd.sb_cc);
 870:             ourfinisacked = 1;
 871:         } else {
 872:             sbdrop(&so->so_snd, acked);
 873:             tp->snd_wnd -= acked;
 874:             ourfinisacked = 0;
 875:         }
 876:         if ((so->so_snd.sb_flags & SB_WAIT) || so->so_snd.sb_sel)
 877:             sowwakeup(so);
 878:         tp->snd_una = ti->ti_ack;
 879:         if (SEQ_LT(tp->snd_nxt, tp->snd_una))
 880:             tp->snd_nxt = tp->snd_una;
 881: 
 882:         switch (tp->t_state) {
 883: 
 884:         /*
 885: 		 * In FIN_WAIT_1 STATE in addition to the processing
 886: 		 * for the ESTABLISHED state if our FIN is now acknowledged
 887: 		 * then enter FIN_WAIT_2.
 888: 		 */
 889:         case TCPS_FIN_WAIT_1:
 890:             if (ourfinisacked) {
 891:                 /*
 892: 				 * If we can't receive any more
 893: 				 * data, then closing user can proceed.
 894: 				 * Starting the timer is contrary to the
 895: 				 * specification, but if we don't get a FIN
 896: 				 * we'll hang forever.
 897: 				 */
 898:                 if (so->so_state & SS_CANTRCVMORE) {
 899:                     soisdisconnected(so);
 900:                     tp->t_timer[TCPT_2MSL] = tcp_maxidle;
 901:                 }
 902:                 tp->t_state = TCPS_FIN_WAIT_2;
 903:             }
 904:             break;
 905: 
 906:         /*
 907: 		 * In CLOSING STATE in addition to the processing for
 908: 		 * the ESTABLISHED state if the ACK acknowledges our FIN
 909: 		 * then enter the TIME-WAIT state, otherwise ignore
 910: 		 * the segment.
 911: 		 */
 912:         case TCPS_CLOSING:
 913:             if (ourfinisacked) {
 914:                 tp->t_state = TCPS_TIME_WAIT;
 915:                 tcp_canceltimers(tp);
 916:                 tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
 917:                 soisdisconnected(so);
 918:             }
 919:             break;
 920: 
 921:         /*
 922: 		 * In LAST_ACK, we may still be waiting for data to drain
 923: 		 * and/or to be acked, as well as for the ack of our FIN.
 924: 		 * If our FIN is now acknowledged, delete the TCB,
 925: 		 * enter the closed state and return.
 926: 		 */
 927:         case TCPS_LAST_ACK:
 928:             if (ourfinisacked) {
 929:                 tp = tcp_close(tp);
 930:                 goto drop;
 931:             }
 932:             break;
 933: 
 934:         /*
 935: 		 * In TIME_WAIT state the only thing that should arrive
 936: 		 * is a retransmission of the remote FIN.  Acknowledge
 937: 		 * it and restart the finack timer.
 938: 		 */
 939:         case TCPS_TIME_WAIT:
 940:             tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
 941:             goto dropafterack;
 942:         }
 943:     }
 944: 
 945: step6:
 946:     /*
 947: 	 * Update window information.
 948: 	 * Don't look at window if no ACK: TAC's send garbage on first SYN.
 949: 	 */
 950:     if ((tiflags & TH_ACK) &&
 951:         (SEQ_LT(tp->snd_wl1, ti->ti_seq) || tp->snd_wl1 == ti->ti_seq &&
 952:         (SEQ_LT(tp->snd_wl2, ti->ti_ack) ||
 953:          tp->snd_wl2 == ti->ti_ack && ti->ti_win > tp->snd_wnd))) {
 954:         /* keep track of pure window updates */
 955:         if (ti->ti_len == 0 &&
 956:             tp->snd_wl2 == ti->ti_ack && ti->ti_win > tp->snd_wnd)
 957:             tcpstat.tcps_rcvwinupd++;
 958:         tp->snd_wnd = ti->ti_win;
 959:         tp->snd_wl1 = ti->ti_seq;
 960:         tp->snd_wl2 = ti->ti_ack;
 961:         if (tp->snd_wnd > tp->max_sndwnd)
 962:             tp->max_sndwnd = tp->snd_wnd;
 963:         needoutput = 1;
 964:     }
 965: 
 966:     /*
 967: 	 * Process segments with URG.
 968: 	 */
 969:     if ((tiflags & TH_URG) && ti->ti_urp &&
 970:         TCPS_HAVERCVDFIN(tp->t_state) == 0) {
 971:         /*
 972: 		 * This is a kludge, but if we receive and accept
 973: 		 * random urgent pointers, we'll crash in
 974: 		 * soreceive.  It's hard to imagine someone
 975: 		 * actually wanting to send this much urgent data.
 976: 		 */
 977:         if (ti->ti_urp + so->so_rcv.sb_cc > SB_MAX) {
 978:             ti->ti_urp = 0;         /* XXX */
 979:             tiflags &= ~TH_URG;     /* XXX */
 980:             goto dodata;            /* XXX */
 981:         }
 982:         /*
 983: 		 * If this segment advances the known urgent pointer,
 984: 		 * then mark the data stream.  This should not happen
 985: 		 * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since
 986: 		 * a FIN has been received from the remote side.
 987: 		 * In these states we ignore the URG.
 988: 		 *
 989: 		 * According to RFC961 (Assigned Protocols),
 990: 		 * the urgent pointer points to the last octet
 991: 		 * of urgent data.  We continue, however,
 992: 		 * to consider it to indicate the first octet
 993: 		 * of data past the urgent section
 994: 		 * as the original spec states.
 995: 		 */
 996:         if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) {
 997:             tp->rcv_up = ti->ti_seq + ti->ti_urp;
 998:             so->so_oobmark = so->so_rcv.sb_cc +
 999:                 (tp->rcv_up - tp->rcv_nxt) - 1;
1000:             if (so->so_oobmark == 0)
1001:                 so->so_state |= SS_RCVATMARK;
1002:             sohasoutofband(so);
1003:             tp->t_oobflags &= ~(TCPOOB_HAVEDATA | TCPOOB_HADDATA);
1004:         }
1005:         /*
1006: 		 * Remove out of band data so doesn't get presented to user.
1007: 		 * This can happen independent of advancing the URG pointer,
1008: 		 * but if two URG's are pending at once, some out-of-band
1009: 		 * data may creep in... ick.
1010: 		 */
1011:         if (ti->ti_urp <= ti->ti_len
1012: #ifdef SO_OOBINLINE
1013:              && (so->so_options & SO_OOBINLINE) == 0
1014: #endif
1015:                                )
1016:             tcp_pulloutofband(so, ti);
1017:     } else
1018:         /*
1019: 		 * If no out of band data is expected,
1020: 		 * pull receive urgent pointer along
1021: 		 * with the receive window.
1022: 		 */
1023:         if (SEQ_GT(tp->rcv_nxt, tp->rcv_up))
1024:             tp->rcv_up = tp->rcv_nxt;
1025: dodata:                         /* XXX */
1026: 
1027:     /*
1028: 	 * Process the segment text, merging it into the TCP sequencing queue,
1029: 	 * and arranging for acknowledgment of receipt if necessary.
1030: 	 * This process logically involves adjusting tp->rcv_wnd as data
1031: 	 * is presented to the user (this happens in tcp_usrreq.c,
1032: 	 * case PRU_RCVD).  If a FIN has already been received on this
1033: 	 * connection then we just ignore the text.
1034: 	 */
1035:     if ((ti->ti_len || (tiflags&TH_FIN)) &&
1036:         TCPS_HAVERCVDFIN(tp->t_state) == 0) {
1037:         TCP_REASS(tp, ti, m, so, tiflags);
1038:         if (tcpnodelack == 0)
1039:             tp->t_flags |= TF_DELACK;
1040:         else
1041:             tp->t_flags |= TF_ACKNOW;
1042:         /*
1043: 		 * Note the amount of data that peer has sent into
1044: 		 * our window, in order to estimate the sender's
1045: 		 * buffer size.
1046: 		 */
1047:         len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt);
1048:         if (len > tp->max_rcvd)
1049:             tp->max_rcvd = len;
1050:     } else {
1051:         m_freem(m);
1052:         tiflags &= ~TH_FIN;
1053:     }
1054: 
1055:     /*
1056: 	 * If FIN is received ACK the FIN and let the user know
1057: 	 * that the connection is closing.
1058: 	 */
1059:     if (tiflags & TH_FIN) {
1060:         if (TCPS_HAVERCVDFIN(tp->t_state) == 0) {
1061:             socantrcvmore(so);
1062:             tp->t_flags |= TF_ACKNOW;
1063:             tp->rcv_nxt++;
1064:         }
1065:         switch (tp->t_state) {
1066: 
1067:         /*
1068: 		 * In SYN_RECEIVED and ESTABLISHED STATES
1069: 		 * enter the CLOSE_WAIT state.
1070: 		 */
1071:         case TCPS_SYN_RECEIVED:
1072:         case TCPS_ESTABLISHED:
1073:             tp->t_state = TCPS_CLOSE_WAIT;
1074:             break;
1075: 
1076:         /*
1077: 		 * If still in FIN_WAIT_1 STATE FIN has not been acked so
1078: 		 * enter the CLOSING state.
1079: 		 */
1080:         case TCPS_FIN_WAIT_1:
1081:             tp->t_state = TCPS_CLOSING;
1082:             break;
1083: 
1084:         /*
1085: 		 * In FIN_WAIT_2 state enter the TIME_WAIT state,
1086: 		 * starting the time-wait timer, turning off the other
1087: 		 * standard timers.
1088: 		 */
1089:         case TCPS_FIN_WAIT_2:
1090:             tp->t_state = TCPS_TIME_WAIT;
1091:             tcp_canceltimers(tp);
1092:             tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
1093:             soisdisconnected(so);
1094:             break;
1095: 
1096:         /*
1097: 		 * In TIME_WAIT state restart the 2 MSL time_wait timer.
1098: 		 */
1099:         case TCPS_TIME_WAIT:
1100:             tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
1101:             break;
1102:         }
1103:     }
1104:     if (so->so_options & SO_DEBUG)
1105:         tcp_trace(TA_INPUT, ostate, tp, &tcp_saveti, 0);
1106: 
1107:     /*
1108: 	 * Return any desired output.
1109: 	 */
1110:     if (needoutput || (tp->t_flags & TF_ACKNOW))
1111:         (void) tcp_output(tp);
1112:     return;
1113: 
1114: dropafterack:
1115:     /*
1116: 	 * Generate an ACK dropping incoming segment if it occupies
1117: 	 * sequence space, where the ACK reflects our state.
1118: 	 */
1119:     if (tiflags & TH_RST)
1120:         goto drop;
1121:     m_freem(m);
1122:     tp->t_flags |= TF_ACKNOW;
1123:     (void) tcp_output(tp);
1124:     return;
1125: 
1126: dropwithreset:
1127:     if (om) {
1128:         (void) m_free(om);
1129:         om = 0;
1130:     }
1131:     /*
1132: 	 * Generate a RST, dropping incoming segment.
1133: 	 * Make ACK acceptable to originator of segment.
1134: 	 * Don't bother to respond if destination was broadcast.
1135: 	 */
1136:     if ((tiflags & TH_RST) || in_broadcast(ti->ti_dst))
1137:         goto drop;
1138:     if (tiflags & TH_ACK)
1139:         tcp_respond(tp, ti, (tcp_seq)0, ti->ti_ack, TH_RST);
1140:     else {
1141:         if (tiflags & TH_SYN)
1142:             ti->ti_len++;
1143:         tcp_respond(tp, ti, ti->ti_seq+ti->ti_len, (tcp_seq)0,
1144:             TH_RST|TH_ACK);
1145:     }
1146:     /* destroy temporarily created socket */
1147:     if (dropsocket)
1148:         (void) soabort(so);
1149:     return;
1150: 
1151: drop:
1152:     if (om)
1153:         (void) m_free(om);
1154:     /*
1155: 	 * Drop space held by incoming segment and return.
1156: 	 */
1157:     if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
1158:         tcp_trace(TA_DROP, ostate, tp, &tcp_saveti, 0);
1159:     m_freem(m);
1160:     /* destroy temporarily created socket */
1161:     if (dropsocket)
1162:         (void) soabort(so);
1163:     return;
1164: }
1165: 
1166: tcp_dooptions(tp, om, ti)
1167:     struct tcpcb *tp;
1168:     struct mbuf *om;
1169:     struct tcpiphdr *ti;
1170: {
1171:     register u_char *cp;
1172:     int opt, optlen, cnt;
1173: 
1174:     cp = mtod(om, u_char *);
1175:     cnt = om->m_len;
1176:     for (; cnt > 0; cnt -= optlen, cp += optlen) {
1177:         opt = UCHAR(cp[0]);
1178:         if (opt == TCPOPT_EOL)
1179:             break;
1180:         if (opt == TCPOPT_NOP)
1181:             optlen = 1;
1182:         else {
1183:             optlen = UCHAR(cp[1]);
1184:             if (optlen <= 0)
1185:                 break;
1186:         }
1187:         switch (opt) {
1188: 
1189:         default:
1190:             break;
1191: 
1192:         case TCPOPT_MAXSEG:
1193:             if (optlen != 4)
1194:                 continue;
1195:             if (!(ti->ti_flags & TH_SYN))
1196:                 continue;
1197:             tp->t_maxseg = *(u_short *)(cp + 2);
1198:             tp->t_maxseg = ntohs((u_short)tp->t_maxseg);
1199:             tp->t_maxseg = MIN(tp->t_maxseg, tcp_mss(tp));
1200:             break;
1201:         }
1202:     }
1203:     (void) m_free(om);
1204: }
1205: 
1206: /*
1207:  * Pull out of band byte out of a segment so
1208:  * it doesn't appear in the user's data queue.
1209:  * It is still reflected in the segment length for
1210:  * sequencing purposes.
1211:  */
1212: tcp_pulloutofband(so, ti)
1213:     struct socket *so;
1214:     struct tcpiphdr *ti;
1215: {
1216:     register struct mbuf *m;
1217:     int cnt = ti->ti_urp - 1;
1218: 
1219:     m = dtom(ti);
1220:     while (cnt >= 0) {
1221:         if (m->m_len > cnt) {
1222:             char *cp = mtod(m, caddr_t) + cnt;
1223:             struct tcpcb *tp = sototcpcb(so);
1224: 
1225:             tp->t_iobc = *cp;
1226:             tp->t_oobflags |= TCPOOB_HAVEDATA;
1227:             bcopy(cp+1, cp, (unsigned)(m->m_len - cnt - 1));
1228:             m->m_len--;
1229:             return;
1230:         }
1231:         cnt -= m->m_len;
1232:         m = m->m_next;
1233:         if (m == 0)
1234:             break;
1235:     }
1236:     panic("tcp_pulloutofband");
1237: }
1238: 
1239: /*
1240:  *  Determine a reasonable value for maxseg size.
1241:  *  If the route is known, use one that can be handled
1242:  *  on the given interface without forcing IP to fragment.
1243:  *  If bigger than an mbuf cluster (MCLBYTES), round down to nearest size
1244:  *  to utilize large mbufs.
1245:  *  If interface pointer is unavailable, or the destination isn't local,
1246:  *  use a conservative size (512 or the default IP max size, but no more
1247:  *  than the mtu of the interface through which we route),
1248:  *  as we can't discover anything about intervening gateways or networks.
1249:  *  We also initialize the congestion/slow start window to be a single
1250:  *  segment if the destination isn't local; this information should
1251:  *  probably all be saved with the routing entry at the transport level.
1252:  *
1253:  *  This is ugly, and doesn't belong at this level, but has to happen somehow.
1254:  */
1255: tcp_mss(tp)
1256:     register struct tcpcb *tp;
1257: {
1258:     struct route *ro;
1259:     struct ifnet *ifp;
1260:     int mss;
1261:     struct inpcb *inp;
1262: 
1263:     inp = tp->t_inpcb;
1264:     ro = &inp->inp_route;
1265:     if ((ro->ro_rt == (struct rtentry *)0) ||
1266:         (ifp = ro->ro_rt->rt_ifp) == (struct ifnet *)0) {
1267:         /* No route yet, so try to acquire one */
1268:         if (inp->inp_faddr.s_addr != INADDR_ANY) {
1269:             ro->ro_dst.sa_family = AF_INET;
1270:             ((struct sockaddr_in *) &ro->ro_dst)->sin_addr =
1271:                 inp->inp_faddr;
1272:             rtalloc(ro);
1273:         }
1274:         if ((ro->ro_rt == 0) || (ifp = ro->ro_rt->rt_ifp) == 0)
1275:             return (TCP_MSS);
1276:     }
1277: 
1278:     mss = ifp->if_mtu - sizeof(struct tcpiphdr);
1279: #if (MCLBYTES & (MCLBYTES - 1)) == 0
1280:     if (mss > MCLBYTES)
1281:         mss &= ~(MCLBYTES-1);
1282: #else
1283:     if (mss > MCLBYTES)
1284:         mss = mss / MCLBYTES * MCLBYTES;
1285: #endif
1286:     if (in_localaddr(inp->inp_faddr))
1287:         return (mss);
1288: 
1289:     mss = MIN(mss, TCP_MSS);
1290:     tp->snd_cwnd = mss;
1291:     return (mss);
1292: }
1293: 
1294: #if BSD<43
1295: /* XXX this belongs in netinet/in.c */
1296: in_localaddr(in)
1297:     struct in_addr in;
1298: {
1299:     register u_long i = ntohl(in.s_addr);
1300:     register struct ifnet *ifp;
1301:     register struct sockaddr_in *sin;
1302:     register u_long mask;
1303: 
1304:     if (IN_CLASSA(i))
1305:         mask = IN_CLASSA_NET;
1306:     else if (IN_CLASSB(i))
1307:         mask = IN_CLASSB_NET;
1308:     else if (IN_CLASSC(i))
1309:         mask = IN_CLASSC_NET;
1310:     else
1311:         return (0);
1312: 
1313:     i &= mask;
1314:     for (ifp = ifnet; ifp; ifp = ifp->if_next) {
1315:         if (ifp->if_addr.sa_family != AF_INET)
1316:             continue;
1317:         sin = (struct sockaddr_in *)&ifp->if_addr;
1318:         if ((sin->sin_addr.s_addr & mask) == i)
1319:             return (1);
1320:     }
1321:     return (0);
1322: }
1323: #endif

Defined functions

in_localaddr defined in line 1296; never used
tcp_dooptions defined in line 1166; used 2 times
tcp_input defined in line 178; never used
tcp_mss defined in line 1255; used 3 times
tcp_pulloutofband defined in line 1212; used 1 times
tcp_reass defined in line 70; used 3 times

Defined variables

tcp_saveti defined in line 43; used 3 times
tcpcksum defined in line 41; used 1 times
tcpprintfs defined in line 40; used 2 times
tcprexmtthresh defined in line 42; used 1 times

Defined macros

TCP_REASS defined in line 56; used 1 times
Last modified: 1988-05-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 876
Valid CSS Valid XHTML 1.0 Strict