From: Philip Homburg Date: Wed, 3 Aug 2005 11:15:39 +0000 (+0000) Subject: Implemented some boundary cases for LISTENQ. X-Git-Tag: v3.1.0~469 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/doxygen.log?a=commitdiff_plain;h=547bf3ac361c8e3b80263374e0b47039b55f49a8;p=minix.git Implemented some boundary cases for LISTENQ. --- diff --git a/servers/inet/generic/tcp.c b/servers/inet/generic/tcp.c index 4a8c5cc06..eda4b6e53 100644 --- a/servers/inet/generic/tcp.c +++ b/servers/inet/generic/tcp.c @@ -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) && diff --git a/servers/inet/generic/tcp_recv.c b/servers/inet/generic/tcp_recv.c index 905316534..017c37a1a 100644 --- a/servers/inet/generic/tcp_recv.c +++ b/servers/inet/generic/tcp_recv.c @@ -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; } /* diff --git a/servers/inet/generic/tcp_send.c b/servers/inet/generic/tcp_send.c index f04c8c872..db8e8905c 100644 --- a/servers/inet/generic/tcp_send.c +++ b/servers/inet/generic/tcp_send.c @@ -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; itf_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);