- Add SYN_RCVD timeout
- Fix FIN_WAIT_1 to CLOSING transition
Change-Id: I42ca7fc087f6fdfae15bd7a6175dd3226ed341c7
Signed-off-by: Florin Coras <fcoras@cisco.com>
return rv;
/* Store api_context for when the reply comes. Not the nicest thing
return rv;
/* Store api_context for when the reply comes. Not the nicest thing
- * but better allocating a separate half-open pool. */
+ * but better than allocating a separate half-open pool. */
tc->s_index = api_context;
return 0;
tc->s_index = api_context;
return 0;
int (*session_accept_callback) (stream_session_t * new_session);
/* Connection request callback */
int (*session_accept_callback) (stream_session_t * new_session);
/* Connection request callback */
- int (*session_connected_callback) (u32 app_index, u32 api_context,
+ int (*session_connected_callback) (u32 app_index, u32 opaque,
stream_session_t * s, u8 code);
/** Notify app that session is closing */
stream_session_t * s, u8 code);
/** Notify app that session is closing */
application_t *app;
stream_session_t *new_s = 0;
u64 handle;
application_t *app;
stream_session_t *new_s = 0;
u64 handle;
int error = 0;
handle = stream_session_half_open_lookup_handle (&tc->lcl_ip, &tc->rmt_ip,
int error = 0;
handle = stream_session_half_open_lookup_handle (&tc->lcl_ip, &tc->rmt_ip,
- /* Get the app's index from the handle we stored when opening connection */
+ /* Get the app's index from the handle we stored when opening connection
+ * and the opaque (api_context for external apps) from transport session
+ * index*/
app = application_get (handle >> 32);
app = application_get (handle >> 32);
- api_context = tc->s_index;
}
/* Notify client application */
}
/* Notify client application */
- if (app->cb_fns.session_connected_callback (app->index, api_context, new_s,
+ if (app->cb_fns.session_connected_callback (app->index, opaque, new_s,
is_fail))
{
clib_warning ("failed to notify app");
is_fail))
{
clib_warning ("failed to notify app");
- /** connected (server) session handle */
- u64 server_session_handle;
-
/** Opaque, pad to a 64-octet boundary */
u64 opaque[1];
} stream_session_t;
/** Opaque, pad to a 64-octet boundary */
u64 opaque[1];
} stream_session_t;
tcp_connection_t *tc;
tc = tcp_half_open_connection_get (conn_index);
tcp_connection_t *tc;
tc = tcp_half_open_connection_get (conn_index);
- tc->timers[TCP_TIMER_ESTABLISH] = TCP_TIMER_HANDLE_INVALID;
-
- ASSERT (tc->state == TCP_STATE_SYN_SENT);
- stream_session_connect_notify (&tc->connection, 1 /* fail */ );
+ if (tc)
+ {
+ ASSERT (tc->state == TCP_STATE_SYN_SENT);
+ tc->timers[TCP_TIMER_ESTABLISH] = TCP_TIMER_HANDLE_INVALID;
+ stream_session_connect_notify (&tc->connection, 1 /* fail */ );
+ }
+ else
+ {
+ tc = tcp_connection_get (conn_index, vlib_get_thread_index ());
+ ASSERT (tc->state == TCP_STATE_SYN_RCVD);
+ }
tcp_connection_cleanup (tc);
}
tcp_connection_cleanup (tc);
}
* ticks to timer units */
#define TCP_DELACK_TIME 1 /* 0.1s */
#define TCP_ESTABLISH_TIME 750 /* 75s */
* ticks to timer units */
#define TCP_DELACK_TIME 1 /* 0.1s */
#define TCP_ESTABLISH_TIME 750 /* 75s */
+#define TCP_SYN_RCVD_TIME 100 /* 10s */
#define TCP_2MSL_TIME 300 /* 30s */
#define TCP_CLOSEWAIT_TIME 20 /* 0.1s */
#define TCP_CLEANUP_TIME 5 /* 0.5s Time to wait before cleanup */
#define TCP_2MSL_TIME 300 /* 30s */
#define TCP_CLOSEWAIT_TIME 20 /* 0.1s */
#define TCP_CLEANUP_TIME 5 /* 0.5s Time to wait before cleanup */
tc0->snd_wl2 = vnet_buffer (b0)->tcp.ack_number;
stream_session_accept_notify (&tc0->connection);
tc0->snd_wl2 = vnet_buffer (b0)->tcp.ack_number;
stream_session_accept_notify (&tc0->connection);
- /* Reset SYN-ACK retransmit timer */
+ /* Reset SYN-ACK retransmit and SYN_RCV establish timers */
tcp_retransmit_timer_reset (tc0);
tcp_retransmit_timer_reset (tc0);
+ tcp_timer_reset (tc0, TCP_TIMER_ESTABLISH);
break;
case TCP_STATE_ESTABLISHED:
/* We can get packets in established state here because they
break;
case TCP_STATE_ESTABLISHED:
/* We can get packets in established state here because they
/* If FIN is ACKed */
else if (tc0->snd_una == tc0->snd_una_max)
{
/* If FIN is ACKed */
else if (tc0->snd_una == tc0->snd_una_max)
{
- ASSERT (tcp_fin (tcp0));
tc0->rcv_nxt += 1;
tc0->state = TCP_STATE_FIN_WAIT_2;
TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
tc0->rcv_nxt += 1;
tc0->state = TCP_STATE_FIN_WAIT_2;
TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
- /* Stop all timers, 2MSL will be set lower */
- tcp_connection_timers_reset (tc0);
+ if (tcp_fin (tcp0))
+ {
+ /* Stop all timers, 2MSL will be set lower */
+ tcp_connection_timers_reset (tc0);
+ }
+ else
+ {
+ /* Wait for peer to finish sending its data */
+ tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE,
+ TCP_2MSL_TIME);
+ }
}
break;
case TCP_STATE_FIN_WAIT_2:
}
break;
case TCP_STATE_FIN_WAIT_2:
* acknowledged ("ok") but do not delete the TCB. */
if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
goto drop;
* acknowledged ("ok") but do not delete the TCB. */
if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
goto drop;
-
- /* check if rtx queue is empty and ack CLOSE TODO */
break;
case TCP_STATE_CLOSE_WAIT:
/* Do the same processing as for the ESTABLISHED state. */
break;
case TCP_STATE_CLOSE_WAIT:
/* Do the same processing as for the ESTABLISHED state. */
if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
goto drop;
if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
goto drop;
- /* XXX test that send queue empty */
tc0->state = TCP_STATE_TIME_WAIT;
TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
tc0->state = TCP_STATE_TIME_WAIT;
TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
+ tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
/* move along .. */
break;
case TCP_STATE_FIN_WAIT_1:
/* move along .. */
break;
case TCP_STATE_FIN_WAIT_1:
- tc0->state = TCP_STATE_TIME_WAIT;
- tcp_connection_timers_reset (tc0);
- tcp_timer_set (tc0, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
+ tc0->state = TCP_STATE_CLOSING;
+ tcp_make_ack (tc0, b0);
+ next0 = tcp_next_output (is_ip4);
TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
+ /* Wait for ACK but not forever */
+ tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
break;
case TCP_STATE_FIN_WAIT_2:
/* Got FIN, send ACK! */
break;
case TCP_STATE_FIN_WAIT_2:
/* Got FIN, send ACK! */
/* Reuse buffer to make syn-ack and send */
tcp_make_synack (child0, b0);
next0 = tcp_next_output (is_ip4);
/* Reuse buffer to make syn-ack and send */
tcp_make_synack (child0, b0);
next0 = tcp_next_output (is_ip4);
+ tcp_timer_set (child0, TCP_TIMER_ESTABLISH, TCP_SYN_RCVD_TIME);
drop:
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
drop:
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))