1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 05:12:57 +01:00

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*.
This commit is contained in:
Cenk Gündoğan 2014-07-31 17:53:46 +02:00
parent c924075722
commit 710c7e6cf6
41 changed files with 1951 additions and 1668 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 Normal file
View File

@ -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 Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
(void) addr;
(void) addrlen;
return -1;
}
int __attribute__((weak)) tcp_listen(int s, int backlog)
{
(void) s;
(void) backlog;
return -1;
}
int __attribute__((weak)) tcp_accept(int s, sockaddr6_t *addr, uint32_t *addrlen)
{
(void) s;
(void) addr;
(void) addrlen;
return -1;
}
int32_t __attribute__((weak)) tcp_send(int s, const void *buf, uint32_t len, int flags)
{
(void) s;
(void) buf;
(void) len;
(void) flags;
return -1;
}
int32_t __attribute__((weak)) tcp_recv(int s, void *buf, uint32_t len, int flags)
{
(void) s;
(void) buf;
(void) len;
(void) flags;
return -1;
}
int32_t __attribute__((weak)) udp_recvfrom(int s, void *buf, uint32_t len, int flags,
sockaddr6_t *from, uint32_t *fromlen)
{
(void) s;
(void) buf;
(void) len;
(void) flags;
(void) from;
(void) fromlen;
return -1;
}
int32_t __attribute__((weak)) udp_sendto(int s, const void *buf, uint32_t len, int flags,
sockaddr6_t *to, uint32_t tolen)
{
(void) s;
(void) buf;
(void) len;
(void) flags;
(void) to;
(void) tolen;
return -1;
}
int __attribute__((weak)) tcp_bind_socket(int s, sockaddr6_t *name, int namelen, uint8_t pid)
{
(void) s;
(void) name;
(void) namelen;
(void) pid;
return -1;
}
int __attribute__((weak)) udp_bind_socket(int s, sockaddr6_t *name, int namelen, uint8_t pid)
{
(void) s;
(void) name;
(void) namelen;
(void) pid;
return -1;
}
bool __attribute__((weak)) tcp_socket_compliancy(int s)
{
(void) s;
return false;
}
bool __attribute__((weak)) udp_socket_compliancy(int s)
{
(void) s;
return false;
}
int __attribute__((weak)) tcp_teardown(socket_internal_t *current_socket)
{
(void) current_socket;
return -1;
}
void socket_base_print_socket(socket_t *current_socket)
{
char addr_str[IPV6_MAX_ADDR_STR_LEN];
printf("Domain: %i, Type: %i, Protocol: %i \n",
current_socket->domain,
current_socket->type,
current_socket->protocol);
printf("Local address: %s\n",
ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
&current_socket->local_address.sin6_addr));
printf("Foreign address: %s\n",
ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
&current_socket->foreign_address.sin6_addr));
printf("Local Port: %u, Foreign Port: %u\n",
NTOHS(current_socket->local_address.sin6_port),
NTOHS(current_socket->foreign_address.sin6_port));
}
void socket_base_print_internal_socket(socket_internal_t *current_socket_internal)
{
socket_t *current_socket = &current_socket_internal->socket_values;
printf("\n--------------------------\n");
printf("ID: %i, RECV PID: %i SEND PID: %i\n",
current_socket_internal->socket_id, current_socket_internal->recv_pid,
current_socket_internal->send_pid);
socket_base_print_socket(current_socket);
printf("\n--------------------------\n");
}
int socket_base_exists_socket(int socket)
{
if (socket_base_sockets[socket - 1].socket_id == 0) {
return false;
}
else {
return true;
}
}
socket_internal_t *socket_base_get_socket(int s)
{
if (socket_base_exists_socket(s)) {
return &(socket_base_sockets[s - 1]);
}
else {
return NULL;
}
}
void socket_base_print_sockets(void)
{
int i;
printf("\n--- Socket list: ---\n");
for (i = 1; i < MAX_SOCKETS + 1; i++) {
if (socket_base_get_socket(i) != NULL) {
socket_base_print_internal_socket(socket_base_get_socket(i));
}
}
}
int socket_base_close(int s)
{
socket_internal_t *current_socket = socket_base_get_socket(s);
if (udp_socket_compliancy(s)) {
memset(current_socket, 0, sizeof(socket_internal_t));
return 0;
}
else if (tcp_socket_compliancy(s)) {
return tcp_teardown(current_socket);
}
printf("Socket Type not supported!\n");
return -1;
}
uint16_t socket_base_get_free_source_port(uint8_t protocol)
{
int i;
uint16_t biggest_port = EPHEMERAL_PORTS - 1;
/* Remember biggest ephemeral port number used so far and add 1 */
for (i = 0; i < MAX_SOCKETS; i++) {
if ((socket_base_sockets[i].socket_values.protocol == protocol) &&
(socket_base_sockets[i].socket_values.local_address.sin6_port > biggest_port)) {
biggest_port = socket_base_sockets[i].socket_values.local_address.sin6_port;
}
}
return biggest_port + 1;
}
int socket_base_socket(int domain, int type, int protocol)
{
int i = 1;
while (socket_base_get_socket(i) != NULL) {
i++;
}
if (i > MAX_SOCKETS + 1) {
return -1;
}
else {
socket_t *current_socket = &socket_base_sockets[i - 1].socket_values;
socket_base_sockets[i - 1].socket_id = i;
current_socket->domain = domain;
current_socket->type = type;
current_socket->protocol = protocol;
#ifdef MODULE_TCP
current_socket->tcp_control.state = 0;
#endif
return socket_base_sockets[i - 1].socket_id;
}
}
int socket_base_connect(int socket, sockaddr6_t *addr, uint32_t addrlen)
{
if (tcp_socket_compliancy(socket)) {
return tcp_connect(socket, addr, addrlen);
}
else {
printf("Socket Type not supported!\n");
}
return -1;
}
int socket_base_accept(int s, sockaddr6_t *addr, uint32_t *addrlen)
{
if (tcp_socket_compliancy(s)) {
return tcp_accept(s, addr, addrlen);
}
printf("Socket Type not supported!\n");
return -1;
}
int socket_base_listen(int s, int backlog)
{
if (tcp_socket_compliancy(s)) {
return tcp_listen(s, backlog);
}
printf("Socket Type not supported!\n");
return -1;
}
int32_t socket_base_recv(int s, void *buf, uint32_t len, int flags)
{
if (tcp_socket_compliancy(s)) {
return tcp_recv(s, buf, len, flags);
}
printf("Socket Type not supported!\n");
return -1;
}
int32_t socket_base_recvfrom(int s, void *buf, uint32_t len, int flags,
sockaddr6_t *from, uint32_t *fromlen)
{
if (udp_socket_compliancy(s)) {
return udp_recvfrom(s, buf, len, flags, from, fromlen);
}
else if (tcp_socket_compliancy(s)) {
return tcp_recv(s, buf, len, flags);
}
printf("Socket Type not supported!\n");
return -1;
}
int32_t socket_base_sendto(int s, const void *buf, uint32_t len, int flags,
sockaddr6_t *to, uint32_t tolen)
{
if (udp_socket_compliancy(s)) {
return udp_sendto(s, buf, len, flags, to, tolen);
}
else if (tcp_socket_compliancy(s)) {
return tcp_send(s, buf, len, flags);
}
else {
printf("Socket Type not supported!\n");
return -1;
}
return -1;
}
int32_t socket_base_send(int s, const void *buf, uint32_t len, int flags)
{
if (tcp_socket_compliancy(s)) {
return tcp_send(s, buf, len, flags);
}
else {
printf("Socket Type not supported!\n");
return -1;
}
return -1;
}
int socket_base_bind(int s, sockaddr6_t *addr, int addrlen)
{
if (socket_base_exists_socket(s)) {
socket_t *current_socket = &socket_base_get_socket(s)->socket_values;
switch (current_socket->domain) {
case (PF_INET): {
/* Not provided */
return -1;
break;
}
case (PF_INET6): {
switch (current_socket->type) {
/* TCP */
case (SOCK_STREAM): {
if ((current_socket->protocol == 0) ||
(current_socket->protocol == IPPROTO_TCP)) {
return tcp_bind_socket(s, addr, addrlen,
thread_getpid());
break;
}
else {
return -1;
break;
}
break;
}
/* UDP */
case (SOCK_DGRAM): {
if ((current_socket->protocol == 0) ||
(current_socket->protocol == IPPROTO_UDP)) {
return udp_bind_socket(s, addr, addrlen,
thread_getpid());
break;
}
else {
return -1;
break;
}
break;
}
case (SOCK_SEQPACKET): {
/* not provided */
return -1;
break;
}
case (SOCK_RAW): {
/* not provided */
return -1;
break;
}
default: {
return -1;
break;
}
}
break;
}
case (PF_UNIX): {
/* Not provided */
return -1;
break;
}
}
}
else {
printf("SOCKET DOES NOT EXIST!\n");
return -1;
}
return -1;
}

View File

@ -1,12 +1,25 @@
#ifndef _DESTINY_SOCKET
#define _DESTINY_SOCKET
/*
* 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.
*/
#ifndef _SOCKET_BASE_SOCKET
#define _SOCKET_BASE_SOCKET
#include "cpu.h"
#include "destiny/socket.h"
#include "socket_base/socket.h"
#include "tcp.h"
#ifdef MODULE_UDP
#include "udp.h"
#endif
#ifdef MODULE_TCP
#include "tcp.h"
#endif
#define MAX_SOCKETS 5
// #define MAX_QUEUED_SOCKETS 2
@ -14,6 +27,7 @@
#define INC_PACKET 0
#define OUT_PACKET 1
#ifdef MODULE_TCP
typedef struct __attribute__((packed)) {
uint16_t context_id;
uint32_t seq_rcv; // Last received packet values
@ -49,47 +63,37 @@ typedef struct __attribute__((packed)) {
tcp_hc_context_t tcp_context;
#endif
} tcp_cb_t;
#endif
typedef struct __attribute__((packed)) {
typedef struct {
uint8_t domain;
uint8_t type;
uint8_t protocol;
#ifdef MODULE_TCP
tcp_cb_t tcp_control;
#endif
sockaddr6_t local_address;
sockaddr6_t foreign_address;
} socket_t;
typedef struct {
uint8_t socket_id;
kernel_pid_t recv_pid;
kernel_pid_t send_pid;
uint8_t recv_pid;
uint8_t send_pid;
socket_t socket_values;
#ifdef MODULE_TCP
uint8_t tcp_input_buffer_end;
mutex_t tcp_buffer_mutex;
socket_t socket_values;
uint8_t tcp_input_buffer[DESTINY_SOCKET_MAX_TCP_BUFFER];
uint8_t tcp_input_buffer[TRANSPORT_LAYER_SOCKET_MAX_TCP_BUFFER];
#endif
} socket_internal_t;
extern socket_internal_t sockets[MAX_SOCKETS];
extern socket_internal_t socket_base_sockets[MAX_SOCKETS];
socket_internal_t *get_waiting_connection_socket(int socket,
ipv6_hdr_t *ipv6_header,
tcp_hdr_t *tcp_header);
void close_socket(socket_internal_t *current_socket);
socket_internal_t *get_socket(int s);
socket_internal_t *get_udp_socket(udp_hdr_t *udp_header);
socket_internal_t *get_tcp_socket(ipv6_hdr_t *ipv6_header,
tcp_hdr_t *tcp_header);
socket_internal_t *new_tcp_queued_socket(ipv6_hdr_t *ipv6_header,
tcp_hdr_t *tcp_header);
void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header,
tcp_hdr_t *tcp_header, socket_t *tcp_socket);
void set_tcp_cb(tcp_cb_t *tcp_control, uint32_t rcv_nxt, uint16_t rcv_wnd,
uint32_t send_nxt, uint32_t send_una, uint16_t send_wnd);
int check_tcp_consistency(socket_t *current_tcp_socket, tcp_hdr_t *tcp_header, uint8_t tcp_payload_len);
void switch_tcp_packet_byte_order(tcp_hdr_t *current_tcp_packet);
int send_tcp(socket_internal_t *current_socket, tcp_hdr_t *current_tcp_packet,
ipv6_hdr_t *temp_ipv6_header, uint8_t flags,
uint8_t payload_length);
bool is_tcp_socket(int s);
socket_internal_t *socket_base_get_socket(int s);
uint16_t socket_base_get_free_source_port(uint8_t protocol);
int socket_base_exists_socket(int socket);
int socket_base_socket(int domain, int type, int protocol);
void socket_base_print_sockets(void);
#endif /* _DESTINY_SOCKET */
#endif /* _SOCKET_BASE_SOCKET */

View File

@ -0,0 +1,2 @@
INCLUDES += -I $(RIOTBASE)/sys/net/transport_layer/socket_base
include $(RIOTBASE)/Makefile.base

View File

@ -1,5 +1,5 @@
/**
* Destiny TCP header
* TCP header
*
* 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 transport_layer
* @{
* @file
* @brief TCP data structs and prototypes
@ -18,7 +18,8 @@
#define TCP_H_
#include "ipv6.h"
#include "destiny/types.h"
#include "socket_base/types.h"
#include "socket.h"
#define TCP_EOO_OPTION (0x00) /* End of option list */
#define TCP_NOP_OPTION (0x01) /* No operation */
@ -96,10 +97,16 @@ extern uint8_t global_context_counter;
extern mutex_t global_sequence_counter_mutex;
extern uint32_t global_sequence_counter;
void *tcp_packet_handler(void *);
uint16_t tcp_csum(ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header);
void printTCPHeader(tcp_hdr_t *tcp_header);
void printArrayRange_tcp(uint8_t *udp_header, uint16_t len);
/* methods usde by socket_base */
int tcp_bind_socket(int s, sockaddr6_t *name, int namelen, uint8_t pid);
bool tcp_socket_compliancy(int s);
int32_t tcp_send(int s, const void *buf, uint32_t len, int flags);
int tcp_accept(int s, sockaddr6_t *addr, socklen_t *addrlen);
int tcp_connect(int socket, sockaddr6_t *addr, uint32_t addrlen);
int tcp_listen(int s, int backlog);
int32_t tcp_recv(int s, void *buf, uint32_t len, int flags);
bool tcp_socket_compliancy(int s);
int tcp_teardown(socket_internal_t *current_socket);
/**
* @}

View File

@ -1,5 +1,5 @@
/**
* Destiny TCP header compression
* TCP header compression
*
* 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 transport_layer
* @{
* @file tcp_hc.c
* @brief TCP HC
@ -37,7 +37,7 @@ socket_internal_t *get_tcp_socket_by_context(ipv6_hdr_t *current_ipv6_header,
socket_internal_t *temp_socket;
for (int i = 1; i < MAX_SOCKETS + 1; i++) {
temp_socket = get_socket(i);
temp_socket = socket_base_get_socket(i);
if ((temp_socket != NULL) &&
ipv6_addr_is_equal(&temp_socket->socket_values.foreign_address.sin6_addr,

View File

@ -16,7 +16,7 @@
#include "sixlowpan.h"
#include "destiny/socket.h"
#include "socket_base/socket.h"
#include "tcp.h"

View File

@ -1,5 +1,5 @@
/**
* Destiny TCP timer implementation
* TCP timer implementation
*
* 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 transport_layer
* @{
* @file tcp_timer.c
* @brief TCP timer
@ -23,11 +23,10 @@
#include "thread.h"
#include "vtimer.h"
#include "destiny.h"
#include "msg_help.h"
#include "socket.h"
#include "tcp.h"
#include "tcp_timer.h"
void handle_synchro_timeout(socket_internal_t *current_socket)
@ -41,7 +40,7 @@ void handle_synchro_timeout(socket_internal_t *current_socket)
if ((current_socket->socket_values.tcp_control.no_of_retries == 0) &&
(timex_uint64(timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time)) > TCP_SYN_INITIAL_TIMEOUT)) {
current_socket->socket_values.tcp_control.no_of_retries++;
net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY);
socket_base_net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY);
}
else if ((current_socket->socket_values.tcp_control.no_of_retries > 0) &&
(timex_uint64(timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time)) >
@ -51,10 +50,10 @@ void handle_synchro_timeout(socket_internal_t *current_socket)
if (current_socket->socket_values.tcp_control.no_of_retries >
TCP_MAX_SYN_RETRIES) {
net_msg_send(&send, current_socket->recv_pid, 0, TCP_TIMEOUT);
socket_base_net_msg_send(&send, current_socket->recv_pid, 0, TCP_TIMEOUT);
}
else {
net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY);
socket_base_net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY);
}
}
}
@ -83,12 +82,12 @@ void handle_established(socket_internal_t *current_socket)
vtimer_now(&now);
if (current_timeout > TCP_ACK_MAX_TIMEOUT) {
net_msg_send(&send, current_socket->send_pid, 0, TCP_TIMEOUT);
socket_base_net_msg_send(&send, current_socket->send_pid, 0, TCP_TIMEOUT);
}
else if (timex_uint64(timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time)) >
current_timeout) {
current_socket->socket_values.tcp_control.no_of_retries++;
net_msg_send(&send, current_socket->send_pid, 0, TCP_RETRY);
socket_base_net_msg_send(&send, current_socket->send_pid, 0, TCP_RETRY);
}
}
}
@ -99,9 +98,9 @@ void check_sockets(void)
uint8_t i = 1;
while (i < MAX_SOCKETS + 1) {
current_socket = get_socket(i);
current_socket = socket_base_get_socket(i);
if (is_tcp_socket(i)) {
if (tcp_socket_compliancy(i)) {
switch (current_socket->socket_values.tcp_control.state) {
case TCP_ESTABLISHED: {
handle_established(current_socket);

View File

@ -0,0 +1,2 @@
INCLUDES += -I $(RIOTBASE)/sys/net/transport_layer/socket_base
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,223 @@
/*
* 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 udp
* @{
* @file udp.c
* @brief UDP implementation
* @author Oliver Gesch <oliver.gesch@googlemail.com>
* @author Cenk Gündoğan <cnkgndgn@gmail.com>
* @}
*/
#include <stdio.h>
#include <string.h>
#include "ipv6.h"
#include "msg.h"
#include "sixlowpan.h"
#include "thread.h"
#include "socket_base/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];
char udp_stack_buffer[UDP_STACK_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);
}
socket_internal_t *get_udp_socket(udp_hdr_t *udp_header)
{
uint8_t i = 1;
while (i < MAX_SOCKETS + 1) {
if (udp_socket_compliancy(i) &&
(socket_base_get_socket(i)->socket_values.local_address.sin6_port ==
udp_header->dst_port)) {
return socket_base_get_socket(i);
}
i++;
}
return NULL;
}
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);
}
}
bool udp_socket_compliancy(int s)
{
if ((socket_base_exists_socket(s)) &&
(socket_base_get_socket(s)->socket_values.domain == PF_INET6) &&
(socket_base_get_socket(s)->socket_values.type == SOCK_DGRAM) &&
((socket_base_get_socket(s)->socket_values.protocol == IPPROTO_UDP) ||
(socket_base_get_socket(s)->socket_values.protocol == 0))) {
return true;
}
else {
return false;
}
}
int udp_bind_socket(int s, sockaddr6_t *name, int namelen, uint8_t pid)
{
int i;
if (!socket_base_exists_socket(s)) {
return -1;
}
for (i = 1; i < MAX_SOCKETS + 1; i++) {
if (udp_socket_compliancy(i) &&
(socket_base_get_socket(i)->socket_values.local_address.sin6_port == name->sin6_port)) {
return -1;
}
}
memcpy(&socket_base_get_socket(s)->socket_values.local_address, name, namelen);
socket_base_get_socket(s)->recv_pid = pid;
return 0;
}
int32_t udp_recvfrom(int s, void *buf, uint32_t len, int flags, sockaddr6_t *from, uint32_t *fromlen)
{
(void) flags;
msg_t m_recv, m_send;
ipv6_hdr_t *ipv6_header;
udp_hdr_t *udp_header;
uint8_t *payload;
socket_base_get_socket(s)->recv_pid = thread_getpid();
msg_receive(&m_recv);
ipv6_header = ((ipv6_hdr_t *)m_recv.content.ptr);
udp_header = ((udp_hdr_t *)(m_recv.content.ptr + IPV6_HDR_LEN));
payload = (uint8_t *)(m_recv.content.ptr + IPV6_HDR_LEN + UDP_HDR_LEN);
memset(buf, 0, len);
memcpy(buf, payload, NTOHS(udp_header->length) - UDP_HDR_LEN);
memcpy(&from->sin6_addr, &ipv6_header->srcaddr, 16);
from->sin6_family = AF_INET6;
from->sin6_flowinfo = 0;
from->sin6_port = NTOHS(udp_header->src_port);
*fromlen = sizeof(sockaddr6_t);
msg_reply(&m_recv, &m_send);
return NTOHS(udp_header->length) - UDP_HDR_LEN;
}
int32_t udp_sendto(int s, const void *buf, uint32_t len, int flags,
sockaddr6_t *to, uint32_t tolen)
{
(void) flags;
(void) tolen;
if (udp_socket_compliancy(s) &&
(socket_base_get_socket(s)->socket_values.foreign_address.sin6_port == 0)) {
uint8_t send_buffer[BUFFER_SIZE];
ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer));
udp_hdr_t *current_udp_packet = ((udp_hdr_t *)(&send_buffer[IPV6_HDR_LEN]));
uint8_t *payload = &send_buffer[IPV6_HDR_LEN + UDP_HDR_LEN];
memcpy(&(temp_ipv6_header->destaddr), &to->sin6_addr, 16);
ipv6_net_if_get_best_src_addr(&(temp_ipv6_header->srcaddr), &(temp_ipv6_header->destaddr));
current_udp_packet->src_port = socket_base_get_free_source_port(IPPROTO_UDP);
current_udp_packet->dst_port = to->sin6_port;
current_udp_packet->checksum = 0;
memcpy(payload, buf, len);
current_udp_packet->length = HTONS(UDP_HDR_LEN + len);
temp_ipv6_header->length = UDP_HDR_LEN + len;
current_udp_packet->checksum = ~ipv6_csum(temp_ipv6_header,
(uint8_t *) current_udp_packet,
UDP_HDR_LEN + len,
IPPROTO_UDP);
return ipv6_sendto(&to->sin6_addr, IPPROTO_UDP,
(uint8_t *)(current_udp_packet),
NTOHS(current_udp_packet->length));
}
else {
return -1;
}
}
int udp_init_transport_layer(void)
{
printf("Initializing transport layer protocol: udp\n");
/* SOCKETS */
memset(socket_base_sockets, 0, MAX_SOCKETS * sizeof(socket_internal_t));
int 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 < 0) {
return -1;
}
ipv6_register_next_header_handler(IPV6_PROTO_NUM_UDP, udp_thread_pid);
return 0;
}

View File

@ -0,0 +1,38 @@
/**
* UDP 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 transport_layer
* @{
* @file
* @brief UDP data structs and prototypes
* @author Oliver Gesch <oliver.gesch@googlemail.com>
*/
#ifndef UDP_H_
#define UDP_H_
#include "ipv6.h"
#include "socket_base/types.h"
#define UDP_STACK_SIZE KERNEL_CONF_STACKSIZE_MAIN
#define UDP_PKT_RECV_BUF_SIZE (64)
int udp_bind_socket(int s, sockaddr6_t *name, int namelen, uint8_t pid);
int32_t udp_recvfrom(int s, void *buf, uint32_t len, int flags, sockaddr6_t *from, uint32_t *fromlen);
int32_t udp_sendto(int s, const void *buf, uint32_t len, int flags, sockaddr6_t *to, uint32_t tolen);
bool udp_socket_compliancy(int s);
int32_t udp_recvfrom(int s, void *buf, uint32_t len, int flags, sockaddr6_t *from, uint32_t *fromlen);
int32_t udp_sendto(int s, const void *buf, uint32_t len, int flags, sockaddr6_t *to, socklen_t tolen);
/**
* @}
*/
#endif /* UDP_H_ */

View File

@ -27,7 +27,7 @@
#include <sys/socket.h>
#include <arpa/inet.h>
#include "ipv6.h"
#include "destiny/socket.h"
#include "socket_base/socket.h"
/**
* IPv4 socket address type.

View File

@ -36,7 +36,7 @@
#include "cpu.h"
#include "destiny/socket.h"
#include "socket_base/socket.h"
/**
* @brief Used to define the socket address.
@ -449,10 +449,10 @@ int setsockopt(int socket, int level, int option_name, const void *option_value,
*
* @param[in] domain Specifies the communications domain in which a socket
* is to be created. Valid values are prefixed with ``AF_`
* and defined in @ref destiny/socket.h.
* and defined in @ref transport_layer/socket.h.
* @param[in] type Specifies the type of socket to be created. Valued
* values are prefixed with ``SOCK_`` and defined in
* @ref destiny/socket.h.
* @ref transport_layer/socket.h.
* @param[in] protocol Specifies a particular protocol to be used with the
* socket. Specifying a protocol of 0 causes socket() to
* use an unspecified default protocol appropriate for

View File

@ -14,24 +14,24 @@
*/
#include <errno.h>
#include "destiny/socket.h"
#include "socket_base/socket.h"
#include "fd.h"
#include "sys/socket.h"
int flagless_send(int fd, const void *buf, size_t len)
{
return (int)destiny_socket_send(fd, buf, (uint32_t)len, 0);
return (int)socket_base_send(fd, buf, (uint32_t)len, 0);
}
int flagless_recv(int fd, void *buf, size_t len)
{
return (int)destiny_socket_recv(fd, buf, (uint32_t)len, 0);
return (int)socket_base_recv(fd, buf, (uint32_t)len, 0);
}
int socket(int domain, int type, int protocol)
{
int internal_socket = destiny_socket(domain, type, protocol);
int internal_socket = socket_base_socket(domain, type, protocol);
if (internal_socket < 0) {
errno = ENFILE;
@ -39,7 +39,7 @@ int socket(int domain, int type, int protocol)
}
return fd_new(internal_socket, flagless_recv, flagless_send,
destiny_socket_close);
socket_base_close);
}
@ -51,27 +51,27 @@ int socket(int domain, int type, int protocol)
int accept(int socket, struct sockaddr *restrict address,
socklen_t *restrict address_len)
{
int res = sock_func_wrapper(destiny_socket_accept, socket,
int res = sock_func_wrapper(socket_base_accept, socket,
(sockaddr6_t *)address,
(socklen_t *)address_len);
if (res < 0) {
// destiny needs more granular error handling
// transport_layer needs more granular error handling
errno = EOPNOTSUPP;
return -1;
}
return fd_new(res, flagless_recv, flagless_send,
destiny_socket_close);
socket_base_close);
}
int bind(int socket, const struct sockaddr *address, socklen_t address_len)
{
int res = sock_func_wrapper(destiny_socket_bind, socket,
int res = sock_func_wrapper(socket_base_bind, socket,
(sockaddr6_t *)address, address_len);
if (res < 0) {
// destiny needs more granular error handling
// transport_layer needs more granular error handling
errno = EOPNOTSUPP;
return -1;
}
@ -81,11 +81,11 @@ int bind(int socket, const struct sockaddr *address, socklen_t address_len)
int connect(int socket, const struct sockaddr *address, socklen_t address_len)
{
int res = sock_func_wrapper(destiny_socket_connect, socket,
int res = sock_func_wrapper(socket_base_connect, socket,
(sockaddr6_t *)address, address_len);
if (res < 0) {
// destiny needs more granular error handling
// transport_layer needs more granular error handling
errno = ECONNREFUSED;
return -1;
}
@ -108,10 +108,10 @@ int getsockopt(int socket, int level, int option_name,
int listen(int socket, int backlog)
{
int res = sock_func_wrapper(destiny_socket_listen, socket, backlog);
int res = sock_func_wrapper(socket_base_listen, socket, backlog);
if (res < 0) {
// destiny needs more granular error handling
// transport_layer needs more granular error handling
errno = ECONNREFUSED;
return -1;
}
@ -121,11 +121,11 @@ int listen(int socket, int backlog)
ssize_t recv(int socket, void *buffer, size_t length, int flags)
{
int32_t res = sock_func_wrapper(destiny_socket_recv, socket, buffer,
int32_t res = sock_func_wrapper(socket_base_recv, socket, buffer,
(uint32_t) length, flags);
if (res < 0) {
// destiny needs more granular error handling
// transport_layer needs more granular error handling
errno = ENOTCONN;
return -1;
}
@ -137,13 +137,13 @@ ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
struct sockaddr *restrict address,
socklen_t *restrict address_len)
{
int32_t res = sock_func_wrapper(destiny_socket_recvfrom, socket, buffer,
int32_t res = sock_func_wrapper(socket_base_recvfrom, socket, buffer,
(uint32_t) length, flags,
(sockaddr6_t *)address,
(socklen_t *)address_len);
if (res < 0) {
// destiny needs more granular error handling
// transport_layer needs more granular error handling
errno = ENOTCONN;
return -1;
}
@ -153,11 +153,11 @@ ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
ssize_t send(int socket, const void *buffer, size_t length, int flags)
{
int32_t res = sock_func_wrapper(destiny_socket_send, socket, buffer,
int32_t res = sock_func_wrapper(socket_base_send, socket, buffer,
(uint32_t) length, flags);
if (res < 0) {
// destiny needs more granular error handling
// transport_layer needs more granular error handling
errno = ENOTCONN;
return -1;
}
@ -168,13 +168,13 @@ ssize_t send(int socket, const void *buffer, size_t length, int flags)
ssize_t sendto(int socket, const void *message, size_t length, int flags,
const struct sockaddr *dest_addr, socklen_t dest_len)
{
int32_t res = sock_func_wrapper(destiny_socket_sendto, socket, message,
int32_t res = sock_func_wrapper(socket_base_sendto, socket, message,
(uint32_t) length, flags,
(sockaddr6_t *)dest_addr,
(socklen_t)dest_len);
if (res < 0) {
// destiny needs more granular error handling
// transport_layer needs more granular error handling
errno = ENOTCONN;
return -1;
}