Merge pull request #1508 from cgundogan/transport_layer_refactoring

transport_layer: Splitting UDP and TCP
dev/timer
Oleg Hahm 9 years ago
commit 218635027c

@ -4,11 +4,24 @@ endif
ifneq (,$(filter pnet,$(USEMODULE)))
USEMODULE += posix
USEMODULE += destiny
USEMODULE += socket_base
USEMODULE += net_help
endif
ifneq (,$(filter destiny,$(USEMODULE)))
ifneq (,$(filter transport_layer,$(USEMODULE)))
USEMODULE += tcp
USEMODULE += udp
endif
ifneq (,$(filter udp,$(USEMODULE)))
USEMODULE += socket_base
endif
ifneq (,$(filter tcp,$(USEMODULE)))
USEMODULE += socket_base
endif
ifneq (,$(filter socket_base,$(USEMODULE)))
USEMODULE += sixlowpan
USEMODULE += net_help
USEMODULE += vtimer

@ -1 +1,2 @@
PSEUDOMODULES += defaulttransceiver
PSEUDOMODULES += transport_layer

@ -54,11 +54,10 @@ BOARD_BLACKLIST := arduino-due mbed_lpc1768 msb-430 pttu udoo qemu-i386 stm32f0d
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += posix
USEMODULE += ps
USEMODULE += vtimer
USEMODULE += defaulttransceiver
USEMODULE += rpl
USEMODULE += destiny
USEMODULE += udp
include $(RIOTBASE)/Makefile.include

@ -25,7 +25,7 @@
#include "shell.h"
#include "shell_commands.h"
#include "board_uart0.h"
#include "destiny.h"
#include "udp.h"
#include "rpl_udp.h"

@ -24,7 +24,7 @@
#include "thread.h"
#include "net_if.h"
#include "sixlowpan.h"
#include "destiny.h"
#include "udp.h"
#include "rpl.h"
#include "rpl/rpl_dodag.h"
#include "rpl_udp.h"
@ -122,7 +122,7 @@ void rpl_udp_init(int argc, char **argv)
msg_send_receive(&m, &m, transceiver_pid);
printf("Channel set to %u\n", RADIO_CHANNEL);
puts("Destiny initialized");
puts("Transport Layer initialized");
/* start transceiver watchdog */
}

@ -26,7 +26,7 @@
#include "thread.h"
#include "destiny/socket.h"
#include "socket_base/socket.h"
#include "net_help.h"
@ -63,7 +63,7 @@ static void *init_udp_server(void *arg)
char buffer_main[UDP_BUFFER_SIZE];
int32_t recsize;
uint32_t fromlen;
int sock = destiny_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
int sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
memset(&sa, 0, sizeof(sa));
@ -72,14 +72,14 @@ static void *init_udp_server(void *arg)
fromlen = sizeof(sa);
if (-1 == destiny_socket_bind(sock, &sa, sizeof(sa))) {
if (-1 == socket_base_bind(sock, &sa, sizeof(sa))) {
printf("Error bind failed!\n");
destiny_socket_close(sock);
socket_base_close(sock);
return NULL;
}
while (1) {
recsize = destiny_socket_recvfrom(sock, (void *)buffer_main, UDP_BUFFER_SIZE, 0,
&sa, &fromlen);
recsize = socket_base_recvfrom(sock, (void *)buffer_main, UDP_BUFFER_SIZE, 0, &sa, &fromlen);
if (recsize < 0) {
printf("ERROR: recsize < 0!\n");
@ -88,7 +88,7 @@ static void *init_udp_server(void *arg)
printf("UDP packet received, payload: %s\n", buffer_main);
}
destiny_socket_close(sock);
socket_base_close(sock);
return NULL;
}
@ -113,7 +113,7 @@ void udp_send(int argc, char **argv)
strncpy(text, argv[2], sizeof(text));
text[sizeof(text) - 1] = 0;
sock = destiny_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (-1 == sock) {
printf("Error Creating Socket!");
@ -133,7 +133,7 @@ void udp_send(int argc, char **argv)
memcpy(&sa.sin6_addr, &ipaddr, 16);
sa.sin6_port = HTONS(SERVER_PORT);
bytes_sent = destiny_socket_sendto(sock, (char *)text,
bytes_sent = socket_base_sendto(sock, (char *)text,
strlen(text) + 1, 0, &sa,
sizeof(sa));
@ -146,5 +146,5 @@ void udp_send(int argc, char **argv)
&ipaddr));
}
destiny_socket_close(sock);
socket_base_close(sock);
}

@ -15,7 +15,7 @@ index 0000000..f90baa1
+++ b/Makefile
@@ -0,0 +1,5 @@
+MODULE:=$(shell basename $(CURDIR))
+INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/destiny/include -I$(RIOTBASE)/sys/net/sixlowpan/include/ -I$(RIOTBASE)/sys/net/ieee802154/include -I$(RIOTBASE)/sys/net/net_help -I$(RIOTBASE)/sys/posix/include -I$(RIOTBASE)/sys/posix/pnet/include
+INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/transport_layer/include -I$(RIOTBASE)/sys/net/sixlowpan/include/ -I$(RIOTBASE)/sys/net/ieee802154/include -I$(RIOTBASE)/sys/net/net_help -I$(RIOTBASE)/sys/posix/include -I$(RIOTBASE)/sys/posix/pnet/include
+CFLAGS += -DWITH_POSIX
+
+include $(RIOTBASE)/Makefile.base

@ -359,7 +359,7 @@ index 78fd5b4..cfba7a9 100644
#endif
+#ifdef RIOT
+#include "destiny/socket.h"
+#include "transport_layer/socket.h"
+#define INET_ADDRSTRLEN (16)
+#define INET6_ADDRSTRLEN (48)
+#endif
@ -466,7 +466,7 @@ index 4b3e04d..6b52f72 100644
#include <stdio.h>
#include <stdlib.h>
+#ifdef RIOT
+#include "destiny/socket.h"
+#include "transport_layer/socket.h"
+#include "inet_ntop.h"
+#else
#include <sys/socket.h>

@ -46,8 +46,18 @@ endif
ifneq (,$(filter net_if,$(USEMODULE)))
DIRS += net/link_layer/net_if
endif
ifneq (,$(filter destiny,$(USEMODULE)))
DIRS += net/transport_layer/destiny
ifneq (,$(filter transport_layer,$(USEMODULE)))
USEMODULE += udp
USEMODULE += tcp
endif
ifneq (,$(filter socket_base,$(USEMODULE)))
DIRS += net/transport_layer/socket_base
endif
ifneq (,$(filter udp,$(USEMODULE)))
DIRS += net/transport_layer/udp
endif
ifneq (,$(filter tcp,$(USEMODULE)))
DIRS += net/transport_layer/tcp
endif
ifneq (,$(filter net_help,$(USEMODULE)))
DIRS += net/crosslayer/net_help

@ -1,4 +1,13 @@
ifneq (,$(filter destiny,$(USEMODULE)))
ifneq (,$(filter transport_layer,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
endif
ifneq (,$(filter socket_base,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
endif
ifneq (,$(filter tcp,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
endif
ifneq (,$(filter udp,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
endif
ifneq (,$(filter net_help,$(USEMODULE)))

@ -55,8 +55,12 @@
#include "sixlowpan.h"
#endif
#ifdef MODULE_DESTINY
#include "destiny.h"
#ifdef MODULE_UDP
#include "udp.h"
#endif
#ifdef MODULE_TCP
#include "tcp.h"
#endif
#ifdef MODULE_NET_IF
@ -180,8 +184,13 @@ void auto_init(void)
extern void profiling_init(void);
profiling_init();
#endif
#ifdef MODULE_DESTINY
DEBUG("Auto init transport layer [destiny] module.\n");
destiny_init_transport_layer();
#ifdef MODULE_UDP
DEBUG("Auto init transport layer module: [udp].\n");
udp_init_transport_layer();
#endif
#ifdef MODULE_TCP
DEBUG("Auto init transport layer module: [tcp].\n");
tcp_init_transport_layer();
#endif
}

@ -1,5 +1,5 @@
/**
* destiny.h - Wraps all API types, constants and functions of the transport
* socket_base.h - Wraps all API types, constants and functions of the transport
* layer implementation.
*
* Copyright (C) 2013 INRIA.
@ -10,9 +10,9 @@
*/
/**
* @defgroup destiny DESTiny - Transport layer implementation
* @defgroup socket_base Transport layer implementation
* @ingroup net
* @brief DESTiny module implements the transport layer. This includes
* @brief This module implements the transport layer. This includes
* 6LoWPAN UDP header compression and (experimental) 6LoWPAN TCP header
* compression.
* @see <a href="http://tools.ietf.org/html/rfc6282#section-4.3">
@ -25,23 +25,16 @@
* </a>
* @{
* @file
* @brief destiny functions
* @brief transport_layer functions
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef DESTINY_H
#define DESTINY_H
#ifndef SOCKET_BASE_H
#define SOCKET_BASE_H
#include "destiny/in.h"
#include "destiny/socket.h"
#include "destiny/types.h"
#include "socket_base/in.h"
#include "socket_base/socket.h"
#include "socket_base/types.h"
/**
* Initializes transport layer.
*
* @return 0 on success, other else.
*/
int destiny_init_transport_layer(void);
#endif /* DESTINY_H */
#endif /* SOCKET_BASE_H */

@ -1,5 +1,13 @@
/*
* Copyright (C) 2014 Freie Universität Berlin.
*
* 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.
*/
/**
* destiny/in.h - Constants defined by the internet system, per RFC 790,
* socket_base/in.h - Constants defined by the internet system, per RFC 790,
* September 1981, and numerous additions, inspired by
* netinet/in.h definitions.
* @{
@ -18,8 +26,8 @@
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef DESTINY_IN_H
#define DESTINY_IN_H
#ifndef SOCKET_BASE_IN_H
#define SOCKET_BASE_IN_H
/*
* Protocols (RFC 1700) TODO: may be deleted due to some double definition
@ -141,4 +149,4 @@
#define IN_LOOPBACKNET (127) ///< official!
#endif /* DESTINY_IN_H */
#endif /* SOCKET_BASE_IN_H */

@ -1,5 +1,5 @@
/**
* destiny/socket.h - Destiny socket API
* socket_base/socket.h - Transport Layer socket API
*
* Copyright (C) 2013 INRIA.
*
@ -7,7 +7,7 @@
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* @ingroup destiny
* @ingroup socket_base
* @{
* @file
* @brief Header for BSD socket API
@ -19,14 +19,14 @@
*/
#ifndef DESTINY_SOCKET_H
#define DESTINY_SOCKET_H
#ifndef SOCKET_BASE_SOCKET_H
#define SOCKET_BASE_SOCKET_H
#include <stdint.h>
#include "ipv6.h"
#include "destiny/in.h"
#include "socket_base/in.h"
typedef uint8_t sa_family_t; ///< POSIX compatible type for address family.
typedef uint32_t socklen_t; ///< POSIX compatible type for address length.
@ -159,17 +159,17 @@ typedef uint32_t socklen_t; ///< POSIX compatible type for address length.
#define PF_MAX AF_MAX ///< maximum of protocol families
///< @see AF_MAX
#define DESTINY_SOCKET_STATIC_MSS 48 ///< Static TCP maxmimum segment size.
#define TRANSPORT_LAYER_SOCKET_STATIC_MSS 48 ///< Static TCP maxmimum segment size.
/**
* Static TCP flow control window for window size 1.
*/
#define DESTINY_SOCKET_STATIC_WINDOW 1 * DESTINY_SOCKET_STATIC_MSS
#define TRANSPORT_LAYER_SOCKET_STATIC_WINDOW 1 * TRANSPORT_LAYER_SOCKET_STATIC_MSS
/**
* Maximum size of TCP buffer.
*/
#define DESTINY_SOCKET_MAX_TCP_BUFFER 1 * DESTINY_SOCKET_STATIC_WINDOW
#define TRANSPORT_LAYER_SOCKET_MAX_TCP_BUFFER 1 * TRANSPORT_LAYER_SOCKET_STATIC_WINDOW
/**
* Socket address type for IPv6 communication.
@ -194,7 +194,7 @@ typedef struct __attribute__((packed)) {
* imply IPPROTO_TCP, etc.)
* @return Socket ID on success, -1 otherwise.
*/
int destiny_socket(int domain, int type, int protocol);
int socket_base_socket(int domain, int type, int protocol);
/**
* Connects socket *socket* with a foreign host with IPv6 address *addr*
@ -208,7 +208,7 @@ int destiny_socket(int domain, int type, int protocol);
*
* @return 0 on success, -1 otherwise
*/
int destiny_socket_connect(int socket, sockaddr6_t *addr,
int socket_base_connect(int socket, sockaddr6_t *addr,
socklen_t addrlen);
/**
@ -223,7 +223,7 @@ int destiny_socket_connect(int socket, sockaddr6_t *addr,
*
* @return Number of received bytes, -1 on error.
*/
int32_t destiny_socket_recv(int s, void *buf, uint32_t len, int flags);
int32_t socket_base_recv(int s, void *buf, uint32_t len, int flags);
/**
* Receives data through socket *s* and saves it in buffer *buf*. The address
@ -240,7 +240,7 @@ int32_t destiny_socket_recv(int s, void *buf, uint32_t len, int flags);
*
* @return Number of received bytes, -1 on error.
*/
int32_t destiny_socket_recvfrom(int s, void *buf, uint32_t len, int flags,
int32_t socket_base_recvfrom(int s, void *buf, uint32_t len, int flags,
sockaddr6_t *from, socklen_t *fromlen);
/**
@ -255,7 +255,7 @@ int32_t destiny_socket_recvfrom(int s, void *buf, uint32_t len, int flags,
*
* @return Number of send bytes, -1 on error.
*/
int32_t destiny_socket_send(int s, const void *buf, uint32_t len, int flags);
int32_t socket_base_send(int s, const void *buf, uint32_t len, int flags);
/**
* Sends data *buf* through socket *s* to foreign host with IPv6 address *addr*.
@ -271,7 +271,7 @@ int32_t destiny_socket_send(int s, const void *buf, uint32_t len, int flags);
*
* @return Number of send bytes, -1 on error.
*/
int32_t destiny_socket_sendto(int s, const void *buf, uint32_t len, int flags,
int32_t socket_base_sendto(int s, const void *buf, uint32_t len, int flags,
sockaddr6_t *to, socklen_t tolen);
/**
@ -281,7 +281,7 @@ int32_t destiny_socket_sendto(int s, const void *buf, uint32_t len, int flags,
*
* @return 0 on success, -1 otherwise.
*/
int destiny_socket_close(int s);
int socket_base_close(int s);
/**
* Assigns an IPv6 address *addr* to the socket *s*. Roughly identical to
@ -293,7 +293,7 @@ int destiny_socket_close(int s);
*
* @return 0 on success, -1 otherwise.
*/
int destiny_socket_bind(int s, sockaddr6_t *addr, int addrlen);
int socket_base_bind(int s, sockaddr6_t *addr, int addrlen);
/**
* Marks socket *s* as an passive socket, that listens for incoming messages.
@ -304,7 +304,7 @@ int destiny_socket_bind(int s, sockaddr6_t *addr, int addrlen);
*
* @return 0 on success, -1 otherwise.
*/
int destiny_socket_listen(int s, int backlog);
int socket_base_listen(int s, int backlog);
/**
* Blocks the current thread and waits for incoming communication on the listening
@ -318,16 +318,16 @@ int destiny_socket_listen(int s, int backlog);
*
* @return New socket ID for communication. -1 on error.
*/
int destiny_socket_accept(int s, sockaddr6_t *addr, socklen_t *addrlen);
int socket_base_accept(int s, sockaddr6_t *addr, socklen_t *addrlen);
/**
* Outputs a list of all open sockets to stdout. Information includes its
* creation parameters, local and foreign address and ports, it's ID and the
* PIDs of the send and receive thread.
*/
void destiny_socket_print_sockets(void);
void socket_base_print_sockets(void);
/**
* @}
*/
#endif /* DESTINY_SOCKET_H */
#endif /* SOCKET_BASE_SOCKET_H */

@ -1,5 +1,5 @@
/**
* Destiny types header
* Transport Layer types header
*
* Copyright (C) 2013 INRIA.
*
@ -7,15 +7,15 @@
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* @ingroup destiny
* @ingroup transport_layer
* @{
* @file
* @brief Destiny types
* @brief Transport Layer types
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef DESTINY_TYPES_H_
#define DESTINY_TYPES_H_
#ifndef SOCKET_BASE_TYPES_H_
#define SOCKET_BASE_TYPES_H_
#include <stdint.h>
/**
@ -73,4 +73,4 @@ typedef struct __attribute__((packed)) {
* @}
*/
#endif /* DESTINY_TYPES_H_ */
#endif /* SOCKET_BASE_TYPES_H_ */

@ -0,0 +1,40 @@
/*
* Copyright (C) 2013, 2014 INRIA.
*
* 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 tcp TCP implementation
* @ingroup net
* @brief This module implements the TCP transport layer protocol.
* This includes an (experimental) 6LoWPAN TCP header ompression.
* @see <a href="http://tools.ietf.org/html/draft-aayadi-6lowpan-tcphc-01">
* RFC draft-aayadi-6lowpan-tcphc-01 - TCP header compression for
* 6LoWPAN
* </a>
* @{
* @file
* @brief tcp functions
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @author Cenk Gündoğan <cnkgndgn@gmail.com>
*/
#ifndef TCP_H
#define TCP_H
#include "socket_base/in.h"
#include "socket_base/socket.h"
#include "socket_base/types.h"
/**
* Initializes tcp.
*
* @return 0 on success, other else.
*/
int tcp_init_transport_layer(void);
#endif /* TCP_H */

@ -0,0 +1,40 @@
/*
* Copyright (C) 2013, 2014 INRIA.
*
* 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 tcp UDP implementation
* @ingroup net
* @brief This module implements the transport layer protocol UDP.
* This includes 6LoWPAN UDP header compression.
* @see <a href="http://tools.ietf.org/html/rfc6282#section-4.3">
* RFC 6282 - Compression Format for IPv6 Datagrams over
* IEEE 802.15.4-Based Networks - UDP Header Compression
* </a>
* @{
* @file
* @brief udp functions
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @author Cenk Gündoğan <cnkgndgn@gmail.com>
*/
#ifndef UDP_H
#define UDP_H
#include "socket_base/in.h"
#include "socket_base/socket.h"
#include "socket_base/types.h"
/**
* Initializes udp.
*
* @return 0 on success, other else.
*/
int udp_init_transport_layer(void);
#endif /* UDP_H */

@ -43,7 +43,7 @@
#include "icmp.h"
#include "ieee802154_frame.h"
#include "destiny/in.h"
#include "socket_base/in.h"
#include "net_help.h"
#define ENABLE_DEBUG (0)

@ -1,81 +0,0 @@
/**
* Destiny transport layer implementation
*
* Copyright (C) 2013 INRIA.
*
* 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.
*
* @ingroup destiny
* @{
* @file destiny.c
* @brief transpor layer functions
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @}
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "thread.h"
#include "destiny.h"
#include "vtimer.h"
#include "socket.h"
#include "tcp.h"
#include "tcp_timer.h"
#include "udp.h"
char tcp_stack_buffer[TCP_STACK_SIZE];
char udp_stack_buffer[UDP_STACK_SIZE];
char tcp_timer_stack[TCP_TIMER_STACKSIZE];
int destiny_init_transport_layer(void)
{
printf("Initializing transport layer packages. Size of socket_type: %u\n",
(unsigned int) sizeof(socket_internal_t));
/* SOCKETS */
memset(sockets, 0, MAX_SOCKETS * sizeof(socket_internal_t));
/* UDP */
kernel_pid_t udp_thread_pid = thread_create(udp_stack_buffer, UDP_STACK_SIZE,
PRIORITY_MAIN, CREATE_STACKTEST,
udp_packet_handler, NULL, "udp_packet_handler");
if (udp_thread_pid == KERNEL_PID_UNDEF) {
return -1;
}
ipv6_register_next_header_handler(IPV6_PROTO_NUM_UDP, udp_thread_pid);
/* TCP */
timex_t now;
vtimer_now(&now);
srand(timex_uint64(now));
#ifdef TCP_HC
printf("TCP_HC enabled!\n");
global_context_counter = rand();
#endif
global_sequence_counter = rand();
kernel_pid_t tcp_thread_pid = thread_create(tcp_stack_buffer, TCP_STACK_SIZE,
PRIORITY_MAIN, CREATE_STACKTEST,
tcp_packet_handler, NULL, "tcp_packet_handler");
if (tcp_thread_pid == KERNEL_PID_UNDEF) {
return -1;
}
ipv6_register_next_header_handler(IPV6_PROTO_NUM_TCP, tcp_thread_pid);
if (thread_create(tcp_timer_stack, TCP_TIMER_STACKSIZE, PRIORITY_MAIN + 1,
CREATE_STACKTEST, tcp_general_timer, NULL, "tcp_general_timer") < 0) {
return -1;
}
return 0;
}

@ -1,412 +0,0 @@
/**
* Destiny TCP implementation
*
* Copyright (C) 2013 INRIA.
*
* 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.
*
* @ingroup destiny
* @{
* @file tcp.c
* @brief TCP implementation
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @}
*/
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sixlowpan.h"
#include "thread.h"
#include "vtimer.h"
#include "destiny/in.h"
#include "net_help.h"
#include "msg_help.h"
#include "socket.h"
#include "tcp_hc.h"
#include "tcp_timer.h"
#include "tcp.h"
#ifdef TCP_HC
mutex_t global_context_counter_mutex;
uint8_t global_context_counter;
#endif
mutex_t global_sequence_counter_mutex;
uint32_t global_sequence_counter;
void printTCPHeader(tcp_hdr_t *tcp_header)
{
printf("\nBEGIN: TCP HEADER\n");
printf("ack_nr: %" PRIu32 "\n", tcp_header->ack_nr);
printf("checksum: %i\n", tcp_header->checksum);
printf("data_offset: %i\n", tcp_header->data_offset);
printf("dst_port: %i\n", tcp_header->dst_port);
printf("reserved_flags: %i\n", tcp_header->reserved_flags);
printf("seq_nr: %" PRIu32 "\n", tcp_header->seq_nr);
printf("src_port: %i\n", tcp_header->src_port);
printf("urg_pointer: %i\n", tcp_header->urg_pointer);
printf("window: %i\n", tcp_header->window);
printf("END: TCP HEADER\n");
}
void printArrayRange_tcp(uint8_t *udp_header, uint16_t len)
{
int i = 0;
printf("-------------MEMORY-------------\n");
for (i = 0; i < len; i++) {
printf("%#x ", *(udp_header + i));
}
printf("-------------MEMORY-------------\n");
}
uint16_t tcp_csum(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header)
{
uint16_t sum;
uint16_t len = NTOHS(ipv6_header->length);
sum = len + IPPROTO_TCP;
sum = csum(sum, (uint8_t *)&ipv6_header->srcaddr, 2 * sizeof(ipv6_addr_t));
sum = csum(sum, (uint8_t *)tcp_header, len);
return (sum == 0) ? 0xffff : HTONS(sum);
}
uint8_t handle_payload(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
socket_internal_t *tcp_socket, uint8_t *payload)
{
(void) tcp_header;
msg_t m_send_tcp, m_recv_tcp;
uint8_t tcp_payload_len = NTOHS(ipv6_header->length) - TCP_HDR_LEN;
uint8_t acknowledged_bytes = 0;
if (tcp_payload_len > tcp_socket->socket_values.tcp_control.rcv_wnd) {
mutex_lock(&tcp_socket->tcp_buffer_mutex);
memcpy(tcp_socket->tcp_input_buffer, payload,
tcp_socket->socket_values.tcp_control.rcv_wnd);
acknowledged_bytes = tcp_socket->socket_values.tcp_control.rcv_wnd;
tcp_socket->socket_values.tcp_control.rcv_wnd = 0;
tcp_socket->tcp_input_buffer_end = tcp_socket->tcp_input_buffer_end +
tcp_socket->socket_values.tcp_control.rcv_wnd;
mutex_unlock(&tcp_socket->tcp_buffer_mutex);
}
else {
mutex_lock(&tcp_socket->tcp_buffer_mutex);
memcpy(tcp_socket->tcp_input_buffer, payload, tcp_payload_len);
tcp_socket->socket_values.tcp_control.rcv_wnd =
tcp_socket->socket_values.tcp_control.rcv_wnd - tcp_payload_len;
acknowledged_bytes = tcp_payload_len;
tcp_socket->tcp_input_buffer_end = tcp_socket->tcp_input_buffer_end +
tcp_payload_len;
mutex_unlock(&tcp_socket->tcp_buffer_mutex);
}
if (thread_getstatus(tcp_socket->recv_pid) == STATUS_RECEIVE_BLOCKED) {
net_msg_send_recv(&m_send_tcp, &m_recv_tcp, tcp_socket->recv_pid, UNDEFINED);
}
return acknowledged_bytes;
}
void handle_tcp_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
socket_internal_t *tcp_socket)
{
msg_t m_recv_tcp, m_send_tcp;
kernel_pid_t target_pid = KERNEL_PID_UNDEF;
if (tcp_socket->socket_values.tcp_control.state == TCP_LAST_ACK) {
target_pid = tcp_socket->recv_pid;
close_socket(tcp_socket);
msg_send(&m_send_tcp, target_pid, 0);
return;
}
else if (tcp_socket->socket_values.tcp_control.state == TCP_CLOSING) {
msg_send(&m_send_tcp, tcp_socket->recv_pid, 0);
msg_send(&m_send_tcp, tcp_socket->send_pid, 0);
return;
}
else if (get_waiting_connection_socket(tcp_socket->socket_id, ipv6_header,
tcp_header) != NULL) {
m_send_tcp.content.ptr = (char *)tcp_header;
net_msg_send_recv(&m_send_tcp, &m_recv_tcp, tcp_socket->recv_pid, TCP_ACK);
return;
}
else if (tcp_socket->socket_values.tcp_control.state == TCP_ESTABLISHED) {
if (check_tcp_consistency(&tcp_socket->socket_values, tcp_header, 0) == PACKET_OK) {
m_send_tcp.content.ptr = (char *)tcp_header;
net_msg_send(&m_send_tcp, tcp_socket->send_pid, 0, TCP_ACK);
return;
}
}
printf("NO WAY OF HANDLING THIS ACK!\n");
}
void handle_tcp_rst_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
socket_internal_t *tcp_socket)
{
(void) ipv6_header;
(void) tcp_header;
(void) tcp_socket;
/* TODO: Reset connection */
}
void handle_tcp_syn_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
socket_internal_t *tcp_socket)
{
msg_t m_send_tcp;
if (tcp_socket->socket_values.tcp_control.state == TCP_LISTEN) {
socket_internal_t *new_socket = new_tcp_queued_socket(ipv6_header,
tcp_header);
if (new_socket != NULL) {
#ifdef TCP_HC
update_tcp_hc_context(true, new_socket, tcp_header);
#endif
/* notify socket function destiny_socket_accept(..) that a new
* connection request has arrived. No need to wait for an answer
* because the server destiny_socket_accept() function isnt reading
* from anything other than the queued sockets */
net_msg_send(&m_send_tcp, tcp_socket->recv_pid, 0, TCP_SYN);
}
else {
printf("Dropped TCP SYN Message because an error occured while "\
"requesting a new queued socket!\n");
}
}
else {
printf("Dropped TCP SYN Message because socket was not in state TCP_LISTEN!");
}
}
void handle_tcp_syn_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
socket_internal_t *tcp_socket)
{
(void) ipv6_header;
msg_t m_send_tcp;
if (tcp_socket->socket_values.tcp_control.state == TCP_SYN_SENT) {
m_send_tcp.content.ptr = (char *) tcp_header;
net_msg_send(&m_send_tcp, tcp_socket->recv_pid, 0, TCP_SYN_ACK);
}
else {
printf("Socket not in state TCP_SYN_SENT, dropping SYN-ACK-packet!");
}
}
void handle_tcp_fin_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
socket_internal_t *tcp_socket)
{
(void) ipv6_header;
msg_t m_send;
socket_t *current_tcp_socket = &tcp_socket->socket_values;
uint8_t send_buffer[BUFFER_SIZE];
ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer));
tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN]));
set_tcp_cb(&current_tcp_socket->tcp_control, tcp_header->seq_nr + 1,
current_tcp_socket->tcp_control.send_wnd, tcp_header->ack_nr + 1,
tcp_header->ack_nr, tcp_header->window);
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
#endif
if (current_tcp_socket->tcp_control.state == TCP_FIN_WAIT_1) {
current_tcp_socket->tcp_control.state = TCP_CLOSING;
send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_FIN_ACK, 0);
}
else {
current_tcp_socket->tcp_control.state = TCP_LAST_ACK;
send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_FIN_ACK, 0);
}
net_msg_send(&m_send, tcp_socket->recv_pid, 0, CLOSE_CONN);
}
void handle_tcp_fin_ack_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
socket_internal_t *tcp_socket)
{
(void) ipv6_header;
msg_t m_send;
socket_t *current_tcp_socket = &tcp_socket->socket_values;
uint8_t send_buffer[BUFFER_SIZE];
ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer));
tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN]));
current_tcp_socket->tcp_control.state = TCP_CLOSED;
set_tcp_cb(&current_tcp_socket->tcp_control, tcp_header->seq_nr + 1,
current_tcp_socket->tcp_control.send_wnd, tcp_header->ack_nr,
tcp_header->ack_nr, tcp_header->window);
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
#endif
send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0);
msg_send(&m_send, tcp_socket->send_pid, 0);
msg_send(&m_send, tcp_socket->recv_pid, 0);
}
void handle_tcp_no_flags_packet(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header,
socket_internal_t *tcp_socket, uint8_t *payload, uint8_t tcp_payload_len)
{
uint8_t read_bytes = 0;
socket_t *current_tcp_socket = &tcp_socket->socket_values;
uint8_t send_buffer[BUFFER_SIZE];
ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer));
tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN]));
if (check_tcp_consistency(current_tcp_socket, tcp_header, tcp_payload_len) == PACKET_OK) {
read_bytes = handle_payload(ipv6_header, tcp_header, tcp_socket, payload);
/* Refresh TCP status values */
current_tcp_socket->tcp_control.state = TCP_ESTABLISHED;
set_tcp_cb(&current_tcp_socket->tcp_control,
tcp_header->seq_nr + read_bytes,
current_tcp_socket->tcp_control.rcv_wnd,
current_tcp_socket->tcp_control.send_nxt,
current_tcp_socket->tcp_control.send_una,
current_tcp_socket->tcp_control.send_wnd);
/* Send packet */
// block_continue_thread();
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_HEADER;
#endif
send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0);
}
/* ACK packet probably got lost */
else {
// block_continue_thread();
#ifdef TCP_HC
current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER;
#endif
send_tcp(tcp_socket, current_tcp_packet, temp_ipv6_header, TCP_ACK, 0);
}
}
void *tcp_packet_handler(void *arg)
{
(void) arg;
msg_t m_recv_ip, m_send_ip;
ipv6_hdr_t *ipv6_header;
tcp_hdr_t *tcp_header;
uint8_t *payload;
socket_internal_t *tcp_socket = NULL;
uint16_t chksum;
while (1) {
msg_receive(&m_recv_ip);
ipv6_header = ((ipv6_hdr_t *)m_recv_ip.content.ptr);
tcp_header = ((tcp_hdr_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN));
#ifdef TCP_HC
tcp_socket = decompress_tcp_packet(ipv6_header);
#else
switch_tcp_packet_byte_order(tcp_header);
tcp_socket = get_tcp_socket(ipv6_header, tcp_header);
#endif
chksum = tcp_csum(ipv6_header, tcp_header);
payload = (uint8_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN + tcp_header->data_offset * 4);
if ((chksum == 0xffff) && (tcp_socket != NULL)) {
#ifdef TCP_HC
update_tcp_hc_context(true, tcp_socket, tcp_header);
#endif
/* Remove reserved bits from tcp flags field */
uint8_t tcp_flags = tcp_header->reserved_flags;
switch (tcp_flags) {
case TCP_ACK: {
/* only ACK Bit set */
uint8_t tcp_payload_len = NTOHS(ipv6_header->length) - TCP_HDR_LEN;
uint8_t state = tcp_socket->socket_values.tcp_control.state;
if ((tcp_payload_len > 0) && (state == TCP_ESTABLISHED)) {
/* handle data segments only when the connection was established successfully */
handle_tcp_no_flags_packet(ipv6_header, tcp_header, tcp_socket, payload, tcp_payload_len);
}
else if (tcp_payload_len == 0
&& (state == TCP_ESTABLISHED || state == TCP_SYN_RCVD
|| state == TCP_CLOSING || state == TCP_LAST_ACK)) {
/* no payload, acknowledging data only */
handle_tcp_ack_packet(ipv6_header, tcp_header, tcp_socket);
}
break;
}
case TCP_RST: {
printf("RST Bit set!\n");
/* only RST Bit set */
handle_tcp_rst_packet(ipv6_header, tcp_header, tcp_socket);
break;
}
case TCP_SYN: {
/* only SYN Bit set, look for matching, listening socket
* and request new queued socket */
printf("SYN Bit set!\n");
handle_tcp_syn_packet(ipv6_header, tcp_header, tcp_socket);
break;
}
case TCP_SYN_ACK: {
/* only SYN and ACK Bit set, complete three way handshake
* when socket in state TCP_SYN_SENT */
handle_tcp_syn_ack_packet(ipv6_header, tcp_header, tcp_socket);
break;
}
case TCP_FIN_ACK: {
if (tcp_socket->socket_values.tcp_control.state == TCP_ESTABLISHED) {
/* this is the first FIN */
printf("FIN ACK Bit set!\n");
handle_tcp_fin_packet(ipv6_header, tcp_header, tcp_socket);
}
else {
/* this is the response to FIN */
handle_tcp_fin_ack_packet(ipv6_header, tcp_header, tcp_socket);
}
break;
}
default: {
printf("Unable to process the incoming segment!\n");
}
}
}
else {
printf("Wrong checksum (%x) or no corresponding socket found!\n",
chksum);
printArrayRange(((uint8_t *)ipv6_header), IPV6_HDR_LEN +
NTOHS(ipv6_header->length), "Incoming");
print_tcp_status(INC_PACKET, ipv6_header, tcp_header,
&tcp_socket->socket_values);
}
msg_reply(&m_recv_ip, &m_send_ip);
}
}

@ -1,84 +0,0 @@
/**
* Destiny UDP implementation
*
* Copyright (C) 2013 INRIA.
*
* 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.
*
* @ingroup destiny
* @{
* @file udp.c
* @brief UDP implementation
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @}
*/
#include <stdio.h>
#include <string.h>
#include "ipv6.h"
#include "msg.h"
#include "sixlowpan.h"
#include "thread.h"
#include "destiny/in.h"
#include "net_help.h"
#include "msg_help.h"
#include "socket.h"
#include "udp.h"
msg_t udp_msg_queue[UDP_PKT_RECV_BUF_SIZE];
uint16_t udp_csum(ipv6_hdr_t *ipv6_header, udp_hdr_t *udp_header)
{
uint16_t sum;
uint16_t len = NTOHS(udp_header->length);
sum = len + IPPROTO_UDP;
sum = csum(sum, (uint8_t *)&ipv6_header->srcaddr, 2 * sizeof(ipv6_addr_t));
sum = csum(sum, (uint8_t *)udp_header, len);
return (sum == 0) ? 0xffff : HTONS(sum);
}
void *udp_packet_handler(void *arg)
{
(void) arg;
msg_t m_recv_ip, m_send_ip, m_recv_udp, m_send_udp;
ipv6_hdr_t *ipv6_header;
udp_hdr_t *udp_header;
socket_internal_t *udp_socket = NULL;
uint16_t chksum;
msg_init_queue(udp_msg_queue, UDP_PKT_RECV_BUF_SIZE);
while (1) {
msg_receive(&m_recv_ip);
ipv6_header = ((ipv6_hdr_t *)m_recv_ip.content.ptr);
udp_header = ((udp_hdr_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN));
chksum = ipv6_csum(ipv6_header, (uint8_t*) udp_header, NTOHS(udp_header->length), IPPROTO_UDP);
if (chksum == 0xffff) {
udp_socket = get_udp_socket(udp_header);
if (udp_socket != NULL) {
m_send_udp.content.ptr = (char *)ipv6_header;
msg_send_receive(&m_send_udp, &m_recv_udp, udp_socket->recv_pid);
}
else {
printf("Dropped UDP Message because no thread ID was found for delivery!\n");
}
}
else {
printf("Wrong checksum (%x)!\n", chksum);
}
msg_reply(&m_recv_ip, &m_send_ip);
}
}

@ -1,34 +0,0 @@
/**
* Destiny TCP header
*
* Copyright (C) 2013 INRIA.
*
* 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.
*
* @ingroup destiny
* @{
* @file
* @brief UDP data structs and prototypes
* @author Oliver Gesch <oliver.gesch@googlemail.com>
*/
#ifndef UDP_H_
#define UDP_H_
#include "ipv6.h"
#include "destiny/types.h"
#define UDP_STACK_SIZE KERNEL_CONF_STACKSIZE_MAIN
#define UDP_PKT_RECV_BUF_SIZE (64)
uint16_t udp_csum(ipv6_hdr_t *ipv6_header, udp_hdr_t *udp_header);
void *udp_packet_handler(void *);
/**
* @}
*/
#endif /* UDP_H_ */

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

@ -17,11 +17,9 @@
#include "thread.h"
#include "tcp_timer.h"
#include "msg_help.h"
void block_continue_thread(void)
void socket_base_block_continue_thread(void)
{
// msg_t recv_m;
// recv_m.type = TCP_NOT_DEFINED;
@ -31,24 +29,24 @@ void block_continue_thread(void)
// }
}
int net_msg_receive(msg_t *m)
int socket_base_net_msg_receive(msg_t *m)
{
return msg_receive(m);
}
int net_msg_reply(msg_t *m, msg_t *reply, uint16_t message)
int socket_base_net_msg_reply(msg_t *m, msg_t *reply, uint16_t message)
{
reply->type = message;
return msg_reply(m, reply);
}
int net_msg_send(msg_t *m, kernel_pid_t pid, bool block, uint16_t message)
int socket_base_net_msg_send(msg_t *m, kernel_pid_t pid, bool block, uint16_t message)
{
m->type = message;
return msg_send(m, pid, block);
}
int net_msg_send_recv(msg_t *m, msg_t *reply, kernel_pid_t pid, uint16_t message)
int socket_base_net_msg_send_recv(msg_t *m, msg_t *reply, kernel_pid_t pid, uint16_t message)
{
m->type = message;
return msg_send_receive(m, reply, pid);;

@ -34,11 +34,11 @@
#define RETURNNOW 4000
void block_continue_thread(void);
int net_msg_receive(msg_t *m);
int net_msg_reply(msg_t *m, msg_t *reply, uint16_t message);
int net_msg_send(msg_t *m, kernel_pid_t pid, bool block, uint16_t message);
int net_msg_send_recv(msg_t *m, msg_t *reply, kernel_pid_t pid, uint16_t message);
void socket_base_block_continue_thread(void);
int socket_base_net_msg_receive(msg_t *m);
int socket_base_net_msg_reply(msg_t *m, msg_t *reply, uint16_t message);
int socket_base_net_msg_send(msg_t *m, kernel_pid_t pid, bool block, uint16_t message);
int socket_base_net_msg_send_recv(msg_t *m, msg_t *reply, kernel_pid_t pid, uint16_t message);
#endif /* MSG_HELP_H_ */
/**

@ -0,0 +1,436 @@
/*
* Copyright (C) 2013, 2014 INRIA.
*
* 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.
*/
/**
* @ingroup socket_base
* @{
* @file socket.c
* @brief functions for BSD socket API, methods return default values and
* will be overwritten by appropriate transport layer protocols.
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @author Cenk Gündoğan <cnkgndgn@gmail.com>
* @}
*/
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hwtimer.h"
#include "ipv6.h"
#include "thread.h"
#include "vtimer.h"
#include "net_help.h"
#include "msg_help.h"
#include "socket.h"
#define EPHEMERAL_PORTS 49152
socket_internal_t socket_base_sockets[MAX_SOCKETS];
int __attribute__((weak)) tcp_connect(int socket, sockaddr6_t *addr, uint32_t addrlen)
{
(void) socket;