Implemented some boundary cases for LISTENQ.

This commit is contained in:
Philip Homburg 2005-08-03 11:15:39 +00:00
parent 6f1c7d6016
commit 547bf3ac36
3 changed files with 57 additions and 51 deletions

View File

@ -1578,13 +1578,17 @@ tcp_hdr_t *tcp_hdr;
if (best_conn) if (best_conn)
{ {
assert(!best_conn->tc_fd);
if (!listen_conn) if (!listen_conn)
{
assert(!best_conn->tc_fd);
return best_conn; return best_conn;
}
assert(listen_conn->tc_connInprogress);
tcp_fd= listen_conn->tc_fd; tcp_fd= listen_conn->tc_fd;
assert(tcp_fd && listen_conn->tc_connInprogress && assert(tcp_fd);
tcp_fd->tf_conn == listen_conn); assert((tcp_fd->tf_flags & TFF_LISTENQ) ||
tcp_fd->tf_conn == listen_conn);
if (best_conn->tc_state != TCS_CLOSED) if (best_conn->tc_state != TCS_CLOSED)
tcp_close_connection(best_conn, ENOCONN); tcp_close_connection(best_conn, ENOCONN);
@ -1818,12 +1822,7 @@ tcp_conn_t *tcp_conn;
if (tcp_fd->tf_flags & TFF_LISTENQ) if (tcp_fd->tf_flags & TFF_LISTENQ)
{ {
/* Special code for listen queues */ /* Special code for listen queues */
if (tcp_conn->tc_state == TCS_CLOSED) assert(tcp_conn->tc_state != TCS_CLOSED);
{
assert(NOT_IMPLEMENTED);
reply= tcp_conn->tc_error;
tcp_conn->tc_fd= NULL;
}
/* Reply for select */ /* Reply for select */
if ((tcp_fd->tf_flags & TFF_SEL_READ) && if ((tcp_fd->tf_flags & TFF_SEL_READ) &&

View File

@ -18,8 +18,6 @@ Copyright 1995 Philip Homburg
THIS_FILE THIS_FILE
#define NOT_IMPLEMENTED 0
FORWARD void create_RST ARGS(( tcp_conn_t *tcp_conn, FORWARD void create_RST ARGS(( tcp_conn_t *tcp_conn,
ip_hdr_t *ip_hdr, tcp_hdr_t *tcp_hdr, int data_len )); ip_hdr_t *ip_hdr, tcp_hdr_t *tcp_hdr, int data_len ));
FORWARD void process_data ARGS(( tcp_conn_t *tcp_conn, 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; u32_t seg_ack, seg_seq, rcv_hi, snd_una, snd_nxt;
u16_t seg_wnd, mtu; u16_t seg_wnd, mtu;
size_t mss; 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; ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2;
tcp_hdr_len= (tcp_hdr->th_data_off & TH_DO_MASK) >> 2; tcp_hdr_len= (tcp_hdr->th_data_off & TH_DO_MASK) >> 2;
@ -329,6 +327,7 @@ SYN-RECEIVED:
rcv_hi++; rcv_hi++;
send_rst= tcp_Lmod4G(seg_seq, tcp_conn->tc_IRS) || send_rst= tcp_Lmod4G(seg_seq, tcp_conn->tc_IRS) ||
tcp_Gmod4G(seg_seq, tcp_conn->tc_RCV_NXT+0x10000); tcp_Gmod4G(seg_seq, tcp_conn->tc_RCV_NXT+0x10000);
close_connection= 0;
if (!data_len) if (!data_len)
{ {
@ -396,34 +395,10 @@ SYN-RECEIVED:
error "connection refused" error "connection refused"
exit exit
*/ */
if (tcp_hdr_flags & THF_RST) if (tcp_hdr_flags & THF_RST)
{ close_connection= 1;
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 (connuser)
{
(void)tcp_su4listen(connuser, tcp_conn,
0 /* !do_listenq */);
}
break;
}
else
{
tcp_close_connection(tcp_conn, ECONNREFUSED);
break;
}
}
/* /*
SYN in window ? SYN in window ?
initiated by a LISTEN ? initiated by a LISTEN ?
@ -437,24 +412,38 @@ SYN-RECEIVED:
if ((tcp_hdr_flags & THF_SYN) && tcp_GEmod4G(seg_seq, if ((tcp_hdr_flags & THF_SYN) && tcp_GEmod4G(seg_seq,
tcp_conn->tc_RCV_NXT)) tcp_conn->tc_RCV_NXT))
{ {
if (tcp_conn->tc_orglisten) close_connection= 1;
}
if (close_connection)
{
if (!tcp_conn->tc_orglisten)
{ {
assert(NOT_IMPLEMENTED); tcp_close_connection(tcp_conn, ECONNREFUSED);
break;
connuser= tcp_conn->tc_fd; }
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_connInprogress= 0;
tcp_conn->tc_fd= NULL; tcp_conn->tc_fd= NULL;
tcp_close_connection(tcp_conn, ECONNRESET); tcp_close_connection (tcp_conn,
if (connuser) ECONNREFUSED);
{
(void)tcp_su4listen(connuser, tcp_conn, /* Pick a new ISS next time */
0 /* !do_listenq */); tcp_conn->tc_ISS= 0;
}
break; (void)tcp_su4listen(connuser, tcp_conn,
0 /* !do_listenq */);
} }
tcp_close_connection(tcp_conn, ECONNRESET);
break; break;
} }
/* /*

View File

@ -1300,6 +1300,7 @@ PUBLIC void tcp_close_connection(tcp_conn, error)
tcp_conn_t *tcp_conn; tcp_conn_t *tcp_conn;
int error; int error;
{ {
int i;
tcp_port_t *tcp_port; tcp_port_t *tcp_port;
tcp_fd_t *tcp_fd; tcp_fd_t *tcp_fd;
tcp_conn_t *tc; tcp_conn_t *tc;
@ -1317,8 +1318,25 @@ int error;
tcp_conn->tc_state= TCS_CLOSED; tcp_conn->tc_state= TCS_CLOSED;
DBLOCK(0x10, tcp_print_state(tcp_conn); printf("\n")); 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++; tcp_conn->tc_busy++;
assert(tcp_fd->tf_conn == tcp_conn); assert(tcp_fd->tf_conn == tcp_conn);