diff --git a/Makefile.dep b/Makefile.dep
index be838d4c1..5ddbbb837 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -372,6 +372,7 @@ ifneq (,$(filter newlib,$(USEMODULE)))
endif
ifneq (,$(filter posix_sockets,$(USEMODULE)))
+ USEMODULE += bitfield
USEMODULE += posix
USEMODULE += random
endif
diff --git a/Makefile.pseudomodules b/Makefile.pseudomodules
index 98ef44062..a91c8c63e 100644
--- a/Makefile.pseudomodules
+++ b/Makefile.pseudomodules
@@ -52,10 +52,6 @@ PSEUDOMODULES += printf_float
PSEUDOMODULES += saul_adc
PSEUDOMODULES += saul_default
PSEUDOMODULES += saul_gpio
-PSEUDOMODULES += sock
-PSEUDOMODULES += sock_ip
-PSEUDOMODULES += sock_tcp
-PSEUDOMODULES += sock_udp
PSEUDOMODULES += schedstatistics
PSEUDOMODULES += sock
PSEUDOMODULES += sock_ip
diff --git a/examples/posix_sockets/Makefile b/examples/posix_sockets/Makefile
index acdf20d83..3064fc866 100644
--- a/examples/posix_sockets/Makefile
+++ b/examples/posix_sockets/Makefile
@@ -19,7 +19,7 @@ USEMODULE += auto_init_gnrc_netif
# Specify the mandatory networking modules for socket communication via UDP
USEMODULE += gnrc_ipv6_default
USEMODULE += gnrc_udp
-USEMODULE += gnrc_conn_udp
+USEMODULE += gnrc_sock_udp
USEMODULE += posix_sockets
# Add also the shell, some shell commands
USEMODULE += shell
diff --git a/pkg/libcoap/Makefile.dep b/pkg/libcoap/Makefile.dep
index b05216b27..d29ba7ddb 100644
--- a/pkg/libcoap/Makefile.dep
+++ b/pkg/libcoap/Makefile.dep
@@ -1,4 +1,4 @@
ifneq (,$(filter libcoap,$(USEPKG)))
USEMODULE += posix_sockets
- USEMODULE += gnrc_conn_udp
+ USEMODULE += gnrc_sock_udp
endif
diff --git a/sys/posix/include/sys/socket.h b/sys/posix/include/sys/socket.h
index 2624d5ce4..e9ba8cba9 100644
--- a/sys/posix/include/sys/socket.h
+++ b/sys/posix/include/sys/socket.h
@@ -50,6 +50,29 @@
extern "C" {
#endif
+/**
+ * @brief Maximum number of sockets available on for creation with @ref socket()
+ */
+#ifndef SOCKET_POOL_SIZE
+#ifdef MODULE_SOCK_TCP
+#define SOCKET_POOL_SIZE (6) /* define enough for accepted sockets */
+#else
+#define SOCKET_POOL_SIZE (4)
+#endif
+#endif
+
+/**
+ * @brief Maximum number of incoming TCP connections a listening socket can
+ * handle
+ */
+#ifndef SOCKET_TCP_QUEUE_SIZE
+#ifdef MODULE_SOCK_TCP
+#define SOCKET_TCP_QUEUE_SIZE (2)
+#else
+#define SOCKET_TCP_QUEUE_SIZE (0)
+#endif
+#endif
+
/**
* @brief Maximum data length for a socket address.
*
@@ -293,31 +316,6 @@ int getsockname(int socket, struct sockaddr *__restrict address,
*/
int listen(int socket, int backlog);
-/**
- * @brief Receive a message from a connected socket.
- * @details Shall receive a message from a connection-mode or
- * connectionless-mode socket. It is normally used with connected
- * sockets because it does not permit the application to retrieve the
- * source address of received data.
- *
- * @see
- * The Open Group Base Specification Issue 7, recv
- *
- *
- * @param[in] socket Specifies the socket file descriptor.
- * @param[out] buffer Points to a buffer where the message should be stored.
- * @param[in] length Specifies the length in bytes of the buffer pointed to
- * by the buffer argument.
- * @param[in] flags Specifies the type of message reception. Support for
- * values other than 0 is not implemented yet.
- *
- * @return Upon successful completion, recv() shall return the length of the
- * message in bytes. If no messages are available to be received and
- * the peer has performed an orderly shutdown, recv() shall return 0.
- * Otherwise, -1 shall be returned and errno set to indicate the error.
- */
-ssize_t recv(int socket, void *buffer, size_t length, int flags);
-
/**
* @brief Receive a message from a socket.
* @details The recvfrom() function shall receive a message from a
@@ -357,27 +355,32 @@ ssize_t recvfrom(int socket, void *__restrict buffer, size_t length, int flags,
socklen_t *__restrict address_len);
/**
- * @brief Send a message on a socket.
- * @details Shall initiate transmission of a message from the specified socket
- * to its peer. The send() function shall send a message only when the
- * socket is connected. If the socket is a connectionless-mode socket,
- * the message shall be sent to the pre-specified peer address.
+ * @brief Receive a message from a connected socket.
+ * @details Shall receive a message from a connection-mode or
+ * connectionless-mode socket. It is normally used with connected
+ * sockets because it does not permit the application to retrieve the
+ * source address of received data.
*
- * @see
- * The Open Group Base Specification Issue 7, send
+ * @see
+ * The Open Group Base Specification Issue 7, recv
*
*
* @param[in] socket Specifies the socket file descriptor.
- * @param[in] buffer Points to the buffer containing the message to send.
- * @param[in] length Specifies the length of the message in bytes.
- * @param[in] flags Specifies the type of message reception. Support
- * for values other than 0 is not implemented yet.
+ * @param[out] buffer Points to a buffer where the message should be stored.
+ * @param[in] length Specifies the length in bytes of the buffer pointed to
+ * by the buffer argument.
+ * @param[in] flags Specifies the type of message reception. Support for
+ * values other than 0 is not implemented yet.
*
- * @return Upon successful completion, send() shall return the number of bytes
- * sent. Otherwise, -1 shall be returned and errno set to indicate the
- * error.
+ * @return Upon successful completion, recv() shall return the length of the
+ * message in bytes. If no messages are available to be received and
+ * the peer has performed an orderly shutdown, recv() shall return 0.
+ * Otherwise, -1 shall be returned and errno set to indicate the error.
*/
-ssize_t send(int socket, const void *buffer, size_t length, int flags);
+static inline ssize_t recv(int socket, void *buffer, size_t length, int flags)
+{
+ return recvfrom(socket, buffer, length, flags, NULL, NULL);
+}
/**
* @brief Send a message on a socket.
@@ -423,6 +426,33 @@ ssize_t send(int socket, const void *buffer, size_t length, int flags);
ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
const struct sockaddr *address, socklen_t address_len);
+/**
+ * @brief Send a message on a socket.
+ * @details Shall initiate transmission of a message from the specified socket
+ * to its peer. The send() function shall send a message only when the
+ * socket is connected. If the socket is a connectionless-mode socket,
+ * the message shall be sent to the pre-specified peer address.
+ *
+ * @see
+ * The Open Group Base Specification Issue 7, send
+ *
+ *
+ * @param[in] socket Specifies the socket file descriptor.
+ * @param[in] buffer Points to the buffer containing the message to send.
+ * @param[in] length Specifies the length of the message in bytes.
+ * @param[in] flags Specifies the type of message reception. Support
+ * for values other than 0 is not implemented yet.
+ *
+ * @return Upon successful completion, send() shall return the number of bytes
+ * sent. Otherwise, -1 shall be returned and errno set to indicate the
+ * error.
+ */
+static inline ssize_t send(int socket, const void *buffer, size_t length,
+ int flags)
+{
+ return sendto(socket, buffer, length, flags, NULL, 0);
+}
+
/**
* @brief Create an endpoint for communication.
* @details Shall create an unbound socket in a communications domain, and
diff --git a/sys/posix/sockets/posix_sockets.c b/sys/posix/sockets/posix_sockets.c
index c8539ab4d..0daf94b89 100644
--- a/sys/posix/sockets/posix_sockets.c
+++ b/sys/posix/sockets/posix_sockets.c
@@ -16,14 +16,15 @@
* @todo
*/
+#include
#include
#include
#include
#include
+#include "bitfield.h"
#include "fd.h"
#include "mutex.h"
-#include "net/conn.h"
#include "net/ipv4/addr.h"
#include "net/ipv6/addr.h"
#include "random.h"
@@ -31,35 +32,35 @@
#include "sys/socket.h"
#include "netinet/in.h"
-#ifdef MODULE_CONN_IP
-# include "net/conn/ip.h"
-#endif /* MODULE_CONN_IP */
-#ifdef MODULE_CONN_TCP
-# include "net/conn/tcp.h"
-#endif /* MODULE_CONN_TCP */
-#ifdef MODULE_CONN_UDP
-# include "net/conn/udp.h"
-#endif /* MODULE_CONN_UDP */
+#include "net/sock/ip.h"
+#include "net/sock/udp.h"
+#include "net/sock/tcp.h"
-#define SOCKET_POOL_SIZE (4)
+/* enough to create sockets both with socket() and accept() */
+#define _ACTUAL_SOCKET_POOL_SIZE (SOCKET_POOL_SIZE + \
+ (SOCKET_POOL_SIZE * SOCKET_TCP_QUEUE_SIZE))
/**
* @brief Unitfied connection type.
*/
typedef union {
- /* is not supposed to be used */
+ /* is not supposed to be used, this is only for the case that no
+ * sock module was added (maybe useful for UNIX sockets?) */
/* cppcheck-suppress unusedStructMember */
- int undef; /**< for case that no connection module is present */
-#ifdef MODULE_CONN_IP
- conn_ip_t raw; /**< raw IP connection */
-#endif /* MODULE_CONN_IP */
-#ifdef MODULE_CONN_TCP
- conn_tcp_t tcp; /**< TCP connection */
-#endif /* MODULE_CONN_TCP */
-#ifdef MODULE_CONN_UDP
- conn_udp_t udp; /**< UDP connection */
-#endif /* MODULE_CONN_UDP */
-} socket_conn_t;
+ int undef;
+#ifdef MODULE_SOCK_IP
+ sock_ip_t raw; /**< raw IP sock */
+#endif /* MODULE_SOCK_IP */
+#ifdef MODULE_SOCK_TCP
+ union {
+ sock_tcp_t sock; /**< TCP sock */
+ sock_tcp_queue_t queue; /**< TCP queue */
+ } tcp; /**< both TCP types */
+#endif /* MODULE_SOCK_TCP */
+#ifdef MODULE_SOCK_UDP
+ sock_udp_t udp; /**< UDP sock */
+#endif /* MODULE_SOCK_UDP */
+} socket_sock_t;
typedef struct {
int fd;
@@ -67,40 +68,66 @@ typedef struct {
int type;
int protocol;
bool bound;
- socket_conn_t conn;
- uint16_t src_port;
+ socket_sock_t *sock;
+#ifdef MODULE_SOCK_TCP
+ sock_tcp_t *queue_array;
+ unsigned queue_array_len;
+#endif
+ sock_tcp_ep_t local; /* to store bind before connect/listen */
} socket_t;
-socket_t _pool[SOCKET_POOL_SIZE];
-mutex_t _pool_mutex = MUTEX_INIT;
+static socket_t _socket_pool[_ACTUAL_SOCKET_POOL_SIZE];
+static socket_sock_t _sock_pool[SOCKET_POOL_SIZE];
+#ifdef MODULE_SOCK_TCP
+static sock_tcp_t _tcp_sock_pool[SOCKET_POOL_SIZE][SOCKET_TCP_QUEUE_SIZE];
+#endif
+BITFIELD(_sock_pool_used, SOCKET_POOL_SIZE);
+static mutex_t _socket_pool_mutex = MUTEX_INIT;
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
static socket_t *_get_free_socket(void)
{
- for (int i = 0; i < SOCKET_POOL_SIZE; i++) {
- if (_pool[i].domain == AF_UNSPEC) {
- return &_pool[i];
+ for (int i = 0; i < _ACTUAL_SOCKET_POOL_SIZE; i++) {
+ if (_socket_pool[i].domain == AF_UNSPEC) {
+ return &_socket_pool[i];
}
}
return NULL;
}
+static socket_sock_t *_get_free_sock(void)
+{
+ int i = bf_get_unset(_sock_pool_used, SOCKET_POOL_SIZE);
+ if (i < 0) {
+ return NULL;
+ }
+ return &_sock_pool[i];
+}
+
static socket_t *_get_socket(int fd)
{
- for (int i = 0; i < SOCKET_POOL_SIZE; i++) {
- if (_pool[i].fd == fd) {
- return &_pool[i];
+ for (int i = 0; i < _ACTUAL_SOCKET_POOL_SIZE; i++) {
+ if (_socket_pool[i].fd == fd) {
+ return &_socket_pool[i];
}
}
return NULL;
}
+static int _get_sock_idx(socket_sock_t *sock)
+{
+ if ((sock < &_sock_pool[0]) || (sock > &_sock_pool[SOCKET_POOL_SIZE - 1])) {
+ return -1;
+ }
+ return sock - &_sock_pool[0];
+}
+
static inline int _choose_ipproto(int type, int protocol)
{
switch (type) {
-#ifdef MODULE_CONN_TCP
+#ifdef MODULE_SOCK_TCP
case SOCK_STREAM:
if ((protocol == 0) || (protocol == IPPROTO_TCP)) {
return protocol;
@@ -110,7 +137,7 @@ static inline int _choose_ipproto(int type, int protocol)
}
break;
#endif
-#ifdef MODULE_CONN_UDP
+#ifdef MODULE_SOCK_UDP
case SOCK_DGRAM:
if ((protocol == 0) || (protocol == IPPROTO_UDP)) {
return protocol;
@@ -120,7 +147,7 @@ static inline int _choose_ipproto(int type, int protocol)
}
break;
#endif
-#ifdef MODULE_CONN_IP
+#ifdef MODULE_SOCK_IP
case SOCK_RAW:
return protocol;
#endif
@@ -132,36 +159,45 @@ static inline int _choose_ipproto(int type, int protocol)
return -1;
}
-static inline ipv4_addr_t *_in_addr_ptr(struct sockaddr_storage *addr)
-{
- return (ipv4_addr_t *)(&((struct sockaddr_in *)addr)->sin_addr);
-}
-
-static inline uint16_t *_in_port_ptr(struct sockaddr_storage *addr)
-{
- return &((struct sockaddr_in *)addr)->sin_port;
-}
-
-static inline ipv6_addr_t *_in6_addr_ptr(struct sockaddr_storage *addr)
-{
- return (ipv6_addr_t *)(&((struct sockaddr_in6 *)addr)->sin6_addr);
-}
-
-static inline uint16_t *_in6_port_ptr(struct sockaddr_storage *addr)
-{
- return &((struct sockaddr_in6 *)addr)->sin6_port;
-}
-
static inline socklen_t _addr_truncate(struct sockaddr *out, socklen_t out_len,
- struct sockaddr_storage *in, socklen_t target_size)
-{
- out_len = (out_len < target_size) ? out_len : target_size;
+ struct sockaddr_storage *in,
+ socklen_t target_size) {
+ out_len = (out_len < target_size) ? out_len : target_size;
memcpy(out, in, out_len);
return out_len;
}
-static inline int _get_data_from_sockaddr(const struct sockaddr *address, size_t address_len,
- void **addr, size_t *addr_len, network_uint16_t *port)
+static int _ep_to_sockaddr(const struct _sock_tl_ep *ep,
+ struct sockaddr_storage *out)
+{
+ assert((ep->family == AF_INET) || (ep->family == AF_INET6));
+ switch (ep->family) {
+ case AF_INET: {
+ struct sockaddr_in *in_addr = (struct sockaddr_in *)out;
+
+ in_addr->sin_family = AF_INET;
+ in_addr->sin_addr.s_addr = ep->addr.ipv4_u32;
+ in_addr->sin_port = htons(ep->port);
+ return sizeof(struct sockaddr_in);
+ }
+#ifdef SOCK_HAS_IPV6
+ case AF_INET6: {
+ struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)out;
+
+ in6_addr->sin6_family = AF_INET6;
+ memcpy(&in6_addr->sin6_addr, &ep->addr.ipv6, sizeof(ep->addr.ipv6));
+ in6_addr->sin6_port = htons(ep->port);
+ return sizeof(struct sockaddr_in6);
+ }
+#endif
+ default:
+ /* should not happen */
+ return 0;
+ }
+}
+
+static int _sockaddr_to_ep(const struct sockaddr *address, socklen_t address_len,
+ struct _sock_tl_ep *out)
{
switch (address->sa_family) {
case AF_INET:
@@ -170,20 +206,22 @@ static inline int _get_data_from_sockaddr(const struct sockaddr *address, size_t
return -1;
}
struct sockaddr_in *in_addr = (struct sockaddr_in *)address;
- *addr = &in_addr->sin_addr;
- *addr_len = sizeof(ipv4_addr_t);
- port->u16 = in_addr->sin_port;
+ out->family = AF_INET;
+ out->addr.ipv4_u32 = in_addr->sin_addr.s_addr;
+ out->port = ntohs(in_addr->sin_port);
break;
+#ifdef SOCK_HAS_IPV6
case AF_INET6:
if (address_len < sizeof(struct sockaddr_in6)) {
errno = EINVAL;
return -1;
}
struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)address;
- *addr = &in6_addr->sin6_addr;
- *addr_len = sizeof(ipv6_addr_t);
- port->u16 = in6_addr->sin6_port;
+ out->family = AF_INET6;
+ memcpy(&out->addr.ipv6, &in6_addr->sin6_addr, sizeof(out->addr.ipv6));
+ out->port = ntohs(in6_addr->sin6_port);
break;
+#endif
default:
errno = EAFNOSUPPORT;
return -1;
@@ -191,89 +229,50 @@ static inline int _get_data_from_sockaddr(const struct sockaddr *address, size_t
return 0;
}
-static int _implicit_bind(socket_t *s, void *addr)
-{
- ipv6_addr_t unspec;
- ipv6_addr_t *best_match;
- int res;
-
- /* TODO: ensure that this port hasn't been used yet */
- s->src_port = (uint16_t)random_uint32_range(1LU << 10U, 1LU << 16U);
-
- /* find the best matching source address */
- if ((best_match = conn_find_best_source(addr)) == NULL) {
- ipv6_addr_set_unspecified(&unspec);
- best_match = &unspec;
- }
- switch (s->type) {
-#ifdef MODULE_CONN_TCP
- case SOCK_STREAM:
- res = conn_tcp_create(&s->conn.udp, best_match, sizeof(unspec),
- s->domain, s->src_port);
- break;
-#endif
-#ifdef MODULE_CONN_UDP
- case SOCK_DGRAM:
- res = conn_udp_create(&s->conn.udp, best_match, sizeof(unspec),
- s->domain, s->src_port);
- break;
-#endif
- default:
- res = -1;
- break;
- }
- if (res < 0) {
- errno = -res;
- }
- else {
- s->bound = true;
- }
- return res;
-}
-
static int socket_close(int socket)
{
socket_t *s;
int res = 0;
- if ((unsigned)(socket - 1) > (SOCKET_POOL_SIZE - 1)) {
- return -1;
- }
- mutex_lock(&_pool_mutex);
- s = &_pool[socket];
- if (s->bound) {
- switch (s->domain) {
- case AF_INET:
- case AF_INET6:
- switch (s->type) {
-#ifdef MODULE_CONN_UDP
- case SOCK_DGRAM:
- conn_udp_close(&s->conn.udp);
- break;
-#endif
-#ifdef MODULE_CONN_IP
- case SOCK_RAW:
- conn_ip_close(&s->conn.raw);
- break;
+
+ assert((unsigned)(socket - 1) > (_ACTUAL_SOCKET_POOL_SIZE - 1));
+ s = &_socket_pool[socket];
+ assert((s->domain == AF_INET) || (s->domain == AF_INET6));
+ mutex_lock(&_socket_pool_mutex);
+ if (s->sock != NULL) {
+ int idx = _get_sock_idx(s->sock);
+ switch (s->type) {
+#ifdef MODULE_SOCK_UDP
+ case SOCK_DGRAM:
+ sock_udp_close(&s->sock->udp);
+ break;
#endif
-#ifdef MODULE_CONN_TCP
- case SOCK_STREAM:
- conn_tcp_close(&s->conn.tcp);
- break;
+#ifdef MODULE_SOCK_IP
+ case SOCK_RAW:
+ sock_ip_close(&s->sock->raw);
+ break;
#endif
- default:
- errno = EOPNOTSUPP;
- res = -1;
- break;
+#ifdef MODULE_SOCK_TCP
+ case SOCK_STREAM:
+ if (s->queue_array == 0) {
+ sock_tcp_disconnect(&s->sock->tcp.sock);
+ }
+ else {
+ sock_tcp_stop_listen(&s->sock->tcp.queue);
}
break;
+#endif
default:
+ errno = EOPNOTSUPP;
res = -1;
break;
}
+ if (idx >= 0) {
+ bf_unset(_sock_pool_used, idx);
+ }
}
+ mutex_unlock(&_socket_pool_mutex);
+ s->sock = NULL;
s->domain = AF_UNSPEC;
- s->src_port = 0;
- mutex_unlock(&_pool_mutex);
return res;
}
@@ -291,43 +290,55 @@ int socket(int domain, int type, int protocol)
{
int res = 0;
socket_t *s;
- mutex_lock(&_pool_mutex);
+
+ mutex_lock(&_socket_pool_mutex);
s = _get_free_socket();
if (s == NULL) {
errno = ENFILE;
- mutex_unlock(&_pool_mutex);
+ mutex_unlock(&_socket_pool_mutex);
return -1;
}
switch (domain) {
case AF_INET:
+#ifdef SOCK_HAS_IPV6
case AF_INET6:
+#endif
+ {
+ int fd = fd_new(s - _socket_pool, socket_read, socket_write,
+ socket_close);
+
+ if (fd < 0) {
+ errno = ENFILE;
+ res = -1;
+ break;
+ }
+ else {
+ s->fd = res = fd;
+ }
s->domain = domain;
s->type = type;
if ((s->protocol = _choose_ipproto(type, protocol)) < 0) {
res = -1;
+ break;
+ }
+ s->bound = false;
+ s->sock = NULL;
+#ifdef MODULE_SOCK_TCP
+ if (type == SOCK_STREAM) {
+ s->queue_array = NULL;
+ s->queue_array_len = 0;
+ memset(&s->local, 0, sizeof(sock_tcp_ep_t));
}
+#endif
break;
-
+ }
default:
(void)type;
(void)protocol;
errno = EAFNOSUPPORT;
res = -1;
}
- if (res == 0) {
- /* TODO: add read and write */
- int fd = fd_new(s - _pool, socket_read, socket_write, socket_close);
- if (fd < 0) {
- errno = ENFILE;
- res = -1;
- }
- else {
- s->fd = res = fd;
- }
- }
- s->bound = false;
- s->src_port = 0;
- mutex_unlock(&_pool_mutex);
+ mutex_unlock(&_socket_pool_mutex);
return res;
}
@@ -335,66 +346,58 @@ int socket(int domain, int type, int protocol)
int accept(int socket, struct sockaddr *restrict address,
socklen_t *restrict address_len)
{
+#ifdef MODULE_SOCK_TCP
+ sock_tcp_t *sock = NULL;
socket_t *s, *new_s = NULL;
int res = 0;
- /* May be kept unassigned if no conn module is available */
- /* cppcheck-suppress unassignedVariable */
- struct sockaddr_storage tmp;
- void *addr;
- uint16_t *port;
- socklen_t tmp_len;
- mutex_lock(&_pool_mutex);
+
+ mutex_lock(&_socket_pool_mutex);
s = _get_socket(socket);
if (s == NULL) {
- mutex_unlock(&_pool_mutex);
+ mutex_unlock(&_socket_pool_mutex);
errno = ENOTSOCK;
return -1;
}
- if (!s->bound) {
- mutex_unlock(&_pool_mutex);
+ if (s->sock == NULL) {
+ mutex_unlock(&_socket_pool_mutex);
errno = EINVAL;
return -1;
}
- switch (s->domain) {
- case AF_INET:
- addr = _in_addr_ptr(&tmp);
- port = _in_port_ptr(&tmp);
- tmp_len = sizeof(struct sockaddr_in);
- break;
- case AF_INET6:
- addr = _in6_addr_ptr(&tmp);
- port = _in6_port_ptr(&tmp);
- tmp_len = sizeof(struct sockaddr_in6);
- break;
- default:
- (void)address;
- (void)address_len;
- (void)new_s;
- (void)tmp;
- (void)addr;
- (void)port;
- (void)tmp_len;
- errno = EPROTO;
- res = -1;
- break;
- }
switch (s->type) {
-#ifdef MODULE_CONN_TCP
case SOCK_STREAM:
new_s = _get_free_socket();
+ sock = (sock_tcp_t *)new_s->sock;
if (new_s == NULL) {
errno = ENFILE;
res = -1;
break;
}
- if ((res = conn_tcp_accept(&s->conn.tcp, &new_s->conn.tcp)) < 0) {
+ /* TODO: apply configured timeout */
+ if ((res = sock_tcp_accept(&s->sock->tcp.queue, &sock,
+ SOCK_NO_TIMEOUT)) < 0) {
errno = -res;
res = -1;
break;
}
- else if ((address != NULL) && (address_len != NULL)) {
- /* TODO: add read and write */
- int fd = fd_new(new_s - _pool, NULL, NULL, socket_close);
+ else {
+ if ((address != NULL) && (address_len != NULL)) {
+ sock_tcp_ep_t ep;
+ struct sockaddr_storage sa;
+ socklen_t sa_len;
+
+ if ((res = sock_tcp_get_remote(sock, &ep)) < 0) {
+ errno = -res;
+ res = -1;
+ break;
+ }
+ sa.ss_family = s->domain;
+ sa_len = _ep_to_sockaddr(&ep, &sa);
+ *address_len = _addr_truncate(address, *address_len, &sa,
+ sa_len);
+
+ }
+ int fd = fd_new(new_s - _socket_pool, socket_read, socket_write,
+ socket_close);
if (fd < 0) {
errno = ENFILE;
res = -1;
@@ -406,329 +409,356 @@ int accept(int socket, struct sockaddr *restrict address,
new_s->domain = s->domain;
new_s->type = s->type;
new_s->protocol = s->protocol;
- tmp.ss_family = s->domain;
- if ((res = conn_tcp_getpeeraddr(&s->conn.tcp, addr, port)) < 0) {
- errno = -res;
- res = -1;
- break;
- }
- *port = htons(*port); /* XXX: sin(6)_port is supposed to be
- network byte order */
- *address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
+ new_s->bound = true;
+ new_s->queue_array = NULL;
+ new_s->queue_array_len = 0;
+ memset(&s->local, 0, sizeof(sock_tcp_ep_t));
}
break;
-#endif
default:
errno = EOPNOTSUPP;
res = -1;
break;
}
- mutex_unlock(&_pool_mutex);
+ if ((res < 0) && (sock != NULL)) {
+ sock_tcp_disconnect(sock);
+ }
+ mutex_unlock(&_socket_pool_mutex);
return res;
+#else
+ (void)socket;
+ (void)address;
+ (void)address_len;
+ errno = -EOPNOTSUPP;
+ return -1;
+#endif
}
int bind(int socket, const struct sockaddr *address, socklen_t address_len)
{
socket_t *s;
int res = 0;
- void *addr;
- size_t addr_len;
- network_uint16_t port = { 0 };
- mutex_lock(&_pool_mutex);
+
+ /* only store bind data, real bind happens in _bind_connect/listen */
+ mutex_lock(&_socket_pool_mutex);
s = _get_socket(socket);
- mutex_unlock(&_pool_mutex);
+ mutex_unlock(&_socket_pool_mutex);
if (s == NULL) {
errno = ENOTSOCK;
return -1;
}
- if (address->sa_family != s->domain) {
- errno = EAFNOSUPPORT;
+ if (s->bound) {
+ errno = EINVAL;
return -1;
}
- if (_get_data_from_sockaddr(address, address_len, &addr, &addr_len, &port) < 0) {
+ if (address->sa_family != s->domain) {
+ errno = EAFNOSUPPORT;
return -1;
}
switch (s->type) {
-#ifdef MODULE_CONN_IP
+#ifdef MODULE_SOCK_IP
case SOCK_RAW:
- (void)port;
- if ((res = conn_ip_create(&s->conn.raw, addr, addr_len, s->domain, s->protocol)) < 0) {
- errno = -res;
- return -1;
- }
break;
#endif
-#ifdef MODULE_CONN_TCP
+#ifdef MODULE_SOCK_TCP
case SOCK_STREAM:
- if ((res = conn_tcp_create(&s->conn.tcp, addr, addr_len, s->domain,
- byteorder_ntohs(port))) < 0) {
- errno = -res;
- return -1;
- }
break;
#endif
-#ifdef MODULE_CONN_UDP
+#ifdef MODULE_SOCK_UDP
case SOCK_DGRAM:
- if ((res = conn_udp_create(&s->conn.udp, addr, addr_len, s->domain,
- byteorder_ntohs(port))) < 0) {
-
- errno = -res;
- return -1;
- }
break;
#endif
default:
- (void)addr;
- (void)addr_len;
- (void)port;
(void)res;
errno = EOPNOTSUPP;
return -1;
}
- s->src_port = byteorder_ntohs(port);
+ if (_sockaddr_to_ep(address, address_len, &s->local) < 0) {
+ return -1;
+ }
s->bound = true;
return 0;
}
-int connect(int socket, const struct sockaddr *address, socklen_t address_len)
+static int _bind_connect(socket_t *s, const struct sockaddr *address,
+ socklen_t address_len)
{
- socket_t *s;
- int res = 0;
- void *addr;
- size_t addr_len;
- network_uint16_t port;
- mutex_lock(&_pool_mutex);
- s = _get_socket(socket);
- mutex_unlock(&_pool_mutex);
- if (s == NULL) {
- errno = ENOTSOCK;
- return -1;
+ struct _sock_tl_ep r, *remote = NULL, *local = NULL;
+ int res;
+ socket_sock_t *sock;
+
+ assert((s != NULL) && ((address == NULL) || (address_len > 0)));
+ if (address != NULL) {
+ if (address->sa_family != s->domain) {
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+ if (_sockaddr_to_ep(address, address_len, &r) < 0) {
+ return -1;
+ }
+ remote = &r;
}
- if (address->sa_family != s->domain) {
- errno = EAFNOSUPPORT;
- return -1;
+ if (s->bound) {
+ local = &s->local;
}
- if (_get_data_from_sockaddr(address, address_len, &addr, &addr_len, &port) < 0) {
+ mutex_lock(&_socket_pool_mutex);
+ sock = _get_free_sock();
+ mutex_unlock(&_socket_pool_mutex);
+ if (sock == NULL) {
+ errno = ENOMEM;
return -1;
}
switch (s->type) {
-#ifdef MODULE_CONN_TCP
+#ifdef MODULE_SOCK_IP
+ case SOCK_RAW:
+ /* TODO apply flags if possible */
+ res = sock_ip_create(&sock->raw, (sock_ip_ep_t *)local,
+ (sock_ip_ep_t *)remote, s->protocol, 0);
+ break;
+#endif
+#ifdef MODULE_SOCK_TCP
case SOCK_STREAM:
- /* "If the socket has not already been bound to a local address,
- * connect() shall bind it to an address which, unless the socket's
- * address family is AF_UNIX, is an unused local address." (see
- * http://pubs.opengroup.org/onlinepubs/009695399/functions/connect.html)
- */
- if (!s->bound) {
- if ((res = _implicit_bind(s, addr)) < 0) {
- return res;
- }
- }
-
- if ((res = conn_tcp_connect(&s->conn.tcp, addr, addr_len,
- byteorder_ntohs(port))) < 0) {
-
- errno = -res;
- return -1;
- }
+ /* TODO apply flags if possible */
+ assert(remote != NULL);
+ res = sock_tcp_connect(&sock->tcp.sock, remote,
+ (local == NULL) ? 0 : local->port, 0);
+ break;
+#endif
+#ifdef MODULE_SOCK_UDP
+ case SOCK_DGRAM:
+ /* TODO apply flags if possible */
+ res = sock_udp_create(&sock->udp, local, remote, 0);
break;
#endif
default:
- (void)res;
- errno = EPROTOTYPE;
- return -1;
+ (void)local;
+ (void)remote;
+ res = -EOPNOTSUPP;
+ break;
}
+ if (res < 0) {
+ errno = -res;
+ /* free sock again */
+ mutex_lock(&_socket_pool_mutex);
+ bf_unset(_sock_pool_used, _get_sock_idx(sock));
+ mutex_unlock(&_socket_pool_mutex);
+ return -1;
+ }
+ s->sock = sock;
return 0;
}
-int getpeername(int socket, struct sockaddr *__restrict address,
- socklen_t *__restrict address_len)
+int connect(int socket, const struct sockaddr *address, socklen_t address_len)
{
socket_t *s;
- int res = 0;
- /* May be kept unassigned if no conn module is available */
- /* cppcheck-suppress unassignedVariable */
- struct sockaddr_storage tmp;
- void *addr;
- uint16_t *port;
- socklen_t tmp_len;
- mutex_lock(&_pool_mutex);
+
+ mutex_lock(&_socket_pool_mutex);
s = _get_socket(socket);
- mutex_unlock(&_pool_mutex);
+ mutex_unlock(&_socket_pool_mutex);
if (s == NULL) {
errno = ENOTSOCK;
return -1;
}
- switch (s->domain) {
- case AF_INET:
- addr = _in_addr_ptr(&tmp);
- port = _in_port_ptr(&tmp);
- tmp_len = sizeof(struct sockaddr_in);
- break;
- case AF_INET6:
- addr = _in6_addr_ptr(&tmp);
- port = _in6_port_ptr(&tmp);
- tmp_len = sizeof(struct sockaddr_in6);
- break;
- default:
- (void)address;
- (void)address_len;
- (void)tmp;
- (void)addr;
- (void)port;
- (void)tmp_len;
- (void)res;
- errno = EBADF;
- return -1;
+ if (s->sock != NULL) {
+#ifdef MODULE_SOCK_TCP
+ if (s->queue_array != NULL) {
+ errno = EOPNOTSUPP;
+ }
+ else
+#endif
+ {
+ errno = EISCONN;
+ }
+ return -1;
}
- if (*address_len != tmp_len) {
- errno = EINVAL;
+ return _bind_connect(s, address, address_len);
+}
+
+static int _getpeername(socket_t *s, struct sockaddr *__restrict address,
+ socklen_t *__restrict address_len)
+{
+ struct _sock_tl_ep ep;
+ int res = 0;
+
+ if (s->sock == NULL) {
+ errno = ENOTCONN;
return -1;
}
switch (s->type) {
-#ifdef MODULE_CONN_TCP
+#ifdef MODULE_SOCK_IP
+ case SOCK_RAW:
+ res = sock_ip_get_remote(&s->sock->raw, (sock_ip_ep_t *)&ep);
+ break;
+#endif
+#ifdef MODULE_SOCK_TCP
case SOCK_STREAM:
- if ((res = conn_tcp_getpeeraddr(&s->conn.tcp, addr, port)) < 0) {
- errno = -res;
- return -1;
+ if (s->queue_array == NULL) {
+ res = sock_tcp_get_remote(&s->sock->tcp.sock, &ep);
}
+ else {
+ res = -ENOTCONN;
+ }
+ break;
+#endif
+#ifdef MODULE_SOCK_UDP
+ case SOCK_DGRAM:
+ res = sock_udp_get_remote(&s->sock->udp, &ep);
break;
#endif
default:
- errno = ENOTCONN;
- return -1;
+ res = -EOPNOTSUPP;
+ break;
}
- tmp.ss_family = s->domain;
- *port = htons(*port); /* XXX: sin(6)_port is supposed to be network byte
- order */
- *address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
- return 0;
+ if (res < 0) {
+ errno = -res;
+ res = -1;
+ }
+ else {
+ struct sockaddr_storage sa;
+ socklen_t sa_len = _ep_to_sockaddr(&ep, &sa);
+ *address_len = _addr_truncate(address, *address_len, &sa,
+ sa_len);
+ }
+ return res;
+}
+
+int getpeername(int socket, struct sockaddr *__restrict address,
+ socklen_t *__restrict address_len)
+{
+ socket_t *s;
+
+ mutex_lock(&_socket_pool_mutex);
+ s = _get_socket(socket);
+ mutex_unlock(&_socket_pool_mutex);
+ if (s == NULL) {
+ errno = ENOTSOCK;
+ return -1;
+ }
+ return _getpeername(s, address, address_len);
}
int getsockname(int socket, struct sockaddr *__restrict address,
socklen_t *__restrict address_len)
{
socket_t *s;
+ struct sockaddr_storage sa;
+ socklen_t sa_len;
int res = 0;
- /* May be kept unassigned if no conn module is available */
- /* cppcheck-suppress unassignedVariable */
- struct sockaddr_storage tmp;
- void *addr;
- uint16_t *port;
- socklen_t tmp_len;
- mutex_lock(&_pool_mutex);
+
+ mutex_lock(&_socket_pool_mutex);
s = _get_socket(socket);
- mutex_unlock(&_pool_mutex);
+ mutex_unlock(&_socket_pool_mutex);
if (s == NULL) {
errno = ENOTSOCK;
return -1;
}
- if (!s->bound) {
- memset(address, 0, *address_len);
- return 0;
- }
- switch (s->domain) {
- case AF_INET:
- addr = _in_addr_ptr(&tmp);
- port = _in_port_ptr(&tmp);
- tmp_len = sizeof(struct sockaddr_in);
- break;
- case AF_INET6:
- addr = _in6_addr_ptr(&tmp);
- port = _in6_port_ptr(&tmp);
- tmp_len = sizeof(struct sockaddr_in6);
- break;
- default:
- (void)address;
- (void)address_len;
- (void)tmp;
- (void)addr;
- (void)port;
- (void)tmp_len;
- (void)res;
- errno = EBADF;
- return -1;
- }
- if (*address_len != tmp_len) {
- errno = EINVAL;
- return -1;
+ if (s->sock == NULL) {
+ sa_len = _ep_to_sockaddr(&s->local, &sa);
}
- switch (s->type) {
-#ifdef MODULE_CONN_UDP
- case SOCK_DGRAM:
- if ((res = conn_udp_getlocaladdr(&s->conn.udp, addr, port)) < 0) {
- errno = -res;
- return -1;
- }
- break;
+ else {
+ struct _sock_tl_ep ep;
+ switch (s->type) {
+#ifdef MODULE_SOCK_IP
+ case SOCK_RAW:
+ res = sock_ip_get_local(&s->sock->raw, (sock_ip_ep_t *)&ep);
+ break;
#endif
-#ifdef MODULE_CONN_IP
- case SOCK_RAW:
- if ((res = conn_ip_getlocaladdr(&s->conn.raw, addr)) < 0) {
- errno = -res;
- return -1;
- }
- break;
+#ifdef MODULE_SOCK_TCP
+ case SOCK_STREAM:
+ if (s->queue_array == NULL) {
+ res = sock_tcp_get_local(&s->sock->tcp.sock, &ep);
+ }
+ else {
+ res = sock_tcp_queue_get_local(&s->sock->tcp.queue, &ep);
+ }
+ break;
#endif
-#ifdef MODULE_CONN_TCP
- case SOCK_STREAM:
- if ((res = conn_tcp_getlocaladdr(&s->conn.tcp, addr, port)) < 0) {
- errno = -res;
- return -1;
- }
- break;
+#ifdef MODULE_SOCK_UDP
+ case SOCK_DGRAM:
+ res = sock_udp_get_local(&s->sock->udp, &ep);
+ break;
#endif
- default:
- errno = EOPNOTSUPP;
- return -1;
+ default:
+ res = -EOPNOTSUPP;
+ break;
+ }
+ sa_len = _ep_to_sockaddr(&ep, &sa);
}
- tmp.ss_family = AF_INET;
- *port = htons(*port); /* XXX: sin(6)_port is supposed to be network byte
- order */
- *address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
- return 0;
+ if (res < 0) {
+ errno = -res;
+ res = -1;
+ }
+ else {
+ *address_len = _addr_truncate(address, *address_len, &sa,
+ sa_len);
+ }
+ return res;
}
int listen(int socket, int backlog)
{
+#ifdef MODULE_SOCK_TCP
socket_t *s;
+ socket_sock_t *sock;
int res = 0;
- mutex_lock(&_pool_mutex);
+
+ mutex_lock(&_socket_pool_mutex);
s = _get_socket(socket);
- mutex_unlock(&_pool_mutex);
- if (!s->bound) {
- errno = EINVAL;
+ if (s == NULL) {
+ errno = ENOTSOCK;
+ mutex_unlock(&_socket_pool_mutex);
return -1;
}
- switch (s->domain) {
- case AF_INET:
- case AF_INET6:
- switch (s->type) {
-#ifdef MODULE_CONN_TCP
- case SOCK_STREAM:
- if ((res = conn_tcp_listen(&s->conn.tcp, backlog)) < 0) {
- errno = -res;
- return -1;
- }
- break;
-#endif
- default:
- errno = EOPNOTSUPP;
- return -1;
+ if (s->sock != NULL) {
+ /* or this socket is already connected, this is an error */
+ if (s->queue_array == NULL) {
+ errno = EINVAL;
+ res = -1;
+ }
+ mutex_unlock(&_socket_pool_mutex);
+ return res;
+ }
+ sock = _get_free_sock();
+ mutex_unlock(&_socket_pool_mutex);
+ if (sock == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ s->queue_array = _tcp_sock_pool[_get_sock_idx(sock)];
+ s->queue_array_len = (backlog < SOCKET_TCP_QUEUE_SIZE) ? backlog :
+ SOCKET_TCP_QUEUE_SIZE;
+ switch (s->type) {
+ case SOCK_STREAM:
+ if (s->bound) {
+ /* TODO apply flags if possible */
+ res = sock_tcp_listen(&sock->tcp.queue, &s->local,
+ s->queue_array, s->queue_array_len, 0);
+ }
+ else {
+ res = -EDESTADDRREQ;
}
break;
default:
- (void)backlog;
- (void)res;
- errno = EAFNOSUPPORT;
- return -1;
+ res = -EOPNOTSUPP;
+ break;
}
- return 0;
-}
-
-ssize_t recv(int socket, void *buffer, size_t length, int flags)
-{
- return recvfrom(socket, buffer, length, flags, NULL, NULL);
+ if (res == 0) {
+ s->sock = sock;
+ }
+ else {
+ errno = -res;
+ res = -1;
+ mutex_lock(&_socket_pool_mutex);
+ bf_unset(_sock_pool_used, _get_sock_idx(sock));
+ mutex_unlock(&_socket_pool_mutex);
+ }
+ return -res;
+#else
+ (void)socket;
+ (void)backlog;
+ errno = EOPNOTSUPP;
+ return -1;
+#endif
}
ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
@@ -737,217 +767,139 @@ ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
{
socket_t *s;
int res = 0;
- /* May be kept unassigned if no conn module is available */
- /* cppcheck-suppress unassignedVariable */
- struct sockaddr_storage tmp;
- void *addr;
- size_t addr_len;
- uint16_t *port;
- socklen_t tmp_len;
+ struct _sock_tl_ep ep = { .port = 0 };
+
(void)flags;
- mutex_lock(&_pool_mutex);
+ mutex_lock(&_socket_pool_mutex);
s = _get_socket(socket);
- mutex_unlock(&_pool_mutex);
+ mutex_unlock(&_socket_pool_mutex);
if (s == NULL) {
errno = ENOTSOCK;
return -1;
}
- if (!s->bound) {
- errno = EINVAL;
- return -1;
- }
- memset(&tmp, 0, sizeof(struct sockaddr_storage));
- switch (s->domain) {
- case AF_INET:
- addr = _in_addr_ptr(&tmp);
- port = _in_port_ptr(&tmp);
- addr_len = sizeof(ipv4_addr_t);
- tmp_len = sizeof(struct sockaddr_in);
- break;
- case AF_INET6:
- addr = _in6_addr_ptr(&tmp);
- port = _in6_port_ptr(&tmp);
- addr_len = sizeof(ipv6_addr_t);
- tmp_len = sizeof(struct sockaddr_in6);
- break;
- default:
- (void)buffer;
- (void)length;
- (void)address;
- (void)address_len;
- (void)tmp;
- (void)addr;
- (void)port;
- (void)tmp_len;
- errno = EAFNOSUPPORT;
+ if (s->sock == NULL) { /* socket is not connected */
+#ifdef MODULE_SOCK_TCP
+ if (s->type == SOCK_STREAM) {
+ errno = ENOTCONN;
+ return -1;
+ }
+#endif
+ /* bind implicitly */
+ if ((res = _bind_connect(s, NULL, 0)) < 0) {
+ errno = -res;
return -1;
+ }
}
switch (s->type) {
-#ifdef MODULE_CONN_UDP
- case SOCK_DGRAM:
- if ((res = conn_udp_recvfrom(&s->conn.udp, buffer, length, addr,
- &addr_len, port)) < 0) {
- errno = -res;
- return -1;
- }
- break;
-#endif
-#ifdef MODULE_CONN_IP
+#ifdef MODULE_SOCK_IP
case SOCK_RAW:
- if ((res = conn_ip_recvfrom(&s->conn.raw, buffer, length, addr, &addr_len)) < 0) {
- errno = -res;
- return -1;
- }
+ /* TODO: apply configured timeout */
+ res = sock_ip_recv(&s->sock->raw, buffer, length, SOCK_NO_TIMEOUT,
+ (sock_ip_ep_t *)&ep);
break;
#endif
-#ifdef MODULE_CONN_TCP
+#ifdef MODULE_SOCK_TCP
case SOCK_STREAM:
- if ((res = conn_tcp_recv(&s->conn.tcp, buffer, length)) < 0) {
- errno = -res;
- return -1;
- }
- if ((res = conn_tcp_getpeeraddr(&s->conn.tcp, addr, port)) < 0) {
- errno = -res;
- return -1;
- }
+ /* TODO: apply configured timeout */
+ res = sock_tcp_read(&s->sock->tcp.sock, buffer, length,
+ SOCK_NO_TIMEOUT);
+ break;
+#endif
+#ifdef MODULE_SOCK_UDP
+ case SOCK_DGRAM:
+ /* TODO: apply configured timeout */
+ res = sock_udp_recv(&s->sock->udp, buffer, length, SOCK_NO_TIMEOUT,
+ &ep);
break;
#endif
default:
- (void)addr_len;
- errno = EOPNOTSUPP;
- return -1;
+ res = -EOPNOTSUPP;
+ break;
}
- if ((address != NULL) && (address_len != NULL)) {
- tmp.ss_family = s->domain;
- *port = htons(*port); /* XXX: sin(6)_port is supposed to be network
- byte order */
- *address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
+ if ((res == 0) && (address != NULL) && (address_len != 0)) {
+ switch (s->type) {
+#ifdef MODULE_SOCK_TCP
+ case SOCK_STREAM:
+ res = _getpeername(s, address, address_len);
+ break;
+#endif
+ default: {
+ struct sockaddr_storage sa;
+ socklen_t sa_len;
+
+ sa_len = _ep_to_sockaddr(&ep, &sa);
+ *address_len = _addr_truncate(address, *address_len, &sa,
+ sa_len);
+ break;
+ }
+ }
}
return res;
}
-ssize_t send(int socket, const void *buffer, size_t length, int flags)
-{
- return sendto(socket, buffer, length, flags, NULL, 0);
-}
-
ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
const struct sockaddr *address, socklen_t address_len)
{
socket_t *s;
int res = 0;
- void *addr = NULL;
- size_t addr_len = 0;
- network_uint16_t port;
- port.u16 = 0;
+#if defined(MODULE_SOCK_IP) || defined(MODULE_SOCK_UDP)
+ struct _sock_tl_ep ep = { .port = 0 };
+#endif
+
(void)flags;
- mutex_lock(&_pool_mutex);
+ mutex_lock(&_socket_pool_mutex);
s = _get_socket(socket);
- mutex_unlock(&_pool_mutex);
+ mutex_unlock(&_socket_pool_mutex);
if (s == NULL) {
errno = ENOTSOCK;
return -1;
}
- if (address != NULL) {
- if (address->sa_family != s->domain) {
- errno = EAFNOSUPPORT;
+ if (s->sock == NULL) { /* socket is not connected */
+#ifdef MODULE_SOCK_TCP
+ if (s->type == SOCK_STREAM) {
+ errno = ENOTCONN;
return -1;
}
- if (_get_data_from_sockaddr(address, address_len, &addr, &addr_len, &port) < 0) {
+#endif
+ /* bind implicitly */
+ if ((res = _bind_connect(s, NULL, 0)) < 0) {
+ errno = -res;
return -1;
}
}
+#if defined(MODULE_SOCK_IP) || defined(MODULE_SOCK_UDP)
+ _sockaddr_to_ep(address, address_len, &ep);
+#endif
switch (s->type) {
-#ifdef MODULE_CONN_IP
+#ifdef MODULE_SOCK_IP
case SOCK_RAW:
- if ((address != NULL) && (s->bound)) {
- uint8_t src_addr[sizeof(ipv6_addr_t)];
- size_t src_len;
- int res = conn_ip_getlocaladdr(&s->conn.raw, src_addr);
- if (res < 0) {
- errno = ENOTSOCK; /* Something seems to be wrong with the socket */
- return -1;
- }
- src_len = (size_t)res;
- /* cppcheck bug? res is read below in l824 */
- /* cppcheck-suppress unreadVariable */
- res = conn_ip_sendto(buffer, length, src_addr, src_len, addr, addr_len, s->domain,
- s->protocol);
- }
- else if (address != NULL) {
- res = conn_ip_sendto(buffer, length, NULL, 0, addr, addr_len, s->domain,
- s->protocol);
- }
- else {
- errno = ENOTCONN;
- return -1;
- }
- if (res < 0) {
- errno = -res;
- return -1;
- }
+ res = sock_ip_send(&s->sock->raw, buffer, length,
+ s->protocol, (sock_ip_ep_t *)&ep);
break;
#endif
-#ifdef MODULE_CONN_TCP
+#ifdef MODULE_SOCK_TCP
case SOCK_STREAM:
- if (!s->bound) {
- errno = ENOTCONN;
- return -1;
- }
- if (address != NULL) {
- errno = EISCONN;
- return -1;
+ if (address == NULL) {
+ (void)address_len;
+ res = sock_tcp_write(&s->sock->tcp.sock, buffer, length);
}
- if ((res = conn_tcp_send(&s->conn.tcp, buffer, length)) < 0) {
- errno = -res;
- return -1;
+ else {
+ res = EISCONN;
}
break;
#endif
-#ifdef MODULE_CONN_UDP
+#ifdef MODULE_SOCK_UDP
case SOCK_DGRAM:
- if ((address != NULL) && (s->bound)) {
- uint8_t src_addr[sizeof(ipv6_addr_t)];
- size_t src_len;
- uint16_t sport;
- int res = conn_udp_getlocaladdr(&s->conn.udp, src_addr, &sport);
- if (res < 0) {
- errno = ENOTSOCK; /* Something seems to be wrong with the socket */
- return -1;
- }
- src_len = (size_t)res;
- /* cppcheck bug? res is read below in l824 */
- /* cppcheck-suppress unreadVariable */
- res = conn_udp_sendto(buffer, length, src_addr, src_len, addr, addr_len, s->domain,
- sport, byteorder_ntohs(port));
- }
- else if (address != NULL) {
- if ((res = _implicit_bind(s, addr)) < 0) {
- return res;
- }
- res = conn_udp_sendto(buffer, length, NULL, 0, addr, addr_len, s->domain,
- s->src_port, byteorder_ntohs(port));
- }
- else {
- errno = ENOTCONN;
- return -1;
- }
- if (res < 0) {
- errno = -res;
- return -1;
- }
+ res = sock_udp_send(&s->sock->udp, buffer, length, &ep);
break;
#endif
default:
- (void)buffer;
- (void)length;
- errno = EOPNOTSUPP;
- return -1;
+ res = -EOPNOTSUPP;
+ break;
}
return res;
}
-
/**
* @}
*/
diff --git a/tests/nhdp/Makefile b/tests/nhdp/Makefile
index 2783bf2eb..c776735a2 100644
--- a/tests/nhdp/Makefile
+++ b/tests/nhdp/Makefile
@@ -8,7 +8,7 @@ BOARD_INSUFFICIENT_MEMORY := nucleo-f334 stm32f0discovery weio nucleo-f030 \
nucleo32-f042
USEMODULE += gnrc_ipv6
-USEMODULE += gnrc_conn_udp
+USEMODULE += gnrc_sock_udp
USEMODULE += nhdp
include $(RIOTBASE)/Makefile.include
diff --git a/tests/pkg_libcoap/Makefile b/tests/pkg_libcoap/Makefile
index 0c1e1ce58..95dbab5a0 100644
--- a/tests/pkg_libcoap/Makefile
+++ b/tests/pkg_libcoap/Makefile
@@ -9,7 +9,7 @@ BOARD_INSUFFICIENT_MEMORY := chronos msb-430 msb-430h nucleo-f334 nucleo-f030 \
nucleo-f070 nucleo32-f042
USEMODULE += gnrc_ipv6
-USEMODULE += gnrc_conn_udp
+USEMODULE += gnrc_sock_udp
USEPKG += libcoap
include $(RIOTBASE)/Makefile.include
diff --git a/tests/pkg_oonf_api/Makefile b/tests/pkg_oonf_api/Makefile
index f699d513d..15f5b555d 100644
--- a/tests/pkg_oonf_api/Makefile
+++ b/tests/pkg_oonf_api/Makefile
@@ -4,7 +4,7 @@ include ../Makefile.tests_common
BOARD_WHITELIST := native
USEMODULE += gnrc_ipv6
-USEMODULE += gnrc_conn_udp
+USEMODULE += gnrc_sock_udp
USEMODULE += oonf_common
USEMODULE += oonf_rfc5444
USEPKG += oonf_api