gnrc_tcp: add retransmission timer

This commit is contained in:
Simon Brummer 2020-06-16 13:26:43 +02:00
parent d065b7b613
commit 122616ae7d
4 changed files with 32 additions and 26 deletions

View File

@ -67,8 +67,10 @@ typedef struct _transmission_control_block {
int32_t srtt; /**< Smoothed round trip time */ int32_t srtt; /**< Smoothed round trip time */
int32_t rto; /**< Retransmission timeout duration */ int32_t rto; /**< Retransmission timeout duration */
uint8_t retries; /**< Number of retransmissions */ uint8_t retries; /**< Number of retransmissions */
xtimer_t tim_tout; /**< Timer struct for timeouts */ xtimer_t timer_retransmit; /**< Retransmission timer */
msg_t msg_tout; /**< Message, sent on timeouts */ xtimer_t timer_misc; /**< General purpose timer */
msg_t msg_retransmit; /**< Retransmission timer message */
msg_t msg_misc; /**< General purpose timer message */
gnrc_pktsnip_t *pkt_retransmit; /**< Pointer to packet in "retransmit queue" */ gnrc_pktsnip_t *pkt_retransmit; /**< Pointer to packet in "retransmit queue" */
mbox_t *mbox; /**< TCB mbox for synchronization */ mbox_t *mbox; /**< TCB mbox for synchronization */
uint8_t *rcv_buf_raw; /**< Pointer to the receive buffer */ uint8_t *rcv_buf_raw; /**< Pointer to the receive buffer */

View File

@ -124,7 +124,6 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
msg_t msg; msg_t msg;
msg_t msg_queue[TCP_MSG_QUEUE_SIZE]; msg_t msg_queue[TCP_MSG_QUEUE_SIZE];
mbox_t mbox = MBOX_INIT(msg_queue, TCP_MSG_QUEUE_SIZE); mbox_t mbox = MBOX_INIT(msg_queue, TCP_MSG_QUEUE_SIZE);
xtimer_t connection_timeout;
cb_arg_t connection_timeout_arg = {MSG_TYPE_CONNECTION_TIMEOUT, &mbox}; cb_arg_t connection_timeout_arg = {MSG_TYPE_CONNECTION_TIMEOUT, &mbox};
int ret = 0; int ret = 0;
@ -187,7 +186,7 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
tcb->peer_port = remote->port; tcb->peer_port = remote->port;
/* Setup connection timeout: Put timeout message in TCBs mbox on expiration */ /* Setup connection timeout: Put timeout message in TCBs mbox on expiration */
_setup_timeout(&connection_timeout, CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION, _setup_timeout(&(tcb->timer_misc), CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
_cb_mbox_put_msg, &connection_timeout_arg); _cb_mbox_put_msg, &connection_timeout_arg);
} }
@ -212,8 +211,9 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
* send SYN+ACK we received upon entering SYN_RCVD is never acknowledged * send SYN+ACK we received upon entering SYN_RCVD is never acknowledged
* by the peer. */ * by the peer. */
if ((tcb->state == FSM_STATE_SYN_RCVD) && (tcb->status & STATUS_PASSIVE)) { if ((tcb->state == FSM_STATE_SYN_RCVD) && (tcb->status & STATUS_PASSIVE)) {
_setup_timeout(&connection_timeout, CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION, _setup_timeout(&(tcb->timer_misc),
_cb_mbox_put_msg, &connection_timeout_arg); CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION, _cb_mbox_put_msg,
&connection_timeout_arg);
} }
break; break;
@ -241,7 +241,7 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
/* Cleanup */ /* Cleanup */
_fsm_set_mbox(tcb, NULL); _fsm_set_mbox(tcb, NULL);
xtimer_remove(&connection_timeout); xtimer_remove(&(tcb->timer_misc));
if (tcb->state == FSM_STATE_CLOSED && ret == 0) { if (tcb->state == FSM_STATE_CLOSED && ret == 0) {
ret = -ECONNREFUSED; ret = -ECONNREFUSED;
} }
@ -468,7 +468,6 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
msg_t msg; msg_t msg;
msg_t msg_queue[TCP_MSG_QUEUE_SIZE]; msg_t msg_queue[TCP_MSG_QUEUE_SIZE];
mbox_t mbox = MBOX_INIT(msg_queue, TCP_MSG_QUEUE_SIZE); mbox_t mbox = MBOX_INIT(msg_queue, TCP_MSG_QUEUE_SIZE);
xtimer_t connection_timeout;
cb_arg_t connection_timeout_arg = {MSG_TYPE_CONNECTION_TIMEOUT, &mbox}; cb_arg_t connection_timeout_arg = {MSG_TYPE_CONNECTION_TIMEOUT, &mbox};
xtimer_t user_timeout; xtimer_t user_timeout;
cb_arg_t user_timeout_arg = {MSG_TYPE_USER_SPEC_TIMEOUT, &mbox}; cb_arg_t user_timeout_arg = {MSG_TYPE_USER_SPEC_TIMEOUT, &mbox};
@ -489,7 +488,9 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
/* Setup messaging */ /* Setup messaging */
_fsm_set_mbox(tcb, &mbox); _fsm_set_mbox(tcb, &mbox);
_setup_timeout(&connection_timeout, CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
/* Setup connection timeout: Put timeout message in tcb's mbox on expiration */
_setup_timeout(&(tcb->timer_misc), CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
_cb_mbox_put_msg, &connection_timeout_arg); _cb_mbox_put_msg, &connection_timeout_arg);
if (timeout_duration_us > 0) { if (timeout_duration_us > 0) {
@ -555,7 +556,7 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
DEBUG("gnrc_tcp.c : gnrc_tcp_send() : NOTIFY_USER\n"); DEBUG("gnrc_tcp.c : gnrc_tcp_send() : NOTIFY_USER\n");
/* Connection is alive: Reset Connection Timeout */ /* Connection is alive: Reset Connection Timeout */
_setup_timeout(&connection_timeout, CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION, _setup_timeout(&(tcb->timer_misc), CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
_cb_mbox_put_msg, &connection_timeout_arg); _cb_mbox_put_msg, &connection_timeout_arg);
/* If the window re-opened and we are probing: Stop it */ /* If the window re-opened and we are probing: Stop it */
@ -572,8 +573,8 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
/* Cleanup */ /* Cleanup */
_fsm_set_mbox(tcb, NULL); _fsm_set_mbox(tcb, NULL);
xtimer_remove(&(tcb->timer_misc));
xtimer_remove(&probe_timeout); xtimer_remove(&probe_timeout);
xtimer_remove(&connection_timeout);
xtimer_remove(&user_timeout); xtimer_remove(&user_timeout);
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
return ret; return ret;
@ -588,7 +589,6 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
msg_t msg; msg_t msg;
msg_t msg_queue[TCP_MSG_QUEUE_SIZE]; msg_t msg_queue[TCP_MSG_QUEUE_SIZE];
mbox_t mbox = MBOX_INIT(msg_queue, TCP_MSG_QUEUE_SIZE); mbox_t mbox = MBOX_INIT(msg_queue, TCP_MSG_QUEUE_SIZE);
xtimer_t connection_timeout;
cb_arg_t connection_timeout_arg = {MSG_TYPE_CONNECTION_TIMEOUT, &mbox}; cb_arg_t connection_timeout_arg = {MSG_TYPE_CONNECTION_TIMEOUT, &mbox};
xtimer_t user_timeout; xtimer_t user_timeout;
cb_arg_t user_timeout_arg = {MSG_TYPE_USER_SPEC_TIMEOUT, &mbox}; cb_arg_t user_timeout_arg = {MSG_TYPE_USER_SPEC_TIMEOUT, &mbox};
@ -624,7 +624,9 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
/* Setup messaging */ /* Setup messaging */
_fsm_set_mbox(tcb, &mbox); _fsm_set_mbox(tcb, &mbox);
_setup_timeout(&connection_timeout, CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
/* Setup connection timeout: Put timeout message in tcb's mbox on expiration */
_setup_timeout(&(tcb->timer_misc), CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
_cb_mbox_put_msg, &connection_timeout_arg); _cb_mbox_put_msg, &connection_timeout_arg);
_setup_timeout(&user_timeout, timeout_duration_us, _cb_mbox_put_msg, &user_timeout_arg); _setup_timeout(&user_timeout, timeout_duration_us, _cb_mbox_put_msg, &user_timeout_arg);
@ -672,7 +674,7 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
/* Cleanup */ /* Cleanup */
_fsm_set_mbox(tcb, NULL); _fsm_set_mbox(tcb, NULL);
xtimer_remove(&connection_timeout); xtimer_remove(&(tcb->timer_misc));
xtimer_remove(&user_timeout); xtimer_remove(&user_timeout);
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
return ret; return ret;
@ -685,7 +687,6 @@ void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
msg_t msg; msg_t msg;
msg_t msg_queue[TCP_MSG_QUEUE_SIZE]; msg_t msg_queue[TCP_MSG_QUEUE_SIZE];
mbox_t mbox = MBOX_INIT(msg_queue, TCP_MSG_QUEUE_SIZE); mbox_t mbox = MBOX_INIT(msg_queue, TCP_MSG_QUEUE_SIZE);
xtimer_t connection_timeout;
cb_arg_t connection_timeout_arg = {MSG_TYPE_CONNECTION_TIMEOUT, &mbox}; cb_arg_t connection_timeout_arg = {MSG_TYPE_CONNECTION_TIMEOUT, &mbox};
/* Lock the TCB for this function call */ /* Lock the TCB for this function call */
@ -699,7 +700,9 @@ void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
/* Setup messaging */ /* Setup messaging */
_fsm_set_mbox(tcb, &mbox); _fsm_set_mbox(tcb, &mbox);
_setup_timeout(&connection_timeout, CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
/* Setup connection timeout: Put timeout message in tcb's mbox on expiration */
_setup_timeout(&(tcb->timer_misc), CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION,
_cb_mbox_put_msg, &connection_timeout_arg); _cb_mbox_put_msg, &connection_timeout_arg);
/* Start connection teardown sequence */ /* Start connection teardown sequence */
@ -725,7 +728,7 @@ void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
/* Cleanup */ /* Cleanup */
_fsm_set_mbox(tcb, NULL); _fsm_set_mbox(tcb, NULL);
xtimer_remove(&connection_timeout); xtimer_remove(&(tcb->timer_misc));
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
} }

View File

@ -85,7 +85,7 @@ static int _clear_retransmit(gnrc_tcp_tcb_t *tcb)
{ {
if (tcb->pkt_retransmit != NULL) { if (tcb->pkt_retransmit != NULL) {
gnrc_pktbuf_release(tcb->pkt_retransmit); gnrc_pktbuf_release(tcb->pkt_retransmit);
xtimer_remove(&(tcb->tim_tout)); xtimer_remove(&(tcb->timer_retransmit));
tcb->pkt_retransmit = NULL; tcb->pkt_retransmit = NULL;
} }
return 0; return 0;
@ -100,10 +100,11 @@ static int _clear_retransmit(gnrc_tcp_tcb_t *tcb)
*/ */
static int _restart_timewait_timer(gnrc_tcp_tcb_t *tcb) static int _restart_timewait_timer(gnrc_tcp_tcb_t *tcb)
{ {
xtimer_remove(&tcb->tim_tout); xtimer_remove(&tcb->timer_retransmit);
tcb->msg_tout.type = MSG_TYPE_TIMEWAIT; tcb->msg_retransmit.type = MSG_TYPE_TIMEWAIT;
tcb->msg_tout.content.ptr = (void *)tcb; tcb->msg_retransmit.content.ptr = (void *)tcb;
xtimer_set_msg(&tcb->tim_tout, 2 * CONFIG_GNRC_TCP_MSL, &tcb->msg_tout, gnrc_tcp_pid); xtimer_set_msg(&(tcb->timer_retransmit), 2 * CONFIG_GNRC_TCP_MSL, &(tcb->msg_retransmit),
gnrc_tcp_pid);
return 0; return 0;
} }

View File

@ -412,9 +412,9 @@ int _pkt_setup_retransmit(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *pkt, const bool r
} }
/* Setup retransmission timer, msg to TCP thread with ptr to TCB */ /* Setup retransmission timer, msg to TCP thread with ptr to TCB */
tcb->msg_tout.type = MSG_TYPE_RETRANSMISSION; tcb->msg_retransmit.type = MSG_TYPE_RETRANSMISSION;
tcb->msg_tout.content.ptr = (void *) tcb; tcb->msg_retransmit.content.ptr = (void *) tcb;
xtimer_set_msg(&tcb->tim_tout, tcb->rto, &tcb->msg_tout, gnrc_tcp_pid); xtimer_set_msg(&tcb->timer_retransmit, tcb->rto, &tcb->msg_retransmit, gnrc_tcp_pid);
return 0; return 0;
} }
@ -438,7 +438,7 @@ int _pkt_acknowledge(gnrc_tcp_tcb_t *tcb, const uint32_t ack)
/* If segment can be acknowledged -> stop timer, release packet from pktbuf and update rto. */ /* If segment can be acknowledged -> stop timer, release packet from pktbuf and update rto. */
if (LSS_32_BIT(seg, ack)) { if (LSS_32_BIT(seg, ack)) {
xtimer_remove(&(tcb->tim_tout)); xtimer_remove(&(tcb->timer_retransmit));
gnrc_pktbuf_release(tcb->pkt_retransmit); gnrc_pktbuf_release(tcb->pkt_retransmit);
tcb->pkt_retransmit = NULL; tcb->pkt_retransmit = NULL;