]> Zhao Yanbai Git Server - minix.git/commitdiff
Implemented some boundary cases for LISTENQ.
authorPhilip Homburg <philip@cs.vu.nl>
Wed, 3 Aug 2005 11:15:39 +0000 (11:15 +0000)
committerPhilip Homburg <philip@cs.vu.nl>
Wed, 3 Aug 2005 11:15:39 +0000 (11:15 +0000)
servers/inet/generic/tcp.c
servers/inet/generic/tcp_recv.c
servers/inet/generic/tcp_send.c

index 4a8c5cc06a5341058bff6c2530777f9c67e993d9..eda4b6e534904e467ceee0af3c1a6e3ae2068536 100644 (file)
@@ -1578,13 +1578,17 @@ tcp_hdr_t *tcp_hdr;
 
        if (best_conn)
        {
-               assert(!best_conn->tc_fd);
                if (!listen_conn)
+               {
+                       assert(!best_conn->tc_fd);
                        return best_conn;
+               }
 
+               assert(listen_conn->tc_connInprogress);
                tcp_fd= listen_conn->tc_fd;
-               assert(tcp_fd && listen_conn->tc_connInprogress &&
-                       tcp_fd->tf_conn == listen_conn);
+               assert(tcp_fd);
+               assert((tcp_fd->tf_flags & TFF_LISTENQ) ||
+                        tcp_fd->tf_conn == listen_conn);
 
                if (best_conn->tc_state != TCS_CLOSED)
                        tcp_close_connection(best_conn, ENOCONN);
@@ -1818,12 +1822,7 @@ tcp_conn_t *tcp_conn;
        if (tcp_fd->tf_flags & TFF_LISTENQ)
        {
                /* Special code for listen queues */
-               if (tcp_conn->tc_state == TCS_CLOSED)
-               {
-                       assert(NOT_IMPLEMENTED);
-                       reply= tcp_conn->tc_error;
-                       tcp_conn->tc_fd= NULL;
-               }
+               assert(tcp_conn->tc_state != TCS_CLOSED);
 
                /* Reply for select */
                if ((tcp_fd->tf_flags & TFF_SEL_READ) &&
index 90531653417f67fd25ce7220f76b0a106655676d..017c37a1a5b0854b830075cd3fc28312c87e7aec 100644 (file)
@@ -18,8 +18,6 @@ Copyright 1995 Philip Homburg
 
 THIS_FILE
 
-#define NOT_IMPLEMENTED 0
-
 FORWARD void create_RST ARGS(( tcp_conn_t *tcp_conn,
        ip_hdr_t *ip_hdr, tcp_hdr_t *tcp_hdr, int data_len ));
 FORWARD void process_data ARGS(( tcp_conn_t *tcp_conn,
@@ -40,7 +38,7 @@ size_t data_len;
        u32_t seg_ack, seg_seq, rcv_hi, snd_una, snd_nxt;
        u16_t seg_wnd, mtu;
        size_t mss;
-       int acceptable_ACK, segm_acceptable, send_rst;
+       int acceptable_ACK, segm_acceptable, send_rst, close_connection;
 
        ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2;
        tcp_hdr_len= (tcp_hdr->th_data_off & TH_DO_MASK) >> 2;
@@ -329,6 +327,7 @@ SYN-RECEIVED:
                        rcv_hi++;
                send_rst= tcp_Lmod4G(seg_seq, tcp_conn->tc_IRS) ||
                        tcp_Gmod4G(seg_seq, tcp_conn->tc_RCV_NXT+0x10000);
+               close_connection= 0;
 
                if (!data_len)
                {
@@ -396,34 +395,10 @@ SYN-RECEIVED:
                        error "connection refused"
                        exit
 */
-               if (tcp_hdr_flags & THF_RST)
-               {
-                       if (tcp_conn->tc_orglisten)
-                       {
-                               assert(NOT_IMPLEMENTED);
-                               connuser= tcp_conn->tc_fd;
 
-                               tcp_conn->tc_connInprogress= 0;
-                               tcp_conn->tc_fd= NULL;
-
-                               tcp_close_connection (tcp_conn, ECONNREFUSED);
-
-                               /* Pick a new ISS next time */
-                               tcp_conn->tc_ISS= 0;
+               if (tcp_hdr_flags & THF_RST)
+                       close_connection= 1;
 
-                               if (connuser)
-                               {
-                                       (void)tcp_su4listen(connuser, tcp_conn,
-                                               0 /* !do_listenq */);
-                               }
-                               break;
-                       }
-                       else
-                       {
-                               tcp_close_connection(tcp_conn, ECONNREFUSED);
-                               break;
-                       }
-               }
 /*
        SYN in window ?
                initiated by a LISTEN ?
@@ -437,24 +412,38 @@ SYN-RECEIVED:
                if ((tcp_hdr_flags & THF_SYN) && tcp_GEmod4G(seg_seq,
                        tcp_conn->tc_RCV_NXT))
                {
-                       if (tcp_conn->tc_orglisten)
-                       {
-                               assert(NOT_IMPLEMENTED);
+                       close_connection= 1;
+               }
 
-                               connuser= tcp_conn->tc_fd;
+               if (close_connection)
+               {
+                       if (!tcp_conn->tc_orglisten)
+                       {
+                               tcp_close_connection(tcp_conn, ECONNREFUSED);
+                               break;
+                       }
 
+                       connuser= tcp_conn->tc_fd;
+                       assert(connuser);
+                       if (connuser->tf_flags & TFF_LISTENQ)
+                       {
+                               tcp_close_connection (tcp_conn,
+                                       ECONNREFUSED);
+                       }
+                       else
+                       {
                                tcp_conn->tc_connInprogress= 0;
                                tcp_conn->tc_fd= NULL;
 
-                               tcp_close_connection(tcp_conn, ECONNRESET);
-                               if (connuser)
-                               {
-                                       (void)tcp_su4listen(connuser, tcp_conn,
-                                               0 /* !do_listenq */);
-                               }
-                               break;
+                               tcp_close_connection (tcp_conn,
+                                       ECONNREFUSED);
+
+                               /* Pick a new ISS next time */
+                               tcp_conn->tc_ISS= 0;
+
+                               (void)tcp_su4listen(connuser, tcp_conn,
+                                       0 /* !do_listenq */);
                        }
-                       tcp_close_connection(tcp_conn, ECONNRESET);
                        break;
                }
 /*
index f04c8c872a48c672bee62169a0e3b98750563d52..db8e8905cba51e398f2c37b6b56a18c14b6b95c8 100644 (file)
@@ -1300,6 +1300,7 @@ PUBLIC void tcp_close_connection(tcp_conn, error)
 tcp_conn_t *tcp_conn;
 int error;
 {
+       int i;
        tcp_port_t *tcp_port;
        tcp_fd_t *tcp_fd;
        tcp_conn_t *tc;
@@ -1317,8 +1318,25 @@ int error;
        tcp_conn->tc_state= TCS_CLOSED;
        DBLOCK(0x10, tcp_print_state(tcp_conn); printf("\n"));
 
-       if (tcp_fd)
+       if (tcp_fd && (tcp_fd->tf_flags & TFF_LISTENQ))
        {
+               for (i= 0; i<TFL_LISTEN_MAX; i++)
+               {
+                       if (tcp_fd->tf_listenq[i] == tcp_conn)
+                               break;
+               }
+               assert(i < TFL_LISTEN_MAX);
+               tcp_fd->tf_listenq[i]= NULL;
+
+               assert(tcp_conn->tc_connInprogress);
+               tcp_conn->tc_connInprogress= 0;
+
+               tcp_conn->tc_fd= NULL;
+               tcp_fd= NULL;
+       }
+       else if (tcp_fd)
+       {
+
                tcp_conn->tc_busy++;
                assert(tcp_fd->tf_conn == tcp_conn);