home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / RDP / rdp_input.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-18  |  22.8 KB  |  975 lines

  1. /**************************************************************************/
  2. /*       Copyright(c) 1987, 1992 by BBN Systems and Technologies,         */
  3. /*         A Division of Bolt Beranek and Newman Inc.                     */
  4. /*                                                                        */
  5. /*       RDP implementation for 4.2/4.3bsd by Craig Partridge             */
  6. /*                                                                        */
  7. /*  Permission to use, copy, modify, distribute, and sell this software   */
  8. /*  and its documentation for any purpose is hereby granted without fee,  */
  9. /*  provided that the above copyright notice and this permission appear   */
  10. /*  in all copies and in supporting documentation, and that the name of   */
  11. /*  Bolt Beranek and Newman Inc.  not be used in advertising or           */
  12. /*  publicity pertaining to distribution of the software without          */
  13. /*  specific, written prior permission. BBN makes no representations      */
  14. /*  about the suitability of this software for any purposes.  It is       */
  15. /*  provided "AS IS" without express or implied warranties.               */
  16. /**************************************************************************/
  17.  
  18. #include "../h/param.h"
  19. #include "../h/dir.h"
  20. #include "../h/user.h"
  21. #include "../h/mbuf.h"
  22. #include "../h/protosw.h"
  23. #include "../h/socket.h"
  24. #include "../h/socketvar.h"
  25. #include "../h/errno.h"
  26.  
  27. #include "../net/if.h"
  28. #include "../net/route.h"
  29.  
  30. #include "../netinet/in.h"
  31. #include "../netinet/in_pcb.h"
  32. #include "../netinet/in_systm.h"
  33. #include "../netinet/ip.h"
  34. #include "../netinet/ip_var.h"
  35. #include "../netinet/ip_icmp.h"
  36.  
  37. #include "../netinet/rdp.h"
  38. #include "../netinet/rdp_var.h"
  39. #include "../netinet/rdp_ip.h"
  40. #include "../netinet/rdp_conf.h"
  41.  
  42.  
  43. extern u_long rdpserial;
  44. extern u_short rdp_mtu;
  45. extern short rdp_start[];
  46. extern struct inpcb rdb;
  47.  
  48. struct mbuf rdp_mark;    /* a fake mbuf to mark packets rcvd */
  49.  
  50. /**************************************************************************/
  51. /*                        INPUT routine                                   */
  52. /**************************************************************************/
  53.  
  54. #ifndef BSD4_3
  55.     rdp_input(m0)
  56. #else
  57.     rdp_input(m0, ifp)
  58.     struct ifnet *ifp;
  59. #endif
  60. struct mbuf *m0;
  61. {
  62.     register struct rdpcb *rp;
  63.     register struct rdpip *ri;
  64.     register struct rdpque *rq;
  65.     register int i, j;
  66.     struct mbuf *m;
  67.     struct inpcb *inp;
  68.     struct socket *so;
  69.     u_long savsum, seq;
  70.     int hlen;
  71.     u_short dlen;
  72.  
  73.     rdp_info.rst_ipackets++;
  74.  
  75.     /* get everything up front */
  76.     m = m0;
  77.     if ((m->m_len < RI_SIZE) && ((m = m_pullup(m,RI_SIZE))==0))
  78.     {
  79.     rdp_info.rst_len++;
  80. #ifdef DEBUG
  81.     printf("rdp_input: m_pullup 1\n");
  82. #endif
  83.     goto release;
  84.     }
  85.  
  86.     ri = mtod(m, struct rdpip *);
  87.  
  88.     /* check version */
  89.     if ((ri->ri_flags & RH_VERBITS) != R_VERSION)
  90.     {
  91. #ifdef DEBUG
  92.     printf("rdp_input: version mismatch\n");
  93. #endif
  94.     goto release;
  95.     }
  96.  
  97.     /* strip ip options */
  98.     if (ri->ri_hl > (sizeof(struct ip) >> 2))
  99.     ip_stripoptions((struct ip *)ri,(struct mbuf *)0);
  100.  
  101.     /* now pull all the header stuff */
  102.     hlen = (ri->ri_hlen << 1) + sizeof(struct ip);
  103.     if (hlen > MLEN)
  104.     {
  105.     /* ought to strip excess EACKs? -- or otherwise fiddle? */
  106.     /* this is just because I haven't thought this out */
  107.     panic("rdp_input: hlen");
  108.     }
  109.  
  110.     if ((hlen > m->m_len) && ((m = m_pullup(m,hlen))==0))
  111.     {
  112. #ifdef DEBUG
  113.     printf("rdp_input: m_pullup 2\n");
  114. #endif
  115.     rdp_info.rst_len++;
  116.     goto release;
  117.     }
  118.  
  119.     /* now get total packet len and adjust hlen to just rdp hdr */
  120.     dlen = ntohs(ri->ri_dlen);
  121.     hlen -= sizeof(struct ip);
  122.  
  123. #ifdef DEBUG
  124.     /* rdp_pktprt(ri); */
  125. #endif
  126.  
  127.     /* note that IP subtracted IP header len from ri_len */
  128.     if (ri->ri_len < (hlen+dlen))
  129.     {
  130. #ifdef DEBUG
  131.     printf("rdp_input: rdp length\n");
  132. #endif
  133.     rdp_info.rst_len++;
  134.     goto release;
  135.     }
  136.  
  137.     /* now checksum time */
  138.     savsum = ri->ri_sum;
  139.     ri->ri_sum = 0;
  140.  
  141.     /* adjust mbuf to lose ip header */
  142.     m->m_len -= sizeof(struct ip);
  143.     m->m_off += sizeof(struct ip);
  144.  
  145.     if (savsum != in_cksum(m,(int)dlen + hlen))
  146.     {
  147. #ifdef DEBUG
  148.     printf("rdp_input: bad cksum, 0x%x\n",savsum);
  149. #endif
  150.     rdp_info.rst_cksum++;
  151.     goto release;
  152.     }
  153.  
  154.     /* get rid of rdp header in mbuf but note ri still valid */
  155.     m->m_len -= hlen;
  156.     m->m_off += hlen;
  157.  
  158.     /* find rdpcb */
  159.     inp = in_pcblookup(&rdb,ri->ri_src,ri->ri_sport,ri->ri_dst,ri->ri_dport,INPLOOKUP_WILDCARD);
  160.     if (inp == 0)
  161.     {
  162. #ifdef DEBUG
  163.     printf("rdp_input: no destination for packet\n");
  164. #endif
  165.     /* act closed here ... */
  166.     (void) rdp_iclosed((struct inpcb *)0,(struct rdpcb *)0,ri);
  167.     goto release;
  168.     }
  169.  
  170.     rp = (struct rdpcb *)inp->inp_ppcb;
  171.  
  172.     /* now figure out what to do */
  173.     switch(rp->rp_state)
  174.     {
  175.     case R_OPEN:
  176.         if (rdp_iopen(inp,rp,ri)==0)
  177.         goto release;
  178.         break;
  179.  
  180.     case R_SYN_RCVD:
  181.         if (rdp_ircvdsyn(inp,rp,ri)==0)
  182.         goto release;
  183.         break;
  184.  
  185.     case R_LISTEN:
  186.         (void) rdp_ilisten(inp,rp,ri);
  187.         goto release;
  188.  
  189.     case R_CLOSED:
  190.         (void) rdp_iclosed(inp,rp,ri);
  191.         goto release;
  192.  
  193.     case R_SYN_SENT:
  194.         (void) rdp_isynsent(inp,rp,ri);
  195.         goto release;
  196.  
  197.     case R_CLOSE_WAIT:
  198.         (void) rdp_iclowait(inp,rp,ri);
  199.         goto release;
  200.  
  201.     case R_DRAIN:
  202.         (void)rdp_idrain(inp,rp,ri);
  203.         goto release;
  204.     }
  205.  
  206.     /* now, we are only here if packet should go in our data queues */
  207.  
  208.     /* reset activity timer */
  209.     rp->rp_timer = RT_NULLTIME;
  210.  
  211.     seq = ntohl(ri->ri_sn);
  212.     rq = rp->rp_rq;
  213.  
  214.     i = (seq - rp->rp_rcvcur - 1 + rq->rq_rcvbase) % R_RCVWIN;
  215.  
  216.     /* do we already have it? */
  217.     if (rq->rq_rcvq[i] != 0)
  218.     {
  219.     /* we could send EACK, but that is probably excessive */
  220.     rdp_info.rst_dup++;
  221.     goto release;
  222.     }
  223.  
  224.     /* new hi? */
  225.     if (seq_gt(seq,rp->rp_rcvhi))
  226.     rp->rp_rcvhi = seq;
  227.  
  228.     so = inp->inp_socket;
  229.  
  230. #ifndef BSD4_3
  231.     /* mark the end of the packet -- sbappend should do this but doesn't */
  232.     for(m0=m; m->m_next != 0; m = m->m_next);
  233.  
  234.     m->m_act = (struct mbuf *)1;
  235.     m = m0;
  236. #endif /* not 4.3 */
  237.  
  238.  
  239.     if ((so->so_type == SOCK_RDM) && (ri->ri_flags & RH_NULL)==0)
  240.     {
  241.         /* give it to the user */
  242.         if (sbspace(&(so->so_rcv)) <= 0)
  243.         {
  244.         so->so_error = ENOBUFS;
  245.         rdp_fatal(inp);
  246.         goto release;
  247.         }
  248. #ifdef BSD4_3
  249.         sbappendrecord(&(so->so_rcv),m);
  250. #else
  251.         sbappend(&(so->so_rcv),m);
  252. #endif
  253.         sorwakeup(so);
  254.  
  255.         /* and mark that we took it */
  256.         rq->rq_rcvq[i] = &rdp_mark;
  257.     }
  258.     else
  259.     {
  260.     /* just queue it */
  261.     if (ri->ri_flags & RH_NULL)
  262.     {
  263.         rq->rq_rcvq[i] = &rdp_mark;
  264.         /* and get rid of m */
  265.         (void) m_freem(m);
  266.     }
  267.     else
  268.         rq->rq_rcvq[i] = m;
  269.     }
  270.  
  271.     /* now, was the packet on the left edge? */
  272.     if (seq == (rp->rp_rcvcur+1))
  273.     {
  274.     /* find next unacked packet */
  275.     i = rp->rp_rcvhi - rp->rp_rcvcur;
  276.  
  277.     j = rq->rq_rcvbase;
  278.  
  279.     for(; i > 0; i--)
  280.     {
  281.         if ((m = rq->rq_rcvq[j]) == 0)
  282.         break;
  283.  
  284.         /* mark that packet is spent */
  285.         rq->rq_rcvq[j] = 0;
  286.         rp->rp_rcvcur++;
  287.         rp->rp_rcvuer++;
  288.  
  289.         if (m != &rdp_mark)
  290.         {
  291.         /* pass stuff up... */
  292.         if (sbspace(&(so->so_rcv)) <= 0)
  293.         {
  294.             so->so_error = ENOBUFS;
  295.             rdp_fatal(inp);
  296.             /* release m which we just dequeued */
  297.             goto release;
  298.         }
  299. #ifdef BSD4_3
  300.         sbappendrecord(&(so->so_rcv),m);
  301. #else
  302.         sbappend(&(so->so_rcv),m);
  303. #endif /* 4.3 */
  304.         sorwakeup(so);
  305.         }
  306.  
  307.         if (++j == R_RCVWIN)
  308.         j = 0;
  309.     }
  310.  
  311.     rq->rq_rcvbase = j;
  312.     }
  313.  
  314.     /*
  315.      * send ack for left window.  RFC says just send ACK if packet
  316.      * is in sequence and EACK if out of sequence.  That seems
  317.      * a bit odd.  Just because a packet is on the left edge
  318.      * doesn't mean we don't have other gaps.
  319.      */
  320.  
  321.     (void)rdp_ack(inp,rp->rp_sndnxt,rp->rp_rcvcur);
  322.     return;
  323.  
  324. release:
  325.     /* note that most things here are small segments */
  326.     if (m != 0)
  327.     {
  328.     MFREE(m,m0);
  329.     if (m0 != 0)
  330.         (void) m_freem(m0);
  331.     }
  332. }
  333.  
  334. /**************************************************************************/
  335. /*                           LISTEN                                       */
  336. /**************************************************************************/
  337.  
  338. rdp_ilisten(inp,rp,ri)
  339. struct inpcb *inp;
  340. struct rdpcb *rp;
  341. struct rdpip *ri;
  342. {
  343.     struct inpcb tmpinp;
  344.     struct rdpsyn *rs;
  345.     register struct inpcb *inp2;
  346.     register struct rdpcb *rp2;
  347.     struct rdpque *rq2;
  348.     register struct socket *sonew;
  349.  
  350. #ifdef lint
  351.     rp = rp;
  352. #endif
  353.  
  354.     if (ri->ri_flags & RH_RST)
  355.     goto done;
  356.  
  357.     /* a data packet? */
  358.     if ((ri->ri_flags & RH_ACK) || (ri->ri_flags & RH_NULL))
  359.     {
  360.     /* got to build fake inp to reply here */
  361.     bcopy((caddr_t)inp,(caddr_t)&tmpinp,sizeof(tmpinp));
  362.     tmpinp.inp_faddr = ri->ri_src;
  363.     tmpinp.inp_fport = ri->ri_sport;
  364.  
  365.     (void) rdp_rst(&tmpinp,0,(u_long)(ntohl(ri->ri_an)+1),(u_long)0,0);
  366.     goto done;
  367.     }
  368.  
  369.     /*
  370.      * RFC doesn't anticipate situation in which we run out of resources
  371.      * on the SYN.  We act as if we had crashed, and are closed.
  372.      */
  373.  
  374.     if (ri->ri_flags & RH_SYN)
  375.     {
  376.     if ((sonew = sonewconn(inp->inp_socket))==0)
  377.     {
  378.         /* got to build fake inp to reply here */
  379.         bcopy((caddr_t)inp,(caddr_t)&tmpinp,sizeof(tmpinp));
  380.         tmpinp.inp_faddr = ri->ri_src;
  381.         tmpinp.inp_fport = ri->ri_sport;
  382.  
  383.         (void) rdp_rst(&tmpinp,1,(u_long)0,(u_long)ntohl(ri->ri_sn),0);
  384.         goto done;
  385.     }
  386.  
  387.     /* set up new socket */
  388.     inp2 = sotoinpcb(sonew);
  389.     inp2->inp_laddr = inp->inp_laddr;
  390.     inp2->inp_faddr = ri->ri_src;
  391.     inp2->inp_lport = inp->inp_lport;
  392.     inp2->inp_fport = ri->ri_sport;
  393.  
  394.     rp2 = (struct rdpcb *)inp2->inp_ppcb;
  395.     rq2 = rp2->rp_rq;
  396.  
  397.     rp2->rp_rcvhi = rp2->rp_rcvcur = ntohl(ri->ri_sn);
  398.     rp2->rp_rcvuer = rp2->rp_rcvcur + 1 + R_RCVWIN;
  399.     rp2->rp_sndhsa = rp2->rp_sndnxt = rdpserial++;
  400.     rp2->rp_snduna = rp2->rp_sndnxt;
  401.     rp2->rp_state = R_SYN_RCVD;
  402.  
  403.     /* get the syn variables -- flags aren't interesting */
  404.  
  405.     rs = (struct rdpsyn *)(((caddr_t)ri) + RI_SIZE);
  406.     rp2->rp_sndmax = ntohs(rs->rs_mos);
  407.     if (rp2->rp_sndmax > R_MAXSND)
  408.         rp2->rp_sndmax = R_MAXSND;
  409.     rp2->rp_maxinflt = rp2->rp_sndmax;
  410.  
  411.     rp2->rp_sndbuf = ntohs(rs->rs_mss);
  412.     if (rp2->rp_sndbuf > rdp_mtu)
  413.         rp2->rp_sndbuf = rdp_mtu;
  414.  
  415.     /* steal first timer to retransmit syns */
  416.     rq2->rq_retries[0] = 0;
  417.     rq2->rq_sndtimer[0] = 0;
  418.  
  419.        /* sndnxt == sndiss */
  420.        (void) rdp_syn(inp2,1,rp2->rp_sndnxt,rp2->rp_rcvcur);
  421.     }
  422.  
  423. done:
  424.     return(0);
  425. }
  426.  
  427. /**************************************************************************/
  428. /*                       CLOSED                                           */
  429. /**************************************************************************/
  430.  
  431. rdp_iclosed(inp,rp,ri)
  432. struct inpcb *inp;
  433. struct rdpcb *rp;
  434. struct rdpip *ri;
  435. {
  436.     struct inpcb tmpinp;
  437.  
  438. #ifdef lint
  439.     rp = rp;
  440. #endif
  441.  
  442.  
  443.     if (ri->ri_flags & RH_RST)
  444.     goto done;
  445.  
  446.     /* we have to reply... */
  447.     if (inp == 0)
  448.     {
  449.     tmpinp.inp_laddr = ri->ri_dst;
  450.     tmpinp.inp_lport = ri->ri_dport;
  451.     }
  452.     else
  453.     bcopy((caddr_t)inp,(caddr_t)&tmpinp,sizeof(tmpinp));
  454.  
  455.     tmpinp.inp_faddr = ri->ri_src;
  456.     tmpinp.inp_fport = ri->ri_sport;
  457.  
  458.  
  459.     /* a data segment?? */
  460.     if ((ri->ri_flags & RH_ACK) || (ri->ri_flags & RH_NULL))
  461.     {
  462.     (void) rdp_rst(&tmpinp,0,(u_long)(ntohl(ri->ri_an)+1),(u_long)0,0);
  463.     }
  464.     else
  465.     {
  466.     /*
  467.      * RFC PROBLEM: page 24 says use rcv.cur, but we aren't open
  468.      * so rcv.cur is meaningless.
  469.      */
  470.     (void) rdp_rst(&tmpinp,1,(u_long)0,(u_long)ntohl(ri->ri_sn),0);
  471.     }
  472.  
  473. done:
  474.     return(0);
  475. }
  476.  
  477. /**************************************************************************/
  478. /*                          CLOSE WAIT                                    */
  479. /**************************************************************************/
  480.  
  481. /*ARGSUSED*/
  482.  
  483. rdp_iclowait(inp,rp,ri)
  484. struct inpcb *inp;
  485. struct rdpcb *rp;
  486. struct rdpip *ri;
  487. {
  488.  
  489.     /*
  490.      *  RFC PROBLEM:  page 13 and figure 3 on page 10 suggest we stay in
  491.      *  this state and drop all segments.  Page 24 says we go to CLOSED
  492.      *  on RST.  The first two outvote the third (and seem to make more sense).
  493.      */
  494.  
  495. #ifdef notdef
  496.     if (ri->ri_flags & RH_RST)
  497.     {
  498.     rp->rp_state = R_CLOSED;
  499.     rp->rp_timer = 0;
  500.     (void) rdp_detach(inp->inp_socket,inp);
  501.     }
  502. #endif
  503.  
  504.     return(0);
  505. }
  506.  
  507. /**************************************************************************/
  508. /*                          SYN SENT                                      */
  509. /**************************************************************************/
  510.  
  511. rdp_isynsent(inp,rp,ri)
  512. struct inpcb *inp;
  513. register struct rdpcb *rp;
  514. struct rdpip *ri;
  515. {
  516.     struct rdpsyn *rs;
  517.     register struct rdpque *rq = rp->rp_rq;
  518.  
  519.     /*
  520.      * RFC has all these tests out of order on pages 25-26
  521.      * got to test RST and SYN before ACK!
  522.      */
  523.  
  524.     if (ri->ri_flags & RH_RST)
  525.     {
  526.     /* RST -- may have to close */
  527.  
  528.     if (ri->ri_flags & RH_ACK)
  529.     {
  530.         inp->inp_socket->so_error = ECONNREFUSED;
  531.         (void) rdp_fatal(inp);
  532.     }
  533.     }
  534.     else if (ri->ri_flags & RH_SYN)
  535.     {
  536.     /* SYN -- try to finish up the open */
  537.  
  538.     rp->rp_rcvhi = rp->rp_rcvcur = ntohl(ri->ri_sn);
  539.     rp->rp_rcvuer = rp->rp_rcvcur + 1 + R_RCVWIN;
  540.  
  541.     /* grab the syn variables -- ignore the flags */
  542.  
  543.     rs = (struct rdpsyn *)((caddr_t)ri + RI_SIZE);
  544.     rp->rp_sndmax = ntohs(rs->rs_mos);
  545.     if (rp->rp_sndmax > R_MAXSND)
  546.         rp->rp_sndmax = R_MAXSND;
  547.     rp->rp_maxinflt = rp->rp_sndmax;
  548.  
  549.     rp->rp_sndbuf = ntohs(rs->rs_mss);
  550.     if (rp->rp_sndbuf > rdp_mtu)
  551.         rp->rp_sndbuf = rdp_mtu;
  552.  
  553.     if (ri->ri_flags & RH_ACK)
  554.     {
  555.         /* turn off the timer */
  556.         rp->rp_state = R_OPEN;
  557.         rp->rp_timer = RT_NULLTIME;
  558.  
  559.         rp->rp_sndnxt++;
  560.         rp->rp_snduna++;
  561.         rp->rp_estrtt = rq->rq_sndtimer[0] * RT_G;
  562.         if (rp->rp_estrtt < (RT_G * RT_RTMIN))
  563.         rp->rp_estrtt = RT_G * RT_RTMIN;
  564.  
  565.         soisconnected(inp->inp_socket);
  566.         /* rcvcur == rcvirs */
  567.         (void) rdp_ack(inp,rp->rp_sndnxt,rp->rp_rcvcur);
  568.     }
  569.     else
  570.     {
  571.         rp->rp_state = R_SYN_RCVD;
  572.         rq->rq_retries[0] = 0;
  573.         rq->rq_sndtimer[0] = 0;
  574.         /* rcvcur == rcvirs, sndnxt == sndiss */
  575.         (void) rdp_syn(inp,1,rp->rp_sndnxt,rp->rp_rcvcur);
  576.     }
  577.     }
  578.     else if (ri->ri_flags & RH_ACK)
  579.     {
  580.     /* ACK */
  581.  
  582.     /* sndnxt == sndiss */
  583.     if (ntohl(ri->ri_an) != rp->rp_sndnxt)
  584.     {
  585.         /* they don't like us and we don't like them */
  586.         (void) rdp_rst(inp,1,(u_long)0,(u_long)(ntohl(ri->ri_an)+1),1);
  587.         inp->inp_socket->so_error = ECONNABORTED;
  588.         (void) rdp_fatal(inp);
  589.     }
  590.     }
  591.  
  592.     return(0);
  593. }
  594.  
  595. /**************************************************************************/
  596. /*                           SYN RCVD                                     */
  597. /**************************************************************************/
  598.  
  599. rdp_ircvdsyn(inp,rp,ri)
  600. struct inpcb *inp;
  601. struct rdpcb *rp;
  602. struct rdpip *ri;
  603. {
  604.     struct socket *so = inp->inp_socket;
  605.     struct rdpque *rq = rp->rp_rq;
  606.     u_long seq = ntohl(ri->ri_sn);
  607.  
  608.     /* packet has to be in sequence -- note that (rcvcur == rcvirs) */
  609.     if (seq_ge(rp->rp_rcvcur,seq) || seq_ge(seq,rp->rp_rcvuer))
  610.     {
  611.     /* packet not in sequence */
  612.     (void) rdp_ack(inp,rp->rp_sndnxt,rp->rp_rcvcur);
  613.     rdp_info.rst_range++;
  614.     goto done;
  615.     }
  616.  
  617.     if (ri->ri_flags & RH_RST)
  618.     {
  619.     /* active open then return error to user */
  620.     inp->inp_socket->so_error = ECONNREFUSED;
  621.     (void) rdp_fatal(inp);
  622.     goto done;
  623.     }
  624.  
  625.     if (ri->ri_flags & RH_SYN)
  626.     {
  627.     (void) rdp_rst(inp,0,(u_long)(ntohl(ri->ri_an)+1),(u_long)0,1);
  628.     inp->inp_socket->so_error = ECONNRESET;
  629.     (void) rdp_fatal(inp);
  630.     goto done;
  631.     }
  632.  
  633.  
  634.     /*
  635.      * ack and eack tests folded together in next few lines
  636.      */
  637.  
  638.     /* sndnxt == sndiss */
  639.     if ((ri->ri_flags & RH_ACK) && (ntohl(ri->ri_an) == rp->rp_sndnxt))
  640.     goto open;
  641.  
  642.     if ((ri->ri_flags & RH_ACK) || (ri->ri_flags & RH_EACK))
  643.     {
  644.     /*
  645.      * RFC PROBLEM: doesn't say to close but we are forcing
  646.      * other end to close, so we should.
  647.      */
  648.  
  649.     (void) rdp_rst(inp,0,(u_long)(ntohl(ri->ri_an)+1),(u_long)0,1);
  650.     inp->inp_socket->so_error = ECONNABORTED;
  651.     (void) rdp_fatal(inp);
  652.     goto done;
  653.     }
  654.  
  655. open:
  656.     rp->rp_state = R_OPEN;
  657.     rp->rp_timer = RT_NULLTIME;
  658.  
  659.     rp->rp_estrtt = rq->rq_sndtimer[0] * RT_G;
  660.     if (rp->rp_estrtt < (RT_G * RT_RTMIN))
  661.     rp->rp_estrtt = RT_G * RT_RTMIN;
  662.     rp->rp_sndnxt++;
  663.     rp->rp_snduna++;
  664.     soisconnected(so);
  665.  
  666.     /* do we have any data? */
  667.     if ((ntohs(ri->ri_dlen) != 0) || (ri->ri_flags & RH_NULL))
  668.     return(1);
  669.  
  670. done:
  671.     return(0);
  672. }
  673.  
  674. /**************************************************************************/
  675. /*                              OPEN                                      */
  676. /**************************************************************************/
  677.  
  678. rdp_iopen(inp,rp,ri)
  679. struct inpcb *inp;
  680. register struct rdpcb *rp;
  681. register struct rdpip *ri;
  682. {
  683.     register short i, j;
  684.     register struct rdpque *rq = rp->rp_rq;
  685.     register int numacks=0;
  686.     struct socket *so = inp->inp_socket;
  687.     struct mbuf *m;
  688.     u_long seq = ntohl(ri->ri_sn);
  689.     u_long ack;
  690.     u_long *ea;
  691.  
  692.     /* packet in sequence? */
  693.     if (seq_le(seq,rp->rp_rcvcur) || seq_le(rp->rp_rcvuer,seq))
  694.     {
  695.     /* no ... */
  696.     (void) rdp_ack(inp,rp->rp_sndnxt,rp->rp_rcvcur);
  697.     rdp_info.rst_range++;
  698.     goto discard;
  699.     }
  700.  
  701.     /* 
  702.      * RFC PROBLEM: RFC only treats the case in which this is an
  703.      * error - but if no data outstanding, it is a real close.
  704.      */
  705.     if (ri->ri_flags & RH_RST)
  706.     {
  707.     soisdisconnected(so);
  708.     rp->rp_state = R_CLOSE_WAIT;
  709.     rp->rp_timer = RT_CLOTIME + (R_MAXTRIES * rp->rp_estrtt);
  710.  
  711.     /* a bad close?? */
  712.     if (rdp_clrq(rp) || (ntohl(ri->ri_sn) != rp->rp_rcvcur+1))
  713.         so->so_error = ECONNRESET;
  714.  
  715.     /* don't bother to send RST back */
  716.     rq->rq_retries[0] = R_MAXTRIES;
  717.  
  718.     goto discard;
  719.     }
  720.  
  721.     if (ri->ri_flags & RH_SYN)
  722.     {
  723.     (void) rdp_rst(inp,0,(u_long)(ntohl(ri->ri_an)+1),(u_long)0,1);
  724.  
  725.     /* now close down */
  726.     inp->inp_socket->so_error = ECONNRESET;
  727.     (void) rdp_fatal(inp);
  728.     goto discard;
  729.     }
  730.  
  731.     if (ri->ri_flags & RH_ACK)
  732.     {
  733.     ack = ntohl(ri->ri_an);
  734.  
  735.     if (seq_le(rp->rp_snduna,ack) && seq_lt(ack,rp->rp_sndnxt))
  736.     {
  737.  
  738.         /* new rtt */
  739. #ifdef ALTRTT
  740.         i = ( ack - rp->rp_snduna + rq->rq_sndbase ) % R_MAXSND;
  741.         if (seq_gt(ack,rp->rp_sndhsa) || (rq->rq_retries[i]==0))
  742.         {
  743.         rp->rp_sndhsa = ack;
  744.         rdp_newrtt(&(rp->rp_srtt),rq->rq_sndtimer[i]);
  745.         rp->rp_lastrtt = rq->rq_sndtimer[i];
  746.         }
  747. #endif
  748.  
  749.         /* compute number of packets acked */
  750.         i = (ack - rp->rp_snduna)+1;
  751.         j = rq->rq_sndbase;
  752.  
  753.         for(; i>0; i--)
  754.         {
  755.         if ((m = rq->rq_sndq[j]) != 0)
  756.         {
  757.             numacks++;
  758. #ifdef OLDRTT
  759.             rdp_newrtt(&(rp->rp_srtt),rq->rq_sndtimer[j]);
  760.             rp->rp_lastrtt = rq->rq_sndtimer[j];
  761. #endif
  762.             (void) m_freem(m);
  763.         }
  764.  
  765.         /* increment pointer */
  766.         if (++j == R_MAXSND)
  767.             j = 0;
  768.         }
  769.  
  770.         rq->rq_sndbase = j;
  771.         rp->rp_snduna = ack + 1;
  772.     }
  773.     }
  774.  
  775.     /* keep going... */
  776.  
  777.     if (ri->ri_flags & RH_EACK)
  778.     {
  779.     ea = (u_long *)(((caddr_t)ri)+RI_SIZE);
  780.  
  781.     i = (ri->ri_hlen - (R_HDRSIZE >> 1)) >> 1;
  782.  
  783.     for(; i > 0; i--, ea++)
  784.     {
  785.         *ea = ntohl(*ea);
  786.  
  787.         /*
  788.          * use una+1 to keep from having to worry about left
  789.          * edge shifts, which *should* never happen anyway.
  790.          */
  791.  
  792.         if (seq_le(rp->rp_snduna+1,*ea) && seq_lt(*ea,rp->rp_sndnxt))
  793.         {
  794.  
  795.         j = (*ea - rp->rp_snduna + rq->rq_sndbase) % R_MAXSND;
  796.  
  797.         if (rq->rq_sndq[j] != 0)
  798.         {
  799.             numacks++;
  800. #ifdef OLDRTT
  801.             rdp_newrtt(&(rp->rp_srtt),rq->rq_sndtimer[j]);
  802.             rp->rp_lastrtt = rq->rq_sndtimer[j];
  803. #else /* ALTRTT */
  804.             if (seq_gt(*ea,rp->rp_sndhsa) || (rq->rq_retries[j]==0))
  805.             {
  806.             rp->rp_sndhsa  = *ea;
  807.             rdp_newrtt(&(rp->rp_srtt),rq->rq_sndtimer[j]);
  808.             rp->rp_lastrtt = rq->rq_sndtimer[j];
  809.             }
  810. #endif OLDRTT
  811.  
  812.             (void) m_freem(rq->rq_sndq[j]);
  813.             rq->rq_sndq[j] = 0;
  814.         }
  815.         }
  816.     }
  817.     }
  818.  
  819.     rp->rp_inflt -= numacks;
  820.  
  821.     if ((rp->rp_qwait) && ((rp->rp_qwait -= numacks) <= 0))
  822.     {
  823.     rp->rp_qwait = 0;
  824.  
  825.     /* open window a bit, and set counter to open it more */
  826.     if (++(rp->rp_maxinflt) < rp->rp_sndmax)
  827.         rp->rp_qwait = rp->rp_maxinflt;
  828.     }
  829.  
  830.     /*
  831.      * if we have freed space, and higher level is blocked, consider
  832.      * unblocking...
  833.      */
  834.  
  835.     if ((rp->rp_inflt < rp->rp_maxinflt) && (so->so_snd.sb_cc != 0))
  836.     {
  837.     i = rp->rp_sndnxt - rp->rp_snduna;
  838.  
  839.     /* do we and remote have space? */
  840.     if ((i < R_MAXSND)  && (i < (rp->rp_sndmax << 1)))
  841.     {
  842.         so->so_snd.sb_cc = 0;
  843.         sowwakeup(so);
  844.     }
  845.     else
  846.         rdp_info.rst_hitedge++;
  847.  
  848.     }
  849.  
  850.     if ((ntohs(ri->ri_dlen)!=0) || (ri->ri_flags & RH_NULL))
  851.     return(1);
  852.  
  853. discard:
  854.     /* ignore any data */
  855.     return(0);
  856. }
  857.  
  858. /**************************************************************************/
  859. /*    DRAIN -- similar to OPEN, but no new data, and be lazy about EACKS  */
  860. /**************************************************************************/
  861.  
  862. rdp_idrain(inp,rp,ri)
  863. struct inpcb *inp;
  864. register struct rdpcb *rp;
  865. register struct rdpip *ri;
  866. {
  867.     register u_long seq = ntohl(ri->ri_sn);
  868.     register struct rdpque *rq = rp->rp_rq;
  869.     register short i;
  870.     register short j;
  871.     struct mbuf *m;
  872.     struct socket *so = inp->inp_socket;
  873.     u_long ack;
  874.  
  875.     /* packet in sequence? */
  876.     if (seq_le(seq,rp->rp_rcvcur) || seq_le(rp->rp_rcvuer,seq))
  877.     {
  878.     /* no ... */
  879.     (void) rdp_ack(inp,rp->rp_sndnxt,rp->rp_rcvcur);
  880.     rdp_info.rst_range++;
  881.     goto discard;
  882.     }
  883.  
  884.     /*
  885.      * unlike OPEN, clearly bad close -- we haven't finished sending 
  886.      */
  887.  
  888.     if (ri->ri_flags & RH_RST)
  889.     {
  890.     so->so_error = ECONNRESET;
  891.     soisdisconnected(so);
  892.     rp->rp_state = R_CLOSE_WAIT;
  893.     rp->rp_timer = RT_CLOTIME + (R_MAXTRIES * rp->rp_estrtt);
  894.     /* again, don't send RST back */
  895.     rq->rq_retries[0] = R_MAXTRIES;
  896.     (void) rdp_clrq(rp);
  897.     goto discard;
  898.     }
  899.  
  900.     if (ri->ri_flags & RH_SYN)
  901.     {
  902.     (void) rdp_rst(inp,0,(u_long)(ntohl(ri->ri_an)+1),(u_long)0,1);
  903.  
  904.     /* now close down */
  905.     inp->inp_socket->so_error = ECONNRESET;
  906.     (void) rdp_fatal(inp);
  907.     goto discard;
  908.     }
  909.  
  910.     /* if new data then error */
  911.     if ((ntohs(ri->ri_dlen) != 0) || (ri->ri_flags & RH_NULL))
  912.     {
  913.     (void) rdp_rst(inp,0,(u_long)(ntohl(ri->ri_an)+1),(u_long)0,1);
  914.     inp->inp_socket->so_error = ECONNRESET;
  915.     (void) rdp_fatal(inp);
  916.     goto discard;
  917.     }
  918.  
  919.     /* an ack -- maybe we are done? */
  920.     if (ri->ri_flags & RH_ACK)
  921.     {
  922.     ack = ntohl(ri->ri_an);
  923.  
  924.     if (seq_gt(rp->rp_snduna,ack) || seq_ge(ack,rp->rp_sndnxt))
  925.         goto discard;
  926.  
  927.     /* free packets acked */
  928.     i = (ack - rp->rp_snduna)+1;
  929.     j = rq->rq_sndbase;
  930.  
  931.     for(; i>0; i--)
  932.     {
  933.         if ((m = rq->rq_sndq[j]) != 0)
  934.         (void) m_freem(m);
  935.  
  936.         if (++j == R_MAXSND)
  937.         j = 0;
  938.     }
  939.  
  940.     rq->rq_sndbase = j;
  941.     rp->rp_snduna = ack + 1;
  942.  
  943.     /* are we done? -- then finish the user's close */
  944.     if (rp->rp_snduna == rp->rp_sndnxt)
  945.     {
  946.         (void) rdp_rst(inp,0,rp->rp_sndnxt,(u_long)0,1);
  947.         soisdisconnected(so);
  948.         rp->rp_state = R_CLOSE_WAIT;
  949.         rp->rp_timer = RT_CLOTIME + (R_MAXTRIES * rp->rp_estrtt);
  950.         rq->rq_sndtimer[0] = 0;
  951.         rq->rq_retries[0] = 0;
  952.     }
  953.     }
  954.  
  955. discard:
  956.     return(0);
  957. }
  958.  
  959. /**************************************************************************/
  960. /*              packet printer for debugging inbound packets              */
  961. /**************************************************************************/
  962.  
  963. #ifdef DEBUG
  964. rdp_pktprt(ri)
  965. struct rdpip *ri;
  966. {
  967.     printf("s=0x%x(%d),d=0x%x(%d): ",
  968.     ri->ri_src.s_addr, ri->ri_sport, ri->ri_dst.s_addr, ri->ri_dport);
  969.     printf("fl=0x%x, ",(int)ri->ri_flags);
  970.     printf("sn=0x%x,an=0x%x,",ntohl(ri->ri_sn), ntohl(ri->ri_an));
  971.     printf("sum=0x%x,",ri->ri_sum);
  972.     printf("hl=%d,dl=%d\n",ri->ri_hlen << 1, (int)ntohs(ri->ri_dlen));
  973. }
  974. #endif
  975.