home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / WATTCP / MSWATTCP.ZIP / SRC / TCP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-06  |  76.4 KB  |  2,761 lines

  1. /***
  2.  *
  3.  * File: tcp.c
  4.  *
  5.  * 27-Aug-93 fr    - final cleanup
  6.  * 28-Aug-92 lr
  7.  *      maybe it's worth resetting s->safetysig on closed sockets.
  8.  * 09-Jul-92 lr
  9.  *      sometimes, a connection won't start.
  10.  *      check carefully the udp implementations, it's likely to be
  11.  *      broken by variable-size buffers.
  12.  *
  13.  ***  TCP.C - the true worker of TCP
  14.  ***    contains all opens, closes, major read/write routines and
  15.  ***    basic IP handler for incomming packets
  16.  ***    Much of the TCP/UDP/IP layering is done at the data structure
  17.  ***    level, not in separate routines or tasks
  18.  ***  The network is kept alive by periodically calling tcp_tick(),
  19.  ***  which scans all the sockets. They can be in three 'unhappy'
  20.  ***  states:
  21.  ***    NO      means they don't need any activity.
  22.  ***    YES     means they need attention at next tick.
  23.  ***    VERY    means they need immediate attention.
  24.  ***
  25.  ***/
  26.  
  27. #define WATTCP_KERNEL
  28. #define NEWPCTCP
  29. #include <tcp.h>
  30. #include <time.h>
  31.  
  32. #define NO 0            /*** values for the unhappy flag ***/
  33. #define YES 1
  34. #define VERY 2
  35.  
  36. #define LAZY 1          /** values for inlist field of tcp sockets **/
  37. #define BUSY 2
  38.  
  39. /***
  40.  *** Debugging stuff
  41.  *** DB4 always prints a message (these are bugs in this program)
  42.  ***     or in the other party
  43.  *** DB3 prints a message if debug_on=1
  44.  *** DB2 only prints a message if debug is #defined
  45.  ***
  46.  ***/
  47.  
  48. /*
  49.  * DB_W is a fast output routine for debugging the tcp
  50.  * state machine -- is currently unused
  51.  */ 
  52. #ifndef debug1
  53. #       define DB_W(x) 
  54. #else
  55. #       define DB_W(x) _db_w(x)
  56.  
  57. void _db_w(char *s) {
  58.     static char far *vdu_base=(char far *)0xb8000000L;
  59.     static int vdu_col=0;
  60.     char c;
  61.     while(c= *s++){
  62.         vdu_base[vdu_col]=c; vdu_col +=2;
  63.         if (vdu_col>=3200) vdu_col=0;
  64.     }
  65. }
  66. #endif /* debug1 */
  67.  
  68. /***
  69.  *** end of debugging stuff
  70.  ***/
  71.  
  72. /************************** STATICS **********************************/
  73.  
  74. /* static void largecheck( void *s, int size ); no more static fr */
  75. static void udp_close( udp_Socket *ds );
  76. static void tcp_close( tcp_Socket *ds );
  77. static void tcp_abort( tcp_Socket *ds );
  78. static void tcp_Retransmitter(void);
  79. static void tcp_unthread( tcp_Socket *ds); 
  80. static int udp_write(register udp_Socket *s, byte *datap, int len);
  81. static int udp_read( register udp_Socket *s, byte *datap, int maxlen);
  82. static int tcp_read(register tcp_Socket *s, byte *datap, int maxlen);
  83. static int tcp_write(register tcp_Socket *s, byte *dp, int len);
  84. static void tcp_Flush(tcp_Socket *s);
  85. static void udp_handler(in_Header *ip);
  86. static void tcp_close_sock(register tcp_Socket *s, char *msg);
  87. static void recompute_rto(register tcp_Socket *s);
  88. static int acceptable(tcp_Socket *s, in_Header *ip, tcp_Header *tp);
  89. static void set_UP(int flags, tcp_Socket *s, tcp_Header *tp);
  90. static void tcp_handler1(register tcp_Socket *s,in_Header *ip,tcp_Header *tp,word flags,int len);
  91. static void tcp_handler(in_Header *ip);
  92. static int tcp_ProcessData(register tcp_Socket *s, tcp_Header *tp, int len);
  93. static void tcp_send(register tcp_Socket *s);
  94. static void sock_update( tcp_Socket *s );
  95.  
  96. /*static void (*system_yield)() = NULL;  fr put into proto.h */
  97. static unsigned long far *realclock = (unsigned long far *)0x000046cL;
  98. static int ip_id = 0;                   /* packet number */
  99. static unsigned next_tcp_port = 1024;   /* auto incremented */
  100. static unsigned next_udp_port = 1024;
  101. static udp_Socket *udp_allsocs = NULL;
  102. /*static tcp_Socket *tcp_allsocs = NULL;  fr traslated to proto.h */
  103. static initialized = 0;
  104.  
  105. /*************** END OF STATICS *******************************/
  106.  
  107.  
  108.  
  109. /***
  110.  *** ip user level timer stuff
  111.  ***   void ip_timer_init( void *s, int delayseconds )
  112.  ***   int  ip_timer_expired( void *s )
  113.  ***    - 0 if not expired
  114.  ***/
  115.  
  116. void
  117. ip_timer_init( udp_Socket *s , int delayseconds )
  118. { s->usertimer = delayseconds ? set_ttimeout( delayseconds*18 ): 0 ; }
  119.  
  120. int
  121. ip_timer_expired( udp_Socket *s)
  122. { return( s->usertimer ? chk_timeout( s->usertimer) : 0 ); }
  123.  
  124. longword
  125. MsecClock(void)
  126. { return( (set_ttimeout(0))*55L); }
  127.  
  128. /***
  129.  *** Timer definitions. All of them are in ticks.
  130.  ***/
  131. #define RETRAN_STRAT_TIME 1 /* how often do we check retrans. tables*/
  132. #define tcp_OPENTIMEOUT 31*18  /* timeout for opens */
  133. #define tcp_CLOSETIMEOUT 31*18  /* timeout for close */
  134. #define tcp_FLUSHTIMEOUT 31*18  /* timeout for flushing data after a close */
  135. #define tcp_TTIMEOUT 31*18      /* timeout during a connection */
  136. #define tcpAbortTimeout 18*13   /* about 5 minutes */
  137.  
  138. /***
  139.  *** Initialization/termination stuff
  140.  ***/
  141. /***
  142.  *** Shut down the card and all services
  143.  ***/
  144. void
  145. tcp_shutdown(void)
  146. {
  147.     while (tcp_allsocs) tcp_abort( tcp_allsocs );
  148.     _eth_release();
  149.     initialized = 0;
  150. }
  151.  
  152. /***
  153.  *** tcp_Init - Initialize the tcp implementation
  154.  ***        - may be called more than once without hurting
  155.  ***/
  156. void
  157. tcp_init(void)
  158. {
  159.     /* extern int _arp_last_gateway, _last_nameserver; */
  160.  
  161.     DB2((FDB,"tcp_init():\n"));
  162.     if (!initialized) { /* initialize ethernet interface */
  163.     initialized = 1;
  164.     _eth_init(); /* in pcpkt.c */
  165.     /*ip_id = (int)set_ttimeout( 0 ) ;*/
  166.     /* reset the various tables */
  167.     _arp_last_gateway = 0;  /* reset the gateway table */
  168.     _last_nameserver = 0;   /* reset the nameserver table */
  169.     _last_cookie = 0;       /* eat all remaining crumbs */
  170.     *_hostname = 0;         /* reset the host's name */
  171.  
  172.     if (!my_ip_addr) {
  173.         /* using our local reverse ethernet address thingamajig */
  174.         memcpy( &my_ip_addr, &_eth_addr[2], 4 );
  175.     }
  176.     _eth_free( 0 );
  177.     next_udp_port=next_tcp_port=1024+(unsigned)((*realclock>>7)& 0x1ff);
  178.     }
  179. }
  180.  
  181. /***
  182.  *** Checks for bugs in large model C compiler
  183.  ***/
  184. void
  185. largecheck( void *s, int size )
  186. {
  187.     DB2((FDB,"largecheck():\n"));
  188.     if ( (FP_OFF(s)) > (-size)) {
  189.     outs("ERROR: C compiler sock size error\n");
  190.     exit( 3 );
  191.     }
  192. }
  193.  
  194. /*** Setting new default socket's buffers dimensions. 
  195.  ***/
  196. void
  197. set_tcp_rxbufsize(word size)
  198. {
  199.     RxMaxBufSize = size;
  200. }
  201.  
  202. void
  203. set_tcp_txbufsize(word size)
  204. {
  205.     TxMaxBufSize = size;
  206. }
  207.  
  208. void
  209. set_udp_bufsize(word size)
  210. {
  211.     MaxBufSize = size;
  212. }
  213.  
  214. int
  215. udp_open(udp_Socket *s, word lport, longword ina,
  216.     word port, procref datahandler)
  217. {
  218.     DB2((FDB,"udp_open():\n"));
  219.     largecheck( s, sizeof( udp_Socket ));
  220.     udp_close( s );
  221.     memset( s, 0, sizeof( udp_Socket ));
  222.     s->ip_type = UDP_PROTO;
  223.     if (lport == 0) lport= ++next_udp_port; /* get a nonzero port */
  224.     s->myport = lport;
  225.  
  226.     /* check for broadcast */
  227.     if ( ina == 0xFFFFFFFF || ina == 0 ) {
  228.     DB2((FDB,"udp_open(): found a broadcast\n"));
  229.     memset( s->hisethaddr, 0xff, sizeof( eth_address ));
  230.     } else { 
  231.     DB2((FDB,"udp_open(): calling _arp_resolve \n"));
  232.     if ( ! _arp_resolve(ina, &(s->hisethaddr)) ) return( 0 );
  233.     DB2((FDB,"udp_open(): _arp_resolve succeded.\n"));
  234.     }
  235.  
  236.     s->hisaddr = ina;
  237.     s->hisport = port;
  238.     s->dataHandler = datahandler;
  239.     s->usr_yield = system_yield;
  240.     s->next = udp_allsocs;
  241.  
  242.     if ((s->rdata = (byte *) malloc((int)MaxBufSize)) == NULL) {
  243.     DB3((stderr,"Warning: not enough space for rdata buffer"));
  244.     udp_close(s);
  245.     return(0);
  246.     }
  247.     s->rxbufsize=MaxBufSize;
  248.  
  249.     udp_allsocs = s;
  250.     s->safetysig = SAFETYUDP;
  251.     return( 1 );
  252. }
  253.  
  254. /***
  255.  *** Actively open a TCP connection to a particular destination.
  256.  *** Return 0 on error
  257.  */
  258. /*** CHECK THIS ***/
  259. int
  260. tcp_open(register tcp_Socket *s, word lport,
  261.     longword ina, word port, procref datahandler)
  262. {
  263.     DB2((FDB,"tcp_open():\n"));
  264.     largecheck( s, sizeof( tcp_Socket ));   /* stack space warnings */
  265.     tcp_unthread(s);       /* just in case not totally closed */
  266.  
  267.     memset( s, 0, sizeof( tcp_Socket));
  268.     s->ip_type = TCP_PROTO;
  269.     s->mss = _mss;
  270.     s->state = tcp_StateSYNSENT;
  271.     DB2((FDB,"tcp_open(): going to SYNSENT\n"));
  272.     s->timeout = set_ttimeout( tcp_OPENTIMEOUT );
  273. /***
  274.  *** If cannot connect and the timeout expires, the connection
  275.  *** is aborted.
  276.  ***/
  277.  
  278.     if (lport==0) lport= ++next_tcp_port; /* get a nonzero port val */
  279.     s->myport = lport;
  280.     DB2((FDB,"Calling _arp_resolve():\n"));
  281.     if (! _arp_resolve(ina, &(s->hisethaddr))) return( 0 );
  282.     DB2((FDB,"_arp_resolve() succeeded.\n"));
  283.     s->hisaddr = ina;
  284.     s->hisport = port;
  285.  
  286.     /* choose a pseudo-random iss */
  287.     /* s->seqnum = intel( set_ttimeout( 0 )) & 0xffff0000 ; */
  288.     s->seqnum =  (set_ttimeout( 0 ) & 0xfff) << 20 ;
  289.     s->unacked = s->datalen = 0; /* redundant */
  290.     s->flags = tcp_FlagSYN;
  291.     s->dataHandler = datahandler;
  292.     s->usr_yield = system_yield;
  293.     s->next = tcp_allsocs;
  294.  
  295.     s->rxbufsize = RxMaxBufSize;
  296.     if ((s->rdata = (byte *) malloc((int)RxMaxBufSize)) == NULL) {
  297.     DB3((stderr,"Warning: tcp_open(): not enough room for rdata buffer"));
  298.     tcp_unthread(s);
  299.     return(0);
  300.     }
  301.  
  302.     s->txbufsize = TxMaxBufSize;
  303.     if ((s->data = (byte *) malloc((int)TxMaxBufSize)) == NULL) {
  304.     DB3((stderr,"Warning: tcp_open(): not enough room for tx data buffer"));
  305.     tcp_unthread(s);
  306.     return(0);
  307.     }
  308.  
  309.     tcp_allsocs = s;
  310.     s->safetysig = SAFETYTCP;
  311.     DB2((FDB,"Sending first SYN from tcp_open\n")); 
  312.     s->rto= 9; /* start 1/2 sec. rto */
  313.     tcp_send(s);
  314.     return( 1 );
  315. }
  316.  
  317. /***
  318.  *** Passive open: listen for a connection on a particular port
  319.  ***/
  320. /*** CHECK THIS ***/
  321. int
  322. tcp_listen(register tcp_Socket *s, word lport,
  323.     longword ina, word port, procref datahandler, word timeout)
  324. {
  325.     DB2((FDB,"tcp_listen():\n"));
  326.     largecheck( s, sizeof( tcp_Socket ));
  327.     tcp_unthread(s);    /* just in case not totally closed */
  328.     memset( s, 0, sizeof( tcp_Socket));
  329.     s->ip_type = TCP_PROTO;
  330.     s->mss = _mss;
  331.  
  332.  
  333.     s->state = tcp_StateLISTEN;
  334.     DB2((FDB,"tcp_listen(): going to LISTEN\n"));
  335.     s->timeout = timeout ? set_timeout( timeout ) : 0;
  336. /***
  337.  *** Here it's my choice to have or not a timeout
  338.  *** If there is, and it expires, the connection is aborted.
  339.  ***/
  340.     s->myport = lport;
  341.     s->hisport = port;
  342.     s->hisaddr = ina;
  343.     s->seqnum = intel( (longword)s ); /* not a good idea, but works */
  344.     s->datalen = 0;
  345.     s->flags = 0;
  346.     s->rto= 9; /* start 1/2 sec. rto */
  347.     s->unhappy = NO; /* this is a PASSIVE open */
  348.     s->dataHandler = datahandler;
  349.     s->usr_yield = system_yield;
  350.     s->safetysig = SAFETYTCP;
  351.     s->next = tcp_allsocs;
  352.  
  353.     s->rxbufsize = RxMaxBufSize;
  354.     if ((s->rdata = (byte *) malloc((int)RxMaxBufSize)) == NULL) {
  355.     DB3((stderr,"Warning: tcp_listen(): not enough space for rdata buffer"));
  356.     tcp_unthread(s);
  357.     return(0);
  358.     }
  359.     s->txbufsize = TxMaxBufSize;
  360.     if ((s->data = (byte *) malloc((int)TxMaxBufSize)) == NULL) {
  361.     DB3((stderr,"Warning: tcp_listen(): not enough space for Tx data buffer"));
  362.     tcp_unthread(s);
  363.     return(0);
  364.     }
  365.     tcp_allsocs = s;
  366.     return( 1 );
  367. }
  368.  
  369. /*** added by fr ***/
  370. #ifdef unused
  371. /*
  372.  * multi-listen is superseded by select()
  373.  */
  374. tcp_Socket *
  375. multi_listen(int numsock, word lport, longword ina, word port, 
  376.     procref datahandler, word mode)
  377. {
  378.  
  379.   tcp_Socket   *s[20], *sret = NULL, *bsp=NULL, *sldp = NULL; 
  380.   int i;
  381.  
  382.   DB2((FDB,"multi_listen():\n"));
  383.   if ((sldp = (tcp_Socket *) malloc( (int) sizeof( tcp_Socket ) )) == NULL){
  384.     DB4((stderr,"No room for any socket!\n"));
  385.     return(sldp);
  386.     }
  387.   memset( sldp, 0, sizeof( tcp_Socket));
  388.   sldp->myport = lport;
  389.   sldp->hisport = port;
  390.   sldp->hisaddr = ina;
  391.   sldp->sock_mode = (sldp->sock_mode & 0xfffc) |mode;
  392.   sldp->dataHandler = datahandler;
  393.   sldp->next = NULL;
  394.  
  395.   for( i=0 ; i<numsock ; i++){
  396.     if ( (s[i] = (tcp_Socket *) malloc( (int) sizeof( tcp_Socket ) )) == NULL){
  397.     DB3((stderr,"%d sockets allocated\n",i));
  398.     break;
  399.     }
  400.     
  401.     largecheck( s[i], sizeof( tcp_Socket ));
  402.     memset( s[i], 0, sizeof( tcp_Socket));
  403.     s[i]->ip_type = TCP_PROTO;
  404.     s[i]->mss = _mss;
  405.     s[i]->state = tcp_StateLISTEN;
  406.     DB2((FDB,"tcp_listen(): going to LISTEN\n"));
  407.     s[i]->myport = lport;
  408.     s[i]->hisport = port;
  409.     s[i]->hisaddr = ina;
  410.     s[i]->sock_mode = (s[i]->sock_mode & 0xfffc) | mode;    
  411.     s[i]->seqnum = intel( (longword)s ); /* not a good idea, but works */
  412.     s[i]->datalen = 0;
  413.     s[i]->flags = 0;
  414.     s[i]->rto= 9; /* start 1/2 sec. rto */
  415.     s[i]->unhappy = NO; /* this is a PASSIVE open */
  416.     s[i]->dataHandler = datahandler;
  417.     s[i]->usr_yield = system_yield;
  418.     s[i]->safetysig = SAFETYTCP;
  419.     s[i]->next = tcp_allsocs;
  420.     s[i]->brother = bsp;
  421.     s[i]->father = sldp;
  422.     s[i]->inlist = LAZY;
  423.  
  424.     s[i]->rxbufsize = RxMaxBufSize;
  425.     if ((s[i]->rdata = (byte *) malloc((int)RxMaxBufSize)) == NULL) {
  426.     DB3((stderr,"Warning: not enough space for rdata buffer\n"));
  427.     DB3((stderr,"%d sockets allocated\n",i));
  428.     tcp_unthread(s[i]);
  429.     break;
  430.         }
  431.     s[i]->txbufsize = TxMaxBufSize;
  432.     if ((s[i]->data = (byte *) malloc((int)TxMaxBufSize)) == NULL) {
  433.     DB3((stderr,"Warning: not enough space for data buffer"));
  434.     DB3((stderr,"%d sockets allocated\n",i));
  435.     tcp_unthread(s[i]);
  436.     break;
  437.         }
  438.     tcp_allsocs = s[i];
  439.     bsp=s[i];
  440.     sret=s[i];
  441.     if( !(sldp->next) ) sldp->next = sret; /* memorizzo */
  442.     }/*end for*/
  443.     (sldp->next)->brother = sret; /* chiudo la lista */
  444.     sldp->next = sret;
  445.     return(sldp);
  446. }
  447. #endif /* unused */
  448.  
  449. /***
  450. /***
  451.  *** simply unlink from socket list
  452.  *** It's the UDP version of the tcp_unthread 
  453.  ***/
  454. static void
  455. udp_close( udp_Socket *ds )
  456. {
  457.     register udp_Socket *s, **sp;
  458.  
  459.     DB2((FDB,"udp_close():\n"));
  460.     for (sp = &udp_allsocs;; sp = &s->next) {
  461.     s = *sp;
  462.     if ( s == ds ) {
  463.         *sp = s->next;
  464.         if (s->rdata==NULL) {
  465.         DB3((stderr,"udp_close: socket was already closed\n"));
  466.         break;
  467.         }
  468.         free(s->rdata); 
  469.         s->rdata=NULL; /* 28-Aug-92 lr you never know... */
  470.         break;
  471.     }
  472.     if ( !s ) break;
  473.     if ( ! s->err_msg ) s->err_msg = "UDP Close called";
  474.     }
  475. }
  476.  
  477. /***
  478.  *** Will queue a FIN on a particular port.
  479.  *** In ESTCL or CLOSWTCL it has already been called.
  480.  *** Must still allow receives. A timeout becomes active so
  481.  *** that, if I cannot flush data in a reasonable time, the
  482.  *** connection is aborted anyway.
  483.  ***/
  484. static void
  485. tcp_close(register tcp_Socket *s){
  486.  
  487.     DB2((FDB,"tcp_close():"));
  488.     if ( s->ip_type != TCP_PROTO ) return; /* invalid */
  489.     switch(s->state) {
  490.         default:
  491.            DB3((FDB,"tcp_close(): called in state %s\n",state_names[s->state]));
  492.        return;
  493.         case tcp_StateLISTEN:
  494.         case tcp_StateSYNSENT:
  495.         tcp_unthread(s); /* check this */
  496.         return; /* error: closing */
  497.     case tcp_StateCLOSWT:
  498.         s->state = tcp_StateCLOSWTCL;
  499.         DB2((FDB,"tcp_close(): going from CLOSWT to CLOSWTCL\n"));
  500.         s->timeout=set_ttimeout(tcp_CLOSETIMEOUT);
  501.        case tcp_StateCLOSWTCL:
  502.         goto tcp_close_1;
  503.         case tcp_StateSYNRECLIS:
  504.         case tcp_StateSYNREC:
  505.         case tcp_StateESTAB:
  506.              DB2((FDB,"tcp_close(): going from %s to ESTCL\n",state_names[s->state]));
  507.         s->state = tcp_StateESTCL;
  508.         s->timeout=set_ttimeout(tcp_CLOSETIMEOUT);
  509.         case tcp_StateESTCL:
  510.     tcp_close_1:
  511.         if ( s->datalen ) {     /* must first flush all data */
  512.             s->flags |= tcp_FlagPUSH | tcp_FlagACK;
  513.                 if (s->rtt_time==0) {
  514.                  DB4((stderr,"pending data and rtt=0. Ouch!!!\n"));
  515.                 }
  516.                 } 
  517.         else { /* no more outgoing data, really closing */
  518.             s->flags = tcp_FlagACK | tcp_FlagFIN;
  519.                 if (!s->err_msg)
  520.                 s->err_msg = "Connection closed normally";
  521.                 if ( s->state == tcp_StateESTCL ) {
  522.                 DB2((FDB,"tcp_close(): going from %s to FINWT1\n",state_names[s->state]));
  523.                 s->state = tcp_StateFINWT1;
  524.                     }
  525.                 else {
  526.                 DB2((FDB,"tcp_close(): going from %s to LASTACK\n",state_names[s->state]));
  527.                 s->state= tcp_StateLASTACK;
  528.                     }
  529.             s->timeout = set_ttimeout(tcp_FLUSHTIMEOUT);
  530. /***
  531.  *** The above timeout is for the upper level protocol, so that
  532.  *** all the data in the buffers can be flushed. I'm not so sure
  533.  *** about the actual value. Should be at least rto.
  534.  ***/
  535.                 } /* end else */
  536.         tcp_send( s );
  537.         break;
  538.             } /* end switch */
  539.     } /* tcp_close */
  540.  
  541. /***
  542.  *** Abort a tcp connection. Correct.
  543.  ***/
  544. static void
  545. tcp_abort(register tcp_Socket *s)
  546. {
  547.     DB2((FDB,"tcp_abort():\n"));
  548.     if (!s->err_msg) s->err_msg = "TCP_ABORT";
  549.     if ( s->state != tcp_StateLISTEN && s->state != tcp_StateCLOSED ) {
  550.     s->flags = tcp_FlagRST  | tcp_FlagACK ;
  551.     tcp_send(s);
  552.     }
  553.     s->unhappy = NO;
  554.     s->datalen = 0;
  555.     s->state = tcp_StateCLOSED;
  556.     tcp_unthread(s);
  557. }
  558.  
  559. void
  560. sock_abort(tcp_Socket *s )
  561. {
  562. DB2((FDB,"sock_abort():\n"));
  563.     if ( s->ip_type == TCP_PROTO ) tcp_abort( s );
  564.     else udp_close( (udp_Socket *) s );
  565. }
  566.  
  567.  
  568. /***
  569.  *** make_in_hdr() prepares an internet header
  570.  ***    parameters are in machine format.
  571.  ***/
  572. void
  573. make_in_hdr(in_Header *inp, byte proto, longword dest, word len)
  574. {
  575. DB2((FDB,"make_in_hdr():\n"));
  576.     inp->ver = 4;
  577.     inp->hdrlen = 5;
  578.     inp->tos = 0;
  579.     inp->identification = intel16( ++ip_id );   /* was post inc */
  580.     inp->frag = 0;
  581.     inp->ttl = 254;
  582.     inp->proto = proto;
  583.     inp->checksum = 0;
  584.     inp->source = intel( my_ip_addr );
  585.     inp->destination = intel( dest );
  586.     inp->length = intel16( len );
  587.     inp->checksum = ~inchksum((void *)inp, sizeof(in_Header));
  588. }
  589.  
  590.  
  591. /***
  592.  *** Retransmitter - called periodically to perform tcp retransmissions
  593.  ***/
  594.  
  595. static void
  596. tcp_Retransmitter(void)
  597. {
  598.     static longword retran_strat = 0L; /* timeout retran strategy */
  599.     register tcp_Socket *s;
  600.     int slow=0;
  601. #ifdef UNDEF
  602.     DB2((FDB,"tcp_Retransmitter():\n"));
  603.     gm_tcp_Retransmitter++;
  604. #endif /* UNDEF */
  605.     if (slow=chk_timeout(retran_strat))
  606.     retran_strat = set_ttimeout( RETRAN_STRAT_TIME );
  607.  
  608.     for ( s = tcp_allsocs; s; s = s->next ) {
  609.     if (!slow) {
  610.         if (s->unhappy & VERY) {
  611.         DB2((FDB,"Retransmitting cause of VERY \n")); 
  612.         gm_tcp_send_very++;
  613.         tcp_send(s);
  614.         }
  615.     } 
  616.     else {
  617.         DB_W("RT ");
  618.         /* only do this once per RETRAN_STRAT_TIME milliseconds */
  619.         if (s->rtt_time && chk_timeout(s->rtt_time)) {
  620.         gm_expire++;
  621.         s->unacked=0; /* have lost some ack, resend */
  622. /***
  623.  *** exponential backoff for rto. Should also upper bound it.
  624.  ***/
  625.         if (s->rto) s->rto = (s->rto * 3) / 2;
  626.         else s->rto = 4;
  627.         DB3((FDB,"rtt expired, rto now= %d\n",s->rto));
  628.         s->unhappy = YES;
  629.         }
  630. /***
  631.  *** It is agreed that when, due to a send or an incoming ack,
  632.  *** new data can be sent, then unhappy is also set.
  633.  ***/
  634.         if (s->unhappy) { /* was also s->datalen>0 */
  635.         DB2((FDB,"Sending seqnum %8lx from Retransmitter\n",s->seqnum));
  636.         gm_tcp_send_retr++;
  637.         tcp_send(s);
  638.         }
  639. /***
  640.  *** handle inactive tcp timeouts
  641.  ***/
  642.         if ( sock_inactive && s->inactive_to ) {
  643.         if ( chk_timeout( s->inactive_to)) {
  644.             /* this baby has timed out */
  645.             s->err_msg = "Connection timed out - no activity";
  646.             sock_close((sock_type*) s );
  647.         }
  648.         }
  649. /***
  650.  *** Handle regular timeouts.
  651.  ***/
  652.         if ( s->timeout && chk_timeout( s->timeout)) {
  653.         if ( s->state == tcp_StateTIMEWT ) {
  654.             DB2((FDB,"tcp_close(): going from %s to CLOSED\n",state_names[s->state]));
  655.             s->state=tcp_StateCLOSED;
  656.             tcp_unthread(s); /* can I still do I/O ? */
  657.         } 
  658.         else if (s->state!=tcp_StateESTAB /* && s->state!=tcp_StateCLOSWT */) {
  659.             s->err_msg = "Timeout, aborting";
  660.             DB3((FDB,"Timeout expired for socket in state %s - aborting\n",state_names[s->state]));
  661.             tcp_abort(s);
  662.         }
  663.         else {
  664.             DB3((FDB,"Timeout expired for active socket in state %s\n",state_names[s->state]));
  665.         }
  666.         }
  667.     } /* end if slow */
  668.     }
  669. } /* end Retransmitter */
  670.  
  671. /***
  672.  *** Unthread a socket from the socket list, if it's there
  673.  ***/
  674. void
  675. tcp_unthread( tcp_Socket *ds)
  676. {
  677.     register tcp_Socket *s, *fs, **sp; /* eventualm. *pp */
  678.  
  679.     DB2((FDB,"tcp_unthread():\n"));
  680.     gm_tcp_unthread++;
  681. /*    if (!ds->rdatalen || (ds->state > tcp_StateESTCL)) *//*always */
  682.     ds->ip_type = 0;        /* fail io */
  683.     ds->state = tcp_StateCLOSED;   /* tcp_tick needs this */
  684.     
  685.     if (ds->inlist==BUSY){
  686.     fs = ds->father;
  687.     ds->ip_type = TCP_PROTO;
  688.     ds->sock_mode = fs->sock_mode;
  689.     ds->myport = fs->myport;
  690.     ds->hisport = fs->hisport;
  691.     ds->dataHandler = fs->dataHandler;    
  692.     ds->usertimer = 0L;
  693.     memset(&(ds->hisethaddr ),0,sizeof(eth_address));
  694.     ds->hisaddr = fs->hisaddr;    
  695.     ds->state = tcp_StateLISTEN;
  696.     ds->rdatalen = 0;
  697.     ds->acknum = 0L;
  698.     ds->seqnum = intel((longword)s);
  699.     ds->timeout = 0L;
  700.     ds->unhappy = NO;
  701.     ds->usr_yield = system_yield;
  702.     ds->flags = 0;
  703.     ds->window = 0;
  704.     ds->datalen = 0;
  705.     ds->unacked = 0;
  706.     ds->rto = 9;
  707.     ds->inlist = LAZY;
  708.     /* fs->next = ds->brother;  i don't think it would be a good idea */
  709.     }
  710.     else {    
  711.             sp = &tcp_allsocs;
  712.         for (;;) {
  713.                s = *sp;
  714.         if ( s == ds ) {
  715.             *sp = s->next;
  716.             if (s->rdata==NULL || s->data==NULL) {
  717.             DB3((stderr,"tcp_unthread: socket already closed\n"));
  718.             break;
  719.                   }
  720.             free(s->rdata);
  721.             free(s->data); 
  722.             s->rdata=s->data=NULL;
  723.             break;
  724.             }
  725.         if ( !s ) break;
  726.         sp = &s->next;
  727.             }
  728.     }
  729.  
  730. /*  pp = tcp_allsocs;  when multi_listen sockets where discarded at closing
  731.     for (;;) {
  732.     s = pp->next;
  733.     if ( s == ds ) {
  734.         pp->brother = s->brother;
  735.         break;
  736.         }
  737.     if ( !s ) break;
  738.     pp = s;
  739.     }  */
  740.  
  741.     }
  742.  
  743.  
  744. /***
  745.  *** tcp_tick(s) - called periodically by user application
  746.  ***    returns 0 if s is NULL or not TCP socket
  747.  ***/
  748.  
  749. extern long far lost_packets;
  750.  
  751. short
  752. tcp_tick(register sock_type *s )
  753. {
  754.     register in_Header *ip;
  755.     word packettype;
  756.  
  757. #ifdef UNDEF
  758.     DB2((FDB,"tcp_tick():\n"));
  759.     gm_tcp_tick++;
  760.     if (previous_lost_packets != lost_packets) {
  761.     DB2((stderr,"lost packets: %ld\7\n",lost_packets));
  762.     previous_lost_packets = lost_packets;
  763.     }
  764. #endif /* UNDEF */
  765.     /*** finish off dead sockets ***/
  766.     if ( s && ( s->tcp.ip_type == TCP_PROTO ) &&
  767.     ( s->tcp.state==tcp_StateCLOSED ) && ( s->tcp.rdatalen==0 )) {
  768.         DB3((FDB,"tcp_tick(): unthreading socket\n"));
  769.         tcp_unthread((tcp_Socket *)s);
  770.         /* s->tcp.ip_type = 0; /* redundant, already in unthread */
  771.     }
  772.  
  773. /*** handle incoming packets ***/
  774.  
  775.     DB2((FDB,"tcp_tick(): testing incoming pkts\n"));
  776.     while ( ip = (in_Header *)_eth_arrived( &packettype ) ) {
  777.     DB2((FDB,"tcp_tick(): arrived pkt type %4x\n",packettype));
  778.     switch ( packettype ) {
  779.     case 0x0008 : /* intel16(IP_TYPE) */
  780.         if ( inchksum((void *)ip, ip->hdrlen <<2) == 0xffff ) {
  781.         DB2((FDB,"checksum is OK\n"));
  782.         if (!my_ip_addr || (intel(ip->destination) == my_ip_addr)
  783. #ifdef LR
  784.             /* 19-dec-91 lr: what do I do with local broadcasts ? */
  785.             || (intel(ip->destination)|(~sin_mask) ==
  786.             my_ip_addr| (~sin_mask) ) /* local broadcast */
  787. #endif /* LR */
  788.             ) {
  789.             DB2((FDB,"This pkt is for me\n"));
  790.             switch ( ip->proto ) {
  791.             case TCP_PROTO :
  792.             DB2((FDB,"received TCP packet\n"));
  793.             tcp_handler(ip);
  794.             break;
  795.             case UDP_PROTO :
  796.             DB2((FDB,"received UDP packet\n"));
  797.             udp_handler(ip);
  798.             break;
  799.             case ICMP_PROTO :
  800.             DB2((FDB,"received ICMP packet\n"));
  801.             icmp_handler(ip);
  802.             break;
  803.             default:
  804.             DB3((stderr,"unknown protocol %d\n",ip->proto));
  805.             break;
  806.             }
  807.         }
  808.         else {
  809.             if (intel(ip->destination)|(~sin_mask) ==
  810.             my_ip_addr| (~sin_mask) ) {
  811.                 /* local broadcast */
  812.                 DB2((FDB, "Received local broadcast\7\n"));
  813.             }
  814.             else {
  815.             word *s;
  816.             s=(word *)_eth_hardware((byte *)ip);
  817.             if (s[0]!=0xFFFF || s[1]!=0xffff || s[2]!=0xffff) {
  818.                 DB4((FDB, "This packet is not for me, and not ether broadcast\7\n"));
  819.             }
  820.             }
  821.         }
  822.         } 
  823.         else  { /* bad checksum */
  824.         DB2((FDB, "IP packet, bad checksum\7\n"));
  825.         }
  826.         break;
  827.     case 0x0608 : /* intel16(ARP_TYPE) */
  828.         DB2((FDB,"received ARP packet\n"));
  829.         (void)_arp_handler((arp_Header *)ip);
  830.         break;
  831.     } /* end switch packettype */
  832.     DB2((FDB,"FREE eth arrived\n"));
  833.     if (ip) _eth_free(ip);
  834.     } /* end while etharrived */
  835.  
  836. /***
  837.  *** now check for outstanding packets
  838.  ***/
  839.  
  840.     tcp_Retransmitter();
  841.     return( s ? s->tcp.ip_type : 0 );
  842. }
  843.  
  844. void
  845. tcp_set_debug_state(int x)
  846. { debug_on = x; }
  847.  
  848. /* returns 1 if connection is established */
  849. int
  850. tcp_established(tcp_Socket *s)
  851. {
  852. DB2((FDB,"tcp_established():\n"));
  853.     return( s->state==tcp_StateESTAB || s->state==tcp_StateESTCL
  854.     || s->state==tcp_StateCLOSWT || s->state==tcp_StateCLOSWTCL );
  855. }
  856.  
  857. static int
  858. udp_write(register udp_Socket *s, byte *datap, int len)
  859. {
  860.     tcp_PseudoHeader ph;
  861.     struct _pkt {
  862.     in_Header  in;
  863.     udp_Header udp;
  864.     int        data;
  865.     } *pkt;
  866.     int *dp;
  867.     register in_Header *inp;
  868.     register udp_Header *udpp;
  869.  
  870.     DB2((FDB,"udp_write():\n"));
  871.     pkt=(struct _pkt *)_eth_formatpacket(&s->hisethaddr[0],/*0x800*/8);
  872.     dp = &pkt->data;
  873.     inp = &pkt->in;
  874.     udpp = &pkt->udp;
  875.  
  876.     /* udp header */
  877.     udpp->srcPort = intel16( s->myport );
  878.     udpp->dstPort = intel16( s->hisport );
  879.     udpp->checksum = 0;
  880.     udpp->length = intel16( UDP_LENGTH + len );
  881.     movmem(datap, dp, len );
  882.  
  883.     /* internet header */
  884.     make_in_hdr(inp, UDP_PROTO, s->hisaddr,
  885.     sizeof(in_Header) + UDP_LENGTH + len );
  886.     DB2((FDB,"udp inp length = %d\n",intel16(inp->length)));
  887.  
  888.     /* compute udp checksum if desired */
  889.     if ( s->sock_mode & UDP_MODE_NOCHK ) {
  890.     udpp->checksum = 0;
  891.     } 
  892.     else {
  893.     ph.src = inp->source;   /* already INTELled */
  894.     ph.dst = inp->destination;
  895.     ph.mbz = 0;
  896.     ph.protocol = UDP_PROTO;        /* udp */
  897.     ph.length = udpp->length;       /* already INTELled */
  898.  
  899.     ph.checksum = inchksum((void *)&pkt->udp, intel16(ph.length));
  900.     udpp->checksum =  ~inchksum((void *)&ph, sizeof(ph));
  901.     }
  902.  
  903.     /* if (_dbugxmit) (*_dbugxmit)(s,inp,udpp); */
  904.     DB2((FDB,"calling _eth_send():\n"));
  905.     gm_udp_write++;
  906.     if(_eth_send( intel16( inp->length ))) {
  907.     gm_udp_sendfailed++; }
  908.     /* eth_send may fail. But this is udp, so who cares. */
  909.     return ( len );
  910. }
  911.  
  912. /*
  913.  * udp_read - read data from buffer, does large buffering
  914.  */
  915. static int
  916. udp_read( register udp_Socket *s, byte *datap, int maxlen)
  917. {
  918.     int x;
  919.  
  920.     DB2((FDB,"udp_read():\n"));
  921.     if (( x = s->rdatalen ) > 0) {
  922.     DB2((FDB,"udp_read():datalen = %d  maxlen = %d\n",x,maxlen));
  923.     gm_udp_read++;
  924.     if ( x > maxlen ) x = maxlen;
  925.     if ( x > 0 ) {
  926.     DB2((FDB,"udp_read():before memcpy\n"));
  927.         memcpy( datap, s->rdata, x );
  928.         if ( s->rdatalen -= x )
  929.     DB2((FDB,"udp_read():before memmove\n"));
  930.         movmem(s->rdata+x ,s->rdata, s->rdatalen);
  931.     }
  932.     }
  933.     return( x );
  934. }
  935.  
  936. void
  937. _udp_cancel( in_Header *ip )
  938. {
  939.     int len;
  940.     udp_Header *up;
  941.     register udp_Socket *s;
  942.  
  943.     DB2((FDB,"_udp_cancel():\n"));
  944.     /* match to a udp socket */
  945.     len = ip->hdrlen << 2;
  946.     up = (udp_Header *)((byte *)ip + len);      /* udp frame pointer */
  947.  
  948.     /* demux to active sockets */
  949.     for ( s = udp_allsocs; s; s = s->next )
  950.     if ( s->hisport != 0 &&
  951.         intel16( up->dstPort ) == s->myport &&
  952.         intel16( up->srcPort ) == s->hisport &&
  953.         intel( ip->source ) == s->hisaddr ) break;
  954.     if ( !s ) {
  955.     /* demux to passive sockets */
  956.     for ( s = udp_allsocs; s; s = s->next )
  957.         if ( s->hisport == 0 && intel16( up->dstPort ) == s->myport ) break;
  958.     }
  959.     if (s) {
  960.     s->rdatalen = -1;
  961.     s->ip_type = 0;
  962.     }
  963. }
  964.  
  965. void
  966. _tcp_cancel(in_Header *ip)
  967. {
  968.     int len;
  969.     register tcp_Socket *s;
  970.     tcp_Header *tp;
  971.  
  972.     DB2((FDB,"_tcp_cancel():\n"));
  973.     len = ip->hdrlen;   /* check work */
  974.  
  975.     tp = (tcp_Header *)((byte *)ip + len);      /* tcp frame pointer */
  976.  
  977.     /* demux to active sockets */
  978.     for ( s = tcp_allsocs; s; s = s->next ) {
  979.     if ( s->hisport!=0 &&
  980.         intel16(tp->dstPort) == s->myport &&
  981.         intel16(tp->srcPort) == s->hisport &&
  982.         intel(ip->source) == s->hisaddr ) break;
  983.     }
  984.     if ( !s ) {
  985.     /* demux to passive sockets */
  986.     for ( s = tcp_allsocs; s; s = s->next )
  987.         if ( s->hisport==0 && intel16(tp->dstPort) == s->myport ) break;
  988.     }
  989.     if (s) { /* tcp_unthread should suffice - 27-Jun-92 lr */
  990.     s->rdatalen = -1;
  991.     s->state=tcp_StateCLOSED;
  992.     s->ip_type=0; /* should be in unthread */
  993.     tcp_unthread(s);
  994.     }
  995. } /* end _tcp_cancel */
  996.  
  997. /***
  998.  *** Can always read, even after my close.
  999.  ***/
  1000. int
  1001. tcp_read(register tcp_Socket *s, byte *datap, int maxlen)
  1002. {
  1003.     int x;
  1004.  
  1005.     DB2((FDB,"tcp_read(): data pending  %d\n",s->rdatalen));
  1006.     if ( s->ip_type != TCP_PROTO ) return(0); /* invalid */
  1007.     if (( x = s->rdatalen) > 0) {
  1008.     if ( x > maxlen ) x = maxlen;
  1009.     if ( x > 0 ) {
  1010.         memcpy( datap, s->rdata, x );
  1011.         if (( s->rdatalen -= x ) > 0 )
  1012.         movmem(s->rdata+x , s->rdata, s->rdatalen );
  1013.         /* s->unhappy = VERY ; */
  1014.         DB2((FDB,"Updating window size in tcp_read\n"));
  1015.         tcp_send(s); /* update window size */
  1016.     }
  1017.     } 
  1018.     else if ( s->state == tcp_StateCLOSWT ) {
  1019.     tcp_close( s );
  1020.     }
  1021.     return( x );
  1022. }
  1023.  
  1024.  
  1025.  
  1026. /***
  1027.  *** Write data to a connection.
  1028.  *** Returns number of bytes written, == 0 when connection is not in
  1029.  *** established state.
  1030.  *** Cannot write after my close or other party's FIN.
  1031.  ***/
  1032. int
  1033. tcp_write(register tcp_Socket *s, byte *dp, int len)
  1034. {
  1035.     int x;
  1036.  
  1037.     DB2((FDB,"tcp_write():\n"));
  1038.     if ( s->ip_type != TCP_PROTO ) return(0); /* invalid */
  1039.     if ( s->state != tcp_StateESTAB && s->state !=tcp_StateCLOSWT ) len = 0;
  1040.     if ( len > (x = s->txbufsize - s->datalen) ) len = x; 
  1041.     if ( len > 0 ) {
  1042.     memcpy(s->data + s->datalen, dp, len );
  1043.  
  1044.     s->datalen += len;
  1045.     if ( s->sock_mode & TCP_MODE_NONAGLE ) {
  1046.         tcp_send( s );
  1047.     } else { /* default mode */
  1048.         /* transmit if first data or reached MTU */
  1049.         /* not true MTU, but better than nothing */
  1050.         if ((s->datalen==len )||( s->datalen > (int)(s->mss)/2)) {
  1051.         tcp_send( s );
  1052.         } else {
  1053.         s->unhappy = YES ; /*send at next tick */
  1054.         }
  1055.     }
  1056.     }
  1057.     return ( len );
  1058. } /* end tcp_write */
  1059.  
  1060.  
  1061. /***
  1062.  *** Send pending data
  1063.  ***/
  1064. static void
  1065. tcp_Flush(tcp_Socket *s)
  1066. {
  1067. DB2((FDB,"tcp_flush():\n"));
  1068.     if ( s->datalen > 0 ) {
  1069.     s->flags |= tcp_FlagPUSH;
  1070.     tcp_send(s);
  1071.     }
  1072. }
  1073.  
  1074. /***
  1075.  *** Handler for incoming udp packets.
  1076.  ***/
  1077. static void
  1078. udp_handler(in_Header *ip)
  1079. {
  1080.     register udp_Header *up;
  1081.     tcp_PseudoHeader ph;
  1082.     word len;
  1083.     byte *dp;
  1084.     register udp_Socket *s;
  1085.  
  1086.     DB2((FDB,"udp_handler():\n"));
  1087.     gm_udp_handler++;
  1088.  
  1089.     len = ip->hdrlen << 2;
  1090.     up = (udp_Header *)((byte *)ip + len);      /* udp segment pointer */
  1091.     len = intel16( up->length );
  1092.     DB2((FDB,"udp handler = %d\n",len));
  1093.     
  1094.     /* demux to active sockets */
  1095.     for ( s = udp_allsocs; s; s = s->next ) {
  1096.     if ( s->safetysig != SAFETYUDP ) {
  1097.         outs("chain error in tcp");
  1098.         exit(3);
  1099.     }
  1100.     if ( s->hisport != 0 &&
  1101.         intel16( up->dstPort ) == s->myport &&
  1102.         intel16( up->srcPort ) == s->hisport &&
  1103.         intel( ip->source ) == s->hisaddr ) break;
  1104.     } /* end for */
  1105.     /* if (_dbugrecv) (*_dbugrecv)(s,ip,up); */
  1106.     if ( !s ) { 
  1107.     /* demux to passive sockets */
  1108.     /*  Note: Passive Sockets have their address = 0 */
  1109.     for ( s = udp_allsocs; s; s = s->next )
  1110.         if ( s->hisaddr == 0 && intel16( up->dstPort ) == s->myport ) {
  1111.         if (_arp_resolve(intel(ip->source), &(s->hisethaddr))) {
  1112.             s->hisaddr = intel( ip->source );
  1113.             s->hisport = intel16( up->srcPort );
  1114.         }
  1115.         break;
  1116.         }
  1117.     }
  1118.     if ( !s ) { 
  1119.     /* demux to broadcast sockets */
  1120.     for ( s = udp_allsocs; s; s = s->next )
  1121.         if ( s->hisaddr == 0xffffffff
  1122.          && intel16( up->dstPort ) == s->myport ) break;
  1123.     }
  1124.  
  1125.     if ( !s ) {
  1126.         /* maybe can send back an ICMP ? */
  1127.     DB2((FDB,"Udp_handler: no session seems to exist \n"));
  1128.     return;
  1129.     }
  1130.  
  1131.     if ( up->checksum ) {
  1132.     DB2((FDB,"Udp_handler: filling the pseudoheader \n"));
  1133.     ph.src = ip->source;    /* already INTELled */
  1134.     ph.dst = ip->destination;
  1135.     ph.mbz = 0;
  1136.     ph.protocol = UDP_PROTO;
  1137.     ph.length = up->length;
  1138.     ph.checksum =  inchksum((void *)up, len);
  1139.     if (inchksum((void *)&ph, sizeof( tcp_PseudoHeader)) != 0xffff)
  1140.         return;
  1141.     }
  1142.  
  1143.     /* process user data */
  1144.     /* Remember: UDP_LENGTH = sizeof(udp_Header) */
  1145.     if ( (len -= UDP_LENGTH ) > 0) {
  1146.     DB2((FDB,"udp handler: data = %d\n",len));
  1147.     DB2((FDB,"Udp_handler: proc. data \n"));
  1148.     dp = (byte *)( up );
  1149.     if (s->dataHandler) s->dataHandler( s, &dp[ UDP_LENGTH ], len , &ph);
  1150.     else {
  1151.         if (len > (word)s->rxbufsize) len = s->rxbufsize; 
  1152.         memmove( s->rdata,&dp[UDP_LENGTH], len );
  1153.         s->rdatalen = len;
  1154.     }
  1155.     }
  1156. }
  1157.  
  1158. static void
  1159. tcp_close_sock(register tcp_Socket *s, char *msg)
  1160. {
  1161.     DB2((FDB,"tcp_close_sock():\n"));
  1162.     s->err_msg= msg;
  1163.     s->state=tcp_StateCLOSED;
  1164.     tcp_unthread(s);
  1165. }
  1166.  
  1167. static void
  1168. recompute_rto(register tcp_Socket *s)
  1169. {
  1170.     long delta;
  1171. #define MAXRTO (18*30) /* 30 sec. rto it's a lot */
  1172.  
  1173.     if(s->vj_last) {
  1174.     if((delta=set_ttimeout(0) - s->vj_last) >=0 ) {
  1175.         /* always enter here apart from midnight case */
  1176.         s->rto = (word)(delta +(9*(s->rto-delta))/10);
  1177.         if(s->rto > MAXRTO) s->rto = MAXRTO;
  1178.         else if (s->rto <=4 ) s->rto = 4;
  1179.     }
  1180.     }
  1181.     DB2((FDB,"recompute_rto(): rto becomes %d\n",s->rto));
  1182. }
  1183.  
  1184. /***
  1185.  *** this makes the tests in RFC793, pg.69, and sends the
  1186.  *** ack if needed.
  1187.  ***/
  1188.  
  1189. static int
  1190. acceptable(tcp_Socket *s, in_Header *ip, tcp_Header *tp)
  1191. {
  1192.     int seglen, good=TRUE;
  1193.     longword seglow, seghigh, winlow, winhigh;
  1194.     word flags = intel16(tp->flags);
  1195.  
  1196.     seglen = intel16( ip->length ) /* IP len including header */
  1197.     - (ip->hdrlen << 2)      /* IP header */
  1198.     - (tcp_GetDataOffset(tp)<<2); /* TCP header */
  1199.  
  1200. /***
  1201.  *** seglow and seghigh are the bounds of the incoming segment,
  1202.  *** winlow and winhigh are the bounds of the receive window
  1203.  ***/
  1204.     seglow= intel(tp->seqnum);
  1205.     seghigh= seglow+seglen + (flags&(tcp_FlagACK|tcp_FlagFIN|tcp_FlagSYN) ? 1 : 0);
  1206.     winlow= s->acknum;
  1207.     winhigh= winlow + s->rxbufsize - s->rdatalen;
  1208.     if (winlow==winhigh) winhigh++; /* always room for a Flag */
  1209.     if ( seghigh<=winlow || winhigh <= seglow ) good=FALSE;
  1210.     if (!good) {
  1211.     DB2((FDB,
  1212.         "acceptable(): state %s accept %s: seglen= %d seg: %8lx %8lx, win: %8lx %8lx\n",
  1213.         state_names[s->state], good ? "T":"F",seglen,seglow,seghigh,winlow,winhigh));
  1214.     DB2((FDB,"    send win: %8lx %8lx, tp->ack=%8lx\7\n",
  1215.         s->seqnum,s->seqnum+s->unacked+
  1216.         (s->flags &(tcp_FlagSYN|tcp_FlagFIN)? 1:0),intel(tp->acknum)));
  1217.     /* should send an ack, unless RST is present */
  1218.     if (! (intel16(tp->flags) & tcp_FlagRST) ) {
  1219.         s->flags=tcp_FlagACK;
  1220.         s->unhappy=YES ;
  1221.     }
  1222.     }
  1223.     /* else trim packet if needed */
  1224.     return(good);
  1225. }
  1226.  
  1227.  
  1228. static void
  1229. set_UP(int flags, tcp_Socket *s, tcp_Header *tp)
  1230. {
  1231. DB2((FDB,"set_UP():\n"));
  1232.     if( (flags & tcp_FlagURG) && (s->state== tcp_StateESTAB) ) {
  1233.     s->UP= (s->UP >= intel16(tp->urgentPointer)) ?
  1234.         s->UP : intel16(tp->urgentPointer);
  1235.     }
  1236. }
  1237.  
  1238. static void
  1239. tcp_handler1(register tcp_Socket *s,in_Header *ip,
  1240.     tcp_Header *tp,word flags,int len /* tcp hdr+data */)
  1241. {
  1242.     int acked;          /* counters for acked bytes */
  1243.     long lacked;
  1244.  
  1245.     DB2((FDB,"tcp_handler1(): %d bytes (tcp hdr+data)\n",len));
  1246.     switch(s->state) {  /* break or return is the same */
  1247.     default: /* just to be sure not to forget... */
  1248.     DB3((FDB,"Warning: received a segment in state %s\n",state_names[s->state]));
  1249.     return;
  1250. /***
  1251.  *** these states should be:
  1252.  ***    CLOSING LASTACK TIMEWT  CLOSEMSL        CLOSED
  1253.  ***/
  1254.  
  1255.     case tcp_StateLISTEN:
  1256.     DB2((FDB,"State = LISTEN \n")); DB_W("LI ");
  1257.  
  1258. /***
  1259.  *** I know nothing about sequence numbers here.
  1260.  *** First check for an RST: incoming RST are ignored
  1261.  ***/
  1262.  
  1263.     if (flags & tcp_FlagRST) {
  1264.         DB2((FDB,"ignoring incoming RST\n"));
  1265.         return; /* ignore */
  1266.     }
  1267. /***
  1268.  *** Second check for an ack. Any ACK is bad here, an acceptable
  1269.  *** RST segment should be formed with:
  1270.  ***    s->seqnum= intel(tp->acknum);
  1271.  ***    s->flags= tcp_FlagRST;
  1272.  *** Send it and return.
  1273.  ***/
  1274.  
  1275.     if (flags & tcp_FlagACK) {
  1276.         DB2((FDB,"reply RST to incoming ACK\n"));
  1277.         tcp_rst(ip,tp);
  1278.     }
  1279.  
  1280. /***
  1281.  *** Third, check for a SYN. If set, check security. If ok, set
  1282.  ***    s->acknum= intel(tp->seqnum)+1;
  1283.  ***    s->flags= tcp_FlagSYN | tcp_FlagACK;
  1284.  *** and send the segment, changing state to SYNRECLIS.
  1285.  ***/
  1286.  
  1287.     if (flags & tcp_FlagSYN) {
  1288.         DB2((FDB,"good SYN, goto SYNRECLIS\n"));
  1289.         s->acknum= intel(tp->seqnum)+1;
  1290.         s->hisport = intel16(tp->srcPort);
  1291.         s->hisaddr = intel(ip->source);
  1292.         s->window = intel16( tp->window ); /* set new send window size */
  1293.         DB2((FDB,"LISTEN: window = %d \n",s->window));
  1294.         tcp_ProcessData(s,tp,len); /* for options */
  1295.         s->flags= tcp_FlagSYN | tcp_FlagACK;
  1296.         s->state=tcp_StateSYNRECLIS;
  1297.         DB2((FDB,"Sending SYN+ACK to incoming SYN, going to SYNRECLIS\n"));
  1298.         tcp_send(s); /* send right away, no data */
  1299.         s->timeout=set_ttimeout(tcpAbortTimeout);
  1300.         return;
  1301.     } 
  1302. /***
  1303.  *** Should never arrive here, in any case drop the segment
  1304.  *** and return.
  1305.  ***/
  1306.     DB3((FDB,"LISTEN: don't know what to do with a segment\n"));
  1307.     return;
  1308.  
  1309.     case tcp_StateSYNSENT:
  1310.     DB2((FDB,"State = SYNSENT \n")); DB_W("SYs ");
  1311. /***
  1312.  *** First, check the ACK bit. If set, but not for our SYN,
  1313.  *** and is not a RST (discard it) send RST with
  1314.  ***    s->seqnum= intel(tp->acknum);
  1315.  ***    s->flags= tcp_FlagRST;
  1316.  *** discard the segment and return.
  1317.  ***/
  1318.  
  1319.     if (flags & tcp_FlagACK) {
  1320.         if (intel(tp->acknum) != s->seqnum +1) { 
  1321.         DB2((FDB,"bad ACK\n"));
  1322.         if (!(flags & tcp_FlagRST)) { 
  1323.             tcp_rst(ip,tp);
  1324.         }
  1325.         return;
  1326.         }
  1327.         /*** else, my fin has been acked, but it's easier
  1328.          *** to check it later.
  1329.          ***/
  1330.     }
  1331.     DB2((FDB,"good ACK for a SYNSENT\n"));
  1332.  
  1333. /***
  1334.  *** Second, check RST bit. If set, and the ACK was acceptable,
  1335.  *** signal "error: connection reset", drop the segment and enter
  1336.  *** the CLOSED state. Otherwise drop the segment and return.
  1337.  ***
  1338.  *** NOTE: apparently, NCSA Telnet sends a RST without ACK. Thus,
  1339.  *** I do not check the ACK here. This is a deviation from standard.
  1340.  ***/
  1341.  
  1342.     if (flags & tcp_FlagRST) {
  1343.         DB3((FDB,"whoops, received RST in state %s\n",state_names[s->state]));
  1344.         /* if (flags & tcp_FlagACK) */
  1345.         tcp_close_sock(s,"error: connection reset");
  1346.         return;
  1347.     }                       
  1348.  
  1349. /***
  1350.  *** At this point have a good segment (maybe with an ACK).
  1351.  *** Third check security.
  1352.  *** Fourth, check the SYN bit. If set, then
  1353.  ***    s->acknum= intel(tp->seqnum)+1;
  1354.  *** If our SYN has been acked, go to state ESTAB, and send an ack
  1355.  *** else goto state SYNREC and send SYN,ACK (the SYN is the old one).
  1356.  ***/
  1357.  
  1358.     if (flags & tcp_FlagSYN) {
  1359.         DB2((FDB,"good SYN in SYNSENT\n"));
  1360.         s->flags=tcp_FlagACK; /* ack remote SYN */
  1361.         s->window = intel16( tp->window ); /* set new send window size */
  1362.         DB2((FDB,"SYNSENT: window = %d\n",s->window));
  1363.         s->acknum=intel(tp->seqnum) +1; 
  1364.         if (flags & tcp_FlagACK) {
  1365.         /* seqnum have already been checked */
  1366.         s->seqnum++; /* my SYN has been acked */
  1367.         s->state=tcp_StateESTAB;
  1368.         s->timeout=0; /* no more timeout */
  1369.         s->unhappy = YES; /* is it needed */
  1370.         DB2((FDB,"going from SYNSENT to ESTAB\n"));
  1371.         goto ESTAB_6;
  1372.         } 
  1373.         else {
  1374.         /* maybe there are options, should process them */
  1375.         s->flags = tcp_FlagSYN | tcp_FlagACK;
  1376.         s->state=tcp_StateSYNREC;
  1377.         DB2((FDB,"going from SYNSENT to SYNREC\n"));
  1378.         tcp_send(s);
  1379.         s->timeout=set_ttimeout(tcp_TTIMEOUT); /* why ?? */
  1380.         return;
  1381.         }
  1382.     } 
  1383.  
  1384. /***
  1385.  *** Fifth, if neither SYN or RST, drop the segment and return
  1386.  ***/
  1387.     return;
  1388.  
  1389.     case tcp_StateSYNREC:
  1390.     DB2((FDB,"State = SYNREC\n")); DB_W("SYr ");
  1391.     goto ESTAB_1;
  1392.     case tcp_StateSYNRECLIS:
  1393.     DB2((FDB,"State = SYNRECLIS\n")); DB_W("SYl ");
  1394.     goto ESTAB_1;
  1395.     case tcp_StateESTAB:
  1396.     DB2((FDB,"State = ESTAB\n")); DB_W("ES ");
  1397.     goto ESTAB_1;
  1398.     case tcp_StateESTCL:
  1399.     DB2((FDB,"State = ESTCL\n")); DB_W("EC ");
  1400.     goto ESTAB_1;
  1401.     case tcp_StateCLOSWT:
  1402.     DB2((FDB,"State = CLOSWT\n")); DB_W("CW ");
  1403.     goto ESTAB_1;
  1404.     case tcp_StateCLOSWTCL:
  1405.     DB2((FDB,"State = CLOSWTCL\n")); DB_W("CWc ");
  1406.     goto ESTAB_1;
  1407.     case tcp_StateFINWT1:
  1408.     DB2((FDB,"State = FINWT1\n")); DB_W("FW1 ");
  1409.     goto ESTAB_1;
  1410.     case tcp_StateFINWT2:
  1411.     DB2((FDB,"State = FINWT2\n")); DB_W("FW2 ");
  1412.     goto ESTAB_1;
  1413.     case tcp_StateLASTACK:
  1414.     DB2((FDB,"State = LASTACK\n")); DB_W("LAk ");
  1415.     goto ESTAB_1;
  1416.     case tcp_StateTIMEWT:
  1417.     DB2((FDB,"State = TIMEWT\n")); DB_W("LAk ");
  1418.     goto ESTAB_1;
  1419.  
  1420. /***
  1421.  *** The folloging states are 'connected' states:
  1422.  ***    SYNREC  SYNRECLIS
  1423.  ***    ESTAB   ESTCL
  1424.  ***    FINWT1  FINWT2
  1425.  ***    CLOSWT
  1426.  ***    LASTACK
  1427.  ***    TIMEWT
  1428.  *** There is some common processing here.
  1429.  ***/
  1430.  
  1431. ESTAB_1:
  1432.  
  1433. /***
  1434.  *** First an acceptability test to see if any part of the incoming
  1435.  *** segment falls inside the current receive window. If not,
  1436.  *** RST are ignored, other segments are acked with
  1437.  ***    s->flags= tcp_FlagACK;
  1438.  *** and other fields as from the socket descriptor.
  1439.  ***/
  1440.  
  1441.     if (!acceptable(s,ip,tp)) return;
  1442.  
  1443. /***
  1444.  *** Second, check the RST bit. Here processing differs:
  1445.  ***/
  1446.  
  1447.     if (flags & tcp_FlagRST) { /* valid RST */
  1448.         DB3((FDB,"oops.. found RST\n"));
  1449.         switch(s->state) {
  1450.         case tcp_StateSYNREC:
  1451.         tcp_close_sock(s, "Connection refused");
  1452.         return;
  1453.         case tcp_StateSYNRECLIS:
  1454.         s->state=tcp_StateLISTEN;
  1455.         DB2((FDB,"going from SYNRECLIS to LISTEN\n"));
  1456.         s->timeout=0; /* ouch...where's the original timeout! */
  1457.         return;
  1458.         case tcp_StateESTAB:
  1459.         case tcp_StateESTCL:
  1460.         case tcp_StateFINWT1:
  1461.         case tcp_StateFINWT2:
  1462.         case tcp_StateCLOSWT:
  1463.         case tcp_StateCLOSWTCL:
  1464.         tcp_close_sock(s, "Connection reset");
  1465.         return;
  1466.         case tcp_StateCLOSING:
  1467.         case tcp_StateLASTACK:
  1468.         case tcp_StateTIMEWT:
  1469.         tcp_close_sock(s,"");
  1470.         return;
  1471. /***
  1472.  *** CLOSEMSL and CLOSED are missing
  1473.  ***/
  1474.         } /* end switch */
  1475.         return; /*** of course ***/
  1476.     } /* end if, no RST found */
  1477.  
  1478. /***
  1479.  *** Third, check security.
  1480.  *** Fourth, check the SYN bit: a SYN within the window is an error,
  1481.  *** so send a reset and signal "connection reset".
  1482.  ***/
  1483.     if (flags & tcp_FlagSYN) {
  1484.         DB3((FDB,"oops.. found SYN\n"));
  1485.         tcp_rst(ip,tp);
  1486.         tcp_close_sock(s, "Connection reset");
  1487.         return;
  1488.     }
  1489.  
  1490. /***
  1491.  *** Fifth, check the ACK field. If off, drop segment and return.
  1492.  *** otherwise, processing differs.
  1493.  ***/
  1494.  
  1495.     if (!(flags & tcp_FlagACK)) {
  1496.         DB3((FDB,"oops.. missing ACK\n"));
  1497.         return; /* ack is off */
  1498.     }
  1499.     
  1500.     lacked= intel(tp->acknum) - s->seqnum;
  1501.     acked = (int)lacked;
  1502.     
  1503.     switch(s->state) {
  1504.     case tcp_StateSYNREC:
  1505.     case tcp_StateSYNRECLIS:
  1506. /***
  1507.  *** if the ack is acceptable, goto ESTAB and continue processing.
  1508.  *** otherwise form a RST segment
  1509.  ***    s->seqnum= intel(tp->acknum);
  1510.  ***    s->flags= tcp_FlagRST;
  1511.  *** and send it. I think we can return.
  1512.  ***/
  1513.         if (lacked==1) {
  1514.         s->seqnum++; /* accept it */
  1515.         s->window=intel16(tp->window);
  1516.         s->flags= tcp_FlagACK;
  1517.         DB2((FDB,"Setting ACK in SYNREC\n"));
  1518.         s->unhappy=VERY;
  1519.         DB2((FDB,"Setting VERY in SYNREC\n"));
  1520.         s->state=tcp_StateESTAB;
  1521.         s->timeout=0;
  1522.         DB2((FDB,"Received ACK for SYN in SYNRECLIS- going to ESTAB\n"));
  1523.         goto ESTAB_6;
  1524.         }
  1525.         else {
  1526.         DB3((FDB,"Warning: ack for unsent data/flags\n"));
  1527.         tcp_rst(ip,tp);
  1528.         return;
  1529.         }
  1530.  
  1531.     case tcp_StateESTAB:
  1532.     case tcp_StateESTCL:
  1533.     case tcp_StateCLOSWT:
  1534.     case tcp_StateCLOSWTCL:
  1535. /***
  1536.  *** If ack is valid, remove data from the retransmission queue.
  1537.  *** The send window should be updated.
  1538.  *** Duplicate acks are ignored, invalid acks are acked,
  1539.  *** then drop segment and return.
  1540.  *** An ack also has a new remote window. If it grows,
  1541.  *** we try to send our data becoming VERY unhappy.
  1542.  ***/
  1543.  
  1544.         if ( lacked <= 0 ) {
  1545.         if (lacked==0) {
  1546. /***
  1547.  *** maybe a window re-opening. Or the other party wants to send
  1548.  *** something.
  1549.  ***/
  1550.             int oldwindow;
  1551.             oldwindow = (int)s->window;
  1552.             s->window = intel16( tp->window );
  1553. /***
  1554.  *** DOUBLE CHECK THIS !!!
  1555.  ***/
  1556.             if ( (oldwindow < 1 ) &&
  1557.             ( s->window > (word)s->unacked) &&
  1558.             ( s->window > (word)oldwindow ) ) {
  1559.                s->unhappy= VERY; 
  1560.                DB2((FDB,"Window reopening lacked == 0\n"));
  1561.             }
  1562.         }
  1563.         else {
  1564.             DB2((FDB,"duplicate ack, ignore\n"));
  1565.         }
  1566.         }
  1567.         else {
  1568.         if (lacked <= (long)s-> unacked) {
  1569.             int oldwindow;
  1570.             DB2((FDB,"valid ack\n"));
  1571.             oldwindow = (int)s->window;
  1572.             s->window = intel16( tp->window );
  1573.             DB2((FDB,"State %d: window = %d \n",s->state,s->window));
  1574.             s->datalen -= acked;
  1575.             s->unacked -= acked;
  1576.  
  1577.             s->seqnum += lacked;
  1578.             recompute_rto(s);
  1579.             if (s->datalen) {
  1580.             memmove(s->data,s->data+acked,s->datalen);
  1581.             if (( s->window > (word)s->unacked) &&
  1582.               (s->window>(word)oldwindow)) { /* window reopening */
  1583.                s->unhappy=VERY;
  1584.                DB2((FDB,"Setting VERY in State %d\n",s->state));
  1585.             }
  1586.             }
  1587.             else { /* no more data pending */
  1588.             s->unhappy=NO; /* as far as I know... */
  1589.             s->vj_last=0;
  1590.             s->rtt_time=0; /* and remove timeout. */
  1591.  
  1592. /***
  1593.  *** If I had a CLOSE pending, send a FIN. Must call tcp_send()
  1594.  *** directly because after that I'll be in the new state.
  1595.  ***/
  1596.             if (s->state== tcp_StateESTCL
  1597.                 || s->state==tcp_StateCLOSWTCL) {
  1598.                 s->flags= tcp_FlagFIN | tcp_FlagACK;
  1599.                 tcp_send(s); /* here or later ? */
  1600.                 DB2((FDB,"going from %s",state_names[s->state]));
  1601.                 s->state= s->state== tcp_StateESTCL ?
  1602.                 tcp_StateFINWT1:tcp_StateLASTACK;
  1603.                 DB2((FDB,"to %s\n",state_names[s->state]));
  1604.             }
  1605.             }
  1606.         } else {
  1607.             DB3((FDB,"invalid ack - drop segment\n"));
  1608.             s->flags=tcp_FlagACK;
  1609.             s->unhappy = YES ;
  1610.             return;
  1611.         }
  1612.         }
  1613.         break;
  1614. /***
  1615.  *** FINWT1, FINWT2, CLOSING have a similar processing, plus
  1616.  *** something. Checks are simpler, though, because have at
  1617.  *** most one FIN still unacked.
  1618.  ***
  1619.  *** For FINWT1, if FIN is acked, enter FINWT2 and continue
  1620.  *** processing from there.
  1621.  ***
  1622.  *** For FINWT2, if the retransmission queue is empty, the
  1623.  *** user's CLOSE can be acknowledged but the TCB cannot be
  1624.  *** deleted. Note that I choose to empty out the retran.queue
  1625.  *** before sending my FIN.
  1626.  ***
  1627.  *** For CLOSING, if the ACK is for our FIN then enter TIMEWAIT,
  1628.  *** otherwise ignore the segment.
  1629.  ***/
  1630.     case tcp_StateCLOSING: /***/
  1631.     case tcp_StateFINWT1: /***/
  1632.         if (lacked<=0) break; /* old ack, ignore */
  1633.         if (lacked!=1) return; /* unvalid ack, drop segment */
  1634.         s->seqnum++; /* ack my fin */
  1635.         s->flags= tcp_FlagACK;
  1636.         s->rtt_time=0; /* no more timeout */
  1637.         if (s->state==tcp_StateFINWT1) {
  1638.         DB2((FDB,"going from FINWT1 to FINWT2\n"));
  1639.         s->state=tcp_StateFINWT2;
  1640.         goto FINWT_2;
  1641.         }
  1642.         else {
  1643.         DB2((FDB,"going from CLOSING to TIMEWT\n"));
  1644.         s->state=tcp_StateTIMEWT;
  1645.         s->timeout=set_ttimeout(100); /* 2MSL */
  1646.         }
  1647.         break;
  1648.     case tcp_StateFINWT2: /***/
  1649.         if (lacked != 0) return; /* unvalid ack, drop */
  1650.         break;
  1651.     case tcp_StateLASTACK:
  1652. /***
  1653.  *** The only thing can arrive is an ack to our FIN. if it is it,
  1654.  *** delete TCB, enter CLOSED state and return.
  1655.  ***/
  1656.         if (lacked==1) {
  1657.         tcp_close_sock(s,"");
  1658.         }
  1659.         return;
  1660.     case tcp_StateTIMEWT:
  1661. /***
  1662.  *** The only thing can arrive is a retransmission of the remote FIN.
  1663.  *** Acknowledge it and restart the 2MSL timeout.
  1664.  *** To be completed.
  1665.  ***/
  1666.         break;
  1667.     } /* end switch */
  1668.  
  1669. ESTAB_6:
  1670.  
  1671.     DB2((FDB,"we are in ESTAB_6:\n"));
  1672. /***
  1673.  *** Sixth, check the urgent bit:...
  1674.  ***/
  1675.     /* set_UP(s->flags,ip,tp); */
  1676. /***
  1677.  *** Seventh, process the segment text.
  1678.  ***/
  1679.     if (len>sizeof(tcp_Header)) { /* have data or options */
  1680.         switch(s->state) {
  1681.         case tcp_StateESTAB:
  1682.         case tcp_StateESTCL:
  1683.         case tcp_StateFINWT1:
  1684.         case tcp_StateFINWT2:
  1685. /***
  1686.  *** Text segments can be delivered to user space. I'll ignore
  1687.  *** PUSH requests here. If there are too many data, ProcessData
  1688.  *** returns 0 so that the subsequent FIN is not processed.
  1689.  ***/
  1690. FINWT_2:
  1691.         if (!tcp_ProcessData(s,tp,len)) return;
  1692.         break;
  1693.         default:
  1694. /***
  1695.  *** data shouldn't arrive. Ignore them.
  1696.  ***/
  1697.         DB3((FDB,"Unexpected data in state %s\n",state_names[s->state]));
  1698.         break;
  1699.         } /* end switch */
  1700.     }
  1701. /***
  1702.  *** Eight: check the FIN bit. Do not process FIN in CLOSED,
  1703.  *** LISTEN or SYN_SENT because it cannot be validated (drop
  1704.  *** the segment and return in these cases).
  1705.  *** If FIN is set, signal "connection closing" to any
  1706.  *** pending receive. Advance s->acknum over FIN and ack the FIN.
  1707.  *** FIN implies PUSH for any text not yet delivered to the user.
  1708.  *** Then...
  1709.  *** SYNREC, SYNRECLIS, ESTAB: enter CLOSEWAIT
  1710.  *** FINWT1: if our fin has been acked, so enter TIMEWT, start the
  1711.  *** timewait timer and turn off the other timers. otherwise enter
  1712.  *** the CLOSING state.
  1713.  *** FINWT2: as FINWT1 (and assume FIN has been acked).
  1714.  *** TIMEWAIT: restart the 2MSL timeout.
  1715.  *** other cases, remain in the same state.
  1716.  ***/
  1717.     if (flags & tcp_FlagFIN) {
  1718.         DB2((FDB,"FIN arrived\n"));
  1719.         s->err_msg="Connection closing";
  1720.         switch(s->state) {
  1721.         case tcp_StateESTAB:
  1722.         case tcp_StateSYNREC:
  1723.         case tcp_StateSYNRECLIS:
  1724.         s->acknum++;
  1725.         DB2((FDB,"fin arrived, going from state %s to CLOSWT\n",state_names[s->state]));
  1726.         s->state=tcp_StateCLOSWT;
  1727.         s->timeout= set_ttimeout(100); /* here they should close soon */
  1728.         break;
  1729.         case tcp_StateESTCL:
  1730. /***
  1731.  *** Here, I don't know what to do yet. Ignore the segment until
  1732.  *** all data have been flushed (i.e. we have reached FINWT1).
  1733.  ***/
  1734.         DB3((FDB,"Received CLOSE in ESTCL. Check this.\7\n"));
  1735.         return;
  1736. #ifdef notdef
  1737.         s->acknum++;
  1738.         DB2((FDB,"going from ESTCL to CLOSING\n"));
  1739.         s->state=tcp_StateCLOSING; /* or somewhere else ??? */
  1740.         break;
  1741. #endif /* notdef */
  1742.         case tcp_StateFINWT1:
  1743.         s->acknum++;
  1744.         if (flags & tcp_FlagACK) {
  1745.             DB2((FDB,"going from FINWT1 to TIMEWT\n"));
  1746.             s->state=tcp_StateTIMEWT;
  1747.             s->timeout=set_ttimeout(100);
  1748.         } else {
  1749.             DB2((FDB,"going from FINWT1 to CLOSING\n"));
  1750.             s->state=tcp_StateCLOSING;
  1751.         }
  1752.         break;
  1753.         case tcp_StateFINWT2:
  1754.         s->acknum++;
  1755.         DB2((FDB,"going from FINWT2 to TIMEWT\n"));
  1756.         s->state=tcp_StateTIMEWT;
  1757.         s->timeout=set_ttimeout(100);
  1758.         break;
  1759.         default:
  1760.         DB3((FDB,"Don't want FIN in state %s\n",state_names[ s->state]));
  1761.         return;
  1762.         }
  1763.         DB2((FDB,"Sent ACK\n"));
  1764.         s->flags=tcp_FlagACK;
  1765.         tcp_send(s); /* ack the FIN */
  1766.     }
  1767.     } /* end main switch */
  1768. } /* end tcp_handler1 */
  1769.  
  1770.  
  1771. static void
  1772. tcp_handler(in_Header *ip)
  1773. {
  1774.     tcp_Header *tp;
  1775.     tcp_PseudoHeader ph;
  1776.     int i, len, found = 0;
  1777.     register tcp_Socket *s, *ps;
  1778.     word flags;
  1779.  
  1780. DB2((FDB,"tcp_handler():\n"));
  1781.     gm_tcp_handler++;
  1782.     DB_W("h ");
  1783.     len = ip->hdrlen << 2;
  1784.     tp = (tcp_Header *)((byte *)ip + len);      /* tcp frame pointer */
  1785.     len = intel16( ip->length ) - len;          /* tcp data including TCP hdr*/
  1786.     flags = intel16( tp->flags );               /* this saves time later */
  1787.     DB2((FDB,"entering tcp_handler: %d bytes (tcp hdr+data)\n",len));
  1788.  
  1789.             /* demux to active sockets */
  1790.     for ( s = tcp_allsocs; s; s = s->next ) {
  1791.     if ( s->safetysig != SAFETYTCP ) {
  1792.         outs("chain error in tcp");
  1793.         exit(3);
  1794.         }
  1795.     if ( s->hisport != 0 &&
  1796.         intel16( tp->dstPort ) == s->myport &&
  1797.         intel16( tp->srcPort ) == s->hisport &&
  1798.         intel( ip->source ) == s->hisaddr ) break;
  1799.         } /* end for */
  1800.  
  1801.          /* demux to passive sockets, must be a new session */
  1802.  
  1803.     if ( !s && (flags & tcp_FlagSYN)) {
  1804. #ifdef unused /* because there is no multi_listen() */
  1805.     /* first look at those sockets created with multi_listen */
  1806.     for( ps = tcp_allsocs ; ps ; ps = ps->next ){
  1807.         if( ps->father) break;
  1808.     }
  1809.     if(ps){
  1810.         ps = (ps->father)->next;
  1811.         s = ps;
  1812.         for(;;){
  1813.         if ((s->hisport==0)&&(intel16(tp->dstPort)==s->myport)){
  1814.             found = 1;
  1815.             break;
  1816.         }
  1817.         if ( (s = s->brother) == ps ) break;
  1818.         }
  1819.     }
  1820. #endif /* unused */
  1821.     if(!found){
  1822.         /* then look at those socket created with listen */
  1823.         for( i=0 ; i<MAXSOCK ; i++ ){
  1824.         ps = (tcp_Socket *)sockarr[i].sockp;
  1825.         if( ps && ps->brother ){
  1826.              s = ps;
  1827.             for(;;){    
  1828.                 if ((s->hisport==0)&&(intel16(tp->dstPort)==s->myport)){
  1829.                      found = 1;
  1830.                 break;
  1831.             }
  1832.             if( (s = s->brother) == ps ) break;
  1833.             }
  1834.         }
  1835.         if(found) break;
  1836.         }
  1837.     }
  1838.  
  1839.     if(!found){
  1840.         /* at the end look all the sockets */
  1841.         for ( s = tcp_allsocs; s; s = s->next )
  1842.         if ((s->hisport==0)&&(intel16(tp->dstPort)==s->myport))
  1843.             break;
  1844.     }
  1845.     }
  1846.     if ( !s ) { /* no session seems to exist */
  1847.     tcp_rst( ip, tp ); 
  1848.     return;
  1849.     }
  1850.  
  1851.     if ( sock_inactive ) s->inactive_to = set_timeout( sock_inactive );
  1852.  
  1853.     /* save his ethernet address */
  1854.     memcpy( &s->hisethaddr[0], &((((eth_Header *)ip) - 1)->source[0]),
  1855.         sizeof(eth_address));
  1856.  
  1857.     /*** test checksum ***/
  1858.     ph.src = ip->source;        /* already INTELled */
  1859.     ph.dst = ip->destination;
  1860.     ph.mbz = 0;
  1861.     ph.protocol = TCP_PROTO;
  1862.     ph.length = intel16( len );
  1863.     ph.checksum =  inchksum((void *)tp, len);
  1864.     if ( inchksum((void *)&ph, sizeof(ph)) != 0xffff ) {
  1865.     DB3((FDB,"bad checksum! in tcp_handler\n"));
  1866.     return;
  1867.     }
  1868.     tcp_handler1(s,ip,tp,flags,len);
  1869.     return;
  1870. }
  1871.  
  1872. /***
  1873.  *** Process the data in an incoming packet.
  1874.  *** Called from all states where incoming data can be received:
  1875.  *** ESTAB, ESTCL, FINWT1, FINWT2
  1876.  ***/
  1877. static int
  1878. tcp_ProcessData(register tcp_Socket *s, tcp_Header *tp, int len)
  1879. {
  1880.     int result=TRUE;
  1881.     long lacked;
  1882.     int acked, x;
  1883.     word flags;
  1884.     byte *dp;
  1885.  
  1886.  
  1887.     DB2((FDB,"Enter tcp_ProcessData for %d bytes\n", len));
  1888.     gm_tcp_ProcessData++;
  1889.  
  1890.     flags = intel16( tp->flags );
  1891.     lacked = s->acknum - intel( tp->seqnum );
  1892. /***
  1893.  *** s->acknum is the last ack I sent. If all the data have arrived,
  1894.  *** this is also the seqnum of the first byte of the incoming segment,
  1895.  *** thus lacked==0. If the segment is an old copy, tp->seqnum is lower,
  1896.  *** thus lacked>0 (still it might have some good data).
  1897.  *** If I have lost some data, lacked<0 (this I cannot accept).
  1898.  *** Also, if the segment carries a SYN, it is considered the
  1899.  *** first item, so I have to decrease lacked (the first actual data
  1900.  *** byte is at tp->seqnum+1).
  1901.  ***/
  1902.     if ( flags & tcp_FlagSYN ) lacked--;  /* back up to 0 */
  1903.     acked = (int) lacked; /* shorthand */
  1904.  
  1905.     /*** find the data portion ***/
  1906.     x = tcp_GetDataOffset(tp) << 2;     /* quadword to byte format */
  1907.     dp = (byte *)tp + x;        /* pointer to data */
  1908.  
  1909.     /*** check for options (i.e. a longer header) ***/
  1910.     if ( x > sizeof( tcp_Header )) {
  1911.     byte *op;
  1912.     gm_proc_option++;
  1913.     op = (byte *)(tp) + sizeof(tcp_Header);
  1914.     DB2((FDB,"have %d bytes of options\n",x-sizeof(tcp_Header)));
  1915.     while ( op < dp ) {
  1916.         gm_proc_opt_in++;
  1917.         switch ( *op ) {
  1918.         case  0 : /*** end of options ***/
  1919.         op = dp;
  1920.         break;
  1921.         case  1 : /*** nop ***/
  1922.         op++;
  1923.         break;
  1924.         case  2 : /*** we are very liberal on MSS stuff */
  1925.         op++; /* pointer to option len */
  1926.         if (*op == 4) {
  1927.             word tmp= intel16( *( (word*)(op+1) ) );
  1928.             DB2((stderr,"old mss=%d new mss=%d\n",s->mss, tmp));
  1929.             if (tmp < _mss ) s->mss = tmp;
  1930.         }
  1931.         op += *op - 1;
  1932.         break;
  1933.         default:
  1934.         DB3((stderr,"Warning, unrecognized tcp option %x\n",*op));
  1935.         op=dp;
  1936.         break;
  1937.         }
  1938.     } /* end while */
  1939.     } /* done option processing */
  1940.  
  1941.     len -= x;           /* remove the header length */
  1942.     if ( lacked >= 0 && len>0 ) { /* new data (good ones) */
  1943.     dp += acked; /* skip already received bytes */
  1944.     len -= acked; /* now might be len <= 0 */
  1945.     DB2((FDB,"have %d bytes of new data\n", len));
  1946.  
  1947.     if (s->dataHandler) {
  1948.         int tmp= s->dataHandler(s, dp, len);
  1949.         s->acknum += tmp;
  1950.         result = (tmp==len);
  1951.     } 
  1952.     else {
  1953.         /* no handler, just dump to buffer */
  1954.         /* limit receive size to our window */
  1955.         if ( s->rdatalen >= 0 ) { /* fails only after a cancel */
  1956.         if ( len > ( x = s->rxbufsize - s->rdatalen )) {
  1957.             len = x;
  1958.             result=FALSE;
  1959.             DB3((FDB,"Warning, can't take all the new data\n"));
  1960.         }
  1961.         if ( len > 0 ) {
  1962. /***
  1963.  *** This might fail if the first SYN carries data...
  1964.  ***/
  1965.             s->acknum += len;   /* our new ack begins at end of data */
  1966.             memcpy(s->rdata+s->rdatalen ,dp, len );
  1967.             s->rdatalen += len;
  1968. /***
  1969.  *** Want to send an ack. The strategy to be used may vary.
  1970.  *** Either send it right away, or wait for the input buffer to
  1971.  *** be sufficiently full.
  1972.  ***/
  1973.             s->unhappy |= s->rdatalen < s->rxbufsize/2 ? YES:VERY;
  1974.             DB2((FDB,"Setting VERY in ProcessData\n"));
  1975.         }
  1976.         }
  1977.     }
  1978.     if (s->timeout) s->timeout=set_ttimeout( tcp_TTIMEOUT ); /* check this ??? */
  1979.     }
  1980.     else { /* else no data in this packet */
  1981.     DB2((FDB,"have no new data\n"));
  1982.     }
  1983.     return(result);
  1984. } /* end tcp_ProcessData */
  1985.  
  1986. /*
  1987.  * Format and send an outgoing segment
  1988.  */
  1989. static void
  1990. tcp_send(register tcp_Socket *s)
  1991. {
  1992.     tcp_PseudoHeader ph;
  1993.     struct _pkt {
  1994.     in_Header in;
  1995.     tcp_Header tcp;
  1996.     word maxsegopt[2];
  1997.     } *pkt;
  1998.     byte *dp;
  1999.     in_Header *inp;
  2000.     tcp_Header *tcpp;
  2001.     word senddatalen,
  2002.     sendpktlen,
  2003.     maxsend,    /* max offset of data to be sent */
  2004.     sentdata;   /* # of bytes actually sent */
  2005.  
  2006.     register char *r; /* used as a pointer, for efficiency */
  2007.  
  2008.     DB2((FDB,"tcp_send():\n"));
  2009.     gm_tcp_send++;
  2010.     s->unhappy=FALSE; /* clear it */
  2011.     pkt = (struct _pkt *)_eth_formatpacket(&s->hisethaddr[0], 8 /*IP */);
  2012.     dp = (byte *)&pkt->maxsegopt;       /* dp points to data */
  2013.     inp = &pkt->in;                     /* inp points to ip header */
  2014.     tcpp = &pkt->tcp;                   /* tcpp points to tcp header */
  2015.  
  2016.     maxsend=min((word)s->datalen, s->window); /* max possible send size */
  2017.     if (s->window==0 && s->datalen > s->unacked) {
  2018.     s->flags |= tcp_FlagPUSH; 
  2019.     DB2((FDB,"tcp_send(): datalen=%d, window=%d\n",s->datalen,s->window));
  2020.     }
  2021.     if (s->datalen >0 && s->window ==0 ) s->unhappy=YES;
  2022.     sentdata=0;
  2023.     do {
  2024.     DB2((FDB,"looping in tcp_send - sending %d data bytes\n", maxsend));
  2025.     /* enter at least once, to send flags */
  2026.     /* adjust size for each packet */
  2027.     if( maxsend < (word)s->unacked ) {
  2028.         DB4((stderr,"Error - senddatalen<0\7\n"));
  2029.     }
  2030.     senddatalen= maxsend - (word)s->unacked;
  2031.     if (senddatalen > s->mss) senddatalen = s->mss;
  2032.     DB2((FDB,"tcp_send - truncate to %d data bytes\n", senddatalen));
  2033.  
  2034.     /*** Prepare tcp header ***/
  2035.     r=(char *)tcpp;
  2036. #define tcpp ((tcp_Header *)r)
  2037.  
  2038.     tcpp->srcPort = intel16( s->myport );
  2039.     tcpp->dstPort = intel16( s->hisport );
  2040.     tcpp->seqnum = intel(s->seqnum + (long)s->unacked);
  2041.     tcpp->acknum = intel( s->acknum );
  2042.     tcpp->window = intel16( s->rxbufsize - s->rdatalen );
  2043.  
  2044.     tcpp->flags = intel16( s->flags | 0x5000 );
  2045.         /* 5000 is the tcp_data_offset in the tcp header */
  2046.     tcpp->checksum = 0;
  2047.     tcpp->urgentPointer = 0;
  2048.  
  2049.     if (s->unacked <0 || s->unacked > s->txbufsize) {
  2050.         DB4((FDB,"tcp_send: len=%5d unack=%5d rwin=%5d seq=%10lu\n",
  2051.         senddatalen, s->unacked, s->window, intel(tcpp->seqnum)));
  2052.         DB4((FDB,"     rdatalen=%5d          thiswin=%5d ack=%10lu\n",
  2053.         s->rdatalen, intel16(tcpp->window), s->acknum));
  2054.     }
  2055.     if ((s->flags & (tcp_FlagSYN | tcp_FlagACK)) == tcp_FlagSYN) {
  2056.         /* do options if this is our first packet */
  2057.         sendpktlen = sizeof( tcp_Header ) + sizeof( in_Header ) + 4; 
  2058.         tcpp->flags = intel16( intel16( tcpp->flags) + 0x1000 );
  2059.         /*** 1000 means there are some options in the tcp header ***/
  2060.         pkt->maxsegopt[0] = 0x0402;
  2061.         pkt->maxsegopt[1] = intel16( s->mss );
  2062.         dp += 4;
  2063.     } 
  2064.     else { /* handle packets with data */
  2065.         if (senddatalen > 0) {
  2066.         memcpy(dp, s->data + s->unacked, senddatalen);
  2067.         dp[ senddatalen ] = 0;  /* zero padding is safe */
  2068.         }
  2069.         sendpktlen=senddatalen+sizeof(tcp_Header)+sizeof(in_Header); 
  2070.     }
  2071.  
  2072.     /*** internet header, build IP header ***/
  2073. #undef tcpp
  2074.     make_in_hdr(inp, TCP_PROTO, s->hisaddr, sendpktlen);
  2075.  
  2076.     /* compute tcp checksum */
  2077. #ifdef notdef
  2078.     r= &ph;
  2079. #define ph (*(tcp_PseudoHeader *)r)
  2080. #endif /* notdef  */
  2081.     ph.src = inp->source;   /* already INTELled */
  2082.     ph.dst = inp->destination;
  2083.     ph.mbz = 0;
  2084.     ph.protocol = 6;
  2085.     ph.length = intel16( sendpktlen - sizeof(in_Header));
  2086.     ph.checksum=inchksum((void *)&pkt->tcp,(sendpktlen-sizeof(in_Header)+1)&0xfffe);
  2087.  
  2088.     tcpp->checksum = ~inchksum((void *)&ph, sizeof(ph));
  2089. #ifdef ph
  2090. #undef ph
  2091. #endif /* ph */
  2092.     if (senddatalen==0) {
  2093.         DB2((FDB,"calling _eth_send(): for empty pkt\n"));
  2094.         emptyretr++;    
  2095.     }
  2096.     if (senddatalen==0 && (s->flags & tcp_FlagACK)) {
  2097.         DB2((FDB,"Send ACK\n"));
  2098.         emptyeack++;
  2099.     }
  2100.  
  2101. #ifdef debug
  2102.     if (s->flags & tcp_FlagFIN) { DB2((FDB,"Sending FIN\n")); }
  2103.     if (s->flags & tcp_FlagSYN) { DB2((FDB,"Sending SYN\n")); }
  2104. #endif /* debug */
  2105.     if ( _eth_send( intel16( inp->length ))) { /* encounterred error */
  2106.         s->unhappy=VERY; /* send failed, try later */
  2107.         DB2((FDB,"Setting VERY cause of failure of eth_send\n"));
  2108.         break;
  2109.     }
  2110.     if (senddatalen==0) break; /* can't send more */
  2111.  
  2112.     /* do next ip pkt */
  2113.     sentdata += senddatalen;
  2114.     s->unacked += (int)senddatalen; /* 03-mar-92 lr-gm */
  2115.     if (s->unacked >s->txbufsize) {
  2116.         DB4((stderr,"Wrong value in s->unacked: %d\n",s->unacked));
  2117.     }
  2118.     } while ( s->unacked < (int)maxsend );
  2119.     if (sentdata || (s->flags & (tcp_FlagSYN | tcp_FlagFIN)) ) {
  2120.     s->vj_last = set_ttimeout( 0 ); /* mark send time */
  2121.     s->rtt_time = set_ttimeout( s->rto );
  2122.     } else {
  2123.     s->vj_last = 0; /* might be useless */
  2124.     s->rtt_time = 0;
  2125.     }
  2126. } /* end tcp_send */
  2127.  
  2128. /*
  2129.  * Format and send a reset tcp packet
  2130.  */
  2131. void
  2132. tcp_rst( in_Header *his_ip, tcp_Header *oldtcpp )
  2133. {
  2134.     tcp_PseudoHeader ph;
  2135.     struct _pkt {
  2136.     in_Header in;
  2137.     tcp_Header tcp;
  2138.     word maxsegopt[2];
  2139.     } 
  2140.     *pkt, *his_pkt;
  2141.  
  2142.     static longword nextrst = 0L;
  2143.     byte *dp;
  2144.     word oldflags;
  2145.     in_Header *inp;
  2146.     tcp_Header *tcpp;
  2147.     eth_Header *eth;
  2148.     int sendtotlen;     /* length of packet */
  2149.     longword templong;
  2150.  
  2151.     /* see RFC 793 page 65 for details */
  2152.  
  2153.     DB2((FDB,"tcp_rst():\n"));
  2154.     gm_tcp_rst++;
  2155.     /*
  2156.      * at most one RST per tick
  2157.      */
  2158.     if ( !chk_timeout( nextrst )) return;
  2159.     nextrst = set_ttimeout( 1 );
  2160.  
  2161.     oldflags = intel16( oldtcpp->flags );
  2162.     if (oldflags & tcp_FlagRST ) return;
  2163.     if ( (oldflags & (tcp_FlagACK | tcp_FlagFIN)) == (tcp_FlagACK | tcp_FlagFIN) ){
  2164.     templong = oldtcpp->seqnum;
  2165.     oldtcpp->seqnum = oldtcpp->acknum;
  2166.     oldtcpp->acknum = templong;
  2167.     oldflags = tcp_FlagACK;
  2168.     } 
  2169.     else if ((oldflags & (tcp_FlagSYN | tcp_FlagACK)) ==  tcp_FlagSYN ) {
  2170.     oldtcpp->acknum = intel( intel( oldtcpp->seqnum ) + 1 );
  2171.     oldtcpp->seqnum = 0;
  2172.     oldflags = tcp_FlagACK | tcp_FlagRST;
  2173.     } 
  2174.     else if ( oldflags & tcp_FlagACK ) {
  2175.     oldtcpp->seqnum = oldtcpp->acknum;
  2176.     oldtcpp->acknum = 0;
  2177.     } 
  2178.     else {
  2179.     oldtcpp->acknum = intel( intel(oldtcpp->seqnum) + 1);
  2180.     oldtcpp->seqnum = 0;
  2181.     }
  2182.     if ( (oldflags & ( tcp_FlagFIN | tcp_FlagSYN )) == 0 )
  2183.     oldflags ^= tcp_FlagACK | tcp_FlagRST;
  2184.  
  2185.     his_pkt  = (struct _pkt*)( his_ip );
  2186.  
  2187.     /* convoluted mechanism - reads his ethernet address or garbage */
  2188.     eth = _eth_hardware( (byte *)his_ip );
  2189.  
  2190.     pkt = (struct _pkt *)_eth_formatpacket( eth, 8);
  2191.     dp = (byte *)&pkt->maxsegopt;
  2192.     inp = &pkt->in;
  2193.     tcpp = &pkt->tcp;
  2194.  
  2195.     sendtotlen = sizeof( tcp_Header ) + sizeof( in_Header );
  2196.  
  2197.     /* tcp header */
  2198.     tcpp->srcPort = oldtcpp->dstPort;
  2199.     tcpp->dstPort = oldtcpp->srcPort;
  2200.     tcpp->seqnum = oldtcpp->seqnum;
  2201.     tcpp->acknum = oldtcpp->acknum;
  2202.     tcpp->window = 0;
  2203.     tcpp->flags = intel16( oldflags );
  2204.     tcpp->checksum = 0;
  2205.     tcpp->urgentPointer = 0;
  2206.  
  2207.     /* internet header */
  2208.     make_in_hdr(inp, TCP_PROTO, intel(his_ip->source) , sendtotlen);
  2209.  
  2210.     /* compute tcp checksum */
  2211.     ph.src = inp->source;       /* already INTELled */
  2212.     ph.dst = inp->destination;
  2213.     ph.mbz = 0;
  2214.     ph.protocol = 6;
  2215.     ph.length = intel16( sendtotlen - sizeof(in_Header));
  2216.  
  2217.     ph.checksum = inchksum((void *)&pkt->tcp, (sendtotlen - sizeof(in_Header) +1) & 0xfffe);
  2218.     /* intel16(ph.length));*/ /* 0; *//* watstar */
  2219.     tcpp->checksum =  ~inchksum((void *)&ph, sizeof(ph));
  2220. #ifdef DEBUG
  2221.     if (_dbugxmit) (*_dbugxmit)(NULL,inp,tcpp);
  2222. #endif /* DEBUG */
  2223.     DB2((FDB,"tcp_rst(): calling _eth_send():\n"));
  2224.     _eth_send( intel16( inp->length ));
  2225. } /* end tcp_rst() */
  2226.  
  2227.  
  2228.  
  2229. /*************************************************************
  2230.  ***                      socket functions                 ***
  2231.  *************************************************************/
  2232.  
  2233. /***
  2234.  *** sock_yield - enable user defined yield function
  2235.  ***/
  2236. void
  2237. sock_yield( tcp_Socket *s, void (*fn)())
  2238. { if ( s ) s->usr_yield = fn; else system_yield = fn; }
  2239.  
  2240. /***
  2241.  *** sock_mode - set binary or ascii - affects sock_gets, sock_dataready
  2242.  ***         - set udp checksums
  2243.  ***/
  2244. void sock_mode( sock_type *s, word mode )
  2245. { s->tcp.sock_mode = (s->tcp.sock_mode & 0xfffc) | mode; }
  2246.  
  2247. /***
  2248.  *** sock_read - read a socket with maximum n bytes
  2249.  ***         - busywaits until buffer is full but calls s->usr_yield
  2250.  ***         - returns count also when connection gets closed
  2251.  ***/
  2252. int
  2253. sock_read(sock_type *s, byte *dp, int len )
  2254. {
  2255.     int templen, count=0;
  2256.  
  2257.     DB2((FDB,"sock_read():\n"));
  2258.     while (len) {
  2259.     if ( s->udp.ip_type == UDP_PROTO ) {
  2260.         if (len > (int)_mss) len =_mss;
  2261.         templen = udp_read((udp_Socket *) s, dp, len );
  2262.     }
  2263.     else
  2264.         templen = tcp_read((tcp_Socket *)s, dp, len);
  2265.     if (s->tcp.usr_yield) (s->tcp.usr_yield)();
  2266.     if (templen < 1 ) { /* couldn't read */
  2267.         if (!tcp_tick( s )) { /* closed, or something */
  2268.         /*** should also check for incoming PUSH ***/
  2269.         return( count ); 
  2270.         }
  2271.     } 
  2272.     else {
  2273.         count += templen;
  2274.         dp += templen;
  2275.         len -= templen;
  2276.     }
  2277.     }
  2278.     return( count );
  2279. }
  2280.  
  2281. /***
  2282.  *** sock_fastread - read a socket with maximum n bytes
  2283.  ***         - does not busywait until buffer is full
  2284.  ***/
  2285. int sock_fastread(sock_type *s, byte *dp, int len )
  2286. {
  2287. DB2((FDB,"sock_fastread():\n"));
  2288.     return(s->udp.ip_type==UDP_PROTO ? udp_read((udp_Socket*)s,dp,len)
  2289.     : tcp_read((tcp_Socket *)s,dp,len) );
  2290. }
  2291.  
  2292.  
  2293. /***
  2294.  *** sock_write - writes data and returns length written
  2295.  ***          - does not perform flush
  2296.  ***          - repeatedly calls s->usr_yield
  2297.  ***/
  2298.  
  2299. int
  2300. sock_write(register sock_type *s, byte *dp, int len)
  2301. {
  2302.     register int offset=0;
  2303.     int  oldmode=0, proto;
  2304.     int oldlen;
  2305.     int len1;
  2306.     DB2((FDB,"sock_write():\n"));
  2307.  
  2308.     oldlen=len;
  2309.     proto = (s->udp.ip_type == TCP_PROTO);
  2310.     if ( proto ) oldmode = s->tcp.flags & tcp_FlagPUSH;
  2311.     while ( len > 0) {
  2312.     len1=len;
  2313.     DB2((FDB,"looping in sock_write():\n"));
  2314.     if (proto) {
  2315.         s->tcp.flags |= oldmode;
  2316.         offset += tcp_write( (tcp_Socket *)s, &dp[ offset ], len);
  2317.     } 
  2318.     else {
  2319.     /* 31-mar92 gm Added to warn in case of truncation to mss */
  2320.         if (len > (int)_mss) {
  2321.              printf("Warning! Transmission truncated to MSS=%d\n",_mss);
  2322.              offset += udp_write(( udp_Socket*)s, &dp[offset], _mss); 
  2323.              oldlen=_mss;
  2324.         } else offset += udp_write(( udp_Socket*)s, &dp[offset], len); 
  2325.     }
  2326.     len=oldlen-offset;
  2327.     if (s->udp.usr_yield) {
  2328.         (s->udp.usr_yield)();
  2329.     }
  2330.     if (!tcp_tick(s)) { 
  2331.         return( 0 );
  2332.     } 
  2333.     DB2((FDB,"sock_write(): wrote %d, unacked=%d\n",len1,s->tcp.unacked));
  2334.     DB2((FDB,"end looping in sock_write():\n"));
  2335.     }
  2336.     return( oldlen );
  2337. }
  2338.  
  2339.  
  2340. int
  2341. sock_fastwrite(sock_type *s, byte *dp, int len)
  2342. {
  2343.     DB2((FDB,"sock_fastwrite():\n"));
  2344.     tcp_tick(NULL);     /* updates our output buffer */
  2345.     return( ( s->udp.ip_type == UDP_PROTO ) ?
  2346.     udp_write( (udp_Socket *)s, dp, len ) :
  2347.     tcp_write( (tcp_Socket *)s, dp, len) );
  2348. }
  2349.  
  2350. void
  2351. sock_flush( sock_type *s )
  2352. {
  2353.     if ( s->tcp.ip_type == TCP_PROTO ) tcp_Flush((tcp_Socket *) s );
  2354. }
  2355.  
  2356. int
  2357. sock_waitwrite( sock_type *s, byte *dp, int len )
  2358. {
  2359.     int templen;
  2360.     if ( s->udp.ip_type == UDP_PROTO ) {
  2361.     return udp_write( (udp_Socket *)s,dp,len);
  2362.     } else if ( (templen = s->tcp.datalen) + len > (int)(s->tcp.mss / 2)) {
  2363.     return( tcp_write( (tcp_Socket *)s, dp, len ) - templen );
  2364.     } else {
  2365.     movmem( dp, &s->tcp.data[s->tcp.datalen], len );
  2366.     s->tcp.datalen += len;
  2367.     return( len );
  2368.     }
  2369. }
  2370.  
  2371. /***
  2372.  *** sock_flushnext - cause next transmission to have a flush
  2373.  ***/
  2374. void
  2375. sock_flushnext( sock_type *s)
  2376. {
  2377.     if (s->tcp.ip_type == TCP_PROTO )
  2378.     s->tcp.flags |= tcp_FlagPUSH;
  2379. }
  2380.  
  2381. /***
  2382.  *** sock_putc - put a character
  2383.  ***         - no expansion but flushes on '\n'
  2384.  ***         - returns character
  2385.  ***/
  2386. byte
  2387. sock_putc( sock_type *s, byte c )
  2388. {
  2389.     if (( c == '\n') || ( c == '\r')) sock_flushnext( s );
  2390.     sock_write( s, &c, 1 );
  2391.     return( c );
  2392. }
  2393.  
  2394. word
  2395. sock_getc( sock_type *s )
  2396. {
  2397.     char ch;
  2398.     sock_read( s, &ch, 1 );
  2399.     return( ch );
  2400. }
  2401.  
  2402. /*
  2403.  * sock_puts - does not append carriage return in binary mode
  2404.  *           - returns length
  2405.  */
  2406. int
  2407. sock_puts( sock_type *s, byte *dp )
  2408. {
  2409.     int len;
  2410.     len = strlen( dp );
  2411.     sock_flushnext( s );
  2412.     sock_write( s, dp, len );
  2413.     if (s->tcp.sock_mode & TCP_MODE_ASCII ) sock_write( s, "\r\n", 2 );
  2414.     return( len );
  2415. }
  2416.  
  2417. /*
  2418.  * sock_update - update the socket window size to the other guy
  2419.  */
  2420. static void
  2421. sock_update( tcp_Socket *s )
  2422. {
  2423.     if (s->ip_type == TCP_PROTO) {
  2424.     if ( s->rdatalen < ( 3 * s->rxbufsize) / 4 ) {
  2425.         tcp_send( s );      /* update the window */
  2426.     } 
  2427.     else {
  2428.         s->unhappy=YES;
  2429.     }
  2430.     }
  2431. }
  2432.  
  2433. /*
  2434.  * sock_gets - read a string from any socket
  2435.  *           - return length of returned string
  2436.  *           - removes end of line terminator
  2437.  */
  2438. word
  2439. sock_gets( sock_type *s, byte *dp, int n )
  2440. {
  2441.     int len, templen;
  2442.     char *src_p, *temp, *temp2;
  2443.     word *np;
  2444.     short BufSize=0;
  2445.  
  2446.     if ( s->udp.ip_type == UDP_PROTO ) {
  2447.     src_p = s->udp.rdata;
  2448.     np = &s->udp.rdatalen;
  2449.     BufSize = s->udp.rxbufsize;
  2450.     } 
  2451.     else {
  2452.     src_p = s->tcp.rdata;
  2453.     np = &s->tcp.rdatalen;
  2454.     BufSize = s->tcp.rxbufsize;
  2455.     }
  2456.  
  2457.     if ( n > BufSize) n = BufSize;
  2458.  
  2459.     src_p[ *np ] = 0;           /* terminate string */
  2460.     strncpy( dp, src_p, n );    /* copy everything */
  2461.     dp[ n-1 ] = 0;              /* terminate */
  2462.  
  2463.     if (temp = strchr( dp, '\n')) *temp = 0;
  2464.     if (temp2= strchr( dp, '\r')) *temp2= 0;
  2465.     len = strlen( dp );
  2466.  
  2467.     /* skip if there were no crs or lfs ??? */
  2468.     if (!temp2 && !temp && ( (int)strlen(dp) < n - 1) ) {
  2469.  
  2470.     if ( s->udp.ip_type == TCP_PROTO &&
  2471.         s->tcp.state != tcp_StateESTAB &&
  2472.         s->tcp.state != tcp_StateESTCL &&
  2473.         s->tcp.state != tcp_StateCLOSWT )
  2474.         /* take what we can get from this connection */;
  2475.     else {
  2476.         *dp = 0;
  2477.         return( 0 );
  2478.     }
  2479.     }
  2480.  
  2481.     /* skip over \n and \r but stop on end */
  2482. #ifndef OLD
  2483.     if ( temp ) templen = FP_OFF( temp ) - FP_OFF( dp );
  2484.     else if ( temp2 ) templen = FP_OFF( temp2 ) - FP_OFF( dp );
  2485.     else templen = len + 1;
  2486.  
  2487.     if (templen) {
  2488.     ++templen;
  2489.     movmem( &src_p[ templen ], src_p, *np -= templen);
  2490.     } 
  2491.     else
  2492.     * np = 0;
  2493. #else
  2494.     temp = &src_p[ len + 1 ];
  2495.     while ( *temp && (  ( *temp == '\n' ) || (*temp == '\r')))
  2496.     temp++;
  2497.  
  2498.     if (*temp)
  2499.     movmem( temp, src_p, *np = strlen( temp ));
  2500.     else
  2501.     *np = 0;
  2502. #endif 
  2503.  
  2504.     sock_update((tcp_Socket *) s );     /* new window */
  2505.     return( len );
  2506. }
  2507.  
  2508. /*
  2509.  * sock_dataready - returns number of bytes waiting to be ready
  2510.  *                - if in ASCII mode, return 0 until a line is present
  2511.  *                  or the buffer is full
  2512.  */
  2513. int
  2514. sock_dataready( register sock_type *s )
  2515. {
  2516.     int len;
  2517.     char *p;
  2518.  
  2519.     len = (s->tcp.ip_type == TCP_PROTO) ? s->tcp.rdatalen : s->udp.rdatalen;
  2520.     if (len == -1) return( -1 );  /* correction of fr instead of following 1 */
  2521.     /*if ((len = s->tcp.rdatalen) == -1) return( -1 );*/
  2522.  
  2523.     if( (s->tcp.ip_type == TCP_PROTO) && (s->tcp.sock_mode & TCP_MODE_ASCII)){
  2524.     if ( len == s->tcp.rxbufsize ) return ( s->tcp.rxbufsize );
  2525.  
  2526.     /* check for terminating \n \r */
  2527.     p = s->tcp.rdata;
  2528.     if ( strchr( p , '\n') || strchr( p, '\r')) return( len );
  2529.     return( 0 );
  2530.     } 
  2531.     else
  2532.     return( len );
  2533. }
  2534.  
  2535. int
  2536. sock_established( sock_type *s )
  2537. {
  2538.     switch ( s->tcp.ip_type ) {
  2539.     case UDP_PROTO :
  2540.     return( 1 );
  2541.     case TCP_PROTO :
  2542.     return( s->tcp.state == tcp_StateESTAB ||
  2543.         s->tcp.state == tcp_StateESTCL ||
  2544.         s->tcp.state == tcp_StateCLOSWT );
  2545.     default :
  2546.     return( 0 );
  2547.     }
  2548. }
  2549.  
  2550. void
  2551. sock_close( sock_type *s)
  2552. {
  2553.     DB2((FDB,"sock_close():\n"));
  2554.     DB2((stderr,"Type of socket [%d]\n", s->udp.ip_type));
  2555.     switch (s->udp.ip_type) {
  2556.     default:
  2557.     DB3((stderr,"Warning: calling sock_close on closed socket [%d]\n",
  2558.         s->udp.ip_type));
  2559.     return;
  2560.     case UDP_PROTO :
  2561.     udp_close((udp_Socket *) s );
  2562.     break;
  2563.     case TCP_PROTO :
  2564.     tcp_close((tcp_Socket *) s );
  2565.     tcp_tick( s );
  2566.     break;
  2567.     }
  2568. }
  2569.  
  2570. #ifdef unused
  2571. /*
  2572.  *  tcp_accept is superseded by accept()
  2573.  */
  2574. tcp_Socket *
  2575. tcp_accept( tcp_Socket *sl )
  2576. {
  2577.  
  2578.    register tcp_Socket *s;
  2579.  
  2580.    s=sl->next;
  2581.    for(;;){
  2582.     if (!tcp_tick((sock_type *)s)){
  2583.         DB4((stderr,"Working on non existing socket!\n"));
  2584.         exit(4);
  2585.         }
  2586.     if(!s->brother){
  2587.         DB4((stderr,"You are in the wrong place!\n"));
  2588.         exit(4);
  2589.         }
  2590.     if( (s->inlist) == LAZY && ( tcp_established((tcp_Socket *) s)) ){
  2591.         s->inlist = BUSY;
  2592.         sl->next = s->brother;  /* fair treatment of client calls */
  2593.         return(s);
  2594.         }
  2595.     if((s->brother) == (sl->next)){ 
  2596.         DB3((stderr,"\t\t\t\t\tNo new-call detected!\r"));
  2597.         return(NULL);
  2598.         }
  2599.     s=s->brother;
  2600.     }
  2601.  }         
  2602.  #endif /* unused */
  2603.  
  2604. /***
  2605.  *** _ip_delay0 called by macro sock_wait_established()
  2606.  *** _ip_delay1 called by macro sock_wait_intput()
  2607.  *** _ip_delay2 called by macro sock_wait_closed();
  2608.  ***
  2609.  ***/
  2610.  
  2611. int
  2612. _ip_delay0(register sock_type *s, int timeoutseconds,
  2613.     procref fn, int *statusptr )
  2614. {
  2615.     int status;
  2616.     ip_timer_init((udp_Socket *) s , timeoutseconds );
  2617.     for (;;) {
  2618.     if ( s->tcp.ip_type == TCP_PROTO ) {
  2619.         if ( tcp_established((tcp_Socket *) s )) {
  2620.         status = 0;
  2621.         break;
  2622.         }
  2623.     }
  2624.     kbhit();        /* permit ^c */
  2625.     if ( !tcp_tick( s )) {
  2626.         s->tcp.err_msg = "Host refused connection";
  2627.         status = -1;        /* get an early reset */
  2628.         break;
  2629.     }
  2630.     if ( ip_timer_expired((udp_Socket *) s )) {
  2631.         sock_close( s );
  2632.         status = -1;
  2633.         break;
  2634.     }
  2635.     if ( fn && (status = fn(s))) break;
  2636.     if ( s->tcp.usr_yield ) (*s->tcp.usr_yield)();
  2637.     if ( s->tcp.ip_type == UDP_PROTO ) {
  2638.         status = 0;
  2639.         break;
  2640.     }
  2641.     }
  2642.     if (statusptr) *statusptr = status;
  2643.     return( status );
  2644. }
  2645.  
  2646. int
  2647. _ip_delay1(register sock_type *s, int timeoutseconds,
  2648.     procref fn, int *statusptr)
  2649. {
  2650.     int status;
  2651.     ip_timer_init((udp_Socket *) s , timeoutseconds );
  2652.  
  2653.     sock_flush( s );    /* new enhancement */
  2654.  
  2655.     for (;;) {
  2656.     if ( sock_dataready( s )) {
  2657.         status = 0;
  2658.         break;
  2659.     }
  2660.     kbhit();        /* permit ^c */
  2661.     if ( !tcp_tick( s )) {
  2662.         status = 1;
  2663.         break;
  2664.     }
  2665.     if ( ip_timer_expired((udp_Socket *) s )) {
  2666.         /* sock_close( s ); */
  2667.         status = -1;
  2668.         break;
  2669.     }
  2670.     if (s->tcp.state == tcp_StateCLOSWT && s->tcp.rdatalen == 0) {
  2671.         status = 2; /* no more data can arrive */
  2672.         break;
  2673.     }
  2674.     if (fn && (status = fn(s))) break;
  2675.     if ( s->tcp.usr_yield ) (*s->tcp.usr_yield)();
  2676.     }
  2677.     if (statusptr) *statusptr = status;
  2678.     return( status );
  2679. }
  2680.  
  2681. int
  2682. _ip_delay2(register sock_type *s, int timeoutseconds,
  2683.     procref fn, int *statusptr)
  2684. {
  2685.     int status;
  2686.     ip_timer_init((udp_Socket *)s , timeoutseconds );
  2687.  
  2688.     if (s->tcp.ip_type != TCP_PROTO ) return( 1 );
  2689.  
  2690.     for (;;) {
  2691.     kbhit();        /* permit ^c */
  2692.     if ( (s->tcp.inlist)==LAZY ){
  2693.         status=1;
  2694.         break;
  2695.         }    
  2696.     if ( !tcp_tick( s )) {
  2697.         status = 1;
  2698.         break;
  2699.     }
  2700.     if ( ip_timer_expired((udp_Socket *) s )) {
  2701.         sock_abort((tcp_Socket *) s );
  2702.         status = -1;
  2703.         break;
  2704.     }
  2705.     if (fn && (status = fn(s))) break;
  2706.     if ( s->tcp.usr_yield ) (*s->tcp.usr_yield)();
  2707.  
  2708.     };
  2709.     if (statusptr) *statusptr = status;
  2710.     return( status );
  2711. }
  2712.  
  2713.  
  2714. char
  2715. *rip( char *s )
  2716. {
  2717.     char *temp;
  2718.  
  2719.     if (temp = strchr( s, '\n')) *temp = 0;
  2720.     if (temp = strchr( s, '\r')) *temp = 0;
  2721.     return( s );
  2722. }
  2723.  
  2724.  
  2725. extern long gm_eth_send;
  2726. void
  2727. gm_statistics(void)
  2728. {
  2729.     printf("           TCP statistics \n");
  2730.     printf("tcp_send:        %8ld    (eth_send):    %8ld\n",
  2731.     gm_tcp_send, gm_eth_send);
  2732.     printf("   from retr:    %8ld    from very:     %8ld\n",
  2733.     gm_tcp_send_retr, gm_tcp_send_very);
  2734.     printf("   empty:        %8ld    empty and ack: %8ld\n",
  2735.     emptyretr, emptyeack);
  2736.     printf("rtt expired:     %8ld\n", gm_expire);
  2737.     printf("tcp_handler:     %8ld    ProcessData:   %8ld\n",
  2738.     gm_tcp_handler, gm_tcp_ProcessData);
  2739.     printf("    from SYNSENT:%8ld    from ESTAB:    %8ld\n",
  2740.     gm_proces_sent , gm_proces_estab);
  2741.     printf("tcp_tick:        %8ld    tcp_Retr.:     %8ld\n",
  2742.     gm_tcp_tick,  gm_tcp_Retransmitter);
  2743.     printf("tcp_rst:         %8ld\n", gm_tcp_rst);
  2744.     printf("tcp_unthread:    %8ld\n", gm_tcp_unthread);
  2745. }
  2746.  
  2747. void
  2748. gm_udp_statistics(void)
  2749. {
  2750.     printf("           UDP statistics \n");
  2751.     printf("udp_write:       %8ld    (eth_send):    %8ld\n",
  2752.     gm_udp_write, gm_eth_send);
  2753.     printf("eth_send failed:    %8ld\n", gm_udp_sendfailed);
  2754.     printf("udp_read of data:   %8ld\n", gm_udp_read);
  2755.     printf("udp_handler:     %8ld\n", gm_udp_handler);
  2756.     printf("tcp_tick:        %8ld    tcp_Retr.:     %8ld\n",
  2757.     gm_tcp_tick,  gm_tcp_Retransmitter);
  2758.     printf("tcp_rst:         %8ld\n", gm_tcp_rst);
  2759. }
  2760. /*** end of file tcp.c ***/
  2761.