diff --git a/sys/include/net/gnrc/tcp.h b/sys/include/net/gnrc/tcp.h index b3b52d4bc091de0654e597ede92eae2bf1fef3bf..e12a35ebb104298769a0fb33f5d227af89d73158 100644 --- a/sys/include/net/gnrc/tcp.h +++ b/sys/include/net/gnrc/tcp.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -14,17 +14,16 @@ * @{ * * @file - * @brief TCP interface definition + * @brief GNRC TCP API * - * @author Simon Brummer <simon.brummer@haw-hamburg.de> + * @author Simon Brummer <simon.brummer@posteo.de> */ -#ifndef GNRC_TCP_H_ -#define GNRC_TCP_H_ +#ifndef GNRC_TCP_H +#define GNRC_TCP_H -#include "net/tcp.h" -#include "net/gnrc/netapi.h" -#include "net/gnrc/nettype.h" +#include <stdint.h> +#include "net/gnrc/pkt.h" #include "net/gnrc/tcp/tcb.h" #ifdef MODULE_GNRC_IPV6 @@ -35,23 +34,6 @@ extern "C" { #endif -/** - * @brief Port unspecified. - * - * @note PORT 0 is reserved, according to rfc 1700(https://www.ietf.org/rfc/rfc1700.txt) - */ -#define GNRC_TCP_PORT_UNSPEC 0 - -/** - * @brief Head of conn linked list. - */ -extern gnrc_tcp_tcb_t *_list_gnrc_tcp_tcb_head; - -/** - * @brief Mutex to protect linked list. - */ -extern mutex_t _list_gnrc_tcp_tcb_lock; - /** * @brief Initialize and start TCP * @@ -68,7 +50,7 @@ int gnrc_tcp_init(void); * * @param[in,out] tcb Transmission that should be initialized. */ -void gnrc_tcp_tcb_init(gnrc_tcp_tcb_t* tcb); +void gnrc_tcp_tcb_init(gnrc_tcp_tcb_t *tcb); /** * @brief Opens a connection actively. @@ -85,7 +67,7 @@ void gnrc_tcp_tcb_init(gnrc_tcp_tcb_t* tcb); * @param[in] target_addr Pointer to target address. * @param[in] target_port Targets port number. * @param[in] local_port If zero or GNRC_TCP_PORT_UNSPEC, the connections - * source port is randomly choosen. If local_port is non-zero + * source port is randomly chosen. If local_port is non-zero * the local_port is used as source port. * * @return Zero on success. @@ -116,7 +98,7 @@ int gnrc_tcp_open_active(gnrc_tcp_tcb_t *tcb, const uint8_t address_family, * @param[in,out] tcb This connections Transmission control block. * @param[in] address_family Address Family of @p local_addr. * If local_addr == NULL, address_family is ignored. - * @param[in] local_addr If not NULL the connection is bound to the address in @p local_addr. + * @param[in] local_addr If not NULL the connection is bound to the address @p local_addr. * If NULL a connection request to every local ip address is valid. * @param[in] local_port Portnumber that should used for incomming connection requests. * @@ -200,8 +182,8 @@ int gnrc_tcp_close(gnrc_tcp_tcb_t *tcb); /** * @brief Set checksum calculated from tcp and network-layer header in tcp-header. * - * @param[in] hdr ng_pktsnip that contains tcp header. - * @param[in] pseudo_hdr ng_pktsnip that contains networklayer header. + * @param[in] hdr gnrc_pktsnip that contains tcp header. + * @param[in] pseudo_hdr gnrc_pktsnip that contains networklayer header. * * @return zero on succeed. * @return -EFAULT if hdr or pseudo_hdr were NULL @@ -227,5 +209,5 @@ gnrc_pktsnip_t *gnrc_tcp_hdr_build(gnrc_pktsnip_t *payload, uint16_t src, uint16 } #endif -#endif /* GNRC_TCP_H_ */ +#endif /* GNRC_TCP_H */ /** @} */ diff --git a/sys/include/net/gnrc/tcp/config.h b/sys/include/net/gnrc/tcp/config.h index fe8f20f2b0a04313a39c2b343c5ceb225d65e2db..9088c83686c82722ed5037f22792e6a57c741b08 100644 --- a/sys/include/net/gnrc/tcp/config.h +++ b/sys/include/net/gnrc/tcp/config.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -14,13 +14,13 @@ * @{ * * @file - * @brief TCP configuration, includes buffersizes, timeout durations + * @brief GNRC TCP configuration * - * @author Simon Brummer <simon.brummer@haw-hamburg.de> + * @author Simon Brummer <simon.brummer@posteo.de> */ -#ifndef GNRC_TCP_CONFIG_H_ -#define GNRC_TCP_CONFIG_H_ +#ifndef GNRC_TCP_CONFIG_H +#define GNRC_TCP_CONFIG_H #include "timex.h" @@ -28,48 +28,18 @@ extern "C" { #endif -/** - * @brief Status Flags for TCP - * @{ - */ -#define GNRC_TCP_STATUS_PASSIVE (1 << 0) -#define GNRC_TCP_STATUS_ACCEPTED (1 << 1) -#define GNRC_TCP_STATUS_ALLOW_ANY_ADDR (1 << 2) -/** @} */ - /** * @brief Timeout Duration for user calls. Default 2 minutes */ #ifndef GNRC_TCP_CONNECTION_TIMEOUT_DURATION -#define GNRC_TCP_CONNECTION_TIMEOUT_DURATION (120 * US_PER_SEC) +#define GNRC_TCP_CONNECTION_TIMEOUT_DURATION (120U * US_PER_SEC) #endif /** * @brief Maximum Segment Lifetime. Default 30 secounds */ #ifndef GNRC_TCP_MSL -#define GNRC_TCP_MSL (30 * US_PER_SEC) -#endif - -/** - * @brief Message queue size for the TCP handling thread - */ -#ifndef GNRC_TCP_MSG_QUEUE_SIZE -#define GNRC_TCP_MSG_QUEUE_SIZE (8U) -#endif - -/** - * @brief Priority of the tcp handling thread, must be lower than the applications prio. - */ -#ifndef GNRC_TCP_PRIO -#define GNRC_TCP_PRIO (THREAD_PRIORITY_MAIN - 2U) -#endif - -/** - * @brief Default stack size for the TCP handling thread - */ -#ifndef GNRC_TCP_STACK_SIZE -#define GNRC_TCP_STACK_SIZE (THREAD_STACKSIZE_DEFAULT) +#define GNRC_TCP_MSL (30U * US_PER_SEC) #endif /** @@ -101,7 +71,7 @@ extern "C" { * @brief Number of preallocated receive buffers */ #ifndef GNRC_TCP_RCV_BUFFERS -#define GNRC_TCP_RCV_BUFFERS 1 +#define GNRC_TCP_RCV_BUFFERS (1U) #endif /** @@ -115,21 +85,21 @@ extern "C" { * @brief Lower Bound for RTO = 1 sec (see RFC 6298) */ #ifndef GNRC_TCP_RTO_LOWER_BOUND -#define GNRC_TCP_RTO_LOWER_BOUND (1 * US_PER_SEC) +#define GNRC_TCP_RTO_LOWER_BOUND (1U * US_PER_SEC) #endif /** * @brief Upper Bound for RTO = 60 sec (see RFC 6298) */ #ifndef GNRC_TCP_RTO_UPPER_BOUND -#define GNRC_TCP_RTO_UPPER_BOUND (60 * US_PER_SEC) +#define GNRC_TCP_RTO_UPPER_BOUND (60U * US_PER_SEC) #endif /** * @brief Assumes clock granularity for TCP of 10 ms (see RFC 6298) */ #ifndef GNRC_TCP_RTO_GRANULARITY -#define GNRC_TCP_RTO_GRANULARITY (10 * MS_PER_SEC) +#define GNRC_TCP_RTO_GRANULARITY (10U * MS_PER_SEC) #endif /** @@ -153,30 +123,23 @@ extern "C" { #define GNRC_TCP_RTO_K (4U) #endif -/** - * @brief Macro to mark is the time measurement is uninitialized - */ -#ifndef GNRC_TCP_RTO_UNINITIALIZED -#define GNRC_TCP_RTO_UNINITIALIZED (-1) -#endif - /** * @brief Lower Bound for the duration between probes */ #ifndef GNRC_TCP_PROBE_LOWER_BOUND -#define GNRC_TCP_PROBE_LOWER_BOUND (1 * US_PER_SEC) +#define GNRC_TCP_PROBE_LOWER_BOUND (1U * US_PER_SEC) #endif /** * @brief Upper Bound for the duration between probes */ #ifndef GNRC_TCP_PROBE_UPPER_BOUND -#define GNRC_TCP_PROBE_UPPER_BOUND (60 * US_PER_SEC) +#define GNRC_TCP_PROBE_UPPER_BOUND (60U * US_PER_SEC) #endif #ifdef __cplusplus } #endif -#endif /* GNRC_TCP_CONFIG_H_ */ +#endif /* GNRC_TCP_CONFIG_H */ /** @} */ diff --git a/sys/include/net/gnrc/tcp/fsm.h b/sys/include/net/gnrc/tcp/fsm.h deleted file mode 100644 index 43ca94cdd3a859b7a1724114e4e3fe22f86c554e..0000000000000000000000000000000000000000 --- a/sys/include/net/gnrc/tcp/fsm.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2015 Simon Brummer - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @defgroup net_gnrc_tcp TCP - * @ingroup net_gnrc - * @brief RIOT's tcp implementation for the gnrc stack - * - * @{ - * - * @file - * @brief Definies states and events for TCP finite state maschine - * - * @author Simon Brummer <brummer.simon@googlemail.com> - */ - -#ifndef GNRC_TCP_FSM_H_ -#define GNRC_TCP_FSM_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief The TCP FSM States. - */ -typedef enum { - GNRC_TCP_FSM_STATE_CLOSED, - GNRC_TCP_FSM_STATE_LISTEN, - GNRC_TCP_FSM_STATE_SYN_SENT, - GNRC_TCP_FSM_STATE_SYN_RCVD, - GNRC_TCP_FSM_STATE_ESTABLISHED, - GNRC_TCP_FSM_STATE_CLOSE_WAIT, - GNRC_TCP_FSM_STATE_LAST_ACK, - GNRC_TCP_FSM_STATE_FIN_WAIT_1, - GNRC_TCP_FSM_STATE_FIN_WAIT_2, - GNRC_TCP_FSM_STATE_CLOSING, - GNRC_TCP_FSM_STATE_TIME_WAIT -} gnrc_tcp_fsm_state_t; - -/** - * @brief Events that trigger translations in TCP FSM. - */ -typedef enum { - GNRC_TCP_FSM_EVENT_CALL_OPEN, /* User function call: open */ - GNRC_TCP_FSM_EVENT_CALL_SEND, /* User function call: send */ - GNRC_TCP_FSM_EVENT_CALL_RECV, /* User function call: recv */ - GNRC_TCP_FSM_EVENT_CALL_CLOSE, /* User function call: close */ - GNRC_TCP_FSM_EVENT_CALL_ABORT, /* User function call: abort */ - GNRC_TCP_FSM_EVENT_RCVD_PKT, /* Paket received from peer */ - GNRC_TCP_FSM_EVENT_TIMEOUT_TIMEWAIT, /* Timeout: Timewait */ - GNRC_TCP_FSM_EVENT_TIMEOUT_RETRANSMIT, /* Timeout: Retransmit */ - GNRC_TCP_FSM_EVENT_TIMEOUT_CONNECTION, /* Timeout: Connection */ - GNRC_TCP_FSM_EVENT_SEND_PROBE, /* Send a Zero Window Probe */ - GNRC_TCP_FSM_EVENT_CLEAR_RETRANSMIT /* Clear Retransmission Mechanism */ -} gnrc_tcp_fsm_event_t; - -#ifdef __cplusplus -} -#endif - -#endif /* GNRC_TCP_FSM_H_ */ -/** @} */ diff --git a/sys/include/net/gnrc/tcp/tcb.h b/sys/include/net/gnrc/tcp/tcb.h index 6e8dc15746bf480c869ce752d47d51d0edae3194..bb3faf672864c0d11c88bbbf3f93689fdeb4f12f 100644 --- a/sys/include/net/gnrc/tcp/tcb.h +++ b/sys/include/net/gnrc/tcp/tcb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -14,21 +14,21 @@ * @{ * * @file - * @brief Transmission Control Block definition + * @brief GNRC TCP transmission control block * - * @author Simon Brummer <simon.brummer@haw-hamburg.de> + * @author Simon Brummer <simon.brummer@posteo.de> */ -#ifndef GNRC_TCP_TCB_H_ -#define GNRC_TCP_TCB_H_ +#ifndef GNRC_TCP_TCB_H +#define GNRC_TCP_TCB_H #include <stdint.h> -#include <ringbuffer.h> -#include <xtimer.h> -#include <mutex.h> -#include <msg.h> -#include "net/gnrc.h" -#include "fsm.h" +#include "kernel_types.h" +#include "ringbuffer.h" +#include "xtimer.h" +#include "mutex.h" +#include "msg.h" +#include "net/gnrc/pkt.h" #include "config.h" #ifdef MODULE_GNRC_IPV6 @@ -39,48 +39,53 @@ extern "C" { #endif +/** + * @brief Size of the tcbs internal message queue + */ +#define GNRC_TCP_TCB_MSG_QUEUE_SIZE (8U) + /** * @brief transmission control block of gnrc_tcp */ typedef struct _transmission_control_block { - uint8_t address_family; /**< Address Family of local_addr and peer_addr */ + uint8_t address_family; /**< Address Family of local_addr and peer_addr */ #ifdef MODULE_GNRC_IPV6 - uint8_t local_addr[sizeof(ipv6_addr_t)]; /**< local IP address */ - uint8_t peer_addr[sizeof(ipv6_addr_t)]; /**< peer IP address */ + uint8_t local_addr[sizeof(ipv6_addr_t)]; /**< local IP address */ + uint8_t peer_addr[sizeof(ipv6_addr_t)]; /**< peer IP address */ #endif - uint16_t local_port; /**< local connections port number */ - uint16_t peer_port; /**< port connections port number */ - gnrc_tcp_fsm_state_t state; /**< Connections state */ - uint8_t status; /**< A connections status flags */ - uint32_t snd_una; /**< Send Unacknowledged */ - uint32_t snd_nxt; /**< Send Next */ - uint16_t snd_wnd; /**< Send Window */ - uint32_t snd_wl1; /**< SeqNo. Last Windowupdate */ - uint32_t snd_wl2; /**< AckNo. Last Windowupdate */ - uint32_t rcv_nxt; /**< Receive Next */ - uint16_t rcv_wnd; /**< Receive Window */ - uint32_t iss; /**< Initial Sequence Number */ - uint32_t irs; /**< Initial Received Sequence Number */ - uint16_t mss; /**< The peers MSS */ - uint32_t rtt_start; /**< Timer value for rtt estimation */ - int32_t rtt_var; /**< Round Trip Time variance */ - int32_t srtt; /**< Smoothed Round Trip Time */ - int32_t rto; /**< Retransmission Timeout Duration */ - uint8_t retries; /**< Number of Retransmissions */ - xtimer_t tim_tout; /**< Timer struct for timeouts */ - msg_t msg_tout; /**< Message, sent on timeouts */ - gnrc_pktsnip_t *pkt_retransmit; /**< Pointer to Packet in "retransmit queue" */ - kernel_pid_t owner; /**< PID of this connection handling thread */ - msg_t msg_queue[GNRC_TCP_MSG_QUEUE_SIZE]; /**< Message queue used for asynchronious operation */ - uint8_t *rcv_buf_raw; /**< Pointer to the receive buffer */ - ringbuffer_t rcv_buf; /**< Receive Buffer data structure */ - mutex_t fsm_lock; /**< Mutex for FSM access synchronization */ - mutex_t function_lock; /**< Mutex for Function call synchronization */ - struct _transmission_control_block *next; /**< Pointer next TCP connection */ + uint16_t local_port; /**< local connections port number */ + uint16_t peer_port; /**< port connections port number */ + uint8_t state; /**< Connections state */ + uint8_t status; /**< A connections status flags */ + uint32_t snd_una; /**< Send Unacknowledged */ + uint32_t snd_nxt; /**< Send Next */ + uint16_t snd_wnd; /**< Send Window */ + uint32_t snd_wl1; /**< SeqNo. Last Windowupdate */ + uint32_t snd_wl2; /**< AckNo. Last Windowupdate */ + uint32_t rcv_nxt; /**< Receive Next */ + uint16_t rcv_wnd; /**< Receive Window */ + uint32_t iss; /**< Initial Sequence Number */ + uint32_t irs; /**< Initial Received Sequence Number */ + uint16_t mss; /**< The peers MSS */ + uint32_t rtt_start; /**< Timer value for rtt estimation */ + int32_t rtt_var; /**< Round Trip Time variance */ + int32_t srtt; /**< Smoothed Round Trip Time */ + int32_t rto; /**< Retransmission Timeout Duration */ + uint8_t retries; /**< Number of Retransmissions */ + xtimer_t tim_tout; /**< Timer struct for timeouts */ + msg_t msg_tout; /**< Message, sent on timeouts */ + gnrc_pktsnip_t *pkt_retransmit; /**< Pointer to Packet in "retransmit queue" */ + kernel_pid_t owner; /**< PID of this connection handling thread */ + msg_t msg_queue[GNRC_TCP_TCB_MSG_QUEUE_SIZE]; /**< Tcb's message queue */ + uint8_t *rcv_buf_raw; /**< Pointer to the receive buffer */ + ringbuffer_t rcv_buf; /**< Receive Buffer data structure */ + mutex_t fsm_lock; /**< Mutex for FSM access synchronization */ + mutex_t function_lock; /**< Mutex for Function call synchronization */ + struct _transmission_control_block *next; /**< Pointer next TCP connection */ } gnrc_tcp_tcb_t; #ifdef __cplusplus } #endif -#endif /* GNRC_TCP_TCB_H_ */ +#endif /* GNRC_TCP_TCB_H */ /** @} */ diff --git a/sys/include/net/tcp.h b/sys/include/net/tcp.h index e42bb06ce5fa5504c64632e6e4450ec3c8f13602..9ef4258c639ffe818f6eecae39571faf32dd02d0 100644 --- a/sys/include/net/tcp.h +++ b/sys/include/net/tcp.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -14,9 +14,9 @@ * @{ * * @file - * @brief TCP header and helper functions + * @brief TCP header and helper functions * - * @author Simon Brummer <brummer.simon@googlemail.com> + * @author Simon Brummer <simon.brummer@posteo.de> */ #ifndef TCP_H diff --git a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp.c b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp.c index a957a640901c2225a315a11d5142f883f5794f6b..b8c7fbb7395739076654b0069ad9fa170dbdf21e 100644 --- a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp.c +++ b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -11,34 +11,20 @@ * @{ * * @file - * @brief GNRC's TCP implementation + * @brief GNRC TCP API implementation * - * @author Simon Brummer <brummer.simon@googlemail.com> + * @author Simon Brummer <simon.brummer@posteo.de> * @} */ -#include <stdint.h> #include <errno.h> #include <utlist.h> -#include "msg.h" -#include "assert.h" -#include "thread.h" -#include "byteorder.h" -#include "random.h" -#include "xtimer.h" -#include "mutex.h" -#include "ringbuffer.h" #include "net/af.h" -#include "net/gnrc/nettype.h" -#include "net/gnrc/netapi.h" -#include "net/gnrc/netreg.h" -#include "net/gnrc/pktbuf.h" #include "net/gnrc/tcp.h" - +#include "internal/common.h" #include "internal/fsm.h" #include "internal/pkt.h" #include "internal/option.h" -#include "internal/helper.h" #include "internal/eventloop.h" #include "internal/rcvbuf.h" @@ -53,25 +39,25 @@ * @brief Allocate memory for TCP thread's stack */ #if ENABLE_DEBUG -static char _stack[GNRC_TCP_STACK_SIZE + THREAD_EXTRA_STACKSIZE_PRINTF]; +static char _stack[TCP_EVENTLOOP_STACK_SIZE + THREAD_EXTRA_STACKSIZE_PRINTF]; #else -static char _stack[GNRC_TCP_STACK_SIZE]; +static char _stack[TCP_EVENTLOOP_STACK_SIZE]; #endif /** * @brief TCPs eventloop pid, declared externally */ -kernel_pid_t _gnrc_tcp_pid = KERNEL_PID_UNDEF; +kernel_pid_t gnrc_tcp_pid = KERNEL_PID_UNDEF; /** * @brief Head of liked list of active connections */ -gnrc_tcp_tcb_t *_list_gnrc_tcp_tcb_head; +gnrc_tcp_tcb_t *_list_tcb_head; /** * @brief Mutex to protect the connection list */ -mutex_t _list_gnrc_tcp_tcb_lock; +mutex_t _list_tcb_lock; /** * @brief Establishes a new TCP connection @@ -83,7 +69,7 @@ mutex_t _list_gnrc_tcp_tcb_lock; * @param[in] local_port Local Port to bind on, if this is a passive connection. * @param[in] passive Flag to indicate if this is a active or passive open. * - * @return 0 on success. + * @return 0 on success. * @return -EISCONN if transmission control block is already in use. * @return -ENOMEM if the receive buffer for the tcb could not be allocated. * Increase "GNRC_TCP_RCV_BUFFERS". @@ -103,23 +89,23 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const uint8_t *target_addr, uint1 mutex_lock(&(tcb->function_lock)); /* Connection is already connected: Return -EISCONN */ - if (tcb->state != GNRC_TCP_FSM_STATE_CLOSED) { + if (tcb->state != FSM_STATE_CLOSED) { mutex_unlock(&(tcb->function_lock)); return -EISCONN; } /* Setup connection (common parts) */ - msg_init_queue(tcb->msg_queue, GNRC_TCP_MSG_QUEUE_SIZE); + msg_init_queue(tcb->msg_queue, GNRC_TCP_TCB_MSG_QUEUE_SIZE); tcb->owner = thread_getpid(); /* Setup passive connection */ - if (passive){ + if (passive) { /* Set Status Flags */ - tcb->status |= GNRC_TCP_STATUS_PASSIVE; + tcb->status |= STATUS_PASSIVE; if (local_addr == NULL) { - tcb->status |= GNRC_TCP_STATUS_ALLOW_ANY_ADDR; + tcb->status |= STATUS_ALLOW_ANY_ADDR; } - /* If local address is specified: Copy it into tcb: only connections to this addr are ok */ + /* If local address is specified: Copy it into tcb */ else { switch (tcb->address_family) { #ifdef MODULE_GNRC_IPV6 @@ -133,14 +119,14 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const uint8_t *target_addr, uint1 tcb->local_port = local_port; } /* Setup active connection */ - else{ + else { /* Copy Target Address and Port into tcb structure */ if (target_addr != NULL) { switch (tcb->address_family) { #ifdef MODULE_GNRC_IPV6 - case AF_INET6: - memcpy(tcb->peer_addr, target_addr, sizeof(ipv6_addr_t)); - break; + case AF_INET6: + memcpy(tcb->peer_addr, target_addr, sizeof(ipv6_addr_t)); + break; #endif } } @@ -156,23 +142,22 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const uint8_t *target_addr, uint1 } /* Call FSM with Event: CALL_OPEN */ - ret = _fsm(tcb, GNRC_TCP_FSM_EVENT_CALL_OPEN, NULL, NULL, 0); + ret = _fsm(tcb, FSM_EVENT_CALL_OPEN, NULL, NULL, 0); if (ret == -ENOMEM) { DEBUG("gnrc_tcp.c : gnrc_tcp_connect() : Out of receive buffers.\n"); - } else if(ret == -EADDRINUSE) { + } + else if(ret == -EADDRINUSE) { DEBUG("gnrc_tcp.c : gnrc_tcp_connect() : local_port is already in use.\n"); } /* Wait until a connection was established or closed */ - while (ret >= 0 && tcb->state != GNRC_TCP_FSM_STATE_CLOSED - && tcb->state != GNRC_TCP_FSM_STATE_ESTABLISHED - && tcb->state != GNRC_TCP_FSM_STATE_CLOSE_WAIT - ) { + while (ret >= 0 && tcb->state != FSM_STATE_CLOSED && tcb->state != FSM_STATE_ESTABLISHED && + tcb->state != FSM_STATE_CLOSE_WAIT) { msg_receive(&msg); switch (msg.type) { case MSG_TYPE_CONNECTION_TIMEOUT: DEBUG("gnrc_tcp.c : _gnrc_tcp_open() : CONNECTION_TIMEOUT\n"); - _fsm(tcb, GNRC_TCP_FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0); + _fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0); ret = -ETIMEDOUT; break; @@ -187,7 +172,7 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const uint8_t *target_addr, uint1 /* Cleanup */ xtimer_remove(&connection_timeout_timer); - if (tcb->state == GNRC_TCP_FSM_STATE_CLOSED && ret == 0) { + if (tcb->state == FSM_STATE_CLOSED && ret == 0) { ret = -ECONNREFUSED; } tcb->owner = KERNEL_PID_UNDEF; @@ -199,24 +184,25 @@ static int _gnrc_tcp_open(gnrc_tcp_tcb_t *tcb, const uint8_t *target_addr, uint1 int gnrc_tcp_init(void) { /* Guard: Check if thread is already running */ - if (_gnrc_tcp_pid != KERNEL_PID_UNDEF) { + if (gnrc_tcp_pid != KERNEL_PID_UNDEF) { return -1; } /* Initialize Mutex for linked-list synchronization */ - mutex_init(&(_list_gnrc_tcp_tcb_lock)); + mutex_init(&(_list_tcb_lock)); /* Initialize Linked-List for connection storage */ - _list_gnrc_tcp_tcb_head = NULL; + _list_tcb_head = NULL; /* Initialize receive buffers */ _rcvbuf_init(); /* Start TCP processing loop */ - return thread_create(_stack, sizeof(_stack), GNRC_TCP_PRIO, 0, _event_loop, NULL, "gnrc_tcp"); + return thread_create(_stack, sizeof(_stack), TCP_EVENTLOOP_PRIO, 0, _event_loop, NULL, + "gnrc_tcp"); } -void gnrc_tcp_tcb_init(gnrc_tcp_tcb_t* tcb) +void gnrc_tcp_tcb_init(gnrc_tcp_tcb_t *tcb) { #ifdef MODULE_GNRC_IPV6 tcb->address_family = AF_INET6; @@ -226,9 +212,9 @@ void gnrc_tcp_tcb_init(gnrc_tcp_tcb_t* tcb) tcb->address_family = AF_UNSPEC; DEBUG("gnrc_tcp.c : gnrc_tcp_tcb_init() : Address unspec, add netlayer module to makefile\n"); #endif - tcb->local_port = GNRC_TCP_PORT_UNSPEC; - tcb->peer_port = GNRC_TCP_PORT_UNSPEC; - tcb->state = GNRC_TCP_FSM_STATE_CLOSED; + tcb->local_port = PORT_UNSPEC; + tcb->peer_port = PORT_UNSPEC; + tcb->state = FSM_STATE_CLOSED; tcb->status = 0; tcb->snd_una = 0; tcb->snd_nxt = 0; @@ -241,9 +227,9 @@ void gnrc_tcp_tcb_init(gnrc_tcp_tcb_t* tcb) tcb->irs = 0; tcb->mss = 0; tcb->rtt_start = 0; - tcb->rtt_var = GNRC_TCP_RTO_UNINITIALIZED; - tcb->srtt = GNRC_TCP_RTO_UNINITIALIZED; - tcb->rto = GNRC_TCP_RTO_UNINITIALIZED; + tcb->rtt_var = RTO_UNINITIALIZED; + tcb->srtt = RTO_UNINITIALIZED; + tcb->rto = RTO_UNINITIALIZED; tcb->retries = 0; tcb->pkt_retransmit = NULL; tcb->owner = KERNEL_PID_UNDEF; @@ -259,7 +245,7 @@ int gnrc_tcp_open_active(gnrc_tcp_tcb_t *tcb, const uint8_t address_family, { assert(tcb != NULL); assert(target_addr != NULL); - assert(target_port != GNRC_TCP_PORT_UNSPEC); + assert(target_port != PORT_UNSPEC); /* Check AF-Family Support from target_addr */ switch (address_family) { @@ -322,15 +308,13 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len, mutex_lock(&(tcb->function_lock)); /* Check if connection is in a valid state */ - if (tcb->state != GNRC_TCP_FSM_STATE_ESTABLISHED - && tcb->state != GNRC_TCP_FSM_STATE_CLOSE_WAIT - ) { - mutex_unlock(&(tcb->function_lock)); - return -ENOTCONN; + if (tcb->state != FSM_STATE_ESTABLISHED && tcb->state != FSM_STATE_CLOSE_WAIT) { + mutex_unlock(&(tcb->function_lock)); + return -ENOTCONN; } /* Re-init message queue, take ownership. FSM can send Messages to this thread now */ - msg_init_queue(tcb->msg_queue, GNRC_TCP_MSG_QUEUE_SIZE); + msg_init_queue(tcb->msg_queue, GNRC_TCP_TCB_MSG_QUEUE_SIZE); tcb->owner = thread_getpid(); /* Setup Connection Timeout */ @@ -347,9 +331,9 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len, /* Loop until something was sent and acked */ while (ret == 0 || tcb->pkt_retransmit != NULL) { /* Check if the connections state is closed. If so, a reset was received */ - if (tcb->state == GNRC_TCP_FSM_STATE_CLOSED) { - ret = -ECONNRESET; - break; + if (tcb->state == FSM_STATE_CLOSED) { + ret = -ECONNRESET; + break; } /* If the send window is closed: Setup Probing */ @@ -367,7 +351,7 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len, /* Try to send data in case there nothing has been sent and we are not probing */ if (ret == 0 && !probing) { - ret = _fsm(tcb, GNRC_TCP_FSM_EVENT_CALL_SEND, NULL, (void *) data, len); + ret = _fsm(tcb, FSM_EVENT_CALL_SEND, NULL, (void *) data, len); } /* Wait for responses */ @@ -375,20 +359,20 @@ ssize_t gnrc_tcp_send(gnrc_tcp_tcb_t *tcb, const void *data, const size_t len, switch (msg.type) { case MSG_TYPE_CONNECTION_TIMEOUT: DEBUG("gnrc_tcp.c : gnrc_tcp_send() : CONNECTION_TIMEOUT\n"); - _fsm(tcb, GNRC_TCP_FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0); + _fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0); ret = -ECONNABORTED; break; case MSG_TYPE_USER_SPEC_TIMEOUT: DEBUG("gnrc_tcp.c : gnrc_tcp_send() : USER_SPEC_TIMEOUT\n"); - _fsm(tcb, GNRC_TCP_FSM_EVENT_CLEAR_RETRANSMIT, NULL, NULL, 0); + _fsm(tcb, FSM_EVENT_CLEAR_RETRANSMIT, NULL, NULL, 0); ret = -ETIMEDOUT; break; case MSG_TYPE_PROBE_TIMEOUT: DEBUG("gnrc_tcp.c : gnrc_tcp_send() : PROBE_TIMEOUT\n"); /* Send Probe */ - _fsm(tcb, GNRC_TCP_FSM_EVENT_SEND_PROBE, NULL, NULL, 0); + _fsm(tcb, FSM_EVENT_SEND_PROBE, NULL, NULL, 0); probe_timeout_duration_us += probe_timeout_duration_us; /* Boundry check for time interval between probes */ @@ -444,19 +428,16 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len, mutex_lock(&(tcb->function_lock)); /* Check if connection is in a valid state */ - if (tcb->state != GNRC_TCP_FSM_STATE_ESTABLISHED - && tcb->state != GNRC_TCP_FSM_STATE_FIN_WAIT_1 - && tcb->state != GNRC_TCP_FSM_STATE_FIN_WAIT_2 - && tcb->state != GNRC_TCP_FSM_STATE_CLOSE_WAIT - ) { - mutex_unlock(&(tcb->function_lock)); - return -ENOTCONN; + 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) { + mutex_unlock(&(tcb->function_lock)); + return -ENOTCONN; } /* If this call is non-blocking (timeout_duration_us == 0): Try to read data and return */ if (timeout_duration_us == 0) { - ret = _fsm(tcb, GNRC_TCP_FSM_EVENT_CALL_RECV, NULL, data, max_len); - if(ret == 0) { + ret = _fsm(tcb, FSM_EVENT_CALL_RECV, NULL, data, max_len); + if (ret == 0) { ret = -EAGAIN; } mutex_unlock(&(tcb->function_lock)); @@ -464,7 +445,7 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len, } /* If this call is blocking, setup messages and timers */ - msg_init_queue(tcb->msg_queue, GNRC_TCP_MSG_QUEUE_SIZE); + msg_init_queue(tcb->msg_queue, GNRC_TCP_TCB_MSG_QUEUE_SIZE); tcb->owner = thread_getpid(); /* Setup Connection Timeout */ @@ -479,36 +460,36 @@ ssize_t gnrc_tcp_recv(gnrc_tcp_tcb_t *tcb, void *data, const size_t max_len, /* Processing Loop */ while (ret == 0) { /* Check if the connections state is closed. If so, a reset was received */ - if (tcb->state == GNRC_TCP_FSM_STATE_CLOSED) { - ret = -ECONNRESET; - break; + if (tcb->state == FSM_STATE_CLOSED) { + ret = -ECONNRESET; + break; } /* Try to read available data */ - ret = _fsm(tcb, GNRC_TCP_FSM_EVENT_CALL_RECV, NULL, data, max_len); + ret = _fsm(tcb, FSM_EVENT_CALL_RECV, NULL, data, max_len); /* If there was no data: Wait for next packet or until the timeout fires */ if (ret <= 0) { msg_receive(&msg); switch (msg.type) { - case MSG_TYPE_CONNECTION_TIMEOUT: - DEBUG("gnrc_tcp.c : gnrc_tcp_recv() : CONNECTION_TIMEOUT\n"); - _fsm(tcb, GNRC_TCP_FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0); - ret = -ECONNABORTED; - break; - - case MSG_TYPE_USER_SPEC_TIMEOUT: - DEBUG("gnrc_tcp.c : gnrc_tcp_send() : USER_SPEC_TIMEOUT\n"); - _fsm(tcb, GNRC_TCP_FSM_EVENT_CLEAR_RETRANSMIT, NULL, NULL, 0); - ret = -ETIMEDOUT; - break; - - case MSG_TYPE_NOTIFY_USER: - DEBUG("gnrc_tcp.c : gnrc_tcp_recv() : NOTIFY_USER\n"); - break; - - default: - DEBUG("gnrc_tcp.c : gnrc_tcp_recv() : other message type\n"); + case MSG_TYPE_CONNECTION_TIMEOUT: + DEBUG("gnrc_tcp.c : gnrc_tcp_recv() : CONNECTION_TIMEOUT\n"); + _fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0); + ret = -ECONNABORTED; + break; + + case MSG_TYPE_USER_SPEC_TIMEOUT: + DEBUG("gnrc_tcp.c : gnrc_tcp_send() : USER_SPEC_TIMEOUT\n"); + _fsm(tcb, FSM_EVENT_CLEAR_RETRANSMIT, NULL, NULL, 0); + ret = -ETIMEDOUT; + break; + + case MSG_TYPE_NOTIFY_USER: + DEBUG("gnrc_tcp.c : gnrc_tcp_recv() : NOTIFY_USER\n"); + break; + + default: + DEBUG("gnrc_tcp.c : gnrc_tcp_recv() : other message type\n"); } } } @@ -533,9 +514,9 @@ int gnrc_tcp_close(gnrc_tcp_tcb_t *tcb) mutex_lock(&(tcb->function_lock)); /* Start connection teardown if the connection was not closed before */ - if (tcb->state != GNRC_TCP_FSM_STATE_CLOSED) { + if (tcb->state != FSM_STATE_CLOSED) { /* Take ownership */ - msg_init_queue(tcb->msg_queue, GNRC_TCP_MSG_QUEUE_SIZE); + msg_init_queue(tcb->msg_queue, GNRC_TCP_TCB_MSG_QUEUE_SIZE); tcb->owner = thread_getpid(); /* Setup Connection Timeout */ @@ -544,15 +525,15 @@ int gnrc_tcp_close(gnrc_tcp_tcb_t *tcb) &connection_timeout_msg, tcb->owner); /* Start connection teardown sequence */ - _fsm(tcb, GNRC_TCP_FSM_EVENT_CALL_CLOSE, NULL, NULL, 0); + _fsm(tcb, FSM_EVENT_CALL_CLOSE, NULL, NULL, 0); /* Loop until the connection has been closed */ - while (tcb->state != GNRC_TCP_FSM_STATE_CLOSED) { + while (tcb->state != FSM_STATE_CLOSED) { msg_receive(&msg); switch (msg.type) { case MSG_TYPE_CONNECTION_TIMEOUT: DEBUG("gnrc_tcp.c : gnrc_tcp_close() : CONNECTION_TIMEOUT\n"); - _fsm(tcb, GNRC_TCP_FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0); + _fsm(tcb, FSM_EVENT_TIMEOUT_CONNECTION, NULL, NULL, 0); break; case MSG_TYPE_NOTIFY_USER: diff --git a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_eventloop.c b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_eventloop.c index 45523016d96040071e8e6c99fd5644a17b993e36..c3f44d77985e8f4781a8c926f18f059a8c205cfa 100644 --- a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_eventloop.c +++ b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_eventloop.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -11,9 +11,9 @@ * @{ * * @file - * @brief GNRC's TCP event processing loop + * @brief Implementation of internal/eventloop.h * - * @author Simon Brummer <brummer.simon@googlemail.com> + * @author Simon Brummer <simon.brummer@posteo.de> * @} */ @@ -21,12 +21,9 @@ #include <errno.h> #include "net/af.h" #include "net/tcp.h" -#include "net/gnrc/pkt.h" -#include "net/gnrc/tcp.h" +#include "internal/common.h" #include "internal/pkt.h" #include "internal/fsm.h" -#include "internal/helper.h" -#include "internal/option.h" #include "internal/eventloop.h" #ifdef MODULE_GNRC_IPV6 @@ -37,7 +34,7 @@ #include "debug.h" /** - * @brief send function, used to pass paket down the network stack + * @brief send function, pass paket down the network stack * * @param[in] pkt paket to pass down the network stack * @@ -67,7 +64,7 @@ static int _send(gnrc_pktsnip_t *pkt) } /** - * @brief recv function, used to call fsm on packet reception + * @brief recv function, receive packet from network layer. * * @param[in] pkt incomming paket to process * @@ -114,9 +111,9 @@ static int _receive(gnrc_pktsnip_t *pkt) /* Get TCP Header */ LL_SEARCH_SCALAR(pkt, tcp, type, GNRC_NETTYPE_TCP); if (tcp == NULL) { - DEBUG("gnrc_tcp_eventloop.c : _receive() : pkt contains no TCP Header\n"); - gnrc_pktbuf_release(pkt); - return 0; + DEBUG("gnrc_tcp_eventloop.c : _receive() : pkt contains no TCP Header\n"); + gnrc_pktbuf_release(pkt); + return 0; } /* Extract control bits, src and dst ports and check if SYN is set (not SYN+ACK) */ @@ -155,21 +152,20 @@ static int _receive(gnrc_pktsnip_t *pkt) } /* Find tcb to de-multiplex this packet to */ - mutex_lock(&_list_gnrc_tcp_tcb_lock); - tcb = _list_gnrc_tcp_tcb_head; + mutex_lock(&_list_tcb_lock); + tcb = _list_tcb_head; while (tcb) { #ifdef MODULE_GNRC_IPV6 /* Check if current tcb is fitting for the incomming packet */ if (ip->type == GNRC_NETTYPE_IPV6 && tcb->address_family == AF_INET6) { /* If SYN is set, a connection is listening on that port ... */ - ipv6_addr_t * tmp_addr = NULL; - if (syn && tcb->local_port == dst && tcb->state == GNRC_TCP_FSM_STATE_LISTEN) { + ipv6_addr_t *tmp_addr = NULL; + if (syn && tcb->local_port == dst && tcb->state == FSM_STATE_LISTEN) { /* ... and local addr is unspec or preconfigured */ - tmp_addr = &((ipv6_hdr_t * )ip->data)->dst; - if (ipv6_addr_equal((ipv6_addr_t *) tcb->local_addr, (ipv6_addr_t *) tmp_addr) - || ipv6_addr_is_unspecified((ipv6_addr_t *) tcb->local_addr) - ) { - break; + tmp_addr = &((ipv6_hdr_t *)ip->data)->dst; + if (ipv6_addr_equal((ipv6_addr_t *) tcb->local_addr, (ipv6_addr_t *) tmp_addr) || + ipv6_addr_is_unspecified((ipv6_addr_t *) tcb->local_addr)) { + break; } } @@ -190,18 +186,18 @@ static int _receive(gnrc_pktsnip_t *pkt) #endif tcb = tcb->next; } - mutex_unlock(&_list_gnrc_tcp_tcb_lock); + mutex_unlock(&_list_tcb_lock); /* Call FSM with event RCVD_PKT if a fitting connection was found */ if (tcb != NULL) { - _fsm(tcb, GNRC_TCP_FSM_EVENT_RCVD_PKT, pkt, NULL, 0); + _fsm(tcb, FSM_EVENT_RCVD_PKT, pkt, NULL, 0); } /* No fitting connection has been found. Respond with reset */ else { DEBUG("gnrc_tcp_eventloop.c : _receive() : Can't find fitting connection\n"); if ((ctl & MSK_RST) != MSK_RST) { _pkt_build_reset_from_pkt(&reset, pkt); - gnrc_netapi_send(_gnrc_tcp_pid, reset); + gnrc_netapi_send(gnrc_tcp_pid, reset); } return -ENOTCONN; } @@ -213,21 +209,21 @@ void *_event_loop(__attribute__((unused)) void *arg) { msg_t msg; msg_t reply; - msg_t msg_queue[GNRC_TCP_MSG_QUEUE_SIZE]; + msg_t msg_queue[TCP_EVENTLOOP_MSG_QUEUE_SIZE]; /* Store pid */ - _gnrc_tcp_pid = thread_getpid(); + gnrc_tcp_pid = thread_getpid(); /* Setup reply message */ reply.type = GNRC_NETAPI_MSG_TYPE_ACK; reply.content.value = (uint32_t)-ENOTSUP; /* Init message queue*/ - msg_init_queue(msg_queue, GNRC_TCP_MSG_QUEUE_SIZE); + msg_init_queue(msg_queue, TCP_EVENTLOOP_MSG_QUEUE_SIZE); /* Register GNRC_tcp in netreg */ gnrc_netreg_entry_t entry; - gnrc_netreg_entry_init_pid(&entry, GNRC_NETREG_DEMUX_CTX_ALL, _gnrc_tcp_pid); + gnrc_netreg_entry_init_pid(&entry, GNRC_NETREG_DEMUX_CTX_ALL, gnrc_tcp_pid); gnrc_netreg_register(GNRC_NETTYPE_TCP, &entry); /* dispatch NETAPI Messages */ @@ -255,14 +251,14 @@ void *_event_loop(__attribute__((unused)) void *arg) /* Retransmission Timer expired -> Call FSM with retransmission event */ case MSG_TYPE_RETRANSMISSION: DEBUG("gnrc_tcp_eventloop.c : _event_loop() : MSG_TYPE_RETRANSMISSION\n"); - _fsm((gnrc_tcp_tcb_t *)msg.content.ptr, GNRC_TCP_FSM_EVENT_TIMEOUT_RETRANSMIT, + _fsm((gnrc_tcp_tcb_t *)msg.content.ptr, FSM_EVENT_TIMEOUT_RETRANSMIT, NULL, NULL, 0); break; /* Time Wait Timer expired -> Call FSM with timewait event */ case MSG_TYPE_TIMEWAIT: DEBUG("gnrc_tcp_eventloop.c : _event_loop() : MSG_TYPE_TIMEWAIT\n"); - _fsm((gnrc_tcp_tcb_t *)msg.content.ptr, GNRC_TCP_FSM_EVENT_TIMEOUT_TIMEWAIT, + _fsm((gnrc_tcp_tcb_t *)msg.content.ptr, FSM_EVENT_TIMEOUT_TIMEWAIT, NULL, NULL, 0); break; diff --git a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_fsm.c b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_fsm.c index c9007889cf6daacb674ee609f4e8e651ab46880a..0dd29b305b8ee9681e8bba61e06e78676b64428b 100644 --- a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_fsm.c +++ b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_fsm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -11,22 +11,19 @@ * @{ * * @file - * @brief GNRC's TCP finite state maschine + * @brief Implementation of internal/fsm.h * - * @author Simon Brummer <brummer.simon@googlemail.com> + * @author Simon Brummer <simon.brummer@posteo.de> * @} */ -#include "msg.h" #include "random.h" -#include "ringbuffer.h" #include "net/af.h" - -#include "internal/fsm.h" +#include "internal/common.h" #include "internal/pkt.h" #include "internal/option.h" -#include "internal/helper.h" #include "internal/rcvbuf.h" +#include "internal/fsm.h" #ifdef MODULE_GNRC_IPV6 #include "net/gnrc/ipv6.h" @@ -48,7 +45,7 @@ static int _is_local_port_in_use(const uint16_t portnumber) { gnrc_tcp_tcb_t *iter = NULL; - LL_FOREACH(_list_gnrc_tcp_tcb_head, iter) { + LL_FOREACH(_list_tcb_head, iter) { if (iter->local_port == portnumber) { return 1; } @@ -57,7 +54,7 @@ static int _is_local_port_in_use(const uint16_t portnumber) } /** - * @brief Generate random, currently unused local port above the well-known ports (> 1024) + * @brief Generate random unused local port above the well-known ports (> 1024) * * @return The generated port number */ @@ -76,7 +73,7 @@ static uint16_t _get_random_local_port(void) /** * @brief clears retransmit queue * - * @param[in/out] conn TCP Connection, where the retransmit should be cleared + * @param[in/out] tcb tcb containing the retransmit queue. * * @return zero on success */ @@ -93,16 +90,16 @@ static int _clear_retransmit(gnrc_tcp_tcb_t *tcb) /** * @brief restarts time wait timer * - * @param[in/out] conn TCP Connection, where the timewait_timer should be restarted + * @param[in/out] tcb tcb containing the timer structure to use. * * @return Zero on success */ -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); tcb->msg_tout.type = MSG_TYPE_TIMEWAIT; tcb->msg_tout.content.ptr = (void *)tcb; - xtimer_set_msg(&tcb->tim_tout, 2 * GNRC_TCP_MSL, &tcb->msg_tout, _gnrc_tcp_pid); + xtimer_set_msg(&tcb->tim_tout, 2 * GNRC_TCP_MSL, &tcb->msg_tout, gnrc_tcp_pid); return 0; } @@ -115,49 +112,49 @@ static int _restart_timewait_timer(gnrc_tcp_tcb_t* tcb) * * @return zero on success */ -static int _transition_to(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_state_t state, bool *notify_owner) +static int _transition_to(gnrc_tcp_tcb_t *tcb, fsm_state_t state, bool *notify_owner) { gnrc_tcp_tcb_t *iter = NULL; uint8_t found = 0; switch (state) { - case GNRC_TCP_FSM_STATE_CLOSED: + case FSM_STATE_CLOSED: /* Free Packets in Retransmit queue */ _clear_retransmit(tcb); /* Remove from Connection from active connections */ - mutex_lock(&_list_gnrc_tcp_tcb_lock); - LL_FOREACH(_list_gnrc_tcp_tcb_head, iter) { + mutex_lock(&_list_tcb_lock); + LL_FOREACH(_list_tcb_head, iter) { if (iter == tcb) { found = 1; } } if (found) { - LL_DELETE(_list_gnrc_tcp_tcb_head, iter); + LL_DELETE(_list_tcb_head, iter); } - mutex_unlock(&_list_gnrc_tcp_tcb_lock); + mutex_unlock(&_list_tcb_lock); /* Free potencially allocated Receive Buffer */ _rcvbuf_release_buffer(tcb); *notify_owner = true; break; - case GNRC_TCP_FSM_STATE_LISTEN: + case FSM_STATE_LISTEN: /* Clear Adress Info */ switch (tcb->address_family) { #ifdef MODULE_GNRC_IPV6 - case AF_INET6: - if (tcb->status & GNRC_TCP_STATUS_ALLOW_ANY_ADDR) { - ipv6_addr_set_unspecified((ipv6_addr_t *) tcb->local_addr); - } - ipv6_addr_set_unspecified((ipv6_addr_t *) tcb->peer_addr); - break; + case AF_INET6: + if (tcb->status & STATUS_ALLOW_ANY_ADDR) { + ipv6_addr_set_unspecified((ipv6_addr_t *) tcb->local_addr); + } + ipv6_addr_set_unspecified((ipv6_addr_t *) tcb->peer_addr); + break; #endif - default: - DEBUG("gnrc_tcp_fsm.c : _transition_to() : Undefined Addresses\n"); - break; + default: + DEBUG("gnrc_tcp_fsm.c : _transition_to() : Undefined Addresses\n"); + break; } - tcb->peer_port = GNRC_TCP_PORT_UNSPEC; + tcb->peer_port = PORT_UNSPEC; /* Allocate rcv Buffer */ if (_rcvbuf_get_buffer(tcb) == -ENOMEM) { @@ -165,27 +162,27 @@ static int _transition_to(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_state_t state, bool } /* Add to Connection to active connections (if not already active) */ - mutex_lock(&_list_gnrc_tcp_tcb_lock); - LL_FOREACH(_list_gnrc_tcp_tcb_head, iter) { + mutex_lock(&_list_tcb_lock); + LL_FOREACH(_list_tcb_head, iter) { if (iter == tcb) { found = 1; } } if (!found) { - LL_APPEND(_list_gnrc_tcp_tcb_head, tcb); + LL_APPEND(_list_tcb_head, tcb); } - mutex_unlock(&_list_gnrc_tcp_tcb_lock); + mutex_unlock(&_list_tcb_lock); break; - case GNRC_TCP_FSM_STATE_SYN_SENT: + case FSM_STATE_SYN_SENT: /* Allocate rcv Buffer */ if (_rcvbuf_get_buffer(tcb) == -ENOMEM) { return -ENOMEM; } /* Add to Connections to active connection (if not already active) */ - mutex_lock(&_list_gnrc_tcp_tcb_lock); - LL_FOREACH(_list_gnrc_tcp_tcb_head, iter) { + mutex_lock(&_list_tcb_lock); + LL_FOREACH(_list_tcb_head, iter) { if (iter == tcb) { found = 1; } @@ -193,11 +190,11 @@ static int _transition_to(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_state_t state, bool /* If not already active: Apped tcb but check portnumber first */ if (!found) { /* Check if Port Number is not in use */ - if (tcb->local_port != GNRC_TCP_PORT_UNSPEC ) { + if (tcb->local_port != PORT_UNSPEC) { /* If Portnumber is used: return error and release buffer */ if (_is_local_port_in_use(tcb->local_port)) { - mutex_unlock(&_list_gnrc_tcp_tcb_lock); + mutex_unlock(&_list_tcb_lock); _rcvbuf_release_buffer(tcb); return -EADDRINUSE; } @@ -206,20 +203,20 @@ static int _transition_to(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_state_t state, bool else { tcb->local_port = _get_random_local_port(); } - LL_APPEND(_list_gnrc_tcp_tcb_head, tcb); + LL_APPEND(_list_tcb_head, tcb); } - mutex_unlock(&_list_gnrc_tcp_tcb_lock); + mutex_unlock(&_list_tcb_lock); break; - case GNRC_TCP_FSM_STATE_ESTABLISHED: + case FSM_STATE_ESTABLISHED: *notify_owner = true; break; - case GNRC_TCP_FSM_STATE_CLOSE_WAIT: + case FSM_STATE_CLOSE_WAIT: *notify_owner = true; break; - case GNRC_TCP_FSM_STATE_TIME_WAIT: + case FSM_STATE_TIME_WAIT: _restart_timewait_timer(tcb); break; @@ -240,7 +237,7 @@ static int _transition_to(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_state_t state, bool * @return -ENOMEM Can't allocate receive buffer. * @return -EADDRINUSE Given local port is already in use */ -static int _fsm_call_open(gnrc_tcp_tcb_t* tcb, bool *notify_owner) +static int _fsm_call_open(gnrc_tcp_tcb_t *tcb, bool *notify_owner) { gnrc_pktsnip_t *out_pkt = NULL; /* Outgoing packet */ uint16_t seq_con = 0; /* Sequence number consumption (out_pkt) */ @@ -249,10 +246,10 @@ static int _fsm_call_open(gnrc_tcp_tcb_t* tcb, bool *notify_owner) DEBUG("gnrc_tcp_fsm.c : _fsm_call_open()\n"); tcb->rcv_wnd = GNRC_TCP_DEFAULT_WINDOW; - if (tcb->status & GNRC_TCP_STATUS_PASSIVE) { + if (tcb->status & STATUS_PASSIVE) { /* Passive Open, T: CLOSED -> LISTEN */ - if (_transition_to(tcb, GNRC_TCP_FSM_STATE_LISTEN, notify_owner) == -ENOMEM){ - _transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner); + if (_transition_to(tcb, FSM_STATE_LISTEN, notify_owner) == -ENOMEM) { + _transition_to(tcb, FSM_STATE_CLOSED, notify_owner); return -ENOMEM; } } @@ -263,9 +260,9 @@ static int _fsm_call_open(gnrc_tcp_tcb_t* tcb, bool *notify_owner) tcb->snd_una = tcb->iss; /* Translate to SYN_SENT */ - ret = _transition_to(tcb, GNRC_TCP_FSM_STATE_SYN_SENT, notify_owner); - if ( ret < 0) { - _transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner); + ret = _transition_to(tcb, FSM_STATE_SYN_SENT, notify_owner); + if (ret < 0) { + _transition_to(tcb, FSM_STATE_CLOSED, notify_owner); return ret; } @@ -280,13 +277,13 @@ static int _fsm_call_open(gnrc_tcp_tcb_t* tcb, bool *notify_owner) /** * @brief FSM Handling Function for sending data. * - * @param[in/out] tcb Specifies tcb to use fsm on. - * @param[in/out] buf buffer containing data to send. - * @param[in] nByte Maximum Number of Bytes to send. + * @param[in/out] tcb Specifies tcb to use fsm on. + * @param[in/out] buf Buffer containing data to send. + * @param[in] len Maximum Number of Bytes to send. * * @return number of bytes that was sent. */ -static int _fsm_call_send(gnrc_tcp_tcb_t* tcb, void *buf, size_t nByte) +static int _fsm_call_send(gnrc_tcp_tcb_t *tcb, void *buf, size_t len) { gnrc_pktsnip_t *out_pkt = NULL; /* Outgoing packet */ uint16_t seq_con = 0; /* Sequence number consumption (out_pkt) */ @@ -297,9 +294,9 @@ static int _fsm_call_send(gnrc_tcp_tcb_t* tcb, void *buf, size_t nByte) /* We are allowed to send further bytes if window is open */ if (payload > 0 && tcb->snd_wnd > 0 && tcb->pkt_retransmit == NULL) { /* Calculate segment size */ - payload = (payload < GNRC_TCP_MSS ? payload : GNRC_TCP_MSS); + payload = (payload < GNRC_TCP_MSS) ? payload : GNRC_TCP_MSS; payload = (payload < tcb->mss) ? payload : tcb->mss; - payload = (payload < nByte) ? payload : nByte; + payload = (payload < len) ? payload : len; /* Calculate payload size for this segment */ _pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK, tcb->snd_nxt, tcb->rcv_nxt, buf, payload); @@ -313,13 +310,13 @@ static int _fsm_call_send(gnrc_tcp_tcb_t* tcb, void *buf, size_t nByte) /** * @brief FSM Handling Function for receiving data. * - * @param[in/out] tcb Specifies tcb to use fsm on. - * @param[in/out] buf buffer to store received data into. - * @param[in] nByte Maximum Number of Bytes to receive. + * @param[in/out] tcb Specifies tcb to use fsm on. + * @param[in/out] buf buffer to store received data into. + * @param[in] len Maximum Number of Bytes to receive. * * @return number of bytes that was received. */ -static int _fsm_call_recv(gnrc_tcp_tcb_t* tcb, void *buf, size_t nByte) +static int _fsm_call_recv(gnrc_tcp_tcb_t *tcb, void *buf, size_t len) { gnrc_pktsnip_t *out_pkt = NULL; /* Outgoing packet */ uint16_t seq_con = 0; /* Sequence number consumption (out_pkt) */ @@ -330,14 +327,14 @@ static int _fsm_call_recv(gnrc_tcp_tcb_t* tcb, void *buf, size_t nByte) } /* Read up to the requesed amount of data */ - size_t rcvd = ringbuffer_get(&(tcb->rcv_buf), buf, nByte); + size_t rcvd = ringbuffer_get(&(tcb->rcv_buf), buf, len); /* If the buffer can store more than the GNRC_TCP_MSS: open Window to available buffersize */ if (ringbuffer_get_free(&tcb->rcv_buf) >= GNRC_TCP_MSS) { tcb->rcv_wnd = ringbuffer_get_free(&(tcb->rcv_buf)); /* Send ACK to update window on reopening */ - _pkt_build(tcb, &out_pkt, &seq_con, MSK_ACK, tcb->snd_nxt, tcb->rcv_nxt, 0, 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); } return rcvd; @@ -351,33 +348,31 @@ static int _fsm_call_recv(gnrc_tcp_tcb_t* tcb, void *buf, size_t nByte) * * @return zero on success. */ -static int _fsm_call_close(gnrc_tcp_tcb_t* tcb, bool *notify_owner) +static int _fsm_call_close(gnrc_tcp_tcb_t *tcb, bool *notify_owner) { gnrc_pktsnip_t *out_pkt = NULL; /* Outgoing packet */ uint16_t seq_con = 0; /* Sequence number consumption (out_pkt) */ DEBUG("gnrc_tcp_fsm.c : _fsm_call_close()\n"); - if (tcb->state == GNRC_TCP_FSM_STATE_SYN_RCVD - || tcb->state == GNRC_TCP_FSM_STATE_ESTABLISHED - || tcb->state == GNRC_TCP_FSM_STATE_CLOSE_WAIT - ) { + if (tcb->state == FSM_STATE_SYN_RCVD || tcb->state == FSM_STATE_ESTABLISHED || + tcb->state == FSM_STATE_CLOSE_WAIT) { /* Send FIN packet */ _pkt_build(tcb, &out_pkt, &seq_con, MSK_FIN_ACK, tcb->snd_nxt, tcb->rcv_nxt, NULL, 0); _pkt_setup_retransmit(tcb, out_pkt, false); _pkt_send(tcb, out_pkt, seq_con, false); } switch (tcb->state) { - case GNRC_TCP_FSM_STATE_LISTEN: - _transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner); + case FSM_STATE_LISTEN: + _transition_to(tcb, FSM_STATE_CLOSED, notify_owner); break; - case GNRC_TCP_FSM_STATE_SYN_RCVD: - case GNRC_TCP_FSM_STATE_ESTABLISHED: - _transition_to(tcb, GNRC_TCP_FSM_STATE_FIN_WAIT_1, notify_owner); + case FSM_STATE_SYN_RCVD: + case FSM_STATE_ESTABLISHED: + _transition_to(tcb, FSM_STATE_FIN_WAIT_1, notify_owner); break; - case GNRC_TCP_FSM_STATE_CLOSE_WAIT: - _transition_to(tcb, GNRC_TCP_FSM_STATE_LAST_ACK, notify_owner); + case FSM_STATE_CLOSE_WAIT: + _transition_to(tcb, FSM_STATE_LAST_ACK, notify_owner); break; default: @@ -408,7 +403,7 @@ static int _fsm_call_abort(void) * @return zero on success. * @return -ENOMEM Can't allocate receive buffer. */ -static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *notify_owner) +static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t *tcb, gnrc_pktsnip_t *in_pkt, bool *notify_owner) { gnrc_pktsnip_t *out_pkt = NULL; /* Outgoing packet */ uint16_t seq_con = 0; /* Sequence number consumption (out_pkt) */ @@ -448,7 +443,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti #endif /* Handle state LISTEN */ - if (tcb->state == GNRC_TCP_FSM_STATE_LISTEN) { + if (tcb->state == FSM_STATE_LISTEN) { /* 1) Check RST: if set, return */ if (ctl & MSK_RST) { return 0; @@ -465,7 +460,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti uint16_t dst = byteorder_ntohs(tcp_hdr->dst_port); /* Check if SYN Request is handled by another connection */ - lst = _list_gnrc_tcp_tcb_head; + lst = _list_tcb_head; while (lst) { /* Compare Portnumbers and Network Layer Adresses */ /* Note: Packets without ip-header were discarded earlier */ @@ -475,9 +470,8 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti ipv6_addr_t *dst_addr = &((ipv6_hdr_t *)ip)->dst; ipv6_addr_t *src_addr = &((ipv6_hdr_t *)ip)->src; - if (ipv6_addr_equal((ipv6_addr_t *)lst->local_addr, dst_addr) - && ipv6_addr_equal((ipv6_addr_t *)lst->peer_addr, src_addr) - ) { + if (ipv6_addr_equal((ipv6_addr_t *)lst->local_addr, dst_addr) && + ipv6_addr_equal((ipv6_addr_t *)lst->peer_addr, src_addr)) { break; } } @@ -516,12 +510,12 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti _pkt_build(tcb, &out_pkt, &seq_con, MSK_SYN_ACK, tcb->iss, tcb->rcv_nxt, NULL, 0); _pkt_setup_retransmit(tcb, out_pkt, false); _pkt_send(tcb, out_pkt, seq_con, false); - _transition_to(tcb, GNRC_TCP_FSM_STATE_SYN_RCVD, notify_owner); + _transition_to(tcb, FSM_STATE_SYN_RCVD, notify_owner); } return 0; } /* Handle state SYN_SENT */ - else if (tcb->state == GNRC_TCP_FSM_STATE_SYN_SENT) { + else if (tcb->state == FSM_STATE_SYN_SENT) { /* 1) Check ACK */ if (ctl & MSK_ACK) { /* If ACK is not acceptable ...*/ @@ -538,7 +532,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti if (ctl & MSK_RST) { /* ... and ACK: Translate to CLOSED, if not return */ if (ctl & MSK_ACK) { - _transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner); + _transition_to(tcb, FSM_STATE_CLOSED, notify_owner); } return 0; } @@ -563,18 +557,16 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti /* SYN has been ACKed, reply pure ACK, T: SYN_SENT -> ESTABLISHED */ if (tcb->snd_una > tcb->iss) { - _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); - _transition_to(tcb, GNRC_TCP_FSM_STATE_ESTABLISHED, notify_owner); + _transition_to(tcb, FSM_STATE_ESTABLISHED, notify_owner); } /* Simultaneous SYN received send SYN+ACK, T: SYN_SENT -> SYN_RCVD */ else { - _pkt_build(tcb, &out_pkt, &seq_con, MSK_SYN_ACK, tcb->iss, tcb->rcv_nxt, - NULL, 0); + _pkt_build(tcb, &out_pkt, &seq_con, MSK_SYN_ACK, tcb->iss, tcb->rcv_nxt, NULL, 0); _pkt_setup_retransmit(tcb, out_pkt, false); _pkt_send(tcb, out_pkt, seq_con, false); - _transition_to(tcb, GNRC_TCP_FSM_STATE_SYN_RCVD, notify_owner); + _transition_to(tcb, FSM_STATE_SYN_RCVD, notify_owner); } tcb->snd_wnd = seg_wnd; tcb->snd_wl1 = seg_seq; @@ -590,8 +582,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti if (!_pkt_chk_seq_num(tcb, seg_seq, pay_len)) { /* ... if invalid, and RST not set, reply with pure ACK, return */ if ((ctl & MSK_RST) != MSK_RST) { - _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); } return 0; @@ -599,16 +590,14 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti /* 2) Check RST: If RST is set ... */ if (ctl & MSK_RST) { /* .. and State is SYN_RCVD and passive Open: SYN_RCVD -> LISTEN */ - if (tcb->state == GNRC_TCP_FSM_STATE_SYN_RCVD - && (tcb->status & GNRC_TCP_STATUS_PASSIVE) - ) { - if (_transition_to(tcb, GNRC_TCP_FSM_STATE_LISTEN, notify_owner) == -ENOMEM) { - _transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner); + if (tcb->state == FSM_STATE_SYN_RCVD && (tcb->status & STATUS_PASSIVE)) { + if (_transition_to(tcb, FSM_STATE_LISTEN, notify_owner) == -ENOMEM) { + _transition_to(tcb, FSM_STATE_CLOSED, notify_owner); return -ENOMEM; } } else { - _transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner); + _transition_to(tcb, FSM_STATE_CLOSED, notify_owner); } return 0; } @@ -617,7 +606,7 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti /* ... send RST, seq_no = snd_nxt, ack_no = rcv_nxt */ _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); - _transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner); + _transition_to(tcb, FSM_STATE_CLOSED, notify_owner); return 0; } /* 4) Check ACK */ @@ -625,12 +614,12 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti return 0; } else { - if (tcb->state == GNRC_TCP_FSM_STATE_SYN_RCVD) { + if (tcb->state == FSM_STATE_SYN_RCVD) { if (LSS_32_BIT(tcb->snd_una, seg_ack) && LEQ_32_BIT(seg_ack, tcb->snd_nxt)) { tcb->snd_wnd = seg_wnd; tcb->snd_wl1 = seg_seq; tcb->snd_wl2 = seg_ack; - _transition_to(tcb, GNRC_TCP_FSM_STATE_ESTABLISHED, notify_owner); + _transition_to(tcb, FSM_STATE_ESTABLISHED, notify_owner); } else { _pkt_build(tcb, &out_pkt, &seq_con, MSK_RST, seg_ack, 0, NULL, 0); @@ -638,13 +627,9 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti } } /* Acknowledgment processing */ - if (tcb->state == GNRC_TCP_FSM_STATE_ESTABLISHED - || tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_1 - || tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_2 - || tcb->state == GNRC_TCP_FSM_STATE_CLOSE_WAIT - || tcb->state == GNRC_TCP_FSM_STATE_CLOSING - || tcb->state == GNRC_TCP_FSM_STATE_LAST_ACK - ) { + 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_CLOSING || tcb->state == FSM_STATE_LAST_ACK) { /* Sent data has been acknowledged */ if (LSS_32_BIT(tcb->snd_una, seg_ack) && LEQ_32_BIT(seg_ack, tcb->snd_nxt)) { tcb->snd_una = seg_ack; @@ -659,9 +644,8 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti } /* Update Window */ if (LEQ_32_BIT(tcb->snd_una, seg_ack) && LEQ_32_BIT(seg_ack, tcb->snd_nxt)) { - if (LSS_32_BIT(tcb->snd_wl1, seg_seq) || (tcb->snd_wl1 == seg_seq - && LEQ_32_BIT(tcb->snd_wl2, seg_ack)) - ) { + if (LSS_32_BIT(tcb->snd_wl1, seg_seq) || (tcb->snd_wl1 == seg_seq && + LEQ_32_BIT(tcb->snd_wl2, seg_ack))) { tcb->snd_wnd = seg_wnd; tcb->snd_wl1 = seg_seq; tcb->snd_wl2 = seg_ack; @@ -672,27 +656,27 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti } /* Additional processing */ /* Check additionaly if previous our sent FIN has been acknowledged */ - if (tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_1) { + if (tcb->state == FSM_STATE_FIN_WAIT_1) { if (tcb->pkt_retransmit == NULL) { - _transition_to(tcb, GNRC_TCP_FSM_STATE_FIN_WAIT_2, notify_owner); + _transition_to(tcb, FSM_STATE_FIN_WAIT_2, notify_owner); } } /* If retransmission queue is empty, acknowledge close operation */ - if (tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_2) { + if (tcb->state == FSM_STATE_FIN_WAIT_2) { if (tcb->pkt_retransmit == NULL) { /* Optional: Unblock user close operation */ } } /* If our FIN has been acknowledged: Translate to TIME_WAIT */ - if (tcb->state == GNRC_TCP_FSM_STATE_CLOSING) { + if (tcb->state == FSM_STATE_CLOSING) { if (tcb->pkt_retransmit == NULL) { - _transition_to(tcb, GNRC_TCP_FSM_STATE_TIME_WAIT, notify_owner); + _transition_to(tcb, FSM_STATE_TIME_WAIT, notify_owner); } } /* If our FIN has been acknowledged: last ACK received, close connection */ - if (tcb->state == GNRC_TCP_FSM_STATE_LAST_ACK) { + if (tcb->state == FSM_STATE_LAST_ACK) { if (tcb->pkt_retransmit == NULL) { - _transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner); + _transition_to(tcb, FSM_STATE_CLOSED, notify_owner); return 0; } } @@ -703,10 +687,8 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti /* 6) Process Payload, if existing */ if (pay_len > 0) { /* Check if State is valid */ - if (tcb->state == GNRC_TCP_FSM_STATE_ESTABLISHED - || tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_1 - || tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_2 - ) { + if (tcb->state == FSM_STATE_ESTABLISHED || tcb->state == FSM_STATE_FIN_WAIT_1 || + tcb->state == FSM_STATE_FIN_WAIT_2) { /* Search for begin of payload "chain" */ LL_SEARCH_SCALAR(in_pkt, snp, type, GNRC_NETTYPE_UNDEF); @@ -733,10 +715,8 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti } /* 7) Check FIN */ if (ctl & MSK_FIN) { - if (tcb->state == GNRC_TCP_FSM_STATE_CLOSED - || tcb->state == GNRC_TCP_FSM_STATE_LISTEN - || tcb->state == GNRC_TCP_FSM_STATE_SYN_SENT - ) { + if (tcb->state == FSM_STATE_CLOSED || tcb->state == FSM_STATE_LISTEN || + tcb->state == FSM_STATE_SYN_SENT) { return 0; } /* Advance rcv_nxt over FIN bit. */ @@ -744,23 +724,21 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti _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); - if (tcb->state == GNRC_TCP_FSM_STATE_SYN_RCVD - || tcb->state == GNRC_TCP_FSM_STATE_ESTABLISHED - ) { - _transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSE_WAIT, notify_owner); + if (tcb->state == FSM_STATE_SYN_RCVD || tcb->state == FSM_STATE_ESTABLISHED) { + _transition_to(tcb, FSM_STATE_CLOSE_WAIT, notify_owner); } - else if (tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_1) { + else if (tcb->state == FSM_STATE_FIN_WAIT_1) { if (tcb->pkt_retransmit == NULL) { - _transition_to(tcb, GNRC_TCP_FSM_STATE_TIME_WAIT, notify_owner); + _transition_to(tcb, FSM_STATE_TIME_WAIT, notify_owner); } else { - _transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSING, notify_owner); + _transition_to(tcb, FSM_STATE_CLOSING, notify_owner); } } - else if (tcb->state == GNRC_TCP_FSM_STATE_FIN_WAIT_2) { - _transition_to(tcb, GNRC_TCP_FSM_STATE_TIME_WAIT, notify_owner); + else if (tcb->state == FSM_STATE_FIN_WAIT_2) { + _transition_to(tcb, FSM_STATE_TIME_WAIT, notify_owner); } - else if (tcb->state == GNRC_TCP_FSM_STATE_TIME_WAIT) { + else if (tcb->state == FSM_STATE_TIME_WAIT) { _restart_timewait_timer(tcb); } } @@ -776,10 +754,10 @@ static int _fsm_rcvd_pkt(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *in_pkt, bool *noti * * @return zero on success. */ -static int _fsm_timeout_timewait(gnrc_tcp_tcb_t* tcb, bool *notify_owner) +static int _fsm_timeout_timewait(gnrc_tcp_tcb_t *tcb, bool *notify_owner) { DEBUG("gnrc_tcp_fsm.c : _fsm_timeout_timewait()\n"); - _transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner); + _transition_to(tcb, FSM_STATE_CLOSED, notify_owner); return 0; } @@ -790,10 +768,10 @@ static int _fsm_timeout_timewait(gnrc_tcp_tcb_t* tcb, bool *notify_owner) * * @return zero on success. */ -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"); - if(tcb->pkt_retransmit != NULL){ + if (tcb->pkt_retransmit != NULL) { _pkt_setup_retransmit(tcb, tcb->pkt_retransmit, true); _pkt_send(tcb, tcb->pkt_retransmit, 0, true); } @@ -811,24 +789,24 @@ static int _fsm_timeout_retransmit(gnrc_tcp_tcb_t* tcb) * * @return zero on success. */ -static int _fsm_timeout_connection(gnrc_tcp_tcb_t* tcb, bool *notify_owner) +static int _fsm_timeout_connection(gnrc_tcp_tcb_t *tcb, bool *notify_owner) { DEBUG("gnrc_tcp_fsm.c : _fsm_timeout_connection()\n"); - _transition_to(tcb, GNRC_TCP_FSM_STATE_CLOSED, notify_owner); + _transition_to(tcb, FSM_STATE_CLOSED, notify_owner); return 0; } /** * @brief FSM Handling Function for probe sending * - * @param[in/out] tcb Specifies tcb to use fsm on. + * @param[in/out] tcb tcb of this connection * * @return zero on success. */ -static int _fsm_send_probe(gnrc_tcp_tcb_t* tcb) +static int _fsm_send_probe(gnrc_tcp_tcb_t *tcb) { 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 */ @@ -841,11 +819,11 @@ static int _fsm_send_probe(gnrc_tcp_tcb_t* tcb) /** * @brief FSM Handling Function for clearing the retransmit queue. * - * @param[in/out] tcb Specifies tcb to use fsm on. + * @param[in/out] tcb tcb of this connection. * * @return zero on success. */ -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"); _clear_retransmit(tcb); @@ -859,60 +837,59 @@ static int _fsm_clear_retransmit(gnrc_tcp_tcb_t* tcb) * @param[in] event current event that triggers fsm translation * @param[in] in_pkt packet that triggered fsm event. Only in case of RCVD_PKT * @param[in/out] buf buffer for send and receive functions - * @param[in] nByte number of bytes to send or receive atmost + * @param[in] len number of bytes to send or receive atmost * @param[out] notify_owner non-negative if the tcb owner should be notified * - * @return TODO zero on success + * @return Zero on success * @return -ENOMEM Can't allocate receive buffer. * @return -EADDRINUSE Given local port is already in use * @return -EOPNOTSUPP If event is not implemented */ -static int _fsm_unprotected(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_event_t event, - gnrc_pktsnip_t *in_pkt, void *buf, size_t nByte, bool *notify_owner) +static int _fsm_unprotected(gnrc_tcp_tcb_t *tcb, fsm_event_t event, gnrc_pktsnip_t *in_pkt, + void *buf, size_t len, bool *notify_owner) { - int ret = 0; /* Return Value */ + int ret = 0; DEBUG("gnrc_tcp_fsm.c : _fsm_unprotected()\n"); switch (event) { - case GNRC_TCP_FSM_EVENT_CALL_OPEN : + case FSM_EVENT_CALL_OPEN : ret = _fsm_call_open(tcb, notify_owner); break; - case GNRC_TCP_FSM_EVENT_CALL_SEND : - ret = _fsm_call_send(tcb, buf, nByte); + case FSM_EVENT_CALL_SEND : + ret = _fsm_call_send(tcb, buf, len); break; - case GNRC_TCP_FSM_EVENT_CALL_RECV : - ret = _fsm_call_recv(tcb, buf, nByte); + case FSM_EVENT_CALL_RECV : + ret = _fsm_call_recv(tcb, buf, len); break; - case GNRC_TCP_FSM_EVENT_CALL_CLOSE : + case FSM_EVENT_CALL_CLOSE : ret = _fsm_call_close(tcb, notify_owner); break; - case GNRC_TCP_FSM_EVENT_CALL_ABORT : + case FSM_EVENT_CALL_ABORT : ret = _fsm_call_abort(); break; - case GNRC_TCP_FSM_EVENT_RCVD_PKT : + case FSM_EVENT_RCVD_PKT : ret = _fsm_rcvd_pkt(tcb, in_pkt, notify_owner); break; - case GNRC_TCP_FSM_EVENT_TIMEOUT_TIMEWAIT : + case FSM_EVENT_TIMEOUT_TIMEWAIT : ret = _fsm_timeout_timewait(tcb, notify_owner); break; - case GNRC_TCP_FSM_EVENT_TIMEOUT_RETRANSMIT : + case FSM_EVENT_TIMEOUT_RETRANSMIT : ret = _fsm_timeout_retransmit(tcb); break; - case GNRC_TCP_FSM_EVENT_TIMEOUT_CONNECTION : + case FSM_EVENT_TIMEOUT_CONNECTION : ret = _fsm_timeout_connection(tcb, notify_owner); break; - case GNRC_TCP_FSM_EVENT_SEND_PROBE : + case FSM_EVENT_SEND_PROBE : ret = _fsm_send_probe(tcb); break; - case GNRC_TCP_FSM_EVENT_CLEAR_RETRANSMIT : + case FSM_EVENT_CLEAR_RETRANSMIT : ret = _fsm_clear_retransmit(tcb); break; } return ret; } -int _fsm(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_event_t event, gnrc_pktsnip_t *in_pkt, void *buf, - size_t nByte) +int _fsm(gnrc_tcp_tcb_t *tcb, fsm_event_t event, gnrc_pktsnip_t *in_pkt, void *buf, size_t len) { msg_t msg; int32_t result; @@ -921,7 +898,7 @@ int _fsm(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_event_t event, gnrc_pktsnip_t *in_pkt /* Lock FSM */ mutex_lock(&(tcb->fsm_lock)); notify_owner = false; - result = _fsm_unprotected(tcb, event, in_pkt, buf, nByte, ¬ify_owner); + result = _fsm_unprotected(tcb, event, in_pkt, buf, len, ¬ify_owner); /* Notify owner if something interesting happend */ if (notify_owner && tcb->owner != KERNEL_PID_UNDEF) { diff --git a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_option.c b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_option.c index 0cbfa6d56f70f66415a0701f4db49dbf00521543..9ed5063ac08ef7ec3bb165d2cb9e292c2aa228c3 100644 --- a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_option.c +++ b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_option.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -11,29 +11,18 @@ * @{ * * @file - * @brief GNRC's TCP option handling related functions + * @brief Implementation of internal/option.h * - * @author Simon Brummer <brummer.simon@googlemail.com> + * @author Simon Brummer <simon.brummer@posteo.de> * @} */ -#include "assert.h" +#include "internal/common.h" #include "internal/option.h" #define ENABLE_DEBUG (0) #include "debug.h" -uint32_t _option_build_mss(uint16_t mss) -{ - return (((uint32_t )TCP_OPTION_KIND_MSS) << 24) | (((uint32_t) TCP_OPTION_LENGTH_MSS) << 16) | mss; -} - -uint16_t _option_build_offset_control(uint16_t nopts, uint16_t ctl) -{ - assert(TCP_HDR_OFFSET_MIN <= nopts && nopts <= TCP_HDR_OFFSET_MAX); - return (nopts << 12) | ctl; -} - -int _option_parse(gnrc_tcp_tcb_t* tcb, tcp_hdr_t *hdr) +int _option_parse(gnrc_tcp_tcb_t *tcb, tcp_hdr_t *hdr) { /* Extract Offset value. Return if no options are set */ uint8_t offset = GET_OFFSET(byteorder_ntohs(hdr->off_ctl)); diff --git a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_pkt.c b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_pkt.c index d9ee8c2249604682c0bea7ad88d99a90773cb197..60ed68fc9b24a3dd377231d97e868d0d9813e745 100644 --- a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_pkt.c +++ b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_pkt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -11,29 +11,28 @@ * @{ * * @file - * @brief GNRC's TCP paket related functions + * @brief Implementation of internal/pkt.h * - * @author Simon Brummer <brummer.simon@googlemail.com> + * @author Simon Brummer <simon.brummer@posteo.de> * @} */ -#include <stdlib.h> +#include <string.h> #include <utlist.h> #include <errno.h> -#include "msg.h" +#include "byteorder.h" #include "net/inet_csum.h" #include "net/gnrc/pktbuf.h" -#include "net/gnrc/tcp.h" -#include "internal/pkt.h" -#include "internal/helper.h" +#include "internal/common.h" #include "internal/option.h" -#include "internal/eventloop.h" +#include "internal/pkt.h" + +#ifdef MODULE_GNRC_IPV6 +#include "net/gnrc/ipv6.h" +#endif #define ENABLE_DEBUG (0) #include "debug.h" -/* Check if a sequence number, falls into the receive window */ -#define INSIDE_WND(l_ed, seq_num, r_ed) (LEQ_32_BIT(l_ed, seq_num) && LSS_32_BIT(seq_num, r_ed)) - /** * @brief Calculates the maximum of two unsigned numbers * @@ -92,7 +91,8 @@ int _pkt_build_reset_from_pkt(gnrc_pktsnip_t **out_pkt, gnrc_pktsnip_t *in_pkt) /* Allocate new tcp header */ tcp_snp = gnrc_pktbuf_add(NULL, &tcp_hdr_out, TCP_HDR_OFFSET_MIN * 4, GNRC_NETTYPE_TCP); if (tcp_snp == NULL) { - DEBUG("gnrc_tcp_pkt.c : _pkt_build_reset_from_pkt() : Can't alloc buffer for TCP Header\n."); + DEBUG("gnrc_tcp_pkt.c : _pkt_build_reset_from_pkt() :\ + Can't alloc buffer for TCP Header\n."); *(out_pkt) = NULL; return -ENOMEM; } @@ -102,7 +102,8 @@ int _pkt_build_reset_from_pkt(gnrc_pktsnip_t **out_pkt, gnrc_pktsnip_t *in_pkt) #ifdef MODULE_GNRC_IPV6 ip6_snp = gnrc_ipv6_hdr_build(tcp_snp, &(ip6_hdr->dst), &(ip6_hdr->src)); if (ip6_snp == NULL) { - DEBUG("gnrc_tcp_pkt.c : _pkt_build_reset_from_pkt() : Can't alloc buffer for IPv6 Header.\n"); + DEBUG("gnrc_tcp_pkt.c : _pkt_build_reset_from_pkt() :\ + Can't alloc buffer for IPv6 Header.\n"); gnrc_pktbuf_release(tcp_snp); *(out_pkt) = NULL; return -ENOMEM; @@ -114,7 +115,7 @@ int _pkt_build_reset_from_pkt(gnrc_pktsnip_t **out_pkt, gnrc_pktsnip_t *in_pkt) return 0; } -int _pkt_build(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con, +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, void *payload, const size_t payload_len) { @@ -161,7 +162,7 @@ int _pkt_build(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con, else { /* Add options if existing */ if (TCP_HDR_OFFSET_MIN < offset) { - uint8_t* opt_ptr = (uint8_t *) tcp_snp->data + sizeof(tcp_hdr); + uint8_t *opt_ptr = (uint8_t *) tcp_snp->data + sizeof(tcp_hdr); uint8_t opt_left = (offset - TCP_HDR_OFFSET_MIN) * sizeof(network_uint32_t); /* Init options field with 'End Of List' - option (0) */ @@ -180,7 +181,7 @@ int _pkt_build(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con, /* Build network layer header */ #ifdef MODULE_GNRC_IPV6 - gnrc_pktsnip_t* ip6_snp = gnrc_ipv6_hdr_build(tcp_snp, NULL, (ipv6_addr_t *) tcb->peer_addr); + gnrc_pktsnip_t *ip6_snp = gnrc_ipv6_hdr_build(tcp_snp, NULL, (ipv6_addr_t *) tcb->peer_addr); if (ip6_snp == NULL) { DEBUG("gnrc_tcp_pkt.c : _pkt_build() : Can't allocate buffer for IPv6 Header.\n"); gnrc_pktbuf_release(tcp_snp); @@ -190,7 +191,7 @@ int _pkt_build(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con, else { *(out_pkt) = ip6_snp; } - #else +#else DEBUG("gnrc_tcp_pkt.c : _pkt_build_reset_from_pkt() : Network Layer Module Missing\n"); #endif @@ -208,7 +209,7 @@ int _pkt_build(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con, 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) { if (out_pkt == NULL) { @@ -227,11 +228,11 @@ int _pkt_send(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *out_pkt, const uint16_t seq_c } /* Pass packet down the network stack */ - gnrc_netapi_send(_gnrc_tcp_pid, out_pkt); + gnrc_netapi_send(gnrc_tcp_pid, out_pkt); 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) { uint32_t l_edge = tcb->rcv_nxt; uint32_t r_edge = tcb->rcv_nxt + tcb->rcv_wnd; @@ -240,7 +241,7 @@ int _pkt_chk_seq_num(const gnrc_tcp_tcb_t* tcb, const uint32_t seq_num, const ui /* Possible case 1 */ /* Segment contains no payload and Receive window is closed and */ /* 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) { return 1; } @@ -254,9 +255,8 @@ int _pkt_chk_seq_num(const gnrc_tcp_tcb_t* tcb, const uint32_t seq_num, const ui /* Possible case 3 */ /* Segment contains Payload and Receive window is open and */ /* Sequence Number overlaps with receive window */ - if (seg_len > 0 && tcb->rcv_wnd > 0 - && (INSIDE_WND(l_edge, seq_num, r_edge) || INSIDE_WND(l_edge, last_seq, 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))) { return 1; } @@ -296,7 +296,7 @@ uint32_t _pkt_get_pay_len(gnrc_pktsnip_t *pkt) 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) { gnrc_pktsnip_t *snp = NULL; uint32_t ctl = 0; @@ -331,7 +331,7 @@ int _pkt_setup_retransmit(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *pkt, const bool r /* RTO Adjustment */ if (!retransmit) { /* If this is the first transmission: rto is 1 sec (Lower Bound) */ - if (tcb->srtt == GNRC_TCP_RTO_UNINITIALIZED || tcb->rtt_var == GNRC_TCP_RTO_UNINITIALIZED) { + if (tcb->srtt == RTO_UNINITIALIZED || tcb->rtt_var == RTO_UNINITIALIZED) { tcb->rto = GNRC_TCP_RTO_LOWER_BOUND; } else { @@ -345,8 +345,8 @@ int _pkt_setup_retransmit(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *pkt, const bool r /* If the transmission has been tried five times, we assume srtt and rtt_var are bogus */ /* New measurements must be taken */ if (tcb->retries >= 5) { - tcb->srtt = GNRC_TCP_RTO_UNINITIALIZED; - tcb->rtt_var = GNRC_TCP_RTO_UNINITIALIZED; + tcb->srtt = RTO_UNINITIALIZED; + tcb->rtt_var = RTO_UNINITIALIZED; } } @@ -360,12 +360,12 @@ 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 */ tcb->msg_tout.type = MSG_TYPE_RETRANSMISSION; - tcb->msg_tout.content.ptr = (void *)tcb; - xtimer_set_msg(&tcb->tim_tout, tcb->rto, &tcb->msg_tout, _gnrc_tcp_pid); + tcb->msg_tout.content.ptr = (void *) tcb; + xtimer_set_msg(&tcb->tim_tout, tcb->rto, &tcb->msg_tout, gnrc_tcp_pid); 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) { uint32_t seg = 0; gnrc_pktsnip_t *snp = NULL; @@ -395,32 +395,29 @@ int _pkt_acknowledge(gnrc_tcp_tcb_t* tcb, const uint32_t ack) /* Use sample only if ther was no timeroverflow and no retransmission (Karns Alogrithm) */ if (tcb->retries == 0 && rtt > 0) { /* If this is the first sample taken */ - if (tcb->srtt == GNRC_TCP_RTO_UNINITIALIZED - && tcb->rtt_var == GNRC_TCP_RTO_UNINITIALIZED - ) { + if (tcb->srtt == RTO_UNINITIALIZED && tcb->rtt_var == RTO_UNINITIALIZED) { tcb->srtt = rtt; tcb->rtt_var = (rtt >> 1); } /* If this is a subsequent sample */ else { - tcb->rtt_var = (tcb->rtt_var / GNRC_TCP_RTO_B_DIV) * (GNRC_TCP_RTO_B_DIV-1); - tcb->rtt_var += abs(tcb->srtt - rtt) / GNRC_TCP_RTO_B_DIV; - tcb->srtt = (tcb->srtt / GNRC_TCP_RTO_A_DIV) * (GNRC_TCP_RTO_A_DIV-1); - tcb->srtt += rtt / GNRC_TCP_RTO_A_DIV; + tcb->rtt_var = (tcb->rtt_var / GNRC_TCP_RTO_B_DIV) * (GNRC_TCP_RTO_B_DIV-1); + tcb->rtt_var += abs(tcb->srtt - rtt) / GNRC_TCP_RTO_B_DIV; + tcb->srtt = (tcb->srtt / GNRC_TCP_RTO_A_DIV) * (GNRC_TCP_RTO_A_DIV-1); + tcb->srtt += rtt / GNRC_TCP_RTO_A_DIV; } } } 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) { uint16_t csum = 0; uint16_t len = (uint16_t) hdr->size; - if(pseudo_hdr == NULL) { + if (pseudo_hdr == NULL) { return 0; } @@ -432,9 +429,9 @@ uint16_t _pkt_calc_csum(const gnrc_pktsnip_t *hdr, } /* Process tcp-header, before checksum field(Byte 16 to 18) */ - csum = inet_csum(csum, (uint8_t *)hdr->data, 16); + csum = inet_csum(csum, (uint8_t *) hdr->data, 16); /* Process tcp-header, after checksum field */ - csum = inet_csum(csum, ((uint8_t *)hdr->data) + 18, hdr->size - 18); + csum = inet_csum(csum, ((uint8_t *) hdr->data) + 18, hdr->size - 18); /* Process Network layer Header */ switch (pseudo_hdr->type) { @@ -448,6 +445,3 @@ uint16_t _pkt_calc_csum(const gnrc_pktsnip_t *hdr, } return ~csum; } - -/* Cleanup, defines */ -#undef INSIDE_WND diff --git a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_rcvbuf.c b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_rcvbuf.c index cbe72312285c59e1e123ae1a1c190baf98de5268..f8f59549717edd5a76a7db692658623180dd3c7c 100644 --- a/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_rcvbuf.c +++ b/sys/net/gnrc/transport_layer/tcp/gnrc_tcp_rcvbuf.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Simon Brummer <brummer.simon@googlemail.com> + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -7,12 +7,13 @@ */ /** + * @ingroup net_gnrc * @{ * * @file - * @brief Implementation of tcp_internal/rcvbuf.h + * @brief Implementation of internal/rcvbuf.h * - * @author Brummer Simon <brummer.simon@googlemail.com> + * @author Simon Brummer <simon.brummer@posteo.de> */ #include <errno.h> #include "internal/rcvbuf.h" @@ -20,13 +21,13 @@ #define ENABLE_DEBUG (0) #include "debug.h" -rcvbuf_t _static_buf; /**< Staticly allocated receive buffers */ +rcvbuf_t _static_buf; /**< Staticly allocated receive buffers */ void _rcvbuf_init(void) { DEBUG("gnrc_tcp_rcvbuf.c : _rcvbuf_init() : Entry\n"); mutex_init(&(_static_buf.lock)); - for (int i=0; i<GNRC_TCP_RCV_BUFFERS; i++) { + for (size_t i = 0; i < GNRC_TCP_RCV_BUFFERS; ++i) { _static_buf.entries[i].used = 0; } } @@ -36,7 +37,7 @@ static void* _rcvbuf_alloc(void) void *result = NULL; DEBUG("gnrc_tcp_rcvbuf.c : _rcvbuf_alloc() : Entry\n"); mutex_lock(&(_static_buf.lock)); - for (int i=0; i<GNRC_TCP_RCV_BUFFERS; i++) { + for (size_t i = 0; i < GNRC_TCP_RCV_BUFFERS; ++i) { if (_static_buf.entries[i].used == 0) { _static_buf.entries[i].used = 1; result = (void *)(_static_buf.entries[i].buffer); @@ -51,7 +52,7 @@ static void _rcvbuf_free(void * const buf) { DEBUG("gnrc_tcp_rcvbuf.c : _rcvbuf_free() : Entry\n"); mutex_lock(&(_static_buf.lock)); - for (int i=0; i<GNRC_TCP_RCV_BUFFERS; i++) { + for (size_t i = 0; i < GNRC_TCP_RCV_BUFFERS; ++i) { if (_static_buf.entries[i].used == 1 && buf == _static_buf.entries[i].buffer) { _static_buf.entries[i].used = 0; } @@ -59,7 +60,7 @@ static void _rcvbuf_free(void * const buf) mutex_unlock(&(_static_buf.lock)); } -int _rcvbuf_get_buffer(gnrc_tcp_tcb_t* tcb) +int _rcvbuf_get_buffer(gnrc_tcp_tcb_t *tcb) { if (tcb->rcv_buf_raw == NULL) { tcb->rcv_buf_raw = _rcvbuf_alloc(); @@ -74,7 +75,7 @@ int _rcvbuf_get_buffer(gnrc_tcp_tcb_t* tcb) return 0; } -void _rcvbuf_release_buffer(gnrc_tcp_tcb_t* tcb) +void _rcvbuf_release_buffer(gnrc_tcp_tcb_t *tcb) { if (tcb->rcv_buf_raw != NULL) { _rcvbuf_free(tcb->rcv_buf_raw); diff --git a/sys/net/gnrc/transport_layer/tcp/internal/common.h b/sys/net/gnrc/transport_layer/tcp/internal/common.h new file mode 100644 index 0000000000000000000000000000000000000000..8d7f98f93ddddf0fc5e36b936050e68529bec709 --- /dev/null +++ b/sys/net/gnrc/transport_layer/tcp/internal/common.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2015-2017 Simon Brummer + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup net_gnrc_tcp TCP + * @ingroup net_gnrc + * @brief RIOT's tcp implementation for the gnrc stack + * + * @{ + * + * @file + * @brief Internally used common defines, macros and variable declaration + * + * @author Simon Brummer <simon.brummer@posteo.de> + */ + +#ifndef GNRC_TCP_INTERNAL_COMMON_H +#define GNRC_TCP_INTERNAL_COMMON_H + +#include <stdint.h> +#include "kernel_types.h" +#include "thread.h" +#include "mutex.h" +#include "net/gnrc/netapi.h" +#include "net/gnrc/tcp/tcb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Port unspecified. + * + * @note PORT 0 is unspecified (@see https://www.ietf.org/rfc/rfc1700.txt) + */ +#define PORT_UNSPEC (0) + +/** + * @brief Status Flags for TCP + * @{ + */ +#define STATUS_PASSIVE (1 << 0) +#define STATUS_ALLOW_ANY_ADDR (1 << 1) +/** @} */ + +/** + * @brief Defines for gnrc tcps "eventloop" thread + * @{ + */ +#define TCP_EVENTLOOP_MSG_QUEUE_SIZE (8U) +#define TCP_EVENTLOOP_PRIO (THREAD_PRIORITY_MAIN - 2U) +#define TCP_EVENTLOOP_STACK_SIZE (THREAD_STACKSIZE_DEFAULT) +/** @} */ + +/** + * @brief Bitmasks for control bit handling + * @{ + */ +#define MSK_FIN (0x0001) +#define MSK_SYN (0x0002) +#define MSK_RST (0x0004) +#define MSK_PSH (0x0008) +#define MSK_ACK (0x0010) +#define MSK_URG (0x0020) +#define MSK_FIN_ACK (0x0011) +#define MSK_SYN_ACK (0x0012) +#define MSK_RST_ACK (0x0014) +#define MSK_SYN_FIN_ACK (0x0013) +#define MSK_FIN_ACK_PSH (0x0019) +#define MSK_CTL (0x003F) +#define MSK_OFFSET (0xF000) +/** @} */ + +/** + * @brief Type field values for TCP internal Message Passing. + * @{ + */ +#define MSG_TYPE_CONNECTION_TIMEOUT (GNRC_NETAPI_MSG_TYPE_ACK + 101) +#define MSG_TYPE_PROBE_TIMEOUT (GNRC_NETAPI_MSG_TYPE_ACK + 102) +#define MSG_TYPE_USER_SPEC_TIMEOUT (GNRC_NETAPI_MSG_TYPE_ACK + 103) +#define MSG_TYPE_RETRANSMISSION (GNRC_NETAPI_MSG_TYPE_ACK + 104) +#define MSG_TYPE_TIMEWAIT (GNRC_NETAPI_MSG_TYPE_ACK + 105) +#define MSG_TYPE_NOTIFY_USER (GNRC_NETAPI_MSG_TYPE_ACK + 106) +/** @} */ + +/** + * @brief Macro to mark is the time measurement is uninitialized + */ +#define RTO_UNINITIALIZED (-1) + +/** + * @brief Overflow tolerant comparision operators for sequence and + acknowledgement number comparision + * @{ + */ +#define LSS_32_BIT(x, y) (((int32_t) (x)) - ((int32_t) (y)) < 0) +#define LEQ_32_BIT(x, y) (((int32_t) (x)) - ((int32_t) (y)) <= 0) +#define GRT_32_BIT(x, y) (!LEQ_32_BIT(x, y)) +#define GEQ_32_BIT(x, y) (!LSS_32_BOT(x, y)) +/** @} */ + +/** + * @brief Check if a given sequence number, falls into the a receive window + */ +#define INSIDE_WND(l_ed, seq_num, r_ed) (LEQ_32_BIT(l_ed, seq_num) && LSS_32_BIT(seq_num, r_ed)) + +/** + * @brief Extract offset value from "offctl"-header field. + */ +#define GET_OFFSET( x ) (((x) & MSK_OFFSET) >> 12) + +/** + * @brief PID of tcp event handling thread + */ +extern kernel_pid_t gnrc_tcp_pid; + +/** + * @brief Head of linked tcb list. + */ +extern gnrc_tcp_tcb_t *_list_tcb_head; + +/** + * @brief Mutex to protect linked list. + */ +extern mutex_t _list_tcb_lock; + +#ifdef __cplusplus +} +#endif + +#endif /* GNRC_TCP_INTERNAL_COMMON_H */ +/** @} */ diff --git a/sys/net/gnrc/transport_layer/tcp/internal/eventloop.h b/sys/net/gnrc/transport_layer/tcp/internal/eventloop.h index 922b4e6827f3c08096f9944e5a133c77bcd2abbb..febe85c5350cc80cfd2c096fd52805ecf073f019 100644 --- a/sys/net/gnrc/transport_layer/tcp/internal/eventloop.h +++ b/sys/net/gnrc/transport_layer/tcp/internal/eventloop.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -14,23 +14,18 @@ * @{ * * @file - * @brief Definition for gnrc tcp event processing loop + * @brief TCP event loop delarations * - * @author Simon Brummer <brummer.simon@googlemail.com> +* @author Simon Brummer <simon.brummer@posteo.de> */ -#ifndef GNRC_TCP_INTERNAL_EVENTLOOP_H_ -#define GNRC_TCP_INTERNAL_EVENTLOOP_H_ +#ifndef GNRC_TCP_INTERNAL_EVENTLOOP_H +#define GNRC_TCP_INTERNAL_EVENTLOOP_H #ifdef __cplusplus extern "C" { #endif -/** - * @brief PID of tcp event handling thread - */ -extern kernel_pid_t _gnrc_tcp_pid; - /** * @brief TCP's mein processing thread. * @@ -44,5 +39,5 @@ void *_event_loop(__attribute__((unused)) void *arg); } #endif -#endif /* GNRC_TCP_INTERNAL_EVENTLOOP_H_ */ +#endif /* GNRC_TCP_INTERNAL_EVENTLOOP_H */ /** @} */ diff --git a/sys/net/gnrc/transport_layer/tcp/internal/fsm.h b/sys/net/gnrc/transport_layer/tcp/internal/fsm.h index 461f781f67396d9fd542ce02d205ecffe36f4e40..bb2622f4246fa0ffda40a92c833b2454901a757b 100644 --- a/sys/net/gnrc/transport_layer/tcp/internal/fsm.h +++ b/sys/net/gnrc/transport_layer/tcp/internal/fsm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -14,48 +14,74 @@ * @{ * * @file - * @brief Definies function to manipulate a connections state + * @brief TCP finite state maschine declarations * - * @author Simon Brummer <brummer.simon@googlemail.com> + * @author Simon Brummer <simon.brummer@posteo.de> */ -#ifndef GNRC_TCP_INTERNAL_FSM_H_ -#define GNRC_TCP_INTERNAL_FSM_H_ +#ifndef GNRC_TCP_INTERNAL_FSM_H +#define GNRC_TCP_INTERNAL_FSM_H -#include <errno.h> -#include "net/gnrc/pktbuf.h" +#include <stdint.h> #include "net/gnrc/pkt.h" -#include "net/gnrc/tcp/fsm.h" -#include "net/gnrc/tcp.h" +#include "net/gnrc/tcp/tcb.h" #ifdef __cplusplus extern "C" { #endif /** - * @brief PID of tcp event handling thread + * @brief The TCP FSM States. */ -extern kernel_pid_t _gnrc_tcp_pid; +typedef enum { + FSM_STATE_CLOSED, + FSM_STATE_LISTEN, + FSM_STATE_SYN_SENT, + FSM_STATE_SYN_RCVD, + FSM_STATE_ESTABLISHED, + FSM_STATE_CLOSE_WAIT, + FSM_STATE_LAST_ACK, + FSM_STATE_FIN_WAIT_1, + FSM_STATE_FIN_WAIT_2, + FSM_STATE_CLOSING, + FSM_STATE_TIME_WAIT +} fsm_state_t; + +/** + * @brief Events that trigger translations in TCP FSM. + */ +typedef enum { + FSM_EVENT_CALL_OPEN, /* User function call: open */ + FSM_EVENT_CALL_SEND, /* User function call: send */ + FSM_EVENT_CALL_RECV, /* User function call: recv */ + FSM_EVENT_CALL_CLOSE, /* User function call: close */ + FSM_EVENT_CALL_ABORT, /* User function call: abort */ + FSM_EVENT_RCVD_PKT, /* Paket received from peer */ + FSM_EVENT_TIMEOUT_TIMEWAIT, /* Timeout: Timewait */ + FSM_EVENT_TIMEOUT_RETRANSMIT, /* Timeout: Retransmit */ + FSM_EVENT_TIMEOUT_CONNECTION, /* Timeout: Connection */ + FSM_EVENT_SEND_PROBE, /* Send a Zero Window Probe */ + FSM_EVENT_CLEAR_RETRANSMIT /* Clear Retransmission Mechanism */ +} fsm_event_t; /** * @brief TCP finite state maschine * - * @param[in,out] tcb specifies connection to use fsm on. - * @param[in] event current event that triggers fsm translation - * @param[in] in_pkt packet that triggered fsm event. Only in case of RCVD_PKT - * @param[in,out] buf buffer for send and receive functions - * @param[in] nByte number of bytes to send or receive atmost + * @param[in,out] tcb specifies connection to use fsm on. + * @param[in] event current event that triggers fsm translation + * @param[in] in_pkt packet that triggered fsm event. Only in case of RCVD_PKT + * @param[in,out] buf buffer for send and receive functions + * @param[in] len number of bytes to send or receive atmost * * @return Zero on success * @return Positive Number, number of bytes sent from or copied into buf. * @return -ENOSYS if event is not implemented */ -int _fsm(gnrc_tcp_tcb_t* tcb, gnrc_tcp_fsm_event_t event, gnrc_pktsnip_t *in_pkt, void *buf, - size_t nByte); +int _fsm(gnrc_tcp_tcb_t *tcb, fsm_event_t event, gnrc_pktsnip_t *in_pkt, void *buf, size_t len); #ifdef __cplusplus } #endif -#endif /* GNRC_TCP_INTERNAL_FSM_H_ */ +#endif /* GNRC_TCP_INTERNAL_FSM_H */ /** @} */ diff --git a/sys/net/gnrc/transport_layer/tcp/internal/helper.h b/sys/net/gnrc/transport_layer/tcp/internal/helper.h deleted file mode 100644 index ff9039e3bdec3364fbcc2b9bcb79b8cbf5ab6c18..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/transport_layer/tcp/internal/helper.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2015 Simon Brummer - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @defgroup net_gnrc_tcp TCP - * @ingroup net_gnrc - * @brief RIOT's tcp implementation for the gnrc stack - * - * @{ - * - * @file - * @brief Helperfunctions and defines - * - * @author Simon Brummer <brummer.simon@googlemail.com> - */ - -#ifndef GNRC_TCP_INTERNAL_HELPER_H_ -#define GNRC_TCP_INTERNAL_HELPER_H_ - -#include "net/tcp.h" -#include "net/gnrc/netapi.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Bitmasks for control bit handling - * @{ - */ -#define MSK_FIN 0x0001 -#define MSK_SYN 0x0002 -#define MSK_RST 0x0004 -#define MSK_PSH 0x0008 -#define MSK_ACK 0x0010 -#define MSK_URG 0x0020 -#define MSK_FIN_ACK 0x0011 -#define MSK_SYN_ACK 0x0012 -#define MSK_RST_ACK 0x0014 -#define MSK_SYN_FIN_ACK 0x0013 -#define MSK_FIN_ACK_PSH 0x0019 -#define MSK_CTL 0x003F -#define MSK_OFFSET 0xF000 -/** @} */ - -/** - * @brief Type field values for TCP internal Message Passing. - * @{ - */ -#define MSG_TYPE_CONNECTION_TIMEOUT (GNRC_NETAPI_MSG_TYPE_ACK + 101) -#define MSG_TYPE_PROBE_TIMEOUT (GNRC_NETAPI_MSG_TYPE_ACK + 102) -#define MSG_TYPE_USER_SPEC_TIMEOUT (GNRC_NETAPI_MSG_TYPE_ACK + 103) -#define MSG_TYPE_RETRANSMISSION (GNRC_NETAPI_MSG_TYPE_ACK + 104) -#define MSG_TYPE_TIMEWAIT (GNRC_NETAPI_MSG_TYPE_ACK + 105) -#define MSG_TYPE_NOTIFY_USER (GNRC_NETAPI_MSG_TYPE_ACK + 106) -/** @} */ - -/** - * @brief Overflow tolerant comparision operators for sequence and - acknowledgement number comparision - * @{ - */ -#define LSS_32_BIT(x, y) (((int32_t) (x)) - ((int32_t) (y)) < 0) -#define LEQ_32_BIT(x, y) (((int32_t) (x)) - ((int32_t) (y)) <= 0) -#define GRT_32_BIT(x, y) (!LEQ_32_BIT(x, y)) -#define GEQ_32_BIT(x, y) (!LSS_32_BOT(x, y)) -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* GNRC_TCP_INTERNAL_HELPER_H_ */ -/** @} */ diff --git a/sys/net/gnrc/transport_layer/tcp/internal/option.h b/sys/net/gnrc/transport_layer/tcp/internal/option.h index 55a25cddf08733a30a60e851b1ae6baa6028f1b5..2706854c0c70c8a823cdfbd1515d6740d73d2772 100644 --- a/sys/net/gnrc/transport_layer/tcp/internal/option.h +++ b/sys/net/gnrc/transport_layer/tcp/internal/option.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -14,27 +14,23 @@ * @{ * * @file - * @brief Defines and Macros for TCP option handling + * @brief TCP option handling declarations * - * @author Simon Brummer <brummer.simon@googlemail.com> + * @author Simon Brummer <simon.brummer@posteo.de> */ -#ifndef GNRC_TCP_INTERNAL_OPTION_H_ -#define GNRC_TCP_INTERNAL_OPTION_H_ +#ifndef GNRC_TCP_INTERNAL_OPTION_H +#define GNRC_TCP_INTERNAL_OPTION_H -#include "helper.h" +#include <stdint.h> +#include "assert.h" #include "net/tcp.h" -#include "net/gnrc/tcp.h" +#include "net/gnrc/tcp/tcb.h" #ifdef __cplusplus extern "C" { #endif -/** - * @brief Extract offset value from offet and ctl bit field. - */ -#define GET_OFFSET( x ) (((x) & MSK_OFFSET) >> 12) - /** * @brief Helper Function to build the MSS Option * @@ -42,7 +38,11 @@ extern "C" { * * @return Valid MSS Option. */ -uint32_t _option_build_mss(uint16_t mss); +inline static uint32_t _option_build_mss(uint16_t mss) +{ + return (((uint32_t) TCP_OPTION_KIND_MSS << 24) | + ((uint32_t) TCP_OPTION_LENGTH_MSS << 16) | mss); +} /** * @brief Helper Function to build the combined option and control flag field @@ -52,7 +52,11 @@ uint32_t _option_build_mss(uint16_t mss); * * @return Valid option size and control field. */ -uint16_t _option_build_offset_control(uint16_t nopts, uint16_t ctl); +inline static uint16_t _option_build_offset_control(uint16_t nopts, uint16_t ctl) +{ + assert(TCP_HDR_OFFSET_MIN <= nopts && nopts <= TCP_HDR_OFFSET_MAX); + return (nopts << 12) | ctl; +} /** * @brief Parses options of a given tcp-header pktsnip. @@ -63,11 +67,11 @@ uint16_t _option_build_offset_control(uint16_t nopts, uint16_t ctl); * @return Zero on success * @return A negative value on error */ -int _option_parse(gnrc_tcp_tcb_t* tcb, tcp_hdr_t *hdr); +int _option_parse(gnrc_tcp_tcb_t *tcb, tcp_hdr_t *hdr); #ifdef __cplusplus } #endif -#endif /* GNRC_TCP_INTERNAL_OPTION_H_*/ +#endif /* GNRC_TCP_INTERNAL_OPTION_H*/ /** @} */ diff --git a/sys/net/gnrc/transport_layer/tcp/internal/pkt.h b/sys/net/gnrc/transport_layer/tcp/internal/pkt.h index d63ff9c7ed321f107bbc2f81d2cc2f5a5507f6e7..4cc76eb44438d2d6827e25a3fe0bcc2c30cef7cf 100644 --- a/sys/net/gnrc/transport_layer/tcp/internal/pkt.h +++ b/sys/net/gnrc/transport_layer/tcp/internal/pkt.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -14,15 +14,17 @@ * @{ * * @file - * @brief Functions for TCP's paket handling + * @brief TCP paket handling declarations * - * @author Simon Brummer <brummer.simon@googlemail.com> + * @author Simon Brummer <simon.brummer@posteo.de> */ -#ifndef GNRC_TCP_INTERNAL_PKT_H_ -#define GNRC_TCP_INTERNAL_PKT_H_ +#ifndef GNRC_TCP_INTERNAL_PKT_H +#define GNRC_TCP_INTERNAL_PKT_H -#include "net/conn/tcp.h" +#include <stdint.h> +#include "net/gnrc/pkt.h" +#include "net/gnrc/tcp/tcb.h" #ifdef __cplusplus extern "C" { @@ -43,21 +45,21 @@ extern "C" { int _pkt_build_reset_from_pkt(gnrc_pktsnip_t **out_pkt, gnrc_pktsnip_t *in_pkt); /** - * @brief Build and allocate a tcp paket in paketbuffer, conn stores pointer to new paket. + * @brief Build and allocate a tcp paket, tcb stores pointer to new paket. * - * @param[in,out] tcb This connections Transmission control block. + * @param[in,out] tcb This connections transmission control block. * @param[out] out_pkt Pointer to paket to build - * @param[out] seq_con Number of Bytes, the packet will consume in sequence number spce - * @param[in] ctl control bits to set in pkt - * @param[in] seq_num sequence number to use in new paket - * @param[in] ack_num acknowledgment number to use in new paket + * @param[out] seq_con Number of Bytes, the packet will consume in sequence number space + * @param[in] ctl control bits to set in out_pkt + * @param[in] seq_num sequence number of the new paket + * @param[in] ack_num acknowledgment number of the new paket * @param[in] payload pointer to payload buffer * @param[in] payload_len payload size * * @return Zero on success. * @return -ENOMEM if pktbuf is full. */ -int _pkt_build(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con, +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, void *payload, const size_t payload_len); @@ -72,7 +74,7 @@ int _pkt_build(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t **out_pkt, uint16_t *seq_con, * @return Zero on success. * @return -EINVAL if out_pkt was NULL */ -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); /** @@ -85,7 +87,7 @@ int _pkt_send(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *out_pkt, const uint16_t seq_c * @return Zero if the sequence number is invalid * @return Non-zero if the sequence number is acceptable */ -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); /** * @brief Extracts the length of a segment @@ -110,13 +112,13 @@ uint32_t _pkt_get_pay_len(gnrc_pktsnip_t *pkt); * * @param[in,out] tcb This connections Transmission control block. * @param[in] pkt paket to add to the retransmission mechanism - * @param[in] retransmit is this a retransmission ? + * @param[in] retransmit Flag used to indicate that pkt is a retransmit. * * @return Zero on success * @return -ENOMEM if the retransmission queue is full * @return -EINVAL if pkt is null */ -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); /** * @brief Acknowledges and removes packet from the retransmission mechanism @@ -127,7 +129,7 @@ int _pkt_setup_retransmit(gnrc_tcp_tcb_t* tcb, gnrc_pktsnip_t *pkt, const bool r * @return Zero on success * @return -ENODATA if there is nothing to acknowledge */ -int _pkt_acknowledge(gnrc_tcp_tcb_t* tcb, const uint32_t ack); +int _pkt_acknowledge(gnrc_tcp_tcb_t *tcb, const uint32_t ack); /** * @brief Calculates checksum over payload, tcp-header and network layer header @@ -146,5 +148,5 @@ uint16_t _pkt_calc_csum(const gnrc_pktsnip_t *hdr, const gnrc_pktsnip_t *pseudo_ } #endif -#endif /* GNRC_TCP_INTERNAL_PKT_H_ */ +#endif /* GNRC_TCP_INTERNAL_PKT_H */ /** @} */ diff --git a/sys/net/gnrc/transport_layer/tcp/internal/rcvbuf.h b/sys/net/gnrc/transport_layer/tcp/internal/rcvbuf.h index 39a68afe0af22b1ec85f677609a6af21e03280e1..b47d673c2e80ca6e74be50814f399a73c704f9ae 100644 --- a/sys/net/gnrc/transport_layer/tcp/internal/rcvbuf.h +++ b/sys/net/gnrc/transport_layer/tcp/internal/rcvbuf.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -14,17 +14,16 @@ * @{ * * @file - * @brief Functions for allocating and freeing the receive buffer + * @brief Functions for allocating and freeing the receive buffer * - * @author Simon Brummer <brummer.simon@googlemail.com> - * @} + * @author Simon Brummer <simon.brummer@posteo.de> */ - #ifndef GNRC_TCP_INTERNAL_RCVBUF_H_ - #define GNRC_TCP_INTERNAL_RCVBUF_H_ + +#ifndef GNRC_TCP_INTERNAL_RCVBUF_H +#define GNRC_TCP_INTERNAL_RCVBUF_H #include <stdint.h> #include "mutex.h" -#include "ringbuffer.h" #include "net/gnrc/tcp/config.h" #include "net/gnrc/tcp/tcb.h" @@ -64,18 +63,18 @@ void _rcvbuf_init(void); * @return zero on success * @return -ENOMEM If receive buffer is out of memory. */ -int _rcvbuf_get_buffer(gnrc_tcp_tcb_t* tcb); +int _rcvbuf_get_buffer(gnrc_tcp_tcb_t *tcb); /** * @brief Free allocated receive buffer * * @param[in] tcb Transmission control block that buffer should be freed. */ -void _rcvbuf_release_buffer(gnrc_tcp_tcb_t* tcb); +void _rcvbuf_release_buffer(gnrc_tcp_tcb_t *tcb); #ifdef __cplusplus } #endif -#endif /* GNRC_TCP_INTERNAL_RCVBUF_H_ */ +#endif /* GNRC_TCP_INTERNAL_RCVBUF_H */ /** @} */ diff --git a/tests/gnrc_tcp_client/main.c b/tests/gnrc_tcp_client/main.c index 5d1bbbe22df4536e2342855717ece25e4ef423ce..77df29331ee79dd6022cdaf0237598840b1b7d1c 100644 --- a/tests/gnrc_tcp_client/main.c +++ b/tests/gnrc_tcp_client/main.c @@ -1,14 +1,15 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ + #include <stdio.h> #include <errno.h> +#include "thread.h" #include "net/af.h" -#include "random.h" #include "net/gnrc/ipv6.h" #include "net/gnrc/tcp.h" @@ -17,7 +18,7 @@ /* Number of possible parallel connections */ #ifndef CONNS -#define CONNS 1 +#define CONNS (1) #endif /* Amount of data to transmit */ @@ -47,10 +48,9 @@ int main(void) /* Start Connection Handling Threads */ for (int i = 0; i < CONNS; i += 1) { - thread_create((char *)stacks[i], sizeof(stacks[i]), THREAD_PRIORITY_MAIN, 0, cli_thread, - (void *)i, NULL); + thread_create((char *) stacks[i], sizeof(stacks[i]), THREAD_PRIORITY_MAIN, 0, cli_thread, + (void *) i, NULL); } - return 0; } @@ -112,8 +112,7 @@ void *cli_thread(void *arg) return 0; case -ETIMEDOUT: - printf("TID=%d : gnrc_tcp_open_active() : -ETIMEDOUT : retry after 10sec\n", - tid); + printf("TID=%d : gnrc_tcp_open_active() : -ETIMEDOUT : retry after 10sec\n", tid); xtimer_sleep(10); continue; @@ -123,7 +122,7 @@ void *cli_thread(void *arg) } /* Fill Buffer with a test pattern */ - for (size_t i=0; i < sizeof(bufs[tid]); ++i){ + for (size_t i = 0; i < sizeof(bufs[tid]); ++i){ bufs[tid][i] = TEST_PATERN_CLI; } @@ -160,7 +159,7 @@ void *cli_thread(void *arg) /* Receive Data, stop if errors were found */ for (size_t rcvd = 0; rcvd < sizeof(bufs[tid]) && ret >= 0; rcvd += ret) { - ret = gnrc_tcp_recv(&tcb, (void *)(bufs[tid] + rcvd), sizeof(bufs[tid]) - rcvd, + ret = gnrc_tcp_recv(&tcb, (void *) (bufs[tid] + rcvd), sizeof(bufs[tid]) - rcvd, GNRC_TCP_CONNECTION_TIMEOUT_DURATION); switch (ret) { case -ENOTCONN: @@ -197,7 +196,7 @@ void *cli_thread(void *arg) } /* If there was no error: Check received pattern */ - for (size_t i=0; i < sizeof(bufs[tid]); ++i) { + for (size_t i = 0; i < sizeof(bufs[tid]); ++i) { if (bufs[tid][i] != TEST_PATERN_SRV) { printf("TID=%d : Payload verfication failed\n", tid); failed_payload_verifications += 1; @@ -210,7 +209,7 @@ void *cli_thread(void *arg) /* Gather Data */ cycles += 1; - if(ret >= 0) { + if (ret >= 0) { cycles_ok += 1; } printf("TID=%d : %"PRIi32" test cycles completed. %"PRIi32" ok, %"PRIi32" faulty", diff --git a/tests/gnrc_tcp_server/main.c b/tests/gnrc_tcp_server/main.c index 9a9ed39e448c7d9c99fad2032331441e2cb6a441..c938cafc94fb2a259510d579045997eaa0da8014 100644 --- a/tests/gnrc_tcp_server/main.c +++ b/tests/gnrc_tcp_server/main.c @@ -1,10 +1,11 @@ /* - * Copyright (C) 2015 Simon Brummer + * Copyright (C) 2015-2017 Simon Brummer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ + #include <stdio.h> #include <errno.h> #include "thread.h" @@ -17,7 +18,7 @@ /* Number of possible parallel connections */ #ifndef CONNS -#define CONNS 1 +#define CONNS (1) #endif /* Amount of data to transmit */ @@ -54,15 +55,15 @@ int main(void) /* Start Threads to handle each connection */ for (int i = 0; i < CONNS; i += 1) { - thread_create((char *)stacks[i], sizeof(stacks[i]), THREAD_PRIORITY_MAIN, 0, srv_thread, - (void *)i, NULL); + thread_create((char *) stacks[i], sizeof(stacks[i]), THREAD_PRIORITY_MAIN, 0, srv_thread, + (void *) i, NULL); } return 0; } void *srv_thread(void *arg) { - int tid = (int)arg; + int tid = (int) arg; uint32_t cycles = 0; uint32_t cycles_ok = 0; uint32_t failed_payload_verifications = 0; @@ -106,7 +107,7 @@ void *srv_thread(void *arg) /* Receive Data, stop if errors were found */ for (size_t rcvd = 0; rcvd < sizeof(bufs[tid]) && ret >= 0; rcvd += ret) { - ret = gnrc_tcp_recv(&tcb, (void *)(bufs[tid] + rcvd), sizeof(bufs[tid]) - rcvd, + ret = gnrc_tcp_recv(&tcb, (void *) (bufs[tid] + rcvd), sizeof(bufs[tid]) - rcvd, GNRC_TCP_CONNECTION_TIMEOUT_DURATION); switch (ret) { case -ENOTCONN: @@ -143,7 +144,7 @@ void *srv_thread(void *arg) } /* Check received pattern */ - for (size_t i=0; i < sizeof(bufs[tid]); ++i) { + for (size_t i = 0; i < sizeof(bufs[tid]); ++i) { if (bufs[tid][i] != TEST_PATERN_CLI) { printf("TID=%d : Payload verfication failed\n", tid); failed_payload_verifications += 1; @@ -152,7 +153,7 @@ void *srv_thread(void *arg) } /* Fill Buffer with a test pattern */ - for (size_t i=0; i < sizeof(bufs[tid]); ++i) { + for (size_t i = 0; i < sizeof(bufs[tid]); ++i) { bufs[tid][i] = TEST_PATERN_SRV; } @@ -192,7 +193,7 @@ void *srv_thread(void *arg) /* Gather Data */ cycles += 1; - if(ret >= 0) { + if (ret >= 0) { cycles_ok += 1; } printf("TID=%d : %"PRIi32" test cycles completed. %"PRIi32" ok, %"PRIi32" faulty",