gnrc_tcp: Overhaul all debug messages

This commit is contained in:
Simon Brummer 2020-10-09 11:14:42 +02:00
parent 632a3613b5
commit 0cc06a5993
8 changed files with 373 additions and 105 deletions

View File

@ -52,20 +52,26 @@ static evtimer_t _tcp_mbox_timer;
static void _sched_mbox(evtimer_mbox_event_t *event, uint32_t offset, static void _sched_mbox(evtimer_mbox_event_t *event, uint32_t offset,
uint16_t type, mbox_t *mbox) uint16_t type, mbox_t *mbox)
{ {
TCP_DEBUG_ENTER;
event->event.offset = offset; event->event.offset = offset;
event->msg.type = type; event->msg.type = type;
evtimer_add_mbox(&_tcp_mbox_timer, event, mbox); evtimer_add_mbox(&_tcp_mbox_timer, event, mbox);
TCP_DEBUG_LEAVE;
} }
static void _sched_connection_timeout(evtimer_mbox_event_t *event, mbox_t *mbox) static void _sched_connection_timeout(evtimer_mbox_event_t *event, mbox_t *mbox)
{ {
TCP_DEBUG_ENTER;
_sched_mbox(event, CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION_MS, _sched_mbox(event, CONFIG_GNRC_TCP_CONNECTION_TIMEOUT_DURATION_MS,
MSG_TYPE_CONNECTION_TIMEOUT, mbox); MSG_TYPE_CONNECTION_TIMEOUT, mbox);
TCP_DEBUG_LEAVE;
} }
static void _unsched_mbox(evtimer_mbox_event_t *event) static void _unsched_mbox(evtimer_mbox_event_t *event)
{ {
TCP_DEBUG_ENTER;
evtimer_del(&_tcp_mbox_timer, (evtimer_event_t *)event); evtimer_del(&_tcp_mbox_timer, (evtimer_event_t *)event);
TCP_DEBUG_LEAVE;
} }
/** /**
@ -88,6 +94,7 @@ static void _unsched_mbox(evtimer_mbox_event_t *event)
static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote, static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
const uint8_t *local_addr, uint16_t local_port, int passive) const uint8_t *local_addr, uint16_t local_port, int passive)
{ {
TCP_DEBUG_ENTER;
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);
@ -99,6 +106,8 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
/* TCB is already connected: Return -EISCONN */ /* TCB is already connected: Return -EISCONN */
if (tcb->state != FSM_STATE_CLOSED) { if (tcb->state != FSM_STATE_CLOSED) {
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
TCP_DEBUG_ERROR("-EISCONN: TCB already connected.");
TCP_DEBUG_LEAVE;
return -EISCONN; return -EISCONN;
} }
@ -114,7 +123,8 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
if (local_addr && tcb->address_family == AF_INET6) { if (local_addr && tcb->address_family == AF_INET6) {
/* Store given address in TCB */ /* Store given address in TCB */
if (memcpy(tcb->local_addr, local_addr, sizeof(tcb->local_addr)) == NULL) { if (memcpy(tcb->local_addr, local_addr, sizeof(tcb->local_addr)) == NULL) {
DEBUG("gnrc_tcp.c : _gnrc_tcp_open() : Invalid peer addr\n"); TCP_DEBUG_ERROR("-EINVAL: Invalid peer address.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
@ -140,7 +150,8 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
/* Store Address information in TCB */ /* Store Address information in TCB */
if (memcpy(tcb->peer_addr, remote->addr.ipv6, sizeof(tcb->peer_addr)) == NULL) { if (memcpy(tcb->peer_addr, remote->addr.ipv6, sizeof(tcb->peer_addr)) == NULL) {
DEBUG("gnrc_tcp.c : _gnrc_tcp_open() : Invalid peer addr\n"); TCP_DEBUG_ERROR("-EINVAL: Invalid peer address.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
tcb->ll_iface = remote->netif; tcb->ll_iface = remote->netif;
@ -158,10 +169,10 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
/* Call FSM with event: CALL_OPEN */ /* Call FSM with event: CALL_OPEN */
ret = _fsm(tcb, FSM_EVENT_CALL_OPEN, NULL, NULL, 0); ret = _fsm(tcb, FSM_EVENT_CALL_OPEN, NULL, NULL, 0);
if (ret == -ENOMEM) { if (ret == -ENOMEM) {
DEBUG("gnrc_tcp.c : _gnrc_tcp_open() : Out of receive buffers.\n"); TCP_DEBUG_ERROR("-ENOMEM: All receive buffers are in use.");
} }
else if (ret == -EADDRINUSE) { else if (ret == -EADDRINUSE) {
DEBUG("gnrc_tcp.c : _gnrc_tcp_open() : local_port is already in use.\n"); TCP_DEBUG_ERROR("-EADDRINUSE: local_port is already in use.");
} }
/* Wait until a connection was established or closed */ /* Wait until a connection was established or closed */
@ -170,7 +181,7 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
mbox_get(&mbox, &msg); mbox_get(&mbox, &msg);
switch (msg.type) { switch (msg.type) {
case MSG_TYPE_NOTIFY_USER: case MSG_TYPE_NOTIFY_USER:
DEBUG("gnrc_tcp.c : _gnrc_tcp_open() : MSG_TYPE_NOTIFY_USER\n"); TCP_DEBUG_INFO("Received MSG_TYPE_NOTIFY_USER.");
/* Setup a timeout to be able to revert back to LISTEN state, in case the /* Setup a timeout to be able to revert back to LISTEN state, in case the
* send SYN+ACK we received upon entering SYN_RCVD is never acknowledged * send SYN+ACK we received upon entering SYN_RCVD is never acknowledged
@ -182,7 +193,7 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
break; break;
case MSG_TYPE_CONNECTION_TIMEOUT: case MSG_TYPE_CONNECTION_TIMEOUT:
DEBUG("gnrc_tcp.c : _gnrc_tcp_open() : CONNECTION_TIMEOUT\n"); TCP_DEBUG_INFO("Received MSG_TYPE_CONNECTION_TIMEOUT.");
/* The connection establishment attempt timed out: /* The connection establishment attempt timed out:
* 1) Active connections return -ETIMEOUT. * 1) Active connections return -ETIMEOUT.
@ -194,12 +205,13 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
} }
else { else {
_fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0); _fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0);
TCP_DEBUG_ERROR("-ETIMEDOUT: Connection timed out.");
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
} }
break; break;
default: default:
DEBUG("gnrc_tcp.c : _gnrc_tcp_open() : other message type\n"); TCP_DEBUG_ERROR("Received unexpected message.");
} }
} }
@ -207,9 +219,11 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
_fsm_set_mbox(tcb, NULL); _fsm_set_mbox(tcb, NULL);
_unsched_mbox(&tcb->event_misc); _unsched_mbox(&tcb->event_misc);
if (tcb->state == FSM_STATE_CLOSED && ret == 0) { if (tcb->state == FSM_STATE_CLOSED && ret == 0) {
TCP_DEBUG_ERROR("-ECONNREFUSED: Connection refused by peer.");
ret = -ECONNREFUSED; ret = -ECONNREFUSED;
} }
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
TCP_DEBUG_LEAVE;
return ret; return ret;
} }
@ -217,8 +231,11 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote,
int gnrc_tcp_ep_init(gnrc_tcp_ep_t *ep, int family, const uint8_t *addr, size_t addr_size, int gnrc_tcp_ep_init(gnrc_tcp_ep_t *ep, int family, const uint8_t *addr, size_t addr_size,
uint16_t port, uint16_t netif) uint16_t port, uint16_t netif)
{ {
TCP_DEBUG_ENTER;
#ifdef MODULE_GNRC_IPV6 #ifdef MODULE_GNRC_IPV6
if (family != AF_INET6) { if (family != AF_INET6) {
TCP_DEBUG_ERROR("-EAFNOSUPPORT: Parameter family is not AF_INET6.")
TCP_DEBUG_LEAVE;
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
} }
@ -229,23 +246,29 @@ int gnrc_tcp_ep_init(gnrc_tcp_ep_t *ep, int family, const uint8_t *addr, size_t
memcpy(ep->addr.ipv6, addr, sizeof(ipv6_addr_t)); memcpy(ep->addr.ipv6, addr, sizeof(ipv6_addr_t));
} }
else { else {
TCP_DEBUG_ERROR("-EINVAL: Parameter addr is invalid.")
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
#else #else
/* Suppress Compiler Warnings */ /* Suppress Compiler Warnings */
(void) addr; (void) addr;
(void) addr_size; (void) addr_size;
TCP_DEBUG_ERROR("-EAFNOSUPPORT: No network layer configured.")
TCP_DEBUG_LEAVE;
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
#endif #endif
ep->family = family; ep->family = family;
ep->port = port; ep->port = port;
ep->netif = netif; ep->netif = netif;
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
int gnrc_tcp_ep_from_str(gnrc_tcp_ep_t *ep, const char *str) int gnrc_tcp_ep_from_str(gnrc_tcp_ep_t *ep, const char *str)
{ {
TCP_DEBUG_ENTER;
assert(str); assert(str);
unsigned port = 0; unsigned port = 0;
@ -257,10 +280,14 @@ int gnrc_tcp_ep_from_str(gnrc_tcp_ep_t *ep, const char *str)
/* 1) Ensure that str contains a single pair of brackets */ /* 1) Ensure that str contains a single pair of brackets */
if (!addr_begin || !addr_end || strchr(addr_begin + 1, '[') || strchr(addr_end + 1, ']')) { if (!addr_begin || !addr_end || strchr(addr_begin + 1, '[') || strchr(addr_end + 1, ']')) {
TCP_DEBUG_ERROR("-EINVAL: Invalid address string.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
/* 2) Ensure that the first character is the opening bracket */ /* 2) Ensure that the first character is the opening bracket */
else if (addr_begin != str) { else if (addr_begin != str) {
TCP_DEBUG_ERROR("-EINVAL: Invalid address string.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
@ -269,12 +296,16 @@ int gnrc_tcp_ep_from_str(gnrc_tcp_ep_t *ep, const char *str)
if (port_begin) { if (port_begin) {
/* 3.1) Ensure that there are characters left to parse after ':'. */ /* 3.1) Ensure that there are characters left to parse after ':'. */
if (*(++port_begin) == '\0') { if (*(++port_begin) == '\0') {
TCP_DEBUG_ERROR("-EINVAL: Invalid address string.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
/* 3.2) Ensure that port is a number (atol, does not report errors) */ /* 3.2) Ensure that port is a number (atol, does not report errors) */
for (char *ptr = port_begin; *ptr; ++ptr) { for (char *ptr = port_begin; *ptr; ++ptr) {
if ((*ptr < '0') || ('9' < *ptr)) { if ((*ptr < '0') || ('9' < *ptr)) {
TCP_DEBUG_ERROR("-EINVAL: Invalid address string.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
} }
@ -282,6 +313,8 @@ int gnrc_tcp_ep_from_str(gnrc_tcp_ep_t *ep, const char *str)
/* 3.3) Read and verify that given number port is within range */ /* 3.3) Read and verify that given number port is within range */
port = atol(port_begin); port = atol(port_begin);
if (port > 0xFFFF) { if (port > 0xFFFF) {
TCP_DEBUG_ERROR("-EINVAL: Invalid address string.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
} }
@ -291,12 +324,16 @@ int gnrc_tcp_ep_from_str(gnrc_tcp_ep_t *ep, const char *str)
if (if_begin) { if (if_begin) {
/* 4.1) Ensure that the identifier is not empty and within brackets. */ /* 4.1) Ensure that the identifier is not empty and within brackets. */
if (addr_end <= (++if_begin)) { if (addr_end <= (++if_begin)) {
TCP_DEBUG_ERROR("-EINVAL: Invalid address string.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
/* 4.2) Ensure that the identifier is a number (atol, does not report errors) */ /* 4.2) Ensure that the identifier is a number (atol, does not report errors) */
for (char *ptr = if_begin; ptr != addr_end; ++ptr) { for (char *ptr = if_begin; ptr != addr_end; ++ptr) {
if ((*ptr < '0') || ('9' < *ptr)) { if ((*ptr < '0') || ('9' < *ptr)) {
TCP_DEBUG_ERROR("-EINVAL: Invalid address string.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
} }
@ -320,11 +357,15 @@ int gnrc_tcp_ep_from_str(gnrc_tcp_ep_t *ep, const char *str)
tmp[len] = '\0'; tmp[len] = '\0';
} }
else { else {
TCP_DEBUG_ERROR("-EINVAL: Invalid address string.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
/* 5.2) Try to read address into endpoint. */ /* 5.2) Try to read address into endpoint. */
if (ipv6_addr_from_str((ipv6_addr_t *) ep->addr.ipv6, tmp) == NULL) { if (ipv6_addr_from_str((ipv6_addr_t *) ep->addr.ipv6, tmp) == NULL) {
TCP_DEBUG_ERROR("-EINVAL: Invalid address string.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
ep->family = AF_INET6; ep->family = AF_INET6;
@ -332,16 +373,20 @@ int gnrc_tcp_ep_from_str(gnrc_tcp_ep_t *ep, const char *str)
/* Suppress Compiler Warnings */ /* Suppress Compiler Warnings */
(void) port; (void) port;
(void) netif; (void) netif;
TCP_DEBUG_ERROR("-EINVAL: Invalid address string.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
#endif #endif
ep->port = (uint16_t) port; ep->port = (uint16_t) port;
ep->netif = (uint16_t) netif; ep->netif = (uint16_t) netif;
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
int gnrc_tcp_init(void) int gnrc_tcp_init(void)
{ {
TCP_DEBUG_ENTER;
/* Initialize TCB list */ /* Initialize TCB list */
_rcvbuf_init(); _rcvbuf_init();
@ -349,26 +394,31 @@ int gnrc_tcp_init(void)
evtimer_init_mbox(&_tcp_mbox_timer); evtimer_init_mbox(&_tcp_mbox_timer);
/* Start TCP processing thread */ /* Start TCP processing thread */
return _gnrc_tcp_event_loop_init(); kernel_pid_t pid = _gnrc_tcp_event_loop_init();
TCP_DEBUG_LEAVE;
return pid;
} }
void gnrc_tcp_tcb_init(gnrc_tcp_tcb_t *tcb) void gnrc_tcp_tcb_init(gnrc_tcp_tcb_t *tcb)
{ {
TCP_DEBUG_ENTER;
memset(tcb, 0, sizeof(gnrc_tcp_tcb_t)); memset(tcb, 0, sizeof(gnrc_tcp_tcb_t));
#ifdef MODULE_GNRC_IPV6 #ifdef MODULE_GNRC_IPV6
tcb->address_family = AF_INET6; tcb->address_family = AF_INET6;
#else #else
DEBUG("gnrc_tcp.c : gnrc_tcp_tcb_init() : Address unspec, add netlayer module to makefile\n"); TCP_DEBUG_ERROR("Missing network layer. Add module to makefile.");
#endif #endif
tcb->rtt_var = RTO_UNINITIALIZED; tcb->rtt_var = RTO_UNINITIALIZED;
tcb->srtt = RTO_UNINITIALIZED; tcb->srtt = RTO_UNINITIALIZED;
tcb->rto = RTO_UNINITIALIZED; tcb->rto = RTO_UNINITIALIZED;
mutex_init(&(tcb->fsm_lock)); mutex_init(&(tcb->fsm_lock));
mutex_init(&(tcb->function_lock)); mutex_init(&(tcb->function_lock));
TCP_DEBUG_LEAVE;
} }
int gnrc_tcp_open_active(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote, uint16_t local_port) int gnrc_tcp_open_active(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote, uint16_t local_port)
{ {
TCP_DEBUG_ENTER;
assert(tcb != NULL); assert(tcb != NULL);
assert(remote != NULL); assert(remote != NULL);
assert(remote->port != PORT_UNSPEC); assert(remote->port != PORT_UNSPEC);
@ -376,23 +426,32 @@ int gnrc_tcp_open_active(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *remote, uint1
/* Check if given AF-Family in remote is supported */ /* Check if given AF-Family in remote is supported */
#ifdef MODULE_GNRC_IPV6 #ifdef MODULE_GNRC_IPV6
if (remote->family != AF_INET6) { if (remote->family != AF_INET6) {
TCP_DEBUG_ERROR("-EAFNOSUPPORT: remote AF-Family not supported.");
TCP_DEBUG_LEAVE;
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
} }
#else #else
TCP_DEBUG_ERROR("-EAFNOSUPPORT: AF-Family not supported.");
TCP_DEBUG_LEAVE;
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
#endif #endif
/* Check if AF-Family for target address matches internally used AF-Family */ /* Check if AF-Family for target address matches internally used AF-Family */
if (remote->family != tcb->address_family) { if (remote->family != tcb->address_family) {
TCP_DEBUG_ERROR("-EINVAL: local and remote AF-Family don't match.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
/* Proceed with connection opening */ /* Proceed with connection opening */
return _gnrc_tcp_open(tcb, remote, NULL, local_port, 0); int res = _gnrc_tcp_open(tcb, remote, NULL, local_port, 0);
TCP_DEBUG_LEAVE;
return res;
} }
int gnrc_tcp_open_passive(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *local) int gnrc_tcp_open_passive(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *local)
{ {
TCP_DEBUG_ENTER;
assert(tcb != NULL); assert(tcb != NULL);
assert(local != NULL); assert(local != NULL);
assert(local->port != PORT_UNSPEC); assert(local->port != PORT_UNSPEC);
@ -400,17 +459,25 @@ int gnrc_tcp_open_passive(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *local)
/* Check if given AF-Family in local is supported */ /* Check if given AF-Family in local is supported */
#ifdef MODULE_GNRC_IPV6 #ifdef MODULE_GNRC_IPV6
if (local->family != AF_INET6) { if (local->family != AF_INET6) {
TCP_DEBUG_ERROR("-EAFNOSUPPORT: AF-Family not supported.");
TCP_DEBUG_LEAVE;
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
} }
/* Check if AF-Family matches internally used AF-Family */ /* Check if AF-Family matches internally used AF-Family */
if (local->family != tcb->address_family) { if (local->family != tcb->address_family) {
TCP_DEBUG_ERROR("-EINVAL: AF-Family doesn't match.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
/* Proceed with connection opening */ /* Proceed with connection opening */
return _gnrc_tcp_open(tcb, NULL, local->addr.ipv6, local->port, 1); int res = _gnrc_tcp_open(tcb, NULL, local->addr.ipv6, local->port, 1);
TCP_DEBUG_LEAVE;
return res;
#else #else
TCP_DEBUG_ERROR("-EAFNOSUPPORT: AF-Family not supported.");
TCP_DEBUG_LEAVE;
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
#endif #endif
} }
@ -418,6 +485,7 @@ int gnrc_tcp_open_passive(gnrc_tcp_tcb_t *tcb, const gnrc_tcp_ep_t *local)
ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len, ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
const uint32_t timeout_duration_ms) const uint32_t timeout_duration_ms)
{ {
TCP_DEBUG_ENTER;
assert(tcb != NULL); assert(tcb != NULL);
assert(data != NULL); assert(data != NULL);
@ -436,6 +504,8 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
/* Check if connection is in a valid state */ /* Check if connection is in a valid state */
if (tcb->state != FSM_STATE_ESTABLISHED && tcb->state != FSM_STATE_CLOSE_WAIT) { if (tcb->state != FSM_STATE_ESTABLISHED && tcb->state != FSM_STATE_CLOSE_WAIT) {
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
TCP_DEBUG_ERROR("-ENOTCONN: TCB is not connected.");
TCP_DEBUG_LEAVE;
return -ENOTCONN; return -ENOTCONN;
} }
@ -454,6 +524,7 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
while (ret == 0 || tcb->pkt_retransmit != NULL) { while (ret == 0 || tcb->pkt_retransmit != NULL) {
/* Check if the connections state is closed. If so, a reset was received */ /* Check if the connections state is closed. If so, a reset was received */
if (tcb->state == FSM_STATE_CLOSED) { if (tcb->state == FSM_STATE_CLOSED) {
TCP_DEBUG_ERROR("-ECONNRESET: Connection was reset by peer.");
ret = -ECONNRESET; ret = -ECONNRESET;
break; break;
} }
@ -480,19 +551,21 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
mbox_get(&mbox, &msg); mbox_get(&mbox, &msg);
switch (msg.type) { switch (msg.type) {
case MSG_TYPE_CONNECTION_TIMEOUT: case MSG_TYPE_CONNECTION_TIMEOUT:
DEBUG("gnrc_tcp.c : gnrc_tcp_send() : CONNECTION_TIMEOUT\n"); TCP_DEBUG_INFO("Received MSG_TYPE_CONNECTION_TIMEOUT.");
_fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0); _fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0);
TCP_DEBUG_ERROR("-ECONNABORTED: Connection timed out.");
ret = -ECONNABORTED; ret = -ECONNABORTED;
break; break;
case MSG_TYPE_USER_SPEC_TIMEOUT: case MSG_TYPE_USER_SPEC_TIMEOUT:
DEBUG("gnrc_tcp.c : gnrc_tcp_send() : USER_SPEC_TIMEOUT\n"); TCP_DEBUG_INFO("Received MSG_TYPE_USER_SPEC_TIMEOUT.");
_fsm(tcb, FSM_EVENT_CLEAR_RETRANSMIT, NULL, NULL, 0); _fsm(tcb, FSM_EVENT_CLEAR_RETRANSMIT, NULL, NULL, 0);
TCP_DEBUG_ERROR("-ETIMEDOUT: User specified timeout expired.");
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
break; break;
case MSG_TYPE_PROBE_TIMEOUT: case MSG_TYPE_PROBE_TIMEOUT:
DEBUG("gnrc_tcp.c : gnrc_tcp_send() : PROBE_TIMEOUT\n"); TCP_DEBUG_INFO("Received MSG_TYPE_PROBE_TIMEOUT.");
/* Send probe */ /* Send probe */
_fsm(tcb, FSM_EVENT_SEND_PROBE, NULL, NULL, 0); _fsm(tcb, FSM_EVENT_SEND_PROBE, NULL, NULL, 0);
probe_timeout_duration_ms += probe_timeout_duration_ms; probe_timeout_duration_ms += probe_timeout_duration_ms;
@ -507,7 +580,7 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
break; break;
case MSG_TYPE_NOTIFY_USER: case MSG_TYPE_NOTIFY_USER:
DEBUG("gnrc_tcp.c : gnrc_tcp_send() : NOTIFY_USER\n"); TCP_DEBUG_INFO("Received MSG_TYPE_NOTIFY_USER.");
/* Connection is alive: Reset Connection Timeout */ /* Connection is alive: Reset Connection Timeout */
_unsched_mbox(&tcb->event_misc); _unsched_mbox(&tcb->event_misc);
@ -521,7 +594,7 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
break; break;
default: default:
DEBUG("gnrc_tcp.c : gnrc_tcp_send() : other message type\n"); TCP_DEBUG_ERROR("Received unexpected message.");
} }
} }
@ -531,12 +604,14 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len,
_unsched_mbox(&event_probe_timeout); _unsched_mbox(&event_probe_timeout);
_unsched_mbox(&event_user_timeout); _unsched_mbox(&event_user_timeout);
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
TCP_DEBUG_LEAVE;
return ret; return ret;
} }
ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len, ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
const uint32_t timeout_duration_ms) const uint32_t timeout_duration_ms)
{ {
TCP_DEBUG_ENTER;
assert(tcb != NULL); assert(tcb != NULL);
assert(data != NULL); assert(data != NULL);
@ -553,6 +628,8 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
if (tcb->state != FSM_STATE_ESTABLISHED && tcb->state != FSM_STATE_FIN_WAIT_1 && if (tcb->state != FSM_STATE_ESTABLISHED && tcb->state != FSM_STATE_FIN_WAIT_1 &&
tcb->state != FSM_STATE_FIN_WAIT_2 && tcb->state != FSM_STATE_CLOSE_WAIT) { tcb->state != FSM_STATE_FIN_WAIT_2 && tcb->state != FSM_STATE_CLOSE_WAIT) {
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
TCP_DEBUG_ERROR("-ENOTCONN: TCB is not connected.");
TCP_DEBUG_LEAVE;
return -ENOTCONN; return -ENOTCONN;
} }
@ -561,6 +638,7 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
if (tcb->state == FSM_STATE_CLOSE_WAIT) { if (tcb->state == FSM_STATE_CLOSE_WAIT) {
ret = _fsm(tcb, FSM_EVENT_CALL_RECV, NULL, data, max_len); ret = _fsm(tcb, FSM_EVENT_CALL_RECV, NULL, data, max_len);
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
TCP_DEBUG_LEAVE;
return ret; return ret;
} }
@ -568,9 +646,11 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
if (timeout_duration_ms == 0) { if (timeout_duration_ms == 0) {
ret = _fsm(tcb, FSM_EVENT_CALL_RECV, NULL, data, max_len); ret = _fsm(tcb, FSM_EVENT_CALL_RECV, NULL, data, max_len);
if (ret == 0) { if (ret == 0) {
TCP_DEBUG_ERROR("-EAGAIN: Not data available, try later again.");
ret = -EAGAIN; ret = -EAGAIN;
} }
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
TCP_DEBUG_LEAVE;
return ret; return ret;
} }
@ -589,6 +669,7 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
while (ret == 0) { while (ret == 0) {
/* Check if the connections state is closed. If so, a reset was received */ /* Check if the connections state is closed. If so, a reset was received */
if (tcb->state == FSM_STATE_CLOSED) { if (tcb->state == FSM_STATE_CLOSED) {
TCP_DEBUG_ERROR("-ECONNRESET: Connection was reset by peer.");
ret = -ECONNRESET; ret = -ECONNRESET;
break; break;
} }
@ -606,23 +687,25 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
mbox_get(&mbox, &msg); mbox_get(&mbox, &msg);
switch (msg.type) { switch (msg.type) {
case MSG_TYPE_CONNECTION_TIMEOUT: case MSG_TYPE_CONNECTION_TIMEOUT:
DEBUG("gnrc_tcp.c : gnrc_tcp_recv() : CONNECTION_TIMEOUT\n"); TCP_DEBUG_INFO("Received MSG_TYPE_CONNECTION_TIMEOUT.");
_fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0); _fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0);
TCP_DEBUG_ERROR("-ECONNABORTED: Connection timed out.");
ret = -ECONNABORTED; ret = -ECONNABORTED;
break; break;
case MSG_TYPE_USER_SPEC_TIMEOUT: case MSG_TYPE_USER_SPEC_TIMEOUT:
DEBUG("gnrc_tcp.c : gnrc_tcp_recv() : USER_SPEC_TIMEOUT\n"); TCP_DEBUG_INFO("Received MSG_TYPE_USER_SPEC_TIMEOUT.");
_fsm(tcb, FSM_EVENT_CLEAR_RETRANSMIT, NULL, NULL, 0); _fsm(tcb, FSM_EVENT_CLEAR_RETRANSMIT, NULL, NULL, 0);
TCP_DEBUG_ERROR("-ETIMEDOUT: User specified timeout expired.");
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
break; break;
case MSG_TYPE_NOTIFY_USER: case MSG_TYPE_NOTIFY_USER:
DEBUG("gnrc_tcp.c : gnrc_tcp_recv() : NOTIFY_USER\n"); TCP_DEBUG_INFO("Received MSG_TYPE_NOTIFY_USER.");
break; break;
default: default:
DEBUG("gnrc_tcp.c : gnrc_tcp_recv() : other message type\n"); TCP_DEBUG_ERROR("Received unexpected message.");
} }
} }
} }
@ -632,11 +715,13 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len,
_unsched_mbox(&tcb->event_misc); _unsched_mbox(&tcb->event_misc);
_unsched_mbox(&event_user_timeout); _unsched_mbox(&event_user_timeout);
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
TCP_DEBUG_LEAVE;
return ret; return ret;
} }
void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb) void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
{ {
TCP_DEBUG_ENTER;
assert(tcb != NULL); assert(tcb != NULL);
msg_t msg; msg_t msg;
@ -649,6 +734,7 @@ void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
/* Return if connection is closed */ /* Return if connection is closed */
if (tcb->state == FSM_STATE_CLOSED) { if (tcb->state == FSM_STATE_CLOSED) {
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
TCP_DEBUG_LEAVE;
return; return;
} }
@ -666,16 +752,16 @@ void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
mbox_get(&mbox, &msg); mbox_get(&mbox, &msg);
switch (msg.type) { switch (msg.type) {
case MSG_TYPE_CONNECTION_TIMEOUT: case MSG_TYPE_CONNECTION_TIMEOUT:
DEBUG("gnrc_tcp.c : gnrc_tcp_close() : CONNECTION_TIMEOUT\n"); TCP_DEBUG_INFO("Received MSG_TYPE_CONNECTION_TIMEOUT.");
_fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0); _fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0);
break; break;
case MSG_TYPE_NOTIFY_USER: case MSG_TYPE_NOTIFY_USER:
DEBUG("gnrc_tcp.c : gnrc_tcp_close() : NOTIFY_USER\n"); TCP_DEBUG_INFO("Received MSG_TYPE_NOTIFY_USER.");
break; break;
default: default:
DEBUG("gnrc_tcp.c : gnrc_tcp_close() : other message type\n"); TCP_DEBUG_ERROR("Received unexpected message.");
} }
} }
@ -683,10 +769,12 @@ void gnrc_tcp_close(gnrc_tcp_tcb_t *tcb)
_fsm_set_mbox(tcb, NULL); _fsm_set_mbox(tcb, NULL);
_unsched_mbox(&tcb->event_misc); _unsched_mbox(&tcb->event_misc);
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
TCP_DEBUG_LEAVE;
} }
void gnrc_tcp_abort(gnrc_tcp_tcb_t *tcb) void gnrc_tcp_abort(gnrc_tcp_tcb_t *tcb)
{ {
TCP_DEBUG_ENTER;
assert(tcb != NULL); assert(tcb != NULL);
/* Lock the TCB for this function call */ /* Lock the TCB for this function call */
@ -696,36 +784,48 @@ void gnrc_tcp_abort(gnrc_tcp_tcb_t *tcb)
_fsm(tcb, FSM_EVENT_CALL_ABORT, NULL, NULL, 0); _fsm(tcb, FSM_EVENT_CALL_ABORT, NULL, NULL, 0);
} }
mutex_unlock(&(tcb->function_lock)); mutex_unlock(&(tcb->function_lock));
TCP_DEBUG_LEAVE;
} }
int gnrc_tcp_calc_csum(const gnrc_pktsnip_t *hdr, const gnrc_pktsnip_t *pseudo_hdr) int gnrc_tcp_calc_csum(const gnrc_pktsnip_t *hdr, const gnrc_pktsnip_t *pseudo_hdr)
{ {
TCP_DEBUG_ENTER;
uint16_t csum; uint16_t csum;
if ((hdr == NULL) || (pseudo_hdr == NULL)) { if ((hdr == NULL) || (pseudo_hdr == NULL)) {
TCP_DEBUG_ERROR("-EFAULT: hdr or pseudo_hdr is NULL.");
TCP_DEBUG_LEAVE;
return -EFAULT; return -EFAULT;
} }
if (hdr->type != GNRC_NETTYPE_TCP) { if (hdr->type != GNRC_NETTYPE_TCP) {
TCP_DEBUG_ERROR("-EBADMSG: Variable hdr is no TCP header.");
TCP_DEBUG_LEAVE;
return -EBADMSG; return -EBADMSG;
} }
csum = _pkt_calc_csum(hdr, pseudo_hdr, hdr->next); csum = _pkt_calc_csum(hdr, pseudo_hdr, hdr->next);
if (csum == 0) { if (csum == 0) {
TCP_DEBUG_ERROR("-ENOENT");
TCP_DEBUG_LEAVE;
return -ENOENT; return -ENOENT;
} }
((tcp_hdr_t *)hdr->data)->checksum = byteorder_htons(csum); ((tcp_hdr_t *)hdr->data)->checksum = byteorder_htons(csum);
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
gnrc_pktsnip_t *gnrc_tcp_hdr_build(gnrc_pktsnip_t *payload, uint16_t src, uint16_t dst) gnrc_pktsnip_t *gnrc_tcp_hdr_build(gnrc_pktsnip_t *payload, uint16_t src, uint16_t dst)
{ {
TCP_DEBUG_ENTER;
gnrc_pktsnip_t *res; gnrc_pktsnip_t *res;
tcp_hdr_t *hdr; tcp_hdr_t *hdr;
/* Allocate header */ /* Allocate header */
res = gnrc_pktbuf_add(payload, NULL, sizeof(tcp_hdr_t), GNRC_NETTYPE_TCP); res = gnrc_pktbuf_add(payload, NULL, sizeof(tcp_hdr_t), GNRC_NETTYPE_TCP);
if (res == NULL) { if (res == NULL) {
DEBUG("gnrc_tcp.c : gnrc_tcp_hdr_build() : No space left in packet buffer\n"); TCP_DEBUG_ERROR("pktbuf is full.");
TCP_DEBUG_LEAVE;
return NULL; return NULL;
} }
hdr = (tcp_hdr_t *) res->data; hdr = (tcp_hdr_t *) res->data;
@ -738,5 +838,7 @@ gnrc_pktsnip_t *gnrc_tcp_hdr_build(gnrc_pktsnip_t *payload, uint16_t src, uint16
hdr->dst_port = byteorder_htons(dst); hdr->dst_port = byteorder_htons(dst);
hdr->checksum = byteorder_htons(0); hdr->checksum = byteorder_htons(0);
hdr->off_ctl = byteorder_htons(TCP_HDR_OFFSET_MIN); hdr->off_ctl = byteorder_htons(TCP_HDR_OFFSET_MIN);
TCP_DEBUG_LEAVE;
return res; return res;
} }

View File

@ -60,15 +60,19 @@ static kernel_pid_t _tcp_eventloop_pid = KERNEL_PID_UNDEF;
void _gnrc_tcp_event_loop_sched(evtimer_msg_event_t *event, uint32_t offset, void _gnrc_tcp_event_loop_sched(evtimer_msg_event_t *event, uint32_t offset,
uint16_t type, void *context) uint16_t type, void *context)
{ {
TCP_DEBUG_ENTER;
event->event.offset = offset; event->event.offset = offset;
event->msg.type = type; event->msg.type = type;
event->msg.content.ptr = context; event->msg.content.ptr = context;
evtimer_add_msg(&_tcp_msg_timer, event, _tcp_eventloop_pid); evtimer_add_msg(&_tcp_msg_timer, event, _tcp_eventloop_pid);
TCP_DEBUG_LEAVE;
} }
void _gnrc_tcp_event_loop_unsched(evtimer_msg_event_t *event) void _gnrc_tcp_event_loop_unsched(evtimer_msg_event_t *event)
{ {
TCP_DEBUG_ENTER;
evtimer_del(&_tcp_msg_timer, (evtimer_event_t *)event); evtimer_del(&_tcp_msg_timer, (evtimer_event_t *)event);
TCP_DEBUG_LEAVE;
} }
/** /**
@ -78,10 +82,11 @@ void _gnrc_tcp_event_loop_unsched(evtimer_msg_event_t *event)
* *
* @returns Zero on success. * @returns Zero on success.
* Negative value on error. * Negative value on error.
* @returns -EBADMSG if TCP header is missing in @p pkt. * @returns -EBADMSG if required header is missing in @p pkt.
*/ */
static int _send(gnrc_pktsnip_t *pkt) static int _send(gnrc_pktsnip_t *pkt)
{ {
TCP_DEBUG_ENTER;
assert(pkt != NULL); assert(pkt != NULL);
/* NOTE: In sending direction: pkt = nw, nw->next = tcp, tcp->next = payload */ /* NOTE: In sending direction: pkt = nw, nw->next = tcp, tcp->next = payload */
@ -90,8 +95,9 @@ static int _send(gnrc_pktsnip_t *pkt)
gnrc_pktsnip_t *nw = NULL; gnrc_pktsnip_t *nw = NULL;
if (tcp == NULL) { if (tcp == NULL) {
DEBUG("gnrc_tcp_eventloop : _send() : tcp header missing.\n");
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
TCP_DEBUG_ERROR("-EBADMSG: Packet contains no TCP header.");
TCP_DEBUG_LEAVE;
return -EBADMSG; return -EBADMSG;
} }
@ -100,18 +106,19 @@ static int _send(gnrc_pktsnip_t *pkt)
/* Get IPv6 header, discard packet if doesn't contain an ipv6 header */ /* Get IPv6 header, discard packet if doesn't contain an ipv6 header */
nw = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6); nw = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6);
if (nw == NULL) { if (nw == NULL) {
DEBUG("gnrc_tcp_eventloop.c : _send() : pkt contains no ipv6 layer header\n");
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
TCP_DEBUG_ERROR("-EBADMSG: Packet contains no IPv6 header.");
TCP_DEBUG_LEAVE;
return -EBADMSG; return -EBADMSG;
} }
#endif #endif
/* Dispatch packet to network layer */ /* Dispatch packet to network layer */
assert(nw != NULL); assert(nw != NULL);
if (!gnrc_netapi_dispatch_send(nw->type, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) { if (!gnrc_netapi_dispatch_send(nw->type, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) {
DEBUG("gnrc_tcp_eventloop : _send() : network layer not found\n");
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
TCP_DEBUG_ERROR("Can't dispatch to network layer.");
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -122,6 +129,7 @@ static int _send(gnrc_pktsnip_t *pkt)
* *
* @returns Zero on success. * @returns Zero on success.
* Negative value on error. * Negative value on error.
* -EBADMSG if required header is missing or invalid in @p pkt.
* -EACCES if write access to packet was not acquired. * -EACCES if write access to packet was not acquired.
* -ERANGE if segment offset value is less than 5. * -ERANGE if segment offset value is less than 5.
* -ENOMSG if packet couldn't be marked. * -ENOMSG if packet couldn't be marked.
@ -130,6 +138,7 @@ static int _send(gnrc_pktsnip_t *pkt)
*/ */
static int _receive(gnrc_pktsnip_t *pkt) static int _receive(gnrc_pktsnip_t *pkt)
{ {
TCP_DEBUG_ENTER;
/* NOTE: In receiving direction: pkt = payload, payload->next = tcp, tcp->next = nw */ /* NOTE: In receiving direction: pkt = payload, payload->next = tcp, tcp->next = nw */
uint16_t ctl = 0; uint16_t ctl = 0;
uint16_t src = 0; uint16_t src = 0;
@ -144,8 +153,9 @@ static int _receive(gnrc_pktsnip_t *pkt)
/* Get write access to the TCP header */ /* Get write access to the TCP header */
gnrc_pktsnip_t *tcp = gnrc_pktbuf_start_write(pkt); gnrc_pktsnip_t *tcp = gnrc_pktbuf_start_write(pkt);
if (tcp == NULL) { if (tcp == NULL) {
DEBUG("gnrc_tcp_eventloop.c : _receive() : can't write to packet\n");
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
TCP_DEBUG_ERROR("-EACCESS: Can't write to packet.");
TCP_DEBUG_LEAVE;
return -EACCES; return -EACCES;
} }
pkt = tcp; pkt = tcp;
@ -154,24 +164,27 @@ static int _receive(gnrc_pktsnip_t *pkt)
/* Get IPv6 header, discard packet if doesn't contain an ip header */ /* Get IPv6 header, discard packet if doesn't contain an ip header */
ip = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6); ip = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6);
if (ip == NULL) { if (ip == NULL) {
DEBUG("gnrc_tcp_eventloop.c : _receive() : pkt contains no IP Header\n");
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
return 0; TCP_DEBUG_ERROR("-EBADMSG: Packet contains no IPv6 header.");
TCP_DEBUG_LEAVE;
return -EBADMSG;
} }
#endif #endif
/* Get TCP header */ /* Get TCP header */
tcp = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_TCP); tcp = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_TCP);
if (tcp == NULL) { if (tcp == NULL) {
DEBUG("gnrc_tcp_eventloop.c : _receive() : pkt contains no TCP Header\n");
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
return 0; TCP_DEBUG_ERROR("-EBADMSG: Packet contains no TCP header.");
TCP_DEBUG_LEAVE;
return -EBADMSG;
} }
if (tcp->size < sizeof(tcp_hdr_t)) { if (tcp->size < sizeof(tcp_hdr_t)) {
DEBUG("gnrc_tcp_eventloop.c : _receive() : packet is too short\n");
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
return -ERANGE; TCP_DEBUG_ERROR("-EBADMSG: Packet size less than minimal header size.");
TCP_DEBUG_LEAVE;
return -EBADMSG;
} }
/* Extract control bits, src and dst ports and check if SYN is set (not SYN+ACK) */ /* Extract control bits, src and dst ports and check if SYN is set (not SYN+ACK) */
@ -183,8 +196,9 @@ static int _receive(gnrc_pktsnip_t *pkt)
/* Validate offset */ /* Validate offset */
if (GET_OFFSET(ctl) < TCP_HDR_OFFSET_MIN) { if (GET_OFFSET(ctl) < TCP_HDR_OFFSET_MIN) {
DEBUG("gnrc_tcp_eventloop.c : _receive() : unexpected Offset Value\n");
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
TCP_DEBUG_ERROR("-ERANGE: Invalid TCP header offset.");
TCP_DEBUG_LEAVE;
return -ERANGE; return -ERANGE;
} }
@ -195,8 +209,9 @@ static int _receive(gnrc_pktsnip_t *pkt)
if ((pkt->type == GNRC_NETTYPE_TCP) && (pkt->size != hdr_size)) { if ((pkt->type == GNRC_NETTYPE_TCP) && (pkt->size != hdr_size)) {
tcp = gnrc_pktbuf_mark(pkt, hdr_size, GNRC_NETTYPE_TCP); tcp = gnrc_pktbuf_mark(pkt, hdr_size, GNRC_NETTYPE_TCP);
if (tcp == NULL) { if (tcp == NULL) {
DEBUG("gnrc_tcp_eventloop.c : _receive() : Header marking failed\n");
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
TCP_DEBUG_ERROR("-ENOMSG: Header marking failed.");
TCP_DEBUG_LEAVE;
return -ENOMSG; return -ENOMSG;
} }
pkt->type = GNRC_NETTYPE_UNDEF; pkt->type = GNRC_NETTYPE_UNDEF;
@ -205,9 +220,10 @@ static int _receive(gnrc_pktsnip_t *pkt)
/* Validate checksum */ /* Validate checksum */
if (byteorder_ntohs(hdr->checksum) != _pkt_calc_csum(tcp, ip, pkt)) { if (byteorder_ntohs(hdr->checksum) != _pkt_calc_csum(tcp, ip, pkt)) {
DEBUG("gnrc_tcp_eventloop.c : _receive() : Invalid checksum\n");
#ifndef MODULE_FUZZING #ifndef MODULE_FUZZING
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
TCP_DEBUG_ERROR("-EINVAL: Invalid checksum.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
#endif #endif
} }
@ -242,6 +258,7 @@ static int _receive(gnrc_pktsnip_t *pkt)
} }
#else #else
/* Suppress compiler warnings if TCP is built without network layer */ /* Suppress compiler warnings if TCP is built without network layer */
TCP_DEBUG_ERROR("Missing network layer. Add module to makefile.");
(void) syn; (void) syn;
(void) src; (void) src;
(void) dst; (void) dst;
@ -259,23 +276,26 @@ static int _receive(gnrc_pktsnip_t *pkt)
} }
/* No fitting TCB has been found. Respond with reset */ /* No fitting TCB has been found. Respond with reset */
else { else {
DEBUG("gnrc_tcp_eventloop.c : _receive() : Can't find fitting tcb\n");
if ((ctl & MSK_RST) != MSK_RST) { if ((ctl & MSK_RST) != MSK_RST) {
_pkt_build_reset_from_pkt(&reset, pkt); _pkt_build_reset_from_pkt(&reset, pkt);
if (gnrc_netapi_send(_tcp_eventloop_pid, reset) < 1) { if (gnrc_netapi_send(_tcp_eventloop_pid, reset) < 1) {
DEBUG("gnrc_tcp_eventloop.c : _receive() : unable to send reset packet\n");
gnrc_pktbuf_release(reset); gnrc_pktbuf_release(reset);
TCP_DEBUG_ERROR("Can't dispatch to network layer.");
} }
} }
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
TCP_DEBUG_ERROR("-ENOTCONN: Unable to find matching TCB.");
TCP_DEBUG_LEAVE;
return -ENOTCONN; return -ENOTCONN;
} }
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
static void *_event_loop(__attribute__((unused)) void *arg) static void *_event_loop(__attribute__((unused)) void *arg)
{ {
TCP_DEBUG_ENTER;
msg_t msg; msg_t msg;
msg_t reply; msg_t reply;
@ -300,13 +320,13 @@ static void *_event_loop(__attribute__((unused)) void *arg)
switch (msg.type) { switch (msg.type) {
/* Pass message up the network stack */ /* Pass message up the network stack */
case GNRC_NETAPI_MSG_TYPE_RCV: case GNRC_NETAPI_MSG_TYPE_RCV:
DEBUG("gnrc_tcp_eventloop.c : _event_loop() : GNRC_NETAPI_MSG_TYPE_RCV\n"); TCP_DEBUG_INFO("Received GNRC_NETAPI_MSG_TYPE_RCV.");
_receive((gnrc_pktsnip_t *)msg.content.ptr); _receive((gnrc_pktsnip_t *)msg.content.ptr);
break; break;
/* Pass message down the network stack */ /* Pass message down the network stack */
case GNRC_NETAPI_MSG_TYPE_SND: case GNRC_NETAPI_MSG_TYPE_SND:
DEBUG("gnrc_tcp_eventloop.c : _event_loop() : GNRC_NETAPI_MSG_TYPE_SND\n"); TCP_DEBUG_INFO("Received GNRC_NETAPI_MSG_TYPE_SND.");
_send((gnrc_pktsnip_t *)msg.content.ptr); _send((gnrc_pktsnip_t *)msg.content.ptr);
break; break;
@ -318,37 +338,44 @@ static void *_event_loop(__attribute__((unused)) void *arg)
/* Retransmission timer expired: Call FSM with retransmission event */ /* Retransmission timer expired: Call FSM with retransmission event */
case MSG_TYPE_RETRANSMISSION: case MSG_TYPE_RETRANSMISSION:
DEBUG("gnrc_tcp_eventloop.c : _event_loop() : MSG_TYPE_RETRANSMISSION\n"); TCP_DEBUG_INFO("Received MSG_TYPE_RETRANSMISSION.");
_fsm((gnrc_tcp_tcb_t *)msg.content.ptr, FSM_EVENT_TIMEOUT_RETRANSMIT, _fsm((gnrc_tcp_tcb_t *)msg.content.ptr, FSM_EVENT_TIMEOUT_RETRANSMIT,
NULL, NULL, 0); NULL, NULL, 0);
break; break;
/* Timewait timer expired: Call FSM with timewait event */ /* Timewait timer expired: Call FSM with timewait event */
case MSG_TYPE_TIMEWAIT: case MSG_TYPE_TIMEWAIT:
DEBUG("gnrc_tcp_eventloop.c : _event_loop() : MSG_TYPE_TIMEWAIT\n"); TCP_DEBUG_INFO("Received MSG_TYPE_TIMEWAIT.");
_fsm((gnrc_tcp_tcb_t *)msg.content.ptr, FSM_EVENT_TIMEOUT_TIMEWAIT, _fsm((gnrc_tcp_tcb_t *)msg.content.ptr, FSM_EVENT_TIMEOUT_TIMEWAIT,
NULL, NULL, 0); NULL, NULL, 0);
break; break;
default: default:
DEBUG("gnrc_tcp_eventloop.c : _event_loop() : received expected message\n"); TCP_DEBUG_ERROR("Received unexpected message.");
} }
} }
/* Never reached */ /* Never reached */
TCP_DEBUG_ERROR("This function should never exit.");
TCP_DEBUG_LEAVE;
return NULL; return NULL;
} }
int _gnrc_tcp_event_loop_init(void) int _gnrc_tcp_event_loop_init(void)
{ {
TCP_DEBUG_ENTER;
/* Guard: Check if thread is already running */ /* Guard: Check if thread is already running */
if (_tcp_eventloop_pid != KERNEL_PID_UNDEF) { if (_tcp_eventloop_pid != KERNEL_PID_UNDEF) {
TCP_DEBUG_ERROR("-EEXIST: TCP eventloop already running.");
TCP_DEBUG_LEAVE;
return -EEXIST; return -EEXIST;
} }
/* Initialize timers */ /* Initialize timers */
evtimer_init_msg(&_tcp_msg_timer); evtimer_init_msg(&_tcp_msg_timer);
return thread_create(_stack, sizeof(_stack), TCP_EVENTLOOP_PRIO, kernel_pid_t pid = thread_create(_stack, sizeof(_stack), TCP_EVENTLOOP_PRIO,
THREAD_CREATE_STACKTEST, _event_loop, NULL, THREAD_CREATE_STACKTEST, _event_loop, NULL,
"gnrc_tcp"); "gnrc_tcp");
TCP_DEBUG_LEAVE;
return pid;
} }

View File

@ -55,9 +55,11 @@
*/ */
static int _is_local_port_in_use(const uint16_t port_number) static int _is_local_port_in_use(const uint16_t port_number)
{ {
TCP_DEBUG_ENTER;
gnrc_tcp_tcb_t *iter = NULL; gnrc_tcp_tcb_t *iter = NULL;
tcb_list_t *list = _gnrc_tcp_common_get_tcb_list(); tcb_list_t *list = _gnrc_tcp_common_get_tcb_list();
LL_SEARCH_SCALAR(list->head, iter, local_port, port_number); LL_SEARCH_SCALAR(list->head, iter, local_port, port_number);
TCP_DEBUG_LEAVE;
return (iter != NULL); return (iter != NULL);
} }
@ -68,6 +70,7 @@ static int _is_local_port_in_use(const uint16_t port_number)
*/ */
static uint16_t _get_random_local_port(void) static uint16_t _get_random_local_port(void)
{ {
TCP_DEBUG_ENTER;
uint16_t ret = 0; uint16_t ret = 0;
do { do {
ret = random_uint32(); ret = random_uint32();
@ -75,6 +78,7 @@ static uint16_t _get_random_local_port(void)
continue; continue;
} }
} while(_is_local_port_in_use(ret)); } while(_is_local_port_in_use(ret));
TCP_DEBUG_LEAVE;
return ret; return ret;
} }
@ -87,11 +91,13 @@ static uint16_t _get_random_local_port(void)
*/ */
static int _clear_retransmit(gnrc_tcp_tcb_t *tcb) static int _clear_retransmit(gnrc_tcp_tcb_t *tcb)
{ {
TCP_DEBUG_ENTER;
if (tcb->pkt_retransmit != NULL) { if (tcb->pkt_retransmit != NULL) {
_gnrc_tcp_event_loop_unsched(&tcb->event_retransmit); _gnrc_tcp_event_loop_unsched(&tcb->event_retransmit);
gnrc_pktbuf_release(tcb->pkt_retransmit); gnrc_pktbuf_release(tcb->pkt_retransmit);
tcb->pkt_retransmit = NULL; tcb->pkt_retransmit = NULL;
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -104,9 +110,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)
{ {
TCP_DEBUG_ENTER;
_gnrc_tcp_event_loop_unsched(&tcb->event_retransmit); _gnrc_tcp_event_loop_unsched(&tcb->event_retransmit);
_gnrc_tcp_event_loop_sched(&tcb->event_retransmit, 2 * CONFIG_GNRC_TCP_MSL_MS, _gnrc_tcp_event_loop_sched(&tcb->event_retransmit, 2 * CONFIG_GNRC_TCP_MSL_MS,
MSG_TYPE_TIMEWAIT, tcb); MSG_TYPE_TIMEWAIT, tcb);
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -122,8 +130,7 @@ static int _restart_timewait_timer(gnrc_tcp_tcb_t *tcb)
*/ */
static int _transition_to(gnrc_tcp_tcb_t *tcb, fsm_state_t state) static int _transition_to(gnrc_tcp_tcb_t *tcb, fsm_state_t state)
{ {
DEBUG("_transition_to: %d\n", state); TCP_DEBUG_ENTER;
gnrc_tcp_tcb_t *iter = NULL; gnrc_tcp_tcb_t *iter = NULL;
tcb_list_t *list = _gnrc_tcp_common_get_tcb_list(); tcb_list_t *list = _gnrc_tcp_common_get_tcb_list();
@ -174,6 +181,8 @@ static int _transition_to(gnrc_tcp_tcb_t *tcb, fsm_state_t state)
/* Check if given port number is in use: return error */ /* Check if given port number is in use: return error */
if (_is_local_port_in_use(tcb->local_port)) { if (_is_local_port_in_use(tcb->local_port)) {
mutex_unlock(&list->lock); mutex_unlock(&list->lock);
TCP_DEBUG_ERROR("-EADDRINUSE: Port already used.")
TCP_DEBUG_LEAVE;
return -EADDRINUSE; return -EADDRINUSE;
} }
} }
@ -200,6 +209,7 @@ static int _transition_to(gnrc_tcp_tcb_t *tcb, fsm_state_t state)
break; break;
} }
tcb->state = state; tcb->state = state;
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -214,12 +224,13 @@ static int _transition_to(gnrc_tcp_tcb_t *tcb, fsm_state_t state)
*/ */
static int _fsm_call_open(gnrc_tcp_tcb_t *tcb) static int _fsm_call_open(gnrc_tcp_tcb_t *tcb)
{ {
TCP_DEBUG_ENTER;
int ret = 0; int ret = 0;
DEBUG("gnrc_tcp_fsm.c : _fsm_call_open()\n");
/* Allocate receive buffer */ /* Allocate receive buffer */
if (_rcvbuf_get_buffer(tcb) == -ENOMEM) { if (_rcvbuf_get_buffer(tcb) == -ENOMEM) {
TCP_DEBUG_ERROR("-ENOMEM: Can't allocate receive buffer.");
TCP_DEBUG_LEAVE;
return -ENOMEM; return -ENOMEM;
} }
@ -239,6 +250,7 @@ static int _fsm_call_open(gnrc_tcp_tcb_t *tcb)
ret = _transition_to(tcb, FSM_STATE_SYN_SENT); ret = _transition_to(tcb, FSM_STATE_SYN_SENT);
if (ret < 0) { if (ret < 0) {
_transition_to(tcb, FSM_STATE_CLOSED); _transition_to(tcb, FSM_STATE_CLOSED);
TCP_DEBUG_LEAVE;
return ret; return ret;
} }
@ -249,6 +261,7 @@ static int _fsm_call_open(gnrc_tcp_tcb_t *tcb)
_pkt_setup_retransmit(tcb, out_pkt, false); _pkt_setup_retransmit(tcb, out_pkt, false);
_pkt_send(tcb, out_pkt, seq_con, false); _pkt_send(tcb, out_pkt, seq_con, false);
} }
TCP_DEBUG_LEAVE;
return ret; return ret;
} }
@ -263,8 +276,7 @@ static int _fsm_call_open(gnrc_tcp_tcb_t *tcb)
*/ */
static int _fsm_call_send(gnrc_tcp_tcb_t *tcb, void *buf, size_t len) static int _fsm_call_send(gnrc_tcp_tcb_t *tcb, void *buf, size_t len)
{ {
DEBUG("gnrc_tcp_fsm.c : _fsm_call_send()\n"); TCP_DEBUG_ENTER;
size_t payload = (tcb->snd_una + tcb->snd_wnd) - tcb->snd_nxt; size_t payload = (tcb->snd_una + tcb->snd_wnd) - tcb->snd_nxt;
/* Check if window is open and all packets were transmitted */ /* Check if window is open and all packets were transmitted */
@ -280,8 +292,10 @@ static int _fsm_call_send(gnrc_tcp_tcb_t *tcb, void *buf, size_t len)
_pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK | MSK_PSH, tcb->snd_nxt, tcb->rcv_nxt, buf, payload); _pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK | MSK_PSH, tcb->snd_nxt, tcb->rcv_nxt, buf, payload);
_pkt_setup_retransmit(tcb, out_pkt, false); _pkt_setup_retransmit(tcb, out_pkt, false);
_pkt_send(tcb, out_pkt, seq_con, false); _pkt_send(tcb, out_pkt, seq_con, false);
TCP_DEBUG_LEAVE;
return payload; return payload;
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -296,9 +310,10 @@ static int _fsm_call_send(gnrc_tcp_tcb_t *tcb, void *buf, size_t len)
*/ */
static int _fsm_call_recv(gnrc_tcp_tcb_t *tcb, void *buf, size_t len) static int _fsm_call_recv(gnrc_tcp_tcb_t *tcb, void *buf, size_t len)
{ {
DEBUG("gnrc_tcp_fsm.c : _fsm_call_recv()\n"); TCP_DEBUG_ENTER;
if (ringbuffer_empty(&tcb->rcv_buf)) { if (ringbuffer_empty(&tcb->rcv_buf)) {
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -315,6 +330,7 @@ static int _fsm_call_recv(gnrc_tcp_tcb_t *tcb, void *buf, size_t len)
_pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0); _pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0);
_pkt_send(tcb, out_pkt, seq_con, false); _pkt_send(tcb, out_pkt, seq_con, false);
} }
TCP_DEBUG_LEAVE;
return rcvd; return rcvd;
} }
@ -327,7 +343,7 @@ static int _fsm_call_recv(gnrc_tcp_tcb_t *tcb, void *buf, size_t len)
*/ */
static int _fsm_call_close(gnrc_tcp_tcb_t *tcb) static int _fsm_call_close(gnrc_tcp_tcb_t *tcb)
{ {
DEBUG("gnrc_tcp_fsm.c : _fsm_call_close()\n"); TCP_DEBUG_ENTER;
if (tcb->state == FSM_STATE_SYN_RCVD || tcb->state == FSM_STATE_ESTABLISHED || if (tcb->state == FSM_STATE_SYN_RCVD || tcb->state == FSM_STATE_ESTABLISHED ||
tcb->state == FSM_STATE_CLOSE_WAIT) { tcb->state == FSM_STATE_CLOSE_WAIT) {
@ -349,6 +365,7 @@ static int _fsm_call_close(gnrc_tcp_tcb_t *tcb)
else if (tcb->state == FSM_STATE_CLOSE_WAIT) { else if (tcb->state == FSM_STATE_CLOSE_WAIT) {
_transition_to(tcb, FSM_STATE_LAST_ACK); _transition_to(tcb, FSM_STATE_LAST_ACK);
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -361,7 +378,7 @@ static int _fsm_call_close(gnrc_tcp_tcb_t *tcb)
*/ */
static int _fsm_call_abort(gnrc_tcp_tcb_t *tcb) static int _fsm_call_abort(gnrc_tcp_tcb_t *tcb)
{ {
DEBUG("gnrc_tcp_fsm.c : _fsm_call_abort()\n"); TCP_DEBUG_ENTER;
/* A reset must be sent in case the TCB state is in one of those cases */ /* A reset must be sent in case the TCB state is in one of those cases */
if (tcb->state == FSM_STATE_SYN_RCVD || tcb->state == FSM_STATE_ESTABLISHED || if (tcb->state == FSM_STATE_SYN_RCVD || tcb->state == FSM_STATE_ESTABLISHED ||
@ -378,6 +395,7 @@ static int _fsm_call_abort(gnrc_tcp_tcb_t *tcb)
/* From here on any state must transition into CLOSED state */ /* From here on any state must transition into CLOSED state */
_transition_to(tcb, FSM_STATE_CLOSED); _transition_to(tcb, FSM_STATE_CLOSED);
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -392,6 +410,7 @@ static int _fsm_call_abort(gnrc_tcp_tcb_t *tcb)
*/ */
static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt) static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
{ {
TCP_DEBUG_ENTER;
gnrc_pktsnip_t *out_pkt = NULL; /* Outgoing packet */ gnrc_pktsnip_t *out_pkt = NULL; /* Outgoing packet */
uint16_t seq_con = 0; /* Sequence number consumption of outgoing packet */ uint16_t seq_con = 0; /* Sequence number consumption of outgoing packet */
gnrc_pktsnip_t *snp; /* Temporary packet snip */ gnrc_pktsnip_t *snp; /* Temporary packet snip */
@ -401,13 +420,14 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
uint32_t seg_ack = 0; /* Acknowledgment number of the incoming packet */ uint32_t seg_ack = 0; /* Acknowledgment number of the incoming packet */
uint32_t seg_wnd = 0; /* Receive window of the incoming packet */ uint32_t seg_wnd = 0; /* Receive window of the incoming packet */
DEBUG("gnrc_tcp_fsm.c : _fsm_rcvd_pkt()\n");
/* Search for TCP header. */ /* Search for TCP header. */
snp = gnrc_pktsnip_search_type(in_pkt, GNRC_NETTYPE_TCP); snp = gnrc_pktsnip_search_type(in_pkt, GNRC_NETTYPE_TCP);
tcp_hdr_t *tcp_hdr = (tcp_hdr_t *) snp->data; tcp_hdr_t *tcp_hdr = (tcp_hdr_t *) snp->data;
/* Parse packet options, return if they are malformed */ /* Parse packet options, return if they are malformed */
if (_option_parse(tcb, tcp_hdr) < 0) { if (_option_parse(tcb, tcp_hdr) < 0) {
TCP_DEBUG_ERROR("Failed to parse TCP header options.");
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -421,7 +441,8 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
#ifdef MODULE_GNRC_IPV6 #ifdef MODULE_GNRC_IPV6
snp = gnrc_pktsnip_search_type(in_pkt, GNRC_NETTYPE_IPV6); snp = gnrc_pktsnip_search_type(in_pkt, GNRC_NETTYPE_IPV6);
if (snp == NULL) { if (snp == NULL) {
DEBUG("gnrc_tcp_fsm.c : _fsm_rcvd_pkt() : incoming packet had no IPv6 header\n"); TCP_DEBUG_ERROR("Packet contains no IPv6 header.");
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
void *ip = snp->data; void *ip = snp->data;
@ -431,12 +452,16 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
if (tcb->state == FSM_STATE_LISTEN) { if (tcb->state == FSM_STATE_LISTEN) {
/* 1) Check RST: if RST is set: return */ /* 1) Check RST: if RST is set: return */
if (ctl & MSK_RST) { if (ctl & MSK_RST) {
TCP_DEBUG_INFO("RST flag set in packet.");
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
/* 2) Check ACK: if ACK is set: send RST with seq_no = ack_no and return */ /* 2) Check ACK: if ACK is set: send RST with seq_no = ack_no and return */
if (ctl & MSK_ACK) { if (ctl & MSK_ACK) {
_pkt_build_reset_from_pkt(&out_pkt, in_pkt); _pkt_build_reset_from_pkt(&out_pkt, in_pkt);
_pkt_send(tcb, out_pkt, 0, false); _pkt_send(tcb, out_pkt, 0, false);
TCP_DEBUG_INFO("ACK flag set in packet. Send reset.");
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
/* 3) Check SYN: if SYN is set prepare for incoming connection */ /* 3) Check SYN: if SYN is set prepare for incoming connection */
@ -468,7 +493,8 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
* (reason: tmp *lst* can be true at runtime * (reason: tmp *lst* can be true at runtime
*/ */
if (lst) { if (lst) {
DEBUG("gnrc_tcp_fsm.c : _fsm_rcvd_pkt() : Connection already handled\n"); TCP_DEBUG_INFO("Connection is handled by another TCB.");
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -478,19 +504,20 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
memcpy(tcb->local_addr, &((ipv6_hdr_t *)ip)->dst, sizeof(ipv6_addr_t)); memcpy(tcb->local_addr, &((ipv6_hdr_t *)ip)->dst, sizeof(ipv6_addr_t));
memcpy(tcb->peer_addr, &((ipv6_hdr_t *)ip)->src, sizeof(ipv6_addr_t)); memcpy(tcb->peer_addr, &((ipv6_hdr_t *)ip)->src, sizeof(ipv6_addr_t));
/* In case peer_addr is link local: Store interface Id in tcb */ /* In case peer_addr is link local: Store interface Id in TCB */
if (ipv6_addr_is_link_local((ipv6_addr_t *) tcb->peer_addr)) { if (ipv6_addr_is_link_local((ipv6_addr_t *) tcb->peer_addr)) {
gnrc_pktsnip_t *tmp = gnrc_pktsnip_search_type(in_pkt, GNRC_NETTYPE_NETIF); gnrc_pktsnip_t *tmp = gnrc_pktsnip_search_type(in_pkt, GNRC_NETTYPE_NETIF);
if (tmp == NULL) { if (tmp == NULL) {
DEBUG("gnrc_tcp_fsm.c : _fsm_rcvd_pkt() :\ TCP_DEBUG_ERROR("Packet contains no netif header.");
incoming packet had no netif header\n"); TCP_DEBUG_LEAVE;
return 0; return 0;
} }
tcb->ll_iface = ((gnrc_netif_hdr_t *)tmp->data)->if_pid; tcb->ll_iface = ((gnrc_netif_hdr_t *)tmp->data)->if_pid;
} }
} }
#else #else
DEBUG("gnrc_tcp_fsm.c : _fsm_rcvd_pkt() : Received address was not stored\n"); TCP_DEBUG_ERROR("Missing network layer. Add module to makefile.");
TCP_DEBUG_LEAVE;
return 0; return 0;
#endif #endif
@ -509,6 +536,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
_pkt_send(tcb, out_pkt, seq_con, false); _pkt_send(tcb, out_pkt, seq_con, false);
_transition_to(tcb, FSM_STATE_SYN_RCVD); _transition_to(tcb, FSM_STATE_SYN_RCVD);
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
/* Handle state SYN_SENT */ /* Handle state SYN_SENT */
@ -522,6 +550,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
_pkt_build(tcb, &out_pkt, &seq_con, MSK_RST, seg_ack, 0, NULL, 0); _pkt_build(tcb, &out_pkt, &seq_con, MSK_RST, seg_ack, 0, NULL, 0);
_pkt_send(tcb, out_pkt, seq_con, false); _pkt_send(tcb, out_pkt, seq_con, false);
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
} }
@ -531,6 +560,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
if (ctl & MSK_ACK) { if (ctl & MSK_ACK) {
_transition_to(tcb, FSM_STATE_CLOSED); _transition_to(tcb, FSM_STATE_CLOSED);
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
/* 3) Check SYN: Set TCB values accordingly */ /* 3) Check SYN: Set TCB values accordingly */
@ -547,7 +577,8 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
memcpy(tcb->local_addr, &((ipv6_hdr_t *)ip)->dst, sizeof(ipv6_addr_t)); memcpy(tcb->local_addr, &((ipv6_hdr_t *)ip)->dst, sizeof(ipv6_addr_t));
} }
#else #else
DEBUG("gnrc_tcp_fsm.c : _fsm_rcvd_pkt() : Received address was not stored\n"); TCP_DEBUG_ERROR("Missing network layer. Add module to makefile.");
TCP_DEBUG_LEAVE;
return 0; return 0;
#endif #endif
@ -568,6 +599,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
tcb->snd_wl1 = seg_seq; tcb->snd_wl1 = seg_seq;
tcb->snd_wl2 = seg_ack; tcb->snd_wl2 = seg_ack;
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
/* Handle other states */ /* Handle other states */
@ -581,6 +613,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
_pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0); _pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0);
_pkt_send(tcb, out_pkt, seq_con, false); _pkt_send(tcb, out_pkt, seq_con, false);
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
/* 2) Check RST: If RST is set ... */ /* 2) Check RST: If RST is set ... */
@ -592,6 +625,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
else { else {
_transition_to(tcb, FSM_STATE_CLOSED); _transition_to(tcb, FSM_STATE_CLOSED);
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
/* 3) Check SYN: If SYN is set ... */ /* 3) Check SYN: If SYN is set ... */
@ -600,10 +634,12 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
_pkt_build(tcb, &out_pkt, &seq_con, MSK_RST, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0); _pkt_build(tcb, &out_pkt, &seq_con, MSK_RST, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0);
_pkt_send(tcb, out_pkt, seq_con, false); _pkt_send(tcb, out_pkt, seq_con, false);
_transition_to(tcb, FSM_STATE_CLOSED); _transition_to(tcb, FSM_STATE_CLOSED);
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
/* 4) Check ACK */ /* 4) Check ACK */
if (!(ctl & MSK_ACK)) { if (!(ctl & MSK_ACK)) {
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
else { else {
@ -633,6 +669,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
_pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK, tcb->snd_nxt, tcb->rcv_nxt, _pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK, tcb->snd_nxt, tcb->rcv_nxt,
NULL, 0); NULL, 0);
_pkt_send(tcb, out_pkt, seq_con, false); _pkt_send(tcb, out_pkt, seq_con, false);
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
/* Update receive window */ /* Update receive window */
@ -670,6 +707,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
if (tcb->state == FSM_STATE_LAST_ACK) { if (tcb->state == FSM_STATE_LAST_ACK) {
if (tcb->pkt_retransmit == NULL) { if (tcb->pkt_retransmit == NULL) {
_transition_to(tcb, FSM_STATE_CLOSED); _transition_to(tcb, FSM_STATE_CLOSED);
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
} }
@ -711,6 +749,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
if (ctl & MSK_FIN) { if (ctl & MSK_FIN) {
if (tcb->state == FSM_STATE_CLOSED || tcb->state == FSM_STATE_LISTEN || if (tcb->state == FSM_STATE_CLOSED || tcb->state == FSM_STATE_LISTEN ||
tcb->state == FSM_STATE_SYN_SENT) { tcb->state == FSM_STATE_SYN_SENT) {
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
/* Advance rcv_nxt over FIN bit */ /* Advance rcv_nxt over FIN bit */
@ -737,6 +776,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
} }
} }
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -749,8 +789,9 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt)
*/ */
static int _fsm_timeout_timewait(gnrc_tcp_tcb_t *tcb) static int _fsm_timeout_timewait(gnrc_tcp_tcb_t *tcb)
{ {
DEBUG("gnrc_tcp_fsm.c : _fsm_timeout_timewait()\n"); TCP_DEBUG_ENTER;
_transition_to(tcb, FSM_STATE_CLOSED); _transition_to(tcb, FSM_STATE_CLOSED);
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -763,14 +804,15 @@ static int _fsm_timeout_timewait(gnrc_tcp_tcb_t *tcb)
*/ */
static int _fsm_timeout_retransmit(gnrc_tcp_tcb_t *tcb) static int _fsm_timeout_retransmit(gnrc_tcp_tcb_t *tcb)
{ {
DEBUG("gnrc_tcp_fsm.c : _fsm_timeout_retransmit()\n"); TCP_DEBUG_ENTER;
if (tcb->pkt_retransmit != NULL) { if (tcb->pkt_retransmit != NULL) {
_pkt_setup_retransmit(tcb, tcb->pkt_retransmit, true); _pkt_setup_retransmit(tcb, tcb->pkt_retransmit, true);
_pkt_send(tcb, tcb->pkt_retransmit, 0, true); _pkt_send(tcb, tcb->pkt_retransmit, 0, true);
} }
else { else {
DEBUG("gnrc_tcp_fsm.c : _fsm_timeout_retransmit() : Retransmit queue is empty\n"); TCP_DEBUG_INFO("Retransmission queue is empty.");
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -783,8 +825,9 @@ static int _fsm_timeout_retransmit(gnrc_tcp_tcb_t *tcb)
*/ */
static int _fsm_timeout_connection(gnrc_tcp_tcb_t *tcb) static int _fsm_timeout_connection(gnrc_tcp_tcb_t *tcb)
{ {
DEBUG("gnrc_tcp_fsm.c : _fsm_timeout_connection()\n"); TCP_DEBUG_ENTER;
_transition_to(tcb, FSM_STATE_CLOSED); _transition_to(tcb, FSM_STATE_CLOSED);
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -797,14 +840,15 @@ static int _fsm_timeout_connection(gnrc_tcp_tcb_t *tcb)
*/ */
static int _fsm_send_probe(gnrc_tcp_tcb_t *tcb) static int _fsm_send_probe(gnrc_tcp_tcb_t *tcb)
{ {
TCP_DEBUG_ENTER;
gnrc_pktsnip_t *out_pkt = NULL; /* Outgoing packet */ gnrc_pktsnip_t *out_pkt = NULL; /* Outgoing packet */
uint8_t probe_pay[] = {1}; /* Probe payload */ uint8_t probe_pay[] = {1}; /* Probe payload */
DEBUG("gnrc_tcp_fsm.c : _fsm_send_probe()\n");
/* The probe sends a already acknowledged sequence no. with a garbage byte. */ /* The probe sends a already acknowledged sequence no. with a garbage byte. */
_pkt_build(tcb, &out_pkt, NULL, MSK_ACK, tcb->snd_una - 1, tcb->rcv_nxt, probe_pay, _pkt_build(tcb, &out_pkt, NULL, MSK_ACK, tcb->snd_una - 1, tcb->rcv_nxt, probe_pay,
sizeof(probe_pay)); sizeof(probe_pay));
_pkt_send(tcb, out_pkt, 0, false); _pkt_send(tcb, out_pkt, 0, false);
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -817,8 +861,9 @@ static int _fsm_send_probe(gnrc_tcp_tcb_t *tcb)
*/ */
static int _fsm_clear_retransmit(gnrc_tcp_tcb_t *tcb) static int _fsm_clear_retransmit(gnrc_tcp_tcb_t *tcb)
{ {
DEBUG("gnrc_tcp_fsm.c : _fsm_clear_retransmit()\n"); TCP_DEBUG_ENTER;
_clear_retransmit(tcb); _clear_retransmit(tcb);
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -839,9 +884,9 @@ static int _fsm_clear_retransmit(gnrc_tcp_tcb_t *tcb)
static int _fsm_unprotected(gnrc_tcp_tcb_t *tcb, fsm_event_t event, gnrc_pktsnip_t *in_pkt, static int _fsm_unprotected(gnrc_tcp_tcb_t *tcb, fsm_event_t event, gnrc_pktsnip_t *in_pkt,
void *buf, size_t len) void *buf, size_t len)
{ {
TCP_DEBUG_ENTER;
int ret = 0; int ret = 0;
DEBUG("gnrc_tcp_fsm.c : _fsm_unprotected()\n");
switch (event) { switch (event) {
case FSM_EVENT_CALL_OPEN : case FSM_EVENT_CALL_OPEN :
ret = _fsm_call_open(tcb); ret = _fsm_call_open(tcb);
@ -877,11 +922,13 @@ static int _fsm_unprotected(gnrc_tcp_tcb_t *tcb, fsm_event_t event, gnrc_pktsnip
ret = _fsm_clear_retransmit(tcb); ret = _fsm_clear_retransmit(tcb);
break; break;
} }
TCP_DEBUG_LEAVE;
return ret; return ret;
} }
int _fsm(gnrc_tcp_tcb_t *tcb, fsm_event_t event, gnrc_pktsnip_t *in_pkt, void *buf, size_t len) int _fsm(gnrc_tcp_tcb_t *tcb, fsm_event_t event, gnrc_pktsnip_t *in_pkt, void *buf, size_t len)
{ {
TCP_DEBUG_ENTER;
/* Lock FSM */ /* Lock FSM */
mutex_lock(&(tcb->fsm_lock)); mutex_lock(&(tcb->fsm_lock));
@ -898,12 +945,15 @@ int _fsm(gnrc_tcp_tcb_t *tcb, fsm_event_t event, gnrc_pktsnip_t *in_pkt, void *b
} }
/* Unlock FSM */ /* Unlock FSM */
mutex_unlock(&(tcb->fsm_lock)); mutex_unlock(&(tcb->fsm_lock));
TCP_DEBUG_LEAVE;
return result; return result;
} }
void _fsm_set_mbox(gnrc_tcp_tcb_t *tcb, mbox_t *mbox) void _fsm_set_mbox(gnrc_tcp_tcb_t *tcb, mbox_t *mbox)
{ {
TCP_DEBUG_ENTER;
mutex_lock(&(tcb->fsm_lock)); mutex_lock(&(tcb->fsm_lock));
tcb->mbox = mbox; tcb->mbox = mbox;
mutex_unlock(&(tcb->fsm_lock)); mutex_unlock(&(tcb->fsm_lock));
TCP_DEBUG_LEAVE;
} }

View File

@ -24,9 +24,11 @@
int _option_parse(gnrc_tcp_tcb_t *tcb, tcp_hdr_t *hdr) int _option_parse(gnrc_tcp_tcb_t *tcb, tcp_hdr_t *hdr)
{ {
TCP_DEBUG_ENTER;
/* Extract offset value. Return if no options are set */ /* Extract offset value. Return if no options are set */
uint8_t offset = GET_OFFSET(byteorder_ntohs(hdr->off_ctl)); uint8_t offset = GET_OFFSET(byteorder_ntohs(hdr->off_ctl));
if (offset <= TCP_HDR_OFFSET_MIN) { if (offset <= TCP_HDR_OFFSET_MIN) {
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -41,11 +43,12 @@ int _option_parse(gnrc_tcp_tcb_t *tcb, tcp_hdr_t *hdr)
/* Examine current option */ /* Examine current option */
switch (option->kind) { switch (option->kind) {
case TCP_OPTION_KIND_EOL: case TCP_OPTION_KIND_EOL:
DEBUG("gnrc_tcp_option.c : _option_parse() : EOL option found\n"); TCP_DEBUG_INFO("EOL option found.");
TCP_DEBUG_LEAVE;
return 0; return 0;
case TCP_OPTION_KIND_NOP: case TCP_OPTION_KIND_NOP:
DEBUG("gnrc_tcp_option.c : _option_parse() : NOP option found\n"); TCP_DEBUG_INFO("NOP option found.");
opt_ptr += 1; opt_ptr += 1;
opt_left -= 1; opt_left -= 1;
continue; continue;
@ -53,30 +56,30 @@ int _option_parse(gnrc_tcp_tcb_t *tcb, tcp_hdr_t *hdr)
case TCP_OPTION_KIND_MSS: case TCP_OPTION_KIND_MSS:
if (opt_left < TCP_OPTION_LENGTH_MIN || option->length > opt_left || if (opt_left < TCP_OPTION_LENGTH_MIN || option->length > opt_left ||
option->length != TCP_OPTION_LENGTH_MSS) { option->length != TCP_OPTION_LENGTH_MSS) {
TCP_DEBUG_ERROR("Invalid MSS option length.");
DEBUG("gnrc_tcp_option.c : _option_parse() : invalid MSS Option length.\n"); TCP_DEBUG_LEAVE;
return -1; return -1;
} }
TCP_DEBUG_INFO("MSS option found.");
tcb->mss = (option->value[0] << 8) | option->value[1]; tcb->mss = (option->value[0] << 8) | option->value[1];
DEBUG("gnrc_tcp_option.c : _option_parse() : MSS option found. MSS=%"PRIu16"\n",
tcb->mss);
break; break;
default: default:
if (opt_left >= TCP_OPTION_LENGTH_MIN) { if (opt_left >= TCP_OPTION_LENGTH_MIN) {
DEBUG("gnrc_tcp_option.c : _option_parse() : Unsupported option found.\ TCP_DEBUG_INFO("Valid, unsupported option found.");
KIND=%"PRIu8", LENGTH=%"PRIu8"\n", option->kind, option->length);
} }
} }
if ((opt_left < TCP_OPTION_LENGTH_MIN) || (option->length > opt_left) || if ((opt_left < TCP_OPTION_LENGTH_MIN) || (option->length > opt_left) ||
(option->length < TCP_OPTION_LENGTH_MIN)) { (option->length < TCP_OPTION_LENGTH_MIN)) {
DEBUG("gnrc_tcp_option.c : _option_parse() : Invalid option. Drop Packet.\n"); TCP_DEBUG_ERROR("Invalid option found.");
TCP_DEBUG_LEAVE;
return -1; return -1;
} }
opt_ptr += option->length; opt_ptr += option->length;
opt_left -= option->length; opt_left -= option->length;
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }

View File

@ -51,6 +51,7 @@ static inline uint32_t _max(const uint32_t x, const uint32_t y)
int _pkt_build_reset_from_pkt(gnrc_pktsnip_t **out_pkt, gnrc_pktsnip_t *in_pkt) int _pkt_build_reset_from_pkt(gnrc_pktsnip_t **out_pkt, gnrc_pktsnip_t *in_pkt)
{ {
TCP_DEBUG_ENTER;
tcp_hdr_t tcp_hdr_out; tcp_hdr_t tcp_hdr_out;
/* Extract headers */ /* Extract headers */
@ -94,9 +95,9 @@ int _pkt_build_reset_from_pkt(gnrc_pktsnip_t **out_pkt, gnrc_pktsnip_t *in_pkt)
/* Allocate new TCB header */ /* Allocate new TCB header */
tcp_snp = gnrc_pktbuf_add(NULL, &tcp_hdr_out, TCP_HDR_OFFSET_MIN * 4, GNRC_NETTYPE_TCP); tcp_snp = gnrc_pktbuf_add(NULL, &tcp_hdr_out, TCP_HDR_OFFSET_MIN * 4, GNRC_NETTYPE_TCP);
if (tcp_snp == NULL) { if (tcp_snp == NULL) {
DEBUG("gnrc_tcp_pkt.c : _pkt_build_reset_from_pkt() :\
Can't alloc buffer for TCP Header\n.");
*(out_pkt) = NULL; *(out_pkt) = NULL;
TCP_DEBUG_ERROR("-ENOMEM: Can't alloc buffer for TCP header.");
TCP_DEBUG_LEAVE;
return -ENOMEM; return -ENOMEM;
} }
*out_pkt = tcp_snp; *out_pkt = tcp_snp;
@ -105,10 +106,10 @@ int _pkt_build_reset_from_pkt(gnrc_pktsnip_t **out_pkt, gnrc_pktsnip_t *in_pkt)
#ifdef MODULE_GNRC_IPV6 #ifdef MODULE_GNRC_IPV6
ip6_snp = gnrc_ipv6_hdr_build(tcp_snp, &(ip6_hdr->dst), &(ip6_hdr->src)); ip6_snp = gnrc_ipv6_hdr_build(tcp_snp, &(ip6_hdr->dst), &(ip6_hdr->src));
if (ip6_snp == NULL) { if (ip6_snp == NULL) {
DEBUG("gnrc_tcp_pkt.c : _pkt_build_reset_from_pkt() :\
Can't alloc buffer for IPv6 Header.\n");
gnrc_pktbuf_release(tcp_snp); gnrc_pktbuf_release(tcp_snp);
*(out_pkt) = NULL; *(out_pkt) = NULL;
TCP_DEBUG_ERROR("-ENOMEM: Can't alloc buffer for IPv6 header.");
TCP_DEBUG_LEAVE;
return -ENOMEM; return -ENOMEM;
} }
*out_pkt = ip6_snp; *out_pkt = ip6_snp;
@ -124,10 +125,10 @@ int _pkt_build_reset_from_pkt(gnrc_pktsnip_t **out_pkt, gnrc_pktsnip_t *in_pkt)
/* Allocate new header and set interface id */ /* Allocate new header and set interface id */
net_snp = gnrc_netif_hdr_build(NULL, 0, NULL, 0); net_snp = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
if (net_snp == NULL) { if (net_snp == NULL) {
DEBUG("gnrc_tcp_pkt.c : _pkt_build_reset_from_pkt() :\
Can't alloc buffer for netif Header.\n");
gnrc_pktbuf_release(ip6_snp); gnrc_pktbuf_release(ip6_snp);
*(out_pkt) = NULL; *(out_pkt) = NULL;
TCP_DEBUG_ERROR("-ENOMEM: Can't alloc buffer for netif header.");
TCP_DEBUG_LEAVE;
return -ENOMEM; return -ENOMEM;
} }
else { else {
@ -137,8 +138,9 @@ int _pkt_build_reset_from_pkt(gnrc_pktsnip_t **out_pkt, gnrc_pktsnip_t *in_pkt)
} }
} }
#else #else
DEBUG("gnrc_tcp_pkt.c : _pkt_build_reset_from_pkt() : Network Layer Module Missing\n"); TCP_DEBUG_ERROR("Missing network layer. Add module to makefile.");
#endif #endif
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -146,6 +148,7 @@ int _pkt_build(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con,
const uint16_t ctl, const uint32_t seq_num, const uint32_t ack_num, const uint16_t ctl, const uint32_t seq_num, const uint32_t ack_num,
void *payload, const size_t payload_len) void *payload, const size_t payload_len)
{ {
TCP_DEBUG_ENTER;
gnrc_pktsnip_t *pay_snp = NULL; gnrc_pktsnip_t *pay_snp = NULL;
gnrc_pktsnip_t *tcp_snp = NULL; gnrc_pktsnip_t *tcp_snp = NULL;
tcp_hdr_t tcp_hdr; tcp_hdr_t tcp_hdr;
@ -155,8 +158,9 @@ int _pkt_build(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con,
if (payload != NULL && payload_len > 0) { if (payload != NULL && payload_len > 0) {
pay_snp = gnrc_pktbuf_add(pay_snp, payload, payload_len, GNRC_NETTYPE_UNDEF); pay_snp = gnrc_pktbuf_add(pay_snp, payload, payload_len, GNRC_NETTYPE_UNDEF);
if (pay_snp == NULL) { if (pay_snp == NULL) {
DEBUG("gnrc_tcp_pkt.c : _pkt_build() : Can't allocate buffer for payload\n.");
*(out_pkt) = NULL; *(out_pkt) = NULL;
TCP_DEBUG_ERROR("-ENOMEM: Can't alloc buffer for payload.");
TCP_DEBUG_LEAVE;
return -ENOMEM; return -ENOMEM;
} }
} }
@ -180,17 +184,19 @@ int _pkt_build(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con,
tcp_snp = gnrc_pktbuf_add(pay_snp, &tcp_hdr, sizeof(tcp_hdr), GNRC_NETTYPE_TCP); tcp_snp = gnrc_pktbuf_add(pay_snp, &tcp_hdr, sizeof(tcp_hdr), GNRC_NETTYPE_TCP);
if (tcp_snp == NULL) { if (tcp_snp == NULL) {
DEBUG("gnrc_tcp_pkt.c : _pkt_build() : Can't allocate buffer for TCP Header\n.");
gnrc_pktbuf_release(pay_snp); gnrc_pktbuf_release(pay_snp);
*(out_pkt) = NULL; *(out_pkt) = NULL;
TCP_DEBUG_ERROR("-ENOMEM: Can't alloc buffer for TCP header.");
TCP_DEBUG_LEAVE;
return -ENOMEM; return -ENOMEM;
} }
else { else {
/* Resize TCP header: size = offset * 4 bytes */ /* Resize TCP header: size = offset * 4 bytes */
if (gnrc_pktbuf_realloc_data(tcp_snp, offset * 4)) { if (gnrc_pktbuf_realloc_data(tcp_snp, offset * 4)) {
DEBUG("gnrc_tcp_pkt.c : _pkt_build() : Couldn't set size of TCP header\n");
gnrc_pktbuf_release(tcp_snp); gnrc_pktbuf_release(tcp_snp);
*(out_pkt) = NULL; *(out_pkt) = NULL;
TCP_DEBUG_ERROR("-ENOMEM: Can't realloc buffer for TCP header.");
TCP_DEBUG_LEAVE;
return -ENOMEM; return -ENOMEM;
} }
@ -220,9 +226,10 @@ int _pkt_build(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con,
gnrc_pktsnip_t *ip6_snp = gnrc_ipv6_hdr_build(tcp_snp, src_addr, dst_addr); gnrc_pktsnip_t *ip6_snp = gnrc_ipv6_hdr_build(tcp_snp, src_addr, dst_addr);
if (ip6_snp == NULL) { if (ip6_snp == NULL) {
DEBUG("gnrc_tcp_pkt.c : _pkt_build() : Can't allocate buffer for IPv6 Header.\n");
gnrc_pktbuf_release(tcp_snp); gnrc_pktbuf_release(tcp_snp);
*(out_pkt) = NULL; *(out_pkt) = NULL;
TCP_DEBUG_ERROR("-ENOMEM: Can't allocate buffer for IPv6 header.");
TCP_DEBUG_LEAVE;
return -ENOMEM; return -ENOMEM;
} }
else { else {
@ -233,9 +240,10 @@ int _pkt_build(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con,
if (tcb->ll_iface > 0) { if (tcb->ll_iface > 0) {
gnrc_pktsnip_t *net_snp = gnrc_netif_hdr_build(NULL, 0, NULL, 0); gnrc_pktsnip_t *net_snp = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
if (net_snp == NULL) { if (net_snp == NULL) {
DEBUG("gnrc_tcp_pkt.c : _pkt_build() : Can't allocate buffer for netif header.\n");
gnrc_pktbuf_release(ip6_snp); gnrc_pktbuf_release(ip6_snp);
*(out_pkt) = NULL; *(out_pkt) = NULL;
TCP_DEBUG_ERROR("-ENOMEM: Can't allocate buffer for netif header.");
TCP_DEBUG_LEAVE;
return -ENOMEM; return -ENOMEM;
} }
else { else {
@ -245,7 +253,7 @@ int _pkt_build(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con,
} }
} }
#else #else
DEBUG("gnrc_tcp_pkt.c : _pkt_build_reset_from_pkt() : Network Layer Module Missing\n"); TCP_DEBUG_ERROR("Missing network layer. Add module to makefile.");
#endif #endif
/* Calculate sequence space number consumption for this packet */ /* Calculate sequence space number consumption for this packet */
@ -259,14 +267,17 @@ int _pkt_build(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con,
} }
*seq_con += payload_len; *seq_con += payload_len;
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
int _pkt_send(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *out_pkt, const uint16_t seq_con, int _pkt_send(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *out_pkt, const uint16_t seq_con,
const bool retransmit) const bool retransmit)
{ {
TCP_DEBUG_ENTER;
if (out_pkt == NULL) { if (out_pkt == NULL) {
DEBUG("gnrc_tcp_pkt.c : _pkt_send() : Packet to send is null\n"); TCP_DEBUG_ERROR("-EINVAL: out_pkt is null.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
@ -283,14 +294,16 @@ int _pkt_send(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *out_pkt, const uint16_t seq_c
/* Pass packet down the network stack */ /* Pass packet down the network stack */
if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_TCP, GNRC_NETREG_DEMUX_CTX_ALL, if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_TCP, GNRC_NETREG_DEMUX_CTX_ALL,
out_pkt)) { out_pkt)) {
DEBUG("gnrc_tcp_pkt.c : _pkt_send() : unable to send packet\n");
gnrc_pktbuf_release(out_pkt); gnrc_pktbuf_release(out_pkt);
TCP_DEBUG_ERROR("Can't dispatch to network layer.");
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
int _pkt_chk_seq_num(const gnrc_tcp_tcb_t *tcb, const uint32_t seq_num, const uint32_t seg_len) int _pkt_chk_seq_num(const gnrc_tcp_tcb_t *tcb, const uint32_t seq_num, const uint32_t seg_len)
{ {
TCP_DEBUG_ENTER;
uint32_t l_edge = tcb->rcv_nxt; uint32_t l_edge = tcb->rcv_nxt;
uint32_t r_edge = tcb->rcv_nxt + tcb->rcv_wnd; uint32_t r_edge = tcb->rcv_nxt + tcb->rcv_wnd;
uint32_t last_seq = seq_num + seg_len - 1; uint32_t last_seq = seq_num + seg_len - 1;
@ -299,6 +312,7 @@ int _pkt_chk_seq_num(const gnrc_tcp_tcb_t *tcb, const uint32_t seq_num, const ui
/* Segment contains no payload and receive window is closed and */ /* Segment contains no payload and receive window is closed and */
/* sequence number is next expected number */ /* sequence number is next expected number */
if (seg_len == 0 && tcb->rcv_wnd == 0 && l_edge == seq_num) { if (seg_len == 0 && tcb->rcv_wnd == 0 && l_edge == seq_num) {
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -306,6 +320,7 @@ int _pkt_chk_seq_num(const gnrc_tcp_tcb_t *tcb, const uint32_t seq_num, const ui
/* Segment contains no payload and receive window is open and */ /* Segment contains no payload and receive window is open and */
/* sequence number falls inside the receive window */ /* sequence number falls inside the receive window */
if (seg_len == 0 && tcb->rcv_wnd > 0 && INSIDE_WND(l_edge, seq_num, r_edge)) { if (seg_len == 0 && tcb->rcv_wnd > 0 && INSIDE_WND(l_edge, seq_num, r_edge)) {
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -314,15 +329,18 @@ int _pkt_chk_seq_num(const gnrc_tcp_tcb_t *tcb, const uint32_t seq_num, const ui
/* sequence number overlaps with receive window */ /* sequence number overlaps with receive window */
if (seg_len > 0 && tcb->rcv_wnd > 0 && (INSIDE_WND(l_edge, seq_num, r_edge) || if (seg_len > 0 && tcb->rcv_wnd > 0 && (INSIDE_WND(l_edge, seq_num, r_edge) ||
INSIDE_WND(l_edge, last_seq, r_edge))) { INSIDE_WND(l_edge, last_seq, r_edge))) {
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
/* Everything else is not acceptable */ /* Everything else is not acceptable */
TCP_DEBUG_LEAVE;
return -1; return -1;
} }
uint32_t _pkt_get_seg_len(gnrc_pktsnip_t *pkt) uint32_t _pkt_get_seg_len(gnrc_pktsnip_t *pkt)
{ {
TCP_DEBUG_ENTER;
uint32_t seq = 0; uint32_t seq = 0;
uint16_t ctl = 0; uint16_t ctl = 0;
gnrc_pktsnip_t *snp = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_TCP); gnrc_pktsnip_t *snp = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_TCP);
@ -335,35 +353,41 @@ uint32_t _pkt_get_seg_len(gnrc_pktsnip_t *pkt)
if (ctl & MSK_FIN) { if (ctl & MSK_FIN) {
seq += 1; seq += 1;
} }
TCP_DEBUG_LEAVE;
return seq; return seq;
} }
uint32_t _pkt_get_pay_len(gnrc_pktsnip_t *pkt) uint32_t _pkt_get_pay_len(gnrc_pktsnip_t *pkt)
{ {
TCP_DEBUG_ENTER;
uint32_t seg_len = 0; uint32_t seg_len = 0;
gnrc_pktsnip_t *snp = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_UNDEF); gnrc_pktsnip_t *snp = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_UNDEF);
while (snp && snp->type == GNRC_NETTYPE_UNDEF) { while (snp && snp->type == GNRC_NETTYPE_UNDEF) {
seg_len += snp->size; seg_len += snp->size;
snp = snp->next; snp = snp->next;
} }
TCP_DEBUG_LEAVE;
return seg_len; return seg_len;
} }
int _pkt_setup_retransmit(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *pkt, const bool retransmit) int _pkt_setup_retransmit(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *pkt, const bool retransmit)
{ {
TCP_DEBUG_ENTER;
gnrc_pktsnip_t *snp = NULL; gnrc_pktsnip_t *snp = NULL;
uint32_t ctl = 0; uint32_t ctl = 0;
uint32_t len = 0; uint32_t len = 0;
/* No packet received */ /* No packet received */
if (pkt == NULL) { if (pkt == NULL) {
DEBUG("gnrc_tcp_pkt.c : _pkt_setup_retransmit() : pkt=NULL\n"); TCP_DEBUG_ERROR("-EINVAL: pkt == NULL.");
TCP_DEBUG_LEAVE;
return -EINVAL; return -EINVAL;
} }
/* Check if retransmit queue is full and pkt is not already in retransmit queue */ /* Check if retransmit queue is full and pkt is not already in retransmit queue */
if (tcb->pkt_retransmit != NULL && tcb->pkt_retransmit != pkt) { if (tcb->pkt_retransmit != NULL && tcb->pkt_retransmit != pkt) {
DEBUG("gnrc_tcp_pkt.c : _pkt_setup_retransmit() : Nothing to do\n"); TCP_DEBUG_ERROR("-ENOMEM: Retransmit queue is full.");
TCP_DEBUG_LEAVE;
return -ENOMEM; return -ENOMEM;
} }
@ -374,6 +398,7 @@ int _pkt_setup_retransmit(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *pkt, const bool r
/* Check if pkt contains reset or is a pure ACK, return */ /* Check if pkt contains reset or is a pure ACK, return */
if ((ctl & MSK_RST) || (((ctl & MSK_SYN_FIN_ACK) == MSK_ACK) && len == 0)) { if ((ctl & MSK_RST) || (((ctl & MSK_SYN_FIN_ACK) == MSK_ACK) && len == 0)) {
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -415,18 +440,21 @@ 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 */
_gnrc_tcp_event_loop_sched(&tcb->event_retransmit, tcb->rto, _gnrc_tcp_event_loop_sched(&tcb->event_retransmit, tcb->rto,
MSG_TYPE_RETRANSMISSION, tcb); MSG_TYPE_RETRANSMISSION, tcb);
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
int _pkt_acknowledge(gnrc_tcp_tcb_t *tcb, const uint32_t ack) int _pkt_acknowledge(gnrc_tcp_tcb_t *tcb, const uint32_t ack)
{ {
TCP_DEBUG_ENTER;
uint32_t seg = 0; uint32_t seg = 0;
gnrc_pktsnip_t *snp = NULL; gnrc_pktsnip_t *snp = NULL;
tcp_hdr_t *hdr; tcp_hdr_t *hdr;
/* Retransmission queue is empty. Nothing to ACK there */ /* Retransmission queue is empty. Nothing to ACK there */
if (tcb->pkt_retransmit == NULL) { if (tcb->pkt_retransmit == NULL) {
DEBUG("gnrc_tcp_pkt.c : _pkt_acknowledge() : There is no packet to ack\n"); TCP_DEBUG_ERROR("-ENODATA: No packet to acknowledge.");
TCP_DEBUG_LEAVE;
return -ENODATA; return -ENODATA;
} }
@ -461,16 +489,19 @@ int _pkt_acknowledge(gnrc_tcp_tcb_t *tcb, const uint32_t ack)
} }
} }
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
uint16_t _pkt_calc_csum(const gnrc_pktsnip_t *hdr, const gnrc_pktsnip_t *pseudo_hdr, uint16_t _pkt_calc_csum(const gnrc_pktsnip_t *hdr, const gnrc_pktsnip_t *pseudo_hdr,
const gnrc_pktsnip_t *payload) const gnrc_pktsnip_t *payload)
{ {
TCP_DEBUG_ENTER;
uint16_t csum = 0; uint16_t csum = 0;
uint16_t len = (uint16_t) hdr->size; uint16_t len = (uint16_t) hdr->size;
if (pseudo_hdr == NULL) { if (pseudo_hdr == NULL) {
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
@ -496,7 +527,10 @@ uint16_t _pkt_calc_csum(const gnrc_pktsnip_t *hdr, const gnrc_pktsnip_t *pseudo_
default: default:
/* Suppress compiler warnings */ /* Suppress compiler warnings */
(void) len; (void) len;
TCP_DEBUG_ERROR("Missing network layer. Add module to makefile.");
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
TCP_DEBUG_LEAVE;
return ~csum; return ~csum;
} }

View File

@ -16,6 +16,7 @@
* @author Simon Brummer <simon.brummer@posteo.de> * @author Simon Brummer <simon.brummer@posteo.de>
*/ */
#include <errno.h> #include <errno.h>
#include "internal/common.h"
#include "internal/rcvbuf.h" #include "internal/rcvbuf.h"
#define ENABLE_DEBUG (0) #define ENABLE_DEBUG (0)
@ -31,11 +32,12 @@ static rcvbuf_t _static_buf;
*/ */
void _rcvbuf_init(void) void _rcvbuf_init(void)
{ {
DEBUG("gnrc_tcp_rcvbuf.c : _rcvbuf_init() : entry\n"); TCP_DEBUG_ENTER;
mutex_init(&(_static_buf.lock)); mutex_init(&(_static_buf.lock));
for (size_t i = 0; i < CONFIG_GNRC_TCP_RCV_BUFFERS; ++i) { for (size_t i = 0; i < CONFIG_GNRC_TCP_RCV_BUFFERS; ++i) {
_static_buf.entries[i].used = 0; _static_buf.entries[i].used = 0;
} }
TCP_DEBUG_LEAVE;
} }
/** /**
@ -46,8 +48,8 @@ void _rcvbuf_init(void)
*/ */
static void* _rcvbuf_alloc(void) static void* _rcvbuf_alloc(void)
{ {
TCP_DEBUG_ENTER;
void *result = NULL; void *result = NULL;
DEBUG("gnrc_tcp_rcvbuf.c : _rcvbuf_alloc() : Entry\n");
mutex_lock(&(_static_buf.lock)); mutex_lock(&(_static_buf.lock));
for (size_t i = 0; i < CONFIG_GNRC_TCP_RCV_BUFFERS; ++i) { for (size_t i = 0; i < CONFIG_GNRC_TCP_RCV_BUFFERS; ++i) {
if (_static_buf.entries[i].used == 0) { if (_static_buf.entries[i].used == 0) {
@ -57,6 +59,7 @@ static void* _rcvbuf_alloc(void)
} }
} }
mutex_unlock(&(_static_buf.lock)); mutex_unlock(&(_static_buf.lock));
TCP_DEBUG_LEAVE;
return result; return result;
} }
@ -67,7 +70,7 @@ static void* _rcvbuf_alloc(void)
*/ */
static void _rcvbuf_free(void * const buf) static void _rcvbuf_free(void * const buf)
{ {
DEBUG("gnrc_tcp_rcvbuf.c : _rcvbuf_free() : Entry\n"); TCP_DEBUG_ENTER;
mutex_lock(&(_static_buf.lock)); mutex_lock(&(_static_buf.lock));
for (size_t i = 0; i < CONFIG_GNRC_TCP_RCV_BUFFERS; ++i) { for (size_t i = 0; i < CONFIG_GNRC_TCP_RCV_BUFFERS; ++i) {
if ((_static_buf.entries[i].used == 1) && (buf == _static_buf.entries[i].buffer)) { if ((_static_buf.entries[i].used == 1) && (buf == _static_buf.entries[i].buffer)) {
@ -75,27 +78,33 @@ static void _rcvbuf_free(void * const buf)
} }
} }
mutex_unlock(&(_static_buf.lock)); mutex_unlock(&(_static_buf.lock));
TCP_DEBUG_LEAVE;
} }
int _rcvbuf_get_buffer(gnrc_tcp_tcb_t *tcb) int _rcvbuf_get_buffer(gnrc_tcp_tcb_t *tcb)
{ {
TCP_DEBUG_ENTER;
if (tcb->rcv_buf_raw == NULL) { if (tcb->rcv_buf_raw == NULL) {
tcb->rcv_buf_raw = _rcvbuf_alloc(); tcb->rcv_buf_raw = _rcvbuf_alloc();
if (tcb->rcv_buf_raw == NULL) { if (tcb->rcv_buf_raw == NULL) {
DEBUG("gnrc_tcp_rcvbuf.c : _rcvbuf_get_buffer() : Can't allocate rcv_buf_raw\n"); TCP_DEBUG_ERROR("-ENOMEM: Failed to allocate receive buffer.");
TCP_DEBUG_LEAVE;
return -ENOMEM; return -ENOMEM;
} }
else { else {
ringbuffer_init(&tcb->rcv_buf, (char *) tcb->rcv_buf_raw, GNRC_TCP_RCV_BUF_SIZE); ringbuffer_init(&tcb->rcv_buf, (char *) tcb->rcv_buf_raw, GNRC_TCP_RCV_BUF_SIZE);
} }
} }
TCP_DEBUG_LEAVE;
return 0; return 0;
} }
void _rcvbuf_release_buffer(gnrc_tcp_tcb_t *tcb) void _rcvbuf_release_buffer(gnrc_tcp_tcb_t *tcb)
{ {
TCP_DEBUG_ENTER;
if (tcb->rcv_buf_raw != NULL) { if (tcb->rcv_buf_raw != NULL) {
_rcvbuf_free(tcb->rcv_buf_raw); _rcvbuf_free(tcb->rcv_buf_raw);
tcb->rcv_buf_raw = NULL; tcb->rcv_buf_raw = NULL;
} }
TCP_DEBUG_LEAVE;
} }

View File

@ -114,6 +114,38 @@ extern "C" {
*/ */
#define GET_OFFSET( x ) (((x) & MSK_OFFSET) >> 12) #define GET_OFFSET( x ) (((x) & MSK_OFFSET) >> 12)
/**
* @brief Helper macro used to create debug message on function entry.
*
* @note Compilation units using TCP_DEBUG_ENTER must set ENABLE_DEBUG and include debug.h.
*/
#define TCP_DEBUG_ENTER DEBUG("GNRC_TCP: Enter \"%s\", File: %s(%d)\n", \
DEBUG_FUNC, RIOT_FILE_RELATIVE, __LINE__)
/**
* @brief Helper macro used to create debug message on function exit.
*
* @note Compilation units using TCP_DEBUG_LEAVE must set ENABLE_DEBUG and include debug.h.
*/
#define TCP_DEBUG_LEAVE DEBUG("GNRC_TCP: Leave \"%s\", File: %s(%d)\n", \
DEBUG_FUNC, RIOT_FILE_RELATIVE, __LINE__)
/**
* @brief Helper macro used to create debug message on error.
*
* @note Compilation units using TCP_DEBUG_ERROR must set ENABLE_DEBUG and include debug.h.
*/
#define TCP_DEBUG_ERROR(msg) DEBUG("GNRC_TCP: Error: \"%s\", Func: %s, File: %s(%d)\n", \
msg, DEBUG_FUNC, RIOT_FILE_RELATIVE, __LINE__)
/**
* @brief Helper macro used to create informational debug message.
*
* @note Compilation units using TCP_DEBUG_INFO must set ENABLE_DEBUG and include debug.h.
*/
#define TCP_DEBUG_INFO(msg) DEBUG("GNRC_TCP: Info: \"%s\", Func: %s, File: %s(%d)\n", \
msg, DEBUG_FUNC, RIOT_FILE_RELATIVE, __LINE__)
/** /**
* @brief TCB list type. * @brief TCB list type.
*/ */

View File

@ -7,6 +7,7 @@
# directory for more details. # directory for more details.
import base64 import base64
import pexpect
import os import os
import socket import socket
import sys import sys
@ -96,6 +97,16 @@ def test_short_header(child, src_if, src_ll, dst_if, dst_l2, dst_ll, dst_port):
@testfunc @testfunc
def test_send_ack_instead_of_syn(child, src_if, src_ll, def test_send_ack_instead_of_syn(child, src_if, src_ll,
dst_if, dst_l2, dst_ll, dst_port): dst_if, dst_l2, dst_ll, dst_port):
# check if any debug output is generated during `@testfunc` decorator
# execution. If so, send fewer packets to prevent the target node
# from being overwhelmed by packets and output.
debug = child.expect([pexpect.TIMEOUT,
r'GNRC_TCP: Enter "\S+", File: .+\(\d+\)\s'], timeout=1)
if debug:
count = 10
else:
count = 1000
# see https://github.com/RIOT-OS/RIOT/pull/12001 # see https://github.com/RIOT-OS/RIOT/pull/12001
provided_data = base64.b64decode("rwsQf2pekYLaU+exUBBwgPDKAAA=") provided_data = base64.b64decode("rwsQf2pekYLaU+exUBBwgPDKAAA=")
tcp_hdr = TCP(provided_data) tcp_hdr = TCP(provided_data)
@ -103,7 +114,7 @@ def test_send_ack_instead_of_syn(child, src_if, src_ll,
# set destination port to application specific port # set destination port to application specific port
tcp_hdr.dport = dst_port tcp_hdr.dport = dst_port
sendp(Ether(dst=dst_l2) / IPv6(src=src_ll, dst=dst_ll) / tcp_hdr, sendp(Ether(dst=dst_l2) / IPv6(src=src_ll, dst=dst_ll) / tcp_hdr,
iface=src_if, verbose=0, count=1000) iface=src_if, verbose=0, count=count)
# check if server actually still works # check if server actually still works
with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as sock: with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as sock: