Browse Source

transport_layer: Splitting UDP and TCP

Currently, the tcp and udp implementations are bound to each other in a
module called *destiny*. Thus, when using only one of them then the
other one gets also compiled into the binary and initialized,
which results in unnecessary RAM usage and workload for the CPU.

The approach in this PR defines a common module named *socket_base*,
which contains functions used by the posix layer. Compiled by it's own,
those functions return negative error codes, to symbolize upper layers
that they are not supported. When also including the modules *udp* or
*tcp* respectively, functions from *socket_base* get overwritten with the
correct functionality.

Defining *udp* or *tcp* in a Makefile also includes *socket_base*.
Defining *pnet* in a Makefile also includes *socket_base*.
dev/timer
Cenk Gündoğan 9 years ago
parent
commit
710c7e6cf6
  1. 17
      Makefile.dep
  2. 1
      Makefile.pseudomodules
  3. 3
      examples/rpl_udp/Makefile
  4. 2
      examples/rpl_udp/main.c
  5. 4
      examples/rpl_udp/rpl.c
  6. 20
      examples/rpl_udp/udp.c
  7. 2
      pkg/libcoap/0001-Add-RIOT-Makefile.patch
  8. 4
      pkg/oonf_api/0001-add-RIOT-support.patch
  9. 14
      sys/Makefile
  10. 11
      sys/Makefile.include
  11. 19
      sys/auto_init/auto_init.c
  12. 27
      sys/net/include/socket_base.h
  13. 16
      sys/net/include/socket_base/in.h
  14. 40
      sys/net/include/socket_base/socket.h
  15. 12
      sys/net/include/socket_base/types.h
  16. 40
      sys/net/include/tcp.h
  17. 40
      sys/net/include/udp.h
  18. 2
      sys/net/network_layer/sixlowpan/lowpan.c
  19. 0
      sys/net/transport_layer/Makefile
  20. 81
      sys/net/transport_layer/destiny/destiny.c
  21. 412
      sys/net/transport_layer/destiny/tcp.c
  22. 84
      sys/net/transport_layer/destiny/udp.c
  23. 34
      sys/net/transport_layer/destiny/udp.h
  24. 1
      sys/net/transport_layer/socket_base/Makefile
  25. 12
      sys/net/transport_layer/socket_base/msg_help.c
  26. 10
      sys/net/transport_layer/socket_base/msg_help.h
  27. 436
      sys/net/transport_layer/socket_base/socket.c
  28. 70
      sys/net/transport_layer/socket_base/socket.h
  29. 2
      sys/net/transport_layer/tcp/Makefile
  30. 1728
      sys/net/transport_layer/tcp/tcp.c
  31. 21
      sys/net/transport_layer/tcp/tcp.h
  32. 6
      sys/net/transport_layer/tcp/tcp_hc.c
  33. 2
      sys/net/transport_layer/tcp/tcp_hc.h
  34. 21
      sys/net/transport_layer/tcp/tcp_timer.c
  35. 0
      sys/net/transport_layer/tcp/tcp_timer.h
  36. 2
      sys/net/transport_layer/udp/Makefile
  37. 223
      sys/net/transport_layer/udp/udp.c
  38. 38
      sys/net/transport_layer/udp/udp.h
  39. 2
      sys/posix/pnet/include/netinet/in.h
  40. 6
      sys/posix/pnet/include/sys/socket.h
  41. 44
      sys/posix/pnet/sys_socket.c

17
Makefile.dep

@ -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
Makefile.pseudomodules

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

3
examples/rpl_udp/Makefile

@ -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

2
examples/rpl_udp/main.c

@ -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"

4
examples/rpl_udp/rpl.c

@ -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 */
}

20
examples/rpl_udp/udp.c

@ -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);
}

2
pkg/libcoap/0001-Add-RIOT-Makefile.patch

@ -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

4
pkg/oonf_api/0001-add-RIOT-support.patch

@ -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>

14
sys/Makefile

@ -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

11
sys/Makefile.include

@ -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)))

19
sys/auto_init/auto_init.c

@ -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
}

27
sys/net/include/destiny.h → sys/net/include/socket_base.h

@ -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 */

16
sys/net/include/destiny/in.h → sys/net/include/socket_base/in.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 */

40
sys/net/include/destiny/socket.h → sys/net/include/socket_base/socket.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 */

12
sys/net/include/destiny/types.h → sys/net/include/socket_base/types.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_ */

40
sys/net/include/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 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 */

40
sys/net/include/udp.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 */

2
sys/net/network_layer/sixlowpan/lowpan.c

@ -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)

0
sys/net/transport_layer/destiny/Makefile → sys/net/transport_layer/Makefile

81
sys/net/transport_layer/destiny/destiny.c

@ -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;
}

412
sys/net/transport_layer/destiny/tcp.c

@ -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);
}
}

84
sys/net/transport_layer/destiny/udp.c

@ -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);
}
}

34
sys/net/transport_layer/destiny/udp.h

@ -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_ */

1
sys/net/transport_layer/socket_base/Makefile

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

12
sys/net/transport_layer/destiny/msg_help.c → sys/net/transport_layer/socket_base/msg_help.c

@ -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)
{