home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / hamradio / s920603.zip / TCPIN.C < prev    next >
C/C++ Source or Header  |  1992-03-29  |  25KB  |  899 lines

  1. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  2.  * the TCP specification.
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include "global.h"
  7. #include "timer.h"
  8. #include "mbuf.h"
  9. #include "netuser.h"
  10. #include "internet.h"
  11. #include "tcp.h"
  12. #include "icmp.h"
  13. #include "iface.h"
  14. #include "ip.h"
  15.  
  16. static void update __ARGS((struct tcb *tcb,struct tcp *seg,int16 length));
  17. static void proc_syn __ARGS((struct tcb *tcb,char tos,struct tcp *seg));
  18. static void add_reseq __ARGS((struct tcb *tcb,char tos,struct tcp *seg,
  19.     struct mbuf *bp,int16 length));
  20. static void get_reseq __ARGS((struct tcb *tcb,char *tos,struct tcp *seq,
  21.     struct mbuf **bp,int16 *length));
  22. static int trim __ARGS((struct tcb *tcb,struct tcp *seg,struct mbuf **bpp,
  23.     int16 *length));
  24. static int in_window __ARGS((struct tcb *tcb,int32 seq));
  25.  
  26. /* This function is called from IP with the IP header in machine byte order,
  27.  * along with a mbuf chain pointing to the TCP header.
  28.  */
  29. void
  30. tcp_input(iface,ip,bp,rxbroadcast)
  31. struct iface *iface;    /* Incoming interface (ignored) */
  32. struct mbuf *bp;    /* Data field, if any */
  33. struct ip *ip;        /* IP header */
  34. int rxbroadcast;    /* Incoming broadcast - discard if true */
  35. {
  36.     struct tcb *ntcb;
  37.     register struct tcb *tcb;    /* TCP Protocol control block */
  38.     struct tcp seg;            /* Local copy of segment header */
  39.     struct connection conn;        /* Local copy of addresses */
  40.     struct pseudo_header ph;    /* Pseudo-header for checksumming */
  41.     int hdrlen;            /* Length of TCP header */
  42.     int16 length;
  43.  
  44.     if(bp == NULLBUF)
  45.         return;
  46.  
  47.     tcpInSegs++;
  48.     if(rxbroadcast){
  49.         /* Any TCP packet arriving as a broadcast is
  50.          * to be completely IGNORED!!
  51.          */
  52.         free_p(bp);
  53.         return;
  54.     }
  55.     length = ip->length - IPLEN - ip->optlen;
  56.     ph.source = ip->source;
  57.     ph.dest = ip->dest;
  58.     ph.protocol = ip->protocol;
  59.     ph.length = length;
  60.     if(cksum(&ph,bp,length) != 0){
  61.         /* Checksum failed, ignore segment completely */
  62.         tcpInErrs++;
  63.         free_p(bp);
  64.         return;
  65.     }
  66.     /* Form local copy of TCP header in host byte order */
  67.     if((hdrlen = ntohtcp(&seg,&bp)) < 0){
  68.         /* TCP header is too small */
  69.         free_p(bp);
  70.         return;
  71.     }
  72.     length -= hdrlen;
  73.  
  74.     /* Fill in connection structure and find TCB */
  75.     conn.local.address = ip->dest;
  76.     conn.local.port = seg.dest;
  77.     conn.remote.address = ip->source;
  78.     conn.remote.port = seg.source;
  79.     
  80.     if((tcb = lookup_tcb(&conn)) == NULLTCB){
  81.         /* If this segment doesn't carry a SYN, reject it */
  82.         if(!seg.flags.syn){
  83.             free_p(bp);
  84.             reset(ip,&seg);
  85.             return;
  86.         }
  87.         /* See if there's a TCP_LISTEN on this socket with
  88.          * unspecified remote address and port
  89.          */
  90.         conn.remote.address = 0;
  91.         conn.remote.port = 0;
  92.         if((tcb = lookup_tcb(&conn)) == NULLTCB){
  93.             /* Nope, try unspecified local address too */
  94.             conn.local.address = 0;
  95.             if((tcb = lookup_tcb(&conn)) == NULLTCB){
  96.                 /* No LISTENs, so reject */
  97.                 free_p(bp);
  98.                 reset(ip,&seg);
  99.                 return;
  100.             }
  101.         }
  102.         /* We've found an server listen socket, so clone the TCB */
  103.         if(tcb->flags.clone){
  104.             ntcb = (struct tcb *)mallocw(sizeof (struct tcb));
  105.             ASSIGN(*ntcb,*tcb);
  106.             tcb = ntcb;
  107.             tcb->timer.arg = tcb;
  108.             /* Put on list */
  109.             tcb->next = Tcbs;
  110.             Tcbs = tcb;
  111.         }
  112.         /* Put all the socket info into the TCB */
  113.         tcb->conn.local.address = ip->dest;
  114.         tcb->conn.remote.address = ip->source;
  115.         tcb->conn.remote.port = seg.source;
  116.     }
  117.     tcb->flags.congest = ip->flags.congest;
  118.     /* Do unsynchronized-state processing (p. 65-68) */
  119.     switch(tcb->state){
  120.     case TCP_CLOSED:
  121.         free_p(bp);
  122.         reset(ip,&seg);
  123.         return;
  124.     case TCP_LISTEN:
  125.         if(seg.flags.rst){
  126.             free_p(bp);
  127.             return;
  128.         }
  129.         if(seg.flags.ack){
  130.             free_p(bp);
  131.             reset(ip,&seg);
  132.             return;
  133.         }
  134.         if(seg.flags.syn){
  135.             /* (Security check is bypassed) */
  136.             /* page 66 */
  137.             proc_syn(tcb,ip->tos,&seg);
  138.             send_syn(tcb);
  139.             setstate(tcb,TCP_SYN_RECEIVED);        
  140.             if(length != 0 || seg.flags.fin) {
  141.                 /* Continue processing if there's more */
  142.                 break;
  143.             }
  144.             tcp_output(tcb);
  145.         }
  146.         free_p(bp);    /* Unlikely to get here directly */
  147.         return;
  148.     case TCP_SYN_SENT:
  149.         if(seg.flags.ack){
  150.             if(!seq_within(seg.ack,tcb->iss+1,tcb->snd.nxt)){
  151.                 free_p(bp);
  152.                 reset(ip,&seg);
  153.                 return;
  154.             }
  155.         }
  156.         if(seg.flags.rst){    /* p 67 */
  157.             if(seg.flags.ack){
  158.                 /* The ack must be acceptable since we just checked it.
  159.                  * This is how the remote side refuses connect requests.
  160.                  */
  161.                 close_self(tcb,RESET);
  162.             }
  163.             free_p(bp);
  164.             return;
  165.         }
  166.         /* (Security check skipped here) */
  167. #ifdef    PREC_CHECK    /* Turned off for compatibility with BSD */
  168.         /* Check incoming precedence; it must match if there's an ACK */
  169.         if(seg.flags.ack && PREC(ip->tos) != PREC(tcb->tos)){
  170.             free_p(bp);
  171.             reset(ip,&seg);
  172.             return;
  173.         }
  174. #endif
  175.         if(seg.flags.syn){
  176.             proc_syn(tcb,ip->tos,&seg);
  177.             if(seg.flags.ack){
  178.                 /* Our SYN has been acked, otherwise the ACK
  179.                  * wouldn't have been valid.
  180.                  */
  181.                 update(tcb,&seg,length);
  182.                 setstate(tcb,TCP_ESTABLISHED);
  183.             } else {
  184.                 setstate(tcb,TCP_SYN_RECEIVED);
  185.             }
  186.             if(length != 0 || seg.flags.fin) {
  187.                 break;        /* Continue processing if there's more */
  188.             }
  189.             tcp_output(tcb);
  190.         } else {
  191.             free_p(bp);    /* Ignore if neither SYN or RST is set */
  192.         }
  193.         return;
  194.     }
  195.     /* We reach this point directly in any synchronized state. Note that
  196.      * if we fell through from LISTEN or SYN_SENT processing because of a
  197.      * data-bearing SYN, window trimming and sequence testing "cannot fail".
  198.      */
  199.  
  200.     /* Trim segment to fit receive window. */
  201.     if(trim(tcb,&seg,&bp,&length) == -1){
  202.         /* Segment is unacceptable */
  203.         if(!seg.flags.rst){    /* NEVER answer RSTs */
  204.             /* In SYN_RECEIVED state, answer a retransmitted SYN 
  205.              * with a retransmitted SYN/ACK.
  206.              */
  207.             if(tcb->state == TCP_SYN_RECEIVED)
  208.                 tcb->snd.ptr = tcb->snd.una;
  209.             tcb->flags.force = 1;
  210.             tcp_output(tcb);
  211.         }
  212.         return;
  213.     }
  214.     /* If segment isn't the next one expected, and there's data
  215.      * or flags associated with it, put it on the resequencing
  216.      * queue, ACK it and return.
  217.      *
  218.      * Processing the ACK in an out-of-sequence segment without
  219.      * flags or data should be safe, however.
  220.      */
  221.     if(seg.seq != tcb->rcv.nxt
  222.      && (length != 0 || seg.flags.syn || seg.flags.fin)){
  223.         add_reseq(tcb,ip->tos,&seg,bp,length);
  224.         tcb->flags.force = 1;
  225.         tcp_output(tcb);
  226.         return;
  227.     }
  228.     /* This loop first processes the current segment, and then
  229.      * repeats if it can process the resequencing queue.
  230.      */
  231.     for(;;){
  232.         /* We reach this point with an acceptable segment; all data and flags
  233.          * are in the window, and the starting sequence number equals rcv.nxt
  234.          * (p. 70)
  235.          */    
  236.         if(seg.flags.rst){
  237.             if(tcb->state == TCP_SYN_RECEIVED
  238.              && !tcb->flags.clone && !tcb->flags.active){
  239.                 /* Go back to listen state only if this was
  240.                  * not a cloned or active server TCB
  241.                  */
  242.                 setstate(tcb,TCP_LISTEN);
  243.             } else {
  244.                 close_self(tcb,RESET);
  245.             }
  246.             free_p(bp);
  247.             return;
  248.         }
  249.         /* (Security check skipped here) p. 71 */
  250. #ifdef    PREC_CHECK
  251.         /* Check for precedence mismatch */
  252.         if(PREC(ip->tos) != PREC(tcb->tos)){
  253.             free_p(bp);
  254.             reset(ip,&seg);
  255.             return;
  256.         }
  257. #endif
  258.         /* Check for erroneous extra SYN */
  259.         if(seg.flags.syn){
  260.             free_p(bp);
  261.             reset(ip,&seg);
  262.             return;
  263.         }
  264.         /* Check ack field p. 72 */
  265.         if(!seg.flags.ack){
  266.             free_p(bp);    /* All segments after synchronization must have ACK */
  267.             return;
  268.         }
  269.         /* Process ACK */
  270.         switch(tcb->state){
  271.         case TCP_SYN_RECEIVED:
  272.             if(seq_within(seg.ack,tcb->snd.una+1,tcb->snd.nxt)){
  273.                 update(tcb,&seg,length);
  274.                 setstate(tcb,TCP_ESTABLISHED);
  275.             } else {
  276.                 free_p(bp);
  277.                 reset(ip,&seg);
  278.                 return;
  279.             }
  280.             break;
  281.         case TCP_ESTABLISHED:
  282.         case TCP_CLOSE_WAIT:
  283.             update(tcb,&seg,length);
  284.             break;
  285.         case TCP_FINWAIT1:    /* p. 73 */
  286.             update(tcb,&seg,length);
  287.             if(tcb->sndcnt == 0){
  288.                 /* Our FIN is acknowledged */
  289.                 setstate(tcb,TCP_FINWAIT2);
  290.             }
  291.             break;
  292.         case TCP_FINWAIT2:
  293.             update(tcb,&seg,length);
  294.             break;
  295.         case TCP_CLOSING:
  296.             update(tcb,&seg,length);
  297.             if(tcb->sndcnt == 0){
  298.                 /* Our FIN is acknowledged */
  299.                 setstate(tcb,TCP_TIME_WAIT);
  300.                 set_timer(&tcb->timer,MSL2*1000L);
  301.                 start_timer(&tcb->timer);
  302.             }
  303.             break;
  304.         case TCP_LAST_ACK:
  305.             update(tcb,&seg,length);
  306.             if(tcb->sndcnt == 0){
  307.                 /* Our FIN is acknowledged, close connection */
  308.                 close_self(tcb,NORMAL);
  309.                 return;
  310.             }            
  311.             break;
  312.         case TCP_TIME_WAIT:
  313.             start_timer(&tcb->timer);
  314.             break;
  315.         }
  316.  
  317.         /* (URGent bit processing skipped here) */
  318.  
  319.         /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  320.         if(length != 0){
  321.             switch(tcb->state){
  322.             case TCP_SYN_RECEIVED:
  323.             case TCP_ESTABLISHED:
  324.             case TCP_FINWAIT1:
  325.             case TCP_FINWAIT2:
  326.                 /* Place on receive queue */
  327.                 append(&tcb->rcvq,bp);
  328.                 tcb->rcvcnt += length;
  329.                 tcb->rcv.nxt += length;
  330.                 tcb->rcv.wnd -= length;
  331.                 tcb->flags.force = 1;
  332.                 /* Notify user */
  333.                 if(tcb->r_upcall)
  334.                     (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  335.                 break;
  336.             default:
  337.                 /* Ignore segment text */
  338.                 free_p(bp);
  339.                 break;
  340.             }
  341.         }
  342.         /* process FIN bit (p 75) */
  343.         if(seg.flags.fin){
  344.             tcb->flags.force = 1;    /* Always respond with an ACK */
  345.  
  346.             switch(tcb->state){
  347.             case TCP_SYN_RECEIVED:
  348.             case TCP_ESTABLISHED:
  349.                 tcb->rcv.nxt++;
  350.                 setstate(tcb,TCP_CLOSE_WAIT);
  351.                 break;
  352.             case TCP_FINWAIT1:
  353.                 tcb->rcv.nxt++;
  354.                 if(tcb->sndcnt == 0){
  355.                     /* Our FIN has been acked; bypass TCP_CLOSING state */
  356.                     setstate(tcb,TCP_TIME_WAIT);
  357.                     set_timer(&tcb->timer,MSL2*1000L);
  358.                     start_timer(&tcb->timer);
  359.                 } else {
  360.                     setstate(tcb,TCP_CLOSING);
  361.                 }
  362.                 break;
  363.             case TCP_FINWAIT2:
  364.                 tcb->rcv.nxt++;
  365.                 setstate(tcb,TCP_TIME_WAIT);
  366.                 set_timer(&tcb->timer,MSL2*1000L);
  367.                 start_timer(&tcb->timer);
  368.                 break;
  369.             case TCP_CLOSE_WAIT:
  370.             case TCP_CLOSING:
  371.             case TCP_LAST_ACK:
  372.                 break;        /* Ignore */
  373.             case TCP_TIME_WAIT:    /* p 76 */
  374.                 start_timer(&tcb->timer);
  375.                 break;
  376.             }
  377.             /* Call the client again so he can see EOF */
  378.             if(tcb->r_upcall)
  379.                 (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  380.         }
  381.         /* Scan the resequencing queue, looking for a segment we can handle,
  382.          * and freeing all those that are now obsolete.
  383.          */
  384.         while(tcb->reseq != NULLRESEQ && seq_ge(tcb->rcv.nxt,tcb->reseq->seg.seq)){
  385.             get_reseq(tcb,&ip->tos,&seg,&bp,&length);
  386.             if(trim(tcb,&seg,&bp,&length) == 0)
  387.                 goto gotone;
  388.             /* Segment is an old one; trim has freed it */
  389.         }
  390.         break;
  391. gotone:    ;
  392.     }
  393.     tcp_output(tcb);    /* Send any necessary ack */
  394. }
  395.  
  396. /* Process an incoming ICMP response */
  397. void
  398. tcp_icmp(icsource,source,dest,type,code,bpp)
  399. int32 icsource;            /* Sender of ICMP message (not used) */
  400. int32 source;            /* Original IP datagram source (i.e. us) */
  401. int32 dest;            /* Original IP datagram dest (i.e., them) */
  402. char type,code;            /* ICMP error codes */
  403. struct mbuf **bpp;        /* First 8 bytes of TCP header */
  404. {
  405.     struct tcp seg;
  406.     struct connection conn;
  407.     register struct tcb *tcb;
  408.  
  409.     /* Extract the socket info from the returned TCP header fragment
  410.      * Note that since this is a datagram we sent, the source fields
  411.      * refer to the local side.
  412.      */
  413.     ntohtcp(&seg,bpp);
  414.     conn.local.port = seg.source;
  415.     conn.remote.port = seg.dest;
  416.     conn.local.address = source;
  417.     conn.remote.address = dest;
  418.     if((tcb = lookup_tcb(&conn)) == NULLTCB)
  419.         return;    /* Unknown connection, ignore */
  420.  
  421.     /* Verify that the sequence number in the returned segment corresponds
  422.      * to something currently unacknowledged. If not, it can safely
  423.      * be ignored.
  424.      */
  425.     if(!seq_within(seg.seq,tcb->snd.una,tcb->snd.nxt))
  426.         return;
  427.  
  428.     /* Destination Unreachable and Time Exceeded messages never kill a
  429.      * connection; the info is merely saved for future reference.
  430.      */
  431.     switch(uchar(type)){
  432.     case ICMP_DEST_UNREACH:
  433.     case ICMP_TIME_EXCEED:
  434.         tcb->type = type;
  435.         tcb->code = code;
  436.         break;
  437.     case ICMP_QUENCH:
  438.         /* Source quench; cut the congestion window in half,
  439.          * but don't let it go below one packet
  440.          */
  441.         tcb->cwind /= 2;
  442.         tcb->cwind = max(tcb->mss,tcb->cwind);
  443.         break;
  444.     }
  445. }
  446. /* Send an acceptable reset (RST) response for this segment
  447.  * The RST reply is composed in place on the input segment
  448.  */
  449. void
  450. reset(ip,seg)
  451. struct ip *ip;            /* Offending IP header */
  452. register struct tcp *seg;    /* Offending TCP header */
  453. {
  454.     struct mbuf *hbp;
  455.     struct pseudo_header ph;
  456.     int16 tmp;
  457.  
  458.     if(seg->flags.rst)
  459.         return;    /* Never send an RST in response to an RST */
  460.  
  461.     /* Compose the RST IP pseudo-header, swapping addresses */
  462.     ph.source = ip->dest;
  463.     ph.dest = ip->source;
  464.     ph.protocol = TCP_PTCL;
  465.     ph.length = TCPLEN;
  466.  
  467.     /* Swap port numbers */
  468.     tmp = seg->source;
  469.     seg->source = seg->dest;
  470.     seg->dest = tmp;
  471.  
  472.     if(seg->flags.ack){
  473.         /* This reset is being sent to clear a half-open connection.
  474.          * Set the sequence number of the RST to the incoming ACK
  475.          * so it will be acceptable.
  476.          */
  477.         seg->flags.ack = 0;
  478.         seg->seq = seg->ack;
  479.         seg->ack = 0;
  480.     } else {
  481.         /* We're rejecting a connect request (SYN) from TCP_LISTEN state
  482.          * so we have to "acknowledge" their SYN.
  483.          */
  484.         seg->flags.ack = 1;
  485.         seg->ack = seg->seq;
  486.         seg->seq = 0;
  487.         if(seg->flags.syn)
  488.             seg->ack++;
  489.     }
  490.     /* Set remaining parts of packet */
  491.     seg->flags.urg = 0;
  492.     seg->flags.psh = 0;
  493.     seg->flags.rst = 1;
  494.     seg->flags.syn = 0;
  495.     seg->flags.fin = 0;
  496.     seg->wnd = 0;
  497.     seg->up = 0;
  498.     seg->mss = 0;
  499.     seg->optlen = 0;
  500.     if((hbp = htontcp(seg,NULLBUF,&ph)) == NULLBUF)
  501.         return;
  502.     /* Ship it out (note swap of addresses) */
  503.     ip_send(ip->dest,ip->source,TCP_PTCL,ip->tos,0,hbp,ph.length,0,0);
  504.     tcpOutRsts++;
  505. }
  506.  
  507. /* Process an incoming acknowledgement and window indication.
  508.  * From page 72.
  509.  */
  510. static void
  511. update(tcb,seg,length)
  512. register struct tcb *tcb;
  513. register struct tcp *seg;
  514. int16 length;
  515. {
  516.     int16 acked;
  517.     int16 expand;
  518.  
  519.     acked = 0;
  520.     if(seq_gt(seg->ack,tcb->snd.nxt)){
  521.         tcb->flags.force = 1;    /* Acks something not yet sent */
  522.         return;
  523.     }
  524.     /* Decide if we need to do a window update.
  525.      * This is always checked whenever a legal ACK is received,
  526.      * even if it doesn't actually acknowledge anything,
  527.      * because it might be a spontaneous window reopening.
  528.      */
  529.     if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1) 
  530.      && seq_ge(seg->ack,tcb->snd.wl2))){
  531.         /* If the window had been closed, crank back the
  532.          * send pointer so we'll immediately resume transmission.
  533.          * Otherwise we'd have to wait until the next probe.
  534.          */
  535.         if(tcb->snd.wnd == 0 && seg->wnd != 0)
  536.             tcb->snd.ptr = tcb->snd.una;
  537.         tcb->snd.wnd = seg->wnd;
  538.         tcb->snd.wl1 = seg->seq;
  539.         tcb->snd.wl2 = seg->ack;
  540.     }
  541.     /* See if anything new is being acknowledged */
  542.     if(!seq_gt(seg->ack,tcb->snd.una)){
  543.         if(seg->ack != tcb->snd.una)
  544.             return;    /* Old ack, ignore */
  545.  
  546.         if(length != 0 || seg->flags.syn || seg->flags.fin)
  547.             return;    /* Nothing acked, but there is data */
  548.  
  549.         /* Van Jacobson "fast recovery" code */
  550.         if(++tcb->dupacks == TCPDUPACKS){
  551.             /* We've had a burst of do-nothing acks, so
  552.              * we almost certainly lost a packet.
  553.              * Resend it now to avoid a timeout. (This is
  554.              * Van Jacobson's 'quick recovery' algorithm.)
  555.              */
  556.             int32 ptrsave;
  557.  
  558.             /* Knock the threshold down just as though
  559.              * this were a timeout, since we've had
  560.              * network congestion.
  561.              */
  562.             tcb->ssthresh = tcb->cwind/2;
  563.             tcb->ssthresh = max(tcb->ssthresh,tcb->mss);
  564.  
  565.             /* Manipulate the machinery in tcp_output() to
  566.              * retransmit just the missing packet
  567.              */
  568.             ptrsave = tcb->snd.ptr;
  569.             tcb->snd.ptr = tcb->snd.una;
  570.             tcb->cwind = tcb->mss;
  571.             tcp_output(tcb);
  572.             tcb->snd.ptr = ptrsave;
  573.  
  574.             /* "Inflate" the congestion window, pretending as
  575.              * though the duplicate acks were normally acking
  576.              * the packets beyond the one that was lost.
  577.              */
  578.             tcb->cwind = tcb->ssthresh + TCPDUPACKS*tcb->mss;
  579.         } else if(tcb->dupacks > TCPDUPACKS){
  580.             /* Continue to inflate the congestion window
  581.              * until the acks finally get "unstuck".
  582.              */
  583.             tcb->cwind += tcb->mss;
  584.         }
  585.         return;
  586.     }
  587.     if(tcb->dupacks >= TCPDUPACKS && tcb->cwind > tcb->ssthresh){
  588.         /* The acks have finally gotten "unstuck". So now we
  589.          * can "deflate" the congestion window, i.e. take it
  590.          * back down to where it would be after slow start
  591.          * finishes.
  592.          */
  593.         tcb->cwind = tcb->ssthresh;
  594.     }
  595.     tcb->dupacks = 0;
  596.  
  597.     /* We're here, so the ACK must have actually acked something */
  598.     acked = seg->ack - tcb->snd.una;
  599.  
  600.     /* Expand congestion window if not already at limit and if
  601.      * this packet wasn't retransmitted
  602.      */
  603.     if(tcb->cwind < tcb->snd.wnd && !tcb->flags.retran){
  604.         if(tcb->cwind < tcb->ssthresh){
  605.             /* Still doing slow start/CUTE, expand by amount acked */
  606.             expand = min(acked,tcb->mss);
  607.         } else {
  608.             /* Steady-state test of extra path capacity */
  609.             expand = ((long)tcb->mss * tcb->mss) / tcb->cwind;
  610.         }
  611.         /* Guard against arithmetic overflow */
  612.         if(tcb->cwind + expand < tcb->cwind)
  613.             expand = MAXINT16 - tcb->cwind;
  614.  
  615.         /* Don't expand beyond the offered window */
  616.         if(tcb->cwind + expand > tcb->snd.wnd)
  617.             expand = tcb->snd.wnd - tcb->cwind;
  618.  
  619.         if(expand != 0){
  620. #ifdef    notdef
  621.             /* Kick up the mean deviation estimate to prevent
  622.              * unnecessary retransmission should we already be
  623.              * bandwidth limited
  624.              */
  625.             tcb->mdev += ((long)tcb->srtt * expand) / tcb->cwind;
  626. #endif
  627.             tcb->cwind += expand;
  628.         }
  629.     }
  630.     /* Round trip time estimation */
  631.     if(tcb->flags.rtt_run && seq_ge(seg->ack,tcb->rttseq)){
  632.         /* A timed sequence number has been acked */
  633.         tcb->flags.rtt_run = 0;
  634.         if(!(tcb->flags.retran)){
  635.             int32 rtt;    /* measured round trip time */
  636.             int32 abserr;    /* abs(rtt - srtt) */
  637.  
  638.             /* This packet was sent only once and now
  639.              * it's been acked, so process the round trip time
  640.              */
  641.             rtt = msclock() - tcb->rtt_time;
  642.  
  643.             abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  644.             /* Run SRTT and MDEV integrators, with rounding */
  645.             tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt + (AGAIN/2)) >> LAGAIN;
  646.             tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr + (DGAIN/2)) >> LDGAIN;
  647.  
  648.             rtt_add(tcb->conn.remote.address,rtt);
  649.             /* Reset the backoff level */
  650.             tcb->backoff = 0;
  651.         }
  652.     }
  653.     tcb->sndcnt -= acked;    /* Update virtual byte count on snd queue */
  654.     tcb->snd.una = seg->ack;
  655.  
  656.     /* If we're waiting for an ack of our SYN, note it and adjust count */
  657.     if(!(tcb->flags.synack)){
  658.         tcb->flags.synack = 1;
  659.         acked--;    /* One less byte to pull from real snd queue */
  660.     }
  661.     /* Remove acknowledged bytes from the send queue and update the
  662.      * unacknowledged pointer. If a FIN is being acked,
  663.      * pullup won't be able to remove it from the queue, but that
  664.      * causes no harm.
  665.      */
  666.     pullup(&tcb->sndq,NULLCHAR,acked);
  667.  
  668.     /* Stop retransmission timer, but restart it if there is still
  669.      * unacknowledged data. If there is no more unacked data,
  670.      * the transmitter has gone at least momentarily idle, so
  671.      * record the time for the VJ restart-slowstart rule.
  672.      */    
  673.     stop_timer(&tcb->timer);
  674.     if(tcb->snd.una != tcb->snd.nxt)
  675.         start_timer(&tcb->timer);
  676.     else
  677.         tcb->lastactive = msclock();
  678.  
  679.     /* If retransmissions have been occurring, make sure the
  680.      * send pointer doesn't repeat ancient history
  681.      */
  682.     if(seq_lt(tcb->snd.ptr,tcb->snd.una))
  683.         tcb->snd.ptr = tcb->snd.una;
  684.  
  685.     /* Clear the retransmission flag since the oldest
  686.      * unacknowledged segment (the only one that is ever retransmitted)
  687.      * has now been acked.
  688.      */
  689.     tcb->flags.retran = 0;
  690.  
  691.     /* If outgoing data was acked, notify the user so he can send more
  692.      * unless we've already sent a FIN.
  693.      */
  694.     if(acked != 0 && tcb->t_upcall
  695.      && (tcb->state == TCP_ESTABLISHED || tcb->state == TCP_CLOSE_WAIT)){
  696.         (*tcb->t_upcall)(tcb,tcb->window - tcb->sndcnt);
  697.     }
  698. }
  699.  
  700. /* Determine if the given sequence number is in our receiver window.
  701.  * NB: must not be used when window is closed!
  702.  */
  703. static
  704. int
  705. in_window(tcb,seq)
  706. struct tcb *tcb;
  707. int32 seq;
  708. {
  709.     return seq_within(seq,tcb->rcv.nxt,(int32)(tcb->rcv.nxt+tcb->rcv.wnd-1));
  710. }
  711.  
  712. /* Process an incoming SYN */
  713. static void
  714. proc_syn(tcb,tos,seg)
  715. register struct tcb *tcb;
  716. char tos;
  717. struct tcp *seg;
  718. {
  719.     int16 mtu;
  720.     struct tcp_rtt *tp;
  721.  
  722.     tcb->flags.force = 1;    /* Always send a response */
  723.  
  724.     /* Note: It's not specified in RFC 793, but SND.WL1 and
  725.      * SND.WND are initialized here since it's possible for the
  726.      * window update routine in update() to fail depending on the
  727.      * IRS if they are left unitialized.
  728.      */
  729.     /* Check incoming precedence and increase if higher */
  730.     if(PREC(tos) > PREC(tcb->tos))
  731.         tcb->tos = tos;
  732.     tcb->rcv.nxt = seg->seq + 1;    /* p 68 */
  733.     tcb->snd.wl1 = tcb->irs = seg->seq;
  734.     tcb->snd.wnd = seg->wnd;
  735.     if(seg->mss != 0)
  736.         tcb->mss = seg->mss;
  737.     /* Check the MTU of the interface we'll use to reach this guy
  738.      * and lower the MSS so that unnecessary fragmentation won't occur
  739.      */
  740.     if((mtu = ip_mtu(tcb->conn.remote.address)) != 0){
  741.         /* Allow space for the TCP and IP headers */
  742.         mtu -= TCPLEN + IPLEN;
  743.         tcb->cwind = tcb->mss = min(mtu,tcb->mss);
  744.     }
  745.     /* See if there's round-trip time experience */
  746.     if((tp = rtt_get(tcb->conn.remote.address)) != NULLRTT){
  747.         tcb->srtt = tp->srtt;
  748.         tcb->mdev = tp->mdev;
  749.     }
  750. }
  751.  
  752. /* Generate an initial sequence number and put a SYN on the send queue */
  753. void
  754. send_syn(tcb)
  755. register struct tcb *tcb;
  756. {
  757.     tcb->iss = geniss();
  758.     tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  759.     tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  760.     tcb->sndcnt++;
  761.     tcb->flags.force = 1;
  762. }
  763.  
  764. /* Add an entry to the resequencing queue in the proper place */
  765. static void
  766. add_reseq(tcb,tos,seg,bp,length)
  767. struct tcb *tcb;
  768. char tos;
  769. struct tcp *seg;
  770. struct mbuf *bp;
  771. int16 length;
  772. {
  773.     register struct reseq *rp,*rp1;
  774.  
  775.     /* Allocate reassembly descriptor */
  776.     if((rp = (struct reseq *)malloc(sizeof (struct reseq))) == NULLRESEQ){
  777.         /* No space, toss on floor */
  778.         free_p(bp);
  779.         return;
  780.     }
  781.     ASSIGN(rp->seg,*seg);
  782.     rp->tos = tos;
  783.     rp->bp = bp;
  784.     rp->length = length;
  785.  
  786.     /* Place on reassembly list sorting by starting seq number */
  787.     rp1 = tcb->reseq;
  788.     if(rp1 == NULLRESEQ || seq_lt(seg->seq,rp1->seg.seq)){
  789.         /* Either the list is empty, or we're less than all other
  790.          * entries; insert at beginning.
  791.          */
  792.         rp->next = rp1;
  793.         tcb->reseq = rp;
  794.     } else {
  795.         /* Find the last entry less than us */
  796.         for(;;){
  797.             if(rp1->next == NULLRESEQ || seq_lt(seg->seq,rp1->next->seg.seq)){
  798.                 /* We belong just after this one */
  799.                 rp->next = rp1->next;
  800.                 rp1->next = rp;
  801.                 break;
  802.             }
  803.             rp1 = rp1->next;
  804.         }
  805.     }
  806. }
  807.  
  808. /* Fetch the first entry off the resequencing queue */
  809. static void
  810. get_reseq(tcb,tos,seg,bp,length)
  811. register struct tcb *tcb;
  812. char *tos;
  813. struct tcp *seg;
  814. struct mbuf **bp;
  815. int16 *length;
  816. {
  817.     register struct reseq *rp;
  818.  
  819.     if((rp = tcb->reseq) == NULLRESEQ)
  820.         return;
  821.  
  822.     tcb->reseq = rp->next;
  823.  
  824.     *tos = rp->tos;
  825.     ASSIGN(*seg,rp->seg);
  826.     *bp = rp->bp;
  827.     *length = rp->length;
  828.     free((char *)rp);
  829. }
  830.  
  831. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  832.  * unacceptable.
  833.  */
  834. static int
  835. trim(tcb,seg,bpp,length)
  836. register struct tcb *tcb;
  837. register struct tcp *seg;
  838. struct mbuf **bpp;
  839. int16 *length;
  840. {
  841.     long dupcnt,excess;
  842.     int16 len;        /* Segment length including flags */
  843.     char accept = 0;
  844.  
  845.     len = *length;
  846.     if(seg->flags.syn)
  847.         len++;
  848.     if(seg->flags.fin)
  849.         len++;
  850.  
  851.     /* Acceptability tests */
  852.     if(tcb->rcv.wnd == 0){
  853.         /* Only in-order, zero-length segments are acceptable when
  854.          * our window is closed.
  855.          */
  856.         if(seg->seq == tcb->rcv.nxt && len == 0){
  857.             return 0;    /* Acceptable, no trimming needed */
  858.         }
  859.     } else {
  860.         /* Some part of the segment must be in the window */
  861.         if(in_window(tcb,seg->seq)){
  862.             accept++;    /* Beginning is */
  863.         } else if(len != 0){
  864.             if(in_window(tcb,(int32)(seg->seq+len-1)) || /* End is */
  865.              seq_within(tcb->rcv.nxt,seg->seq,(int32)(seg->seq+len-1))){ /* Straddles */
  866.                 accept++;
  867.             }
  868.         }
  869.     }
  870.     if(!accept){
  871.         tcb->rerecv += len;    /* Assume all of it was a duplicate */
  872.         free_p(*bpp);
  873.         return -1;
  874.     }
  875.     if((dupcnt = tcb->rcv.nxt - seg->seq) > 0){
  876.         tcb->rerecv += dupcnt;
  877.         /* Trim off SYN if present */
  878.         if(seg->flags.syn){
  879.             /* SYN is before first data byte */
  880.             seg->flags.syn = 0;
  881.             seg->seq++;
  882.             dupcnt--;
  883.         }
  884.         if(dupcnt > 0){
  885.             pullup(bpp,NULLCHAR,(int16)dupcnt);
  886.             seg->seq += dupcnt;
  887.             *length -= dupcnt;
  888.         }
  889.     }
  890.     if((excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd)) > 0){
  891.         tcb->rerecv += excess;
  892.         /* Trim right edge */
  893.         *length -= excess;
  894.         trim_mbuf(bpp,*length);
  895.         seg->flags.fin = 0;    /* FIN follows last data byte */
  896.     }
  897.     return 0;
  898. }
  899.