# 2.11BSD#431 - /usr/src/sys/netinet/tcp_input.c

##### Functions

    in_localaddr      X
    tcp_dooptions     X
    tcp_input         X
    tcp_mss           X
    tcp_pulloutofband X
    tcp_reass         X

##### Variables

    tcp_saveti        X
    tcpcksum          X
    tcpprintfs        X
    tcprexmtthresh    X

##### Macros

    TCP_REASS         X

       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

- in line 343, 412

tcp_input defined in line 178; never used
tcp_mss defined in line 1255; used 3 times

- in line 468, 699, 1199

tcp_pulloutofband defined in line 1212; used 1 times

- in line 1016

tcp_reass defined in line 70; used 3 times

- in line 67, 469, 700

#### Defined variables

tcp_saveti defined in line 43; used 3 times

- in line 303, 1105, 1158

tcpcksum defined in line 41; used 1 times

- in line 217

tcpprintfs defined in line 40; used 2 times

- in line 224, 237

tcprexmtthresh defined in line 42; used 1 times

- in line 750

#### Defined macros

TCP_REASS defined in line 56; used 1 times

- in line 1037

Last modified: 1988-05-07 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3793 |