mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
posix: redo socket API to use conn
This commit is contained in:
parent
fda6155071
commit
624530c7d0
11
Makefile.dep
11
Makefile.dep
@ -1,9 +1,5 @@
|
|||||||
ifneq (,$(filter libcoap,$(USEPKG)))
|
ifneq (,$(filter libcoap,$(USEPKG)))
|
||||||
USEMODULE += pnet
|
USEMODULE += posix_sockets
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq (,$(filter pnet,$(USEMODULE)))
|
|
||||||
USEMODULE += vtimer
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter gnrc_%,$(filter-out gnrc_netapi gnrc_netreg gnrc_netif% gnrc_pktbuf,$(USEMODULE))))
|
ifneq (,$(filter gnrc_%,$(filter-out gnrc_netapi gnrc_netreg gnrc_netif% gnrc_pktbuf,$(USEMODULE))))
|
||||||
@ -276,6 +272,11 @@ ifneq (,$(filter newlib,$(USEMODULE)))
|
|||||||
USEMODULE += uart_stdio
|
USEMODULE += uart_stdio
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter posix_sockets,$(USEMODULE)))
|
||||||
|
USEMODULE += posix
|
||||||
|
USEMODULE += random
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter posix,$(USEMODULE)))
|
ifneq (,$(filter posix,$(USEMODULE)))
|
||||||
USEMODULE += timex
|
USEMODULE += timex
|
||||||
USEMODULE += vtimer
|
USEMODULE += vtimer
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
ifneq (,$(filter pnet,$(USEMODULE)))
|
ifneq (,$(filter posix_sockets,$(USEMODULE)))
|
||||||
DIRS += posix/pnet
|
DIRS += posix/sockets
|
||||||
endif
|
endif
|
||||||
ifneq (,$(filter pthread,$(USEMODULE)))
|
ifneq (,$(filter pthread,$(USEMODULE)))
|
||||||
DIRS += posix/pthread
|
DIRS += posix/pthread
|
||||||
|
@ -18,7 +18,7 @@ ifneq (,$(filter posix,$(USEMODULE)))
|
|||||||
USEMODULE_INCLUDES += $(RIOTBASE)/sys/posix/include
|
USEMODULE_INCLUDES += $(RIOTBASE)/sys/posix/include
|
||||||
USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
|
USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
|
||||||
endif
|
endif
|
||||||
ifneq (,$(filter pnet,$(USEMODULE)))
|
ifneq (,$(filter posix_sockets,$(USEMODULE)))
|
||||||
USEMODULE_INCLUDES += $(RIOTBASE)/sys/posix/include
|
USEMODULE_INCLUDES += $(RIOTBASE)/sys/posix/include
|
||||||
endif
|
endif
|
||||||
ifneq (,$(filter pthread,$(USEMODULE)))
|
ifneq (,$(filter pthread,$(USEMODULE)))
|
||||||
|
@ -31,29 +31,13 @@
|
|||||||
#include "net/af.h"
|
#include "net/af.h"
|
||||||
#include "net/ipv4/addr.h"
|
#include "net/ipv4/addr.h"
|
||||||
#include "net/ipv6/addr.h"
|
#include "net/ipv6/addr.h"
|
||||||
#include "socket_base/socket.h"
|
#include "sys/bytes.h"
|
||||||
|
#include "netinet/in.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef uint16_t in_port_t; /**< Internet port type */
|
|
||||||
typedef uint32_t in_addr_t; /**< IPv4 address type */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Alias to @ref IPV4_ADDR_MAX_STR_LEN
|
|
||||||
*/
|
|
||||||
#ifndef INET_ADDRSTRLEN
|
|
||||||
#define INET_ADDRSTRLEN (IPV4_ADDR_MAX_STR_LEN)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Alias to @ref IPV6_ADDR_MAX_STR_LEN
|
|
||||||
*/
|
|
||||||
#ifndef INET6_ADDRSTRLEN
|
|
||||||
#define INET6_ADDRSTRLEN (IPV6_ADDR_MAX_STR_LEN)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Size in byte of an IPv4 address
|
* @brief Size in byte of an IPv4 address
|
||||||
*/
|
*/
|
||||||
@ -68,66 +52,6 @@ typedef uint32_t in_addr_t; /**< IPv4 address type */
|
|||||||
#define IN6ADDRSZ (sizeof(ipv6_addr_t))
|
#define IN6ADDRSZ (sizeof(ipv6_addr_t))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief IPv4 address structure type.
|
|
||||||
*/
|
|
||||||
struct in_addr {
|
|
||||||
in_addr_t s_addr; ///< an IPv4 address
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convert values between host and network byte order.
|
|
||||||
*
|
|
||||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/htonl.html">
|
|
||||||
* The Open Group Base Specification Issue 7, htonl
|
|
||||||
* </a>
|
|
||||||
*
|
|
||||||
* @param[in] hostlong A 32 bit number.
|
|
||||||
* @return The argument value converted from host to network byte
|
|
||||||
* order.
|
|
||||||
*/
|
|
||||||
#define htonl(hostlong) HTONL(hostlong)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convert values between host and network byte order.
|
|
||||||
*
|
|
||||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/htons.html">
|
|
||||||
* The Open Group Base Specification Issue 7, htons
|
|
||||||
* </a>
|
|
||||||
*
|
|
||||||
* @param[in] hostshort A 16 bit number.
|
|
||||||
* @return The argument value converted from host to network byte
|
|
||||||
* order.
|
|
||||||
*/
|
|
||||||
#define htons(hostshort) HTONS(hostshort)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convert values between host and network byte order.
|
|
||||||
*
|
|
||||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ntohl.html">
|
|
||||||
* The Open Group Base Specification Issue 7, ntohl
|
|
||||||
* </a>
|
|
||||||
*
|
|
||||||
* @param[in] netlong A 32-bit integer number.
|
|
||||||
* @return The argument value converted from network to host byte
|
|
||||||
* order.
|
|
||||||
*/
|
|
||||||
#define ntohl(netlong) NTOHL(netlong)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convert values between host and network byte order.
|
|
||||||
*
|
|
||||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ntohs.html">
|
|
||||||
* The Open Group Base Specification Issue 7, ntohs
|
|
||||||
* </a>
|
|
||||||
*
|
|
||||||
* @param[in] netshort A 16-bit integer number.
|
|
||||||
* @return The argument value converted from network to host byte
|
|
||||||
* order.
|
|
||||||
*/
|
|
||||||
#define ntohs(netshort) NTOHS(netshort)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Converts an IP address to its string representation
|
* @brief Converts an IP address to its string representation
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013 Freie Universität Berlin
|
* Copyright (C) 2013-15 Freie Universität Berlin
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* 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
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup pnet
|
* @addtogroup posix_sockets
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -25,105 +25,17 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include "net/gnrc/ipv6.h"
|
#include "net/protnum.h"
|
||||||
#include "socket_base/socket.h"
|
#include "net/ipv6/addr.h"
|
||||||
|
#include "sys/bytes.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
#define INET_ADDRSTRLEN (16) /**< Length of the string form for IPv4. */
|
||||||
* IPv4 socket address type.
|
#define INET6_ADDRSTRLEN (46) /**< Length of the string form for IPv6. */
|
||||||
*/
|
|
||||||
struct sockaddr_in {
|
|
||||||
sa_family_t sin_family; ///< Protocol family, always AF_INET.
|
|
||||||
in_port_t sin_port; ///< Port number
|
|
||||||
struct in_addr sin_addr; ///< IPv4 address
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IPv6 address structure type.
|
|
||||||
*/
|
|
||||||
struct in6_addr {
|
|
||||||
/**
|
|
||||||
* Private RIOT-internal data, needs not to be touched by the user.
|
|
||||||
*/
|
|
||||||
ipv6_addr_t __in6_u;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IPv6 Address represented as sequence of 8-bit numbers. Member of
|
|
||||||
* struct in6_addr.
|
|
||||||
*/
|
|
||||||
#define s6_addr __in6_u.uint8
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IPv6 Address represented as sequence of 16-bit numbers. Member of
|
|
||||||
* struct in6_addr.
|
|
||||||
*/
|
|
||||||
#define s6_addr16 __in6_u.uint16
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IPv6 Address represented as sequence of 32-bit numbers. Member of
|
|
||||||
* struct in6_addr.
|
|
||||||
*/
|
|
||||||
#define s6_addr32 __in6_u.uint32
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IPv6 socket address type.
|
|
||||||
*/
|
|
||||||
struct sockaddr_in6 {
|
|
||||||
/**
|
|
||||||
* Private RIOT-internal data, needs not to be touched by the user.
|
|
||||||
*/
|
|
||||||
sockaddr6_t __in6_a;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Protocol family, always AF_INET6. Member of struct sockaddr_in6
|
|
||||||
*/
|
|
||||||
#define sin6_family __in6_a.sin6_family
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Port number. Member of struct sockaddr_in6
|
|
||||||
*/
|
|
||||||
#define sin6_port __in6_a.sin6_port
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IPv6 traffic class and flow information. Member of struct sockaddr_in6
|
|
||||||
*/
|
|
||||||
#define sin6_flowinfo __in6_a.sin6_flowinfo
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IPv6 address. Member of struct sockaddr_in6
|
|
||||||
*/
|
|
||||||
#define sin6_addr __in6_a.sin6_addr
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set of interfaces for a scope.
|
|
||||||
*/
|
|
||||||
uint32_t sin6_scope_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IPv6 wildcard address.
|
|
||||||
*/
|
|
||||||
#define IN6ADDR_ANY_INIT {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IPv6 loopback address.
|
|
||||||
*/
|
|
||||||
#define IN6ADDR_LOOPBACK_INIT {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IPv6 socket address for the wildcard address.
|
|
||||||
*/
|
|
||||||
extern const struct sockaddr_in6 in6addr_any;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IPv6 socket address for the loopback address.
|
|
||||||
*/
|
|
||||||
extern const struct sockaddr_in6 in6addr_loopback;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IPv4 local host address.
|
* IPv4 local host address.
|
||||||
@ -136,24 +48,221 @@ extern const struct sockaddr_in6 in6addr_loopback;
|
|||||||
#define INADDR_BROADCAST ((in_addr_t)0xffffffff)
|
#define INADDR_BROADCAST ((in_addr_t)0xffffffff)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Multicast hop limit option name for getsockopt() or setsockopt()
|
* IPv6 wildcard address.
|
||||||
*
|
|
||||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html">
|
|
||||||
* The Open Group Base Specification Issue 7, getsockopt
|
|
||||||
* </a>
|
|
||||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html">
|
|
||||||
* The Open Group Base Specification Issue 7, setsockopt
|
|
||||||
* </a>
|
|
||||||
*/
|
*/
|
||||||
#define IPV6_MULTICAST_HOPS 0x12
|
#define IN6ADDR_ANY_INIT IPV6_ADDR_UNSPECIFIED
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for IPv6 multicast address.
|
* IPv6 loopback address.
|
||||||
*
|
|
||||||
* @param[in] a An IPv6 address.
|
|
||||||
* @return 1 if *a* is an multicast address, 0 if not.
|
|
||||||
*/
|
*/
|
||||||
#define IN6_IS_ADDR_MULTICAST(a) (((const uint8_t *) (a))[0] == 0xff)
|
#define IN6ADDR_LOOPBACK_INIT IPV6_ADDR_LOOPBACK
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name IPv6 address macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief Check if address is the unspecified address (`::`).
|
||||||
|
*
|
||||||
|
* @param[in] addr address of type `const struct in6_addr *`
|
||||||
|
*
|
||||||
|
* @return 0, when an address is not the unspecified address.
|
||||||
|
* @return any other value otherwise.
|
||||||
|
*/
|
||||||
|
#define IN6_IS_ADDR_UNSPECIFIED(addr) ((int)(ipv6_addr_is_unspecified((const ipv6_addr_t *)(addr))))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if address is the loopback address (`::1`).
|
||||||
|
*
|
||||||
|
* @param[in] addr address of type `const struct in6_addr *`
|
||||||
|
*
|
||||||
|
* @return 0, when an address is not the loopback address.
|
||||||
|
* @return any other value otherwise.
|
||||||
|
*/
|
||||||
|
#define IN6_IS_ADDR_LOOPBACK(addr) ((int)(ipv6_addr_is_loopback((const ipv6_addr_t *)(addr))))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if address is a multicast address.
|
||||||
|
*
|
||||||
|
* @param[in] addr address of type `const struct in6_addr *`
|
||||||
|
*
|
||||||
|
* @return 0, when an address is not a multicast address.
|
||||||
|
* @return any other value otherwise.
|
||||||
|
*/
|
||||||
|
#define IN6_IS_ADDR_MULTICAST(addr) ((int)(ipv6_addr_is_multicast((const ipv6_addr_t *)(addr))))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if address is a link-local address.
|
||||||
|
*
|
||||||
|
* @param[in] addr address of type `const struct in6_addr *`
|
||||||
|
*
|
||||||
|
* @return 0, when an address is not a link-local address.
|
||||||
|
* @return any other value otherwise.
|
||||||
|
*/
|
||||||
|
#define IN6_IS_ADDR_LINKLOCAL(addr) ((int)(ipv6_addr_is_link_local((const ipv6_addr_t *)addr)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if address is a site-local address.
|
||||||
|
*
|
||||||
|
* @param[in] addr address of type `const struct in6_addr *`
|
||||||
|
*
|
||||||
|
* @return 0, when an address is not a site-local address.
|
||||||
|
* @return any other value otherwise.
|
||||||
|
*/
|
||||||
|
#define IN6_IS_ADDR_SITELOCAL(addr) ((int)(ipv6_addr_is_site_local((const ipv6_addr_t *)addr)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if address is an IPv4 mapped address.
|
||||||
|
*
|
||||||
|
* @param[in] addr address of type `const struct in6_addr *`
|
||||||
|
*
|
||||||
|
* @return 0, when an address is not an IPv4 mapped address.
|
||||||
|
* @return any other value otherwise.
|
||||||
|
*/
|
||||||
|
#define IN6_IS_ADDR_V4MAPPED(addr) ((int)(ipv6_addr_is_ipv4_mapped((const ipv6_addr_t *)addr)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if address is an IPv4-compatible address.
|
||||||
|
*
|
||||||
|
* @param[in] addr address of type `const struct in6_addr *`
|
||||||
|
*
|
||||||
|
* @return 0, when an address is not an IPv4-compatible address.
|
||||||
|
* @return any other value otherwise.
|
||||||
|
*/
|
||||||
|
#define IN6_IS_ADDR_V4COMPAT(addr) ((int)(ipv6_addr_is_ipv4_compat((const ipv6_addr_t *)addr)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if address is a multicast node-local address.
|
||||||
|
*
|
||||||
|
* @param[in] addr address of type `const struct in6_addr *`
|
||||||
|
*
|
||||||
|
* @return 0, when an address is not a multicast node-local address.
|
||||||
|
* @return any other value otherwise.
|
||||||
|
*/
|
||||||
|
#define IN6_IS_ADDR_MC_NODELOCAL(addr) (IN6_IS_ADDR_MULTICAST(addr) && \
|
||||||
|
(int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_IF_LOCAL))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if address is a multicast link-local address.
|
||||||
|
*
|
||||||
|
* @param[in] addr address of type `const struct in6_addr *`
|
||||||
|
*
|
||||||
|
* @return 0, when an address is not a multicast link-local address.
|
||||||
|
* @return any other value otherwise.
|
||||||
|
*/
|
||||||
|
#define IN6_IS_ADDR_MC_LINKLOCAL(addr) (IN6_IS_ADDR_MULTICAST(addr) && \
|
||||||
|
(int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_LINK_LOCAL))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if address is a multicast site-local address.
|
||||||
|
*
|
||||||
|
* @param[in] addr address of type `const struct in6_addr *`
|
||||||
|
*
|
||||||
|
* @return 0, when an address is not a multicast site-local address.
|
||||||
|
* @return any other value otherwise.
|
||||||
|
*/
|
||||||
|
#define IN6_IS_ADDR_MC_SITELOCAL(addr) (IN6_IS_ADDR_MULTICAST(addr) && \
|
||||||
|
(int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_SITE_LOCAL))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if address is a multicast organization-local address.
|
||||||
|
*
|
||||||
|
* @param[in] addr address of type `const struct in6_addr *`
|
||||||
|
*
|
||||||
|
* @return 0, when an address is not a multicast organization-local address.
|
||||||
|
* @return any other value otherwise.
|
||||||
|
*/
|
||||||
|
#define IN6_IS_ADDR_MC_ORGLOCAL(addr) (IN6_IS_ADDR_MULTICAST(addr) && \
|
||||||
|
(int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_ORG_LOCAL))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if address is a multicast global address.
|
||||||
|
*
|
||||||
|
* @param[in] addr address of type `const struct in6_addr *`
|
||||||
|
*
|
||||||
|
* @return 0, when an address is not a multicast global address.
|
||||||
|
* @return any other value otherwise.
|
||||||
|
*/
|
||||||
|
#define IN6_IS_ADDR_MC_GLOBAL(addr) (IN6_IS_ADDR_MULTICAST(addr) && \
|
||||||
|
(int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_GLOBAL))
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Protocol numbers for option
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define IPPROTO_IP (PROTNUM_IPV4) /**< Internet Protocol version 4 */
|
||||||
|
#define IPPROTO_IPV6 (PROTNUM_IPV6) /**< Internet Protocol version 6 */
|
||||||
|
#define IPPROTO_ICMP (PROTNUM_ICMP) /**< Internet Control Message Protocol */
|
||||||
|
#define IPPROTO_ICMPV6 (PROTNUM_ICMPV6) /**< ICMP for IPv6 */
|
||||||
|
#define IPPROTO_RAW (PROTNUM_RESERVED) /**< Raw IP packets protocol */
|
||||||
|
#define IPPROTO_TCP (PROTNUM_TCP) /**< Transmission control protocol */
|
||||||
|
#define IPPROTO_UDP (PROTNUM_UDP) /**< User datagram protocol */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo IPv6 option names
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef uint16_t in_port_t; /**< Internet port type */
|
||||||
|
typedef uint32_t in_addr_t; /**< IPv4 address type */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IPv4 address structure type.
|
||||||
|
*/
|
||||||
|
struct in_addr {
|
||||||
|
in_addr_t s_addr; /**< an IPv4 address */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IPv6 address structure type.
|
||||||
|
*/
|
||||||
|
struct in6_addr {
|
||||||
|
uint8_t s6_addr[16]; /**< unsigned 8-bit integer array */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IPv4 socket address type.
|
||||||
|
* @extends struct sockaddr
|
||||||
|
*/
|
||||||
|
struct sockaddr_in {
|
||||||
|
sa_family_t sin_family; /**< Protocol family, always AF_INET */
|
||||||
|
in_port_t sin_port; /**< Port number */
|
||||||
|
struct in_addr sin_addr; /**< IPv4 address */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IPv6 socket address type.
|
||||||
|
* @extends struct sockaddr
|
||||||
|
*/
|
||||||
|
struct sockaddr_in6 {
|
||||||
|
/**
|
||||||
|
* Protocol family, always AF_INET6. Member of struct sockaddr_in6
|
||||||
|
*/
|
||||||
|
int sin6_family; /**< Protocol family, always AF_INET6 */
|
||||||
|
in_port_t sin6_port; /**< Port number */
|
||||||
|
uint32_t sin6_flowinfo; /**< IPv6 traffic class and flow information */
|
||||||
|
struct in6_addr sin6_addr; /**< IPv6 address */
|
||||||
|
uint32_t sin6_scope_id; /**< Set of interfaces for a scope */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IPv6 multicast request.
|
||||||
|
*/
|
||||||
|
struct ipv6_mreq {
|
||||||
|
struct in6_addr ipv6mr_multiaddr; /**< an IPv6 multicast address */
|
||||||
|
unsigned ipv6mr_interface; /**< interface index, leave 0 for default */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IPv6 socket address for the wildcard address.
|
||||||
|
*/
|
||||||
|
extern const struct sockaddr_in6 in6addr_any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IPv6 socket address for the loopback address.
|
||||||
|
*/
|
||||||
|
extern const struct sockaddr_in6 in6addr_loopback;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
96
sys/posix/include/sys/bytes.h
Normal file
96
sys/posix/include/sys/bytes.h
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup posix_sockets
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief System-internal byte operations.
|
||||||
|
*
|
||||||
|
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||||
|
*/
|
||||||
|
#ifndef BYTES_H_
|
||||||
|
#define BYTES_H_
|
||||||
|
|
||||||
|
#include "byteorder.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert values between host and network byte order.
|
||||||
|
*
|
||||||
|
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/htonl.html">
|
||||||
|
* The Open Group Base Specification Issue 7, htonl
|
||||||
|
* </a>
|
||||||
|
*
|
||||||
|
* @param[in] hostlong A 32 bit number.
|
||||||
|
* @return The argument value converted from host to network byte
|
||||||
|
* order.
|
||||||
|
*/
|
||||||
|
#ifndef htonl
|
||||||
|
#define htonl(hostlong) HTONL(hostlong)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert values between host and network byte order.
|
||||||
|
*
|
||||||
|
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/htons.html">
|
||||||
|
* The Open Group Base Specification Issue 7, htons
|
||||||
|
* </a>
|
||||||
|
*
|
||||||
|
* @param[in] hostshort A 16 bit number.
|
||||||
|
* @return The argument value converted from host to network byte
|
||||||
|
* order.
|
||||||
|
*/
|
||||||
|
#ifndef htons
|
||||||
|
#define htons(hostshort) HTONS(hostshort)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert values between host and network byte order.
|
||||||
|
*
|
||||||
|
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ntohl.html">
|
||||||
|
* The Open Group Base Specification Issue 7, ntohl
|
||||||
|
* </a>
|
||||||
|
*
|
||||||
|
* @param[in] netlong A 32-bit integer number.
|
||||||
|
* @return The argument value converted from network to host byte
|
||||||
|
* order.
|
||||||
|
*/
|
||||||
|
#ifndef ntohl
|
||||||
|
#define ntohl(netlong) NTOHL(netlong)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert values between host and network byte order.
|
||||||
|
*
|
||||||
|
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ntohs.html">
|
||||||
|
* The Open Group Base Specification Issue 7, ntohs
|
||||||
|
* </a>
|
||||||
|
*
|
||||||
|
* @param[in] netshort A 16-bit integer number.
|
||||||
|
* @return The argument value converted from network to host byte
|
||||||
|
* order.
|
||||||
|
*/
|
||||||
|
#ifndef ntohs
|
||||||
|
#define ntohs(netshort) NTOHS(netshort)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef size_t socklen_t; /**< socket address length */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* BYTES_H_ */
|
||||||
|
/** @} */
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013 Freie Universität Berlin
|
* Copyright (C) 2013-15 Freie Universität Berlin
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* 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
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup pnet
|
* @addtogroup posix_sockets
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -18,6 +18,12 @@
|
|||||||
* The Open Group Base Specifications Issue 7, <sys/socket.h>
|
* The Open Group Base Specifications Issue 7, <sys/socket.h>
|
||||||
* </a>
|
* </a>
|
||||||
*
|
*
|
||||||
|
* @todo Omitted from original specification for now:
|
||||||
|
* * struct msghdr, struct cmesghdr, and struct linger and all related defines
|
||||||
|
* * getsockopt()/setsockopt() and all related defines.
|
||||||
|
* * shutdown() and all related defines.
|
||||||
|
* * sockatmark()
|
||||||
|
*
|
||||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||||
*/
|
*/
|
||||||
#ifndef _SYS_SOCKET_H
|
#ifndef _SYS_SOCKET_H
|
||||||
@ -32,135 +38,81 @@
|
|||||||
#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))
|
#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "kernel_types.h"
|
||||||
#include "net/af.h"
|
#include "net/af.h"
|
||||||
|
#include "sys/bytes.h"
|
||||||
#include "socket_base/socket.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum data length for a socket address.
|
||||||
|
*
|
||||||
|
* It is assumed that struct sockaddr_in6 is currently the longest socket address struct.
|
||||||
|
* As such it's data length is taken consisting of the IPv6 address (16 byte), the port (2 byte),
|
||||||
|
* the flow information (4 byte) and the scope ID (4 byte)
|
||||||
|
*/
|
||||||
|
#define SOCKADDR_MAX_DATA_LEN (26)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Socket types
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SOCK_DGRAM (1) /**< Datagram socket */
|
||||||
|
#define SOCK_RAW (2) /**< Raw socket */
|
||||||
|
#define SOCK_SEQPACKET (3) /**< Sequenced-packet socket */
|
||||||
|
#define SOCK_STREAM (4) /**< Stream socket */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#define SOL_SOCKET (-1) /**< Options to be accessed at socket level, not protocol level */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Option names
|
||||||
|
* @brief Option names for getsockopt() and setsockopt()
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SO_ACCEPTCONN (0) /**< Socket is accepting connections. */
|
||||||
|
#define SO_BROADCAST (1) /**< Transmission of broadcast messages is supported. */
|
||||||
|
#define SO_DEBUG (2) /**< Debugging information is being recorded. */
|
||||||
|
#define SO_DONTROUTE (3) /**< Bypass normal routing. */
|
||||||
|
#define SO_ERROR (4) /**< Socket error status. */
|
||||||
|
#define SO_KEEPALIVE (5) /**< Connections are kept alive with periodic messages. */
|
||||||
|
#define SO_LINGER (6) /**< Socket lingers on close. */
|
||||||
|
#define SO_OOBINLINE (7) /**< Out-of-band data is transmitted in line. */
|
||||||
|
#define SO_RCVBUF (8) /**< Receive buffer size. */
|
||||||
|
#define SO_RCVLOWAT (9) /**< Receive "low water mark". */
|
||||||
|
#define SO_RCVTIMEO (10) /**< Receive timeout. */
|
||||||
|
#define SO_REUSEADDR (11) /**< Reuse of local addresses is supported. */
|
||||||
|
#define SO_SNDBUF (12) /**< Send buffer size. */
|
||||||
|
#define SO_SNDLOWAT (13) /**< Send "low water mark". */
|
||||||
|
#define SO_SNDTIMEO (14) /**< Send timeout. */
|
||||||
|
#define SO_TYPE (15) /**< Socket type. */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
typedef unsigned int sa_family_t; /**< address family type */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Used to define the socket address.
|
* @brief Used to define the socket address.
|
||||||
*/
|
*/
|
||||||
struct __attribute__((packed)) sockaddr {
|
struct sockaddr {
|
||||||
sa_family_t sa_family; ///< Address family
|
sa_family_t sa_family; /**< Address family */
|
||||||
char sa_data[14]; ///< Socket address (variable length data)
|
char sa_data[SOCKADDR_MAX_DATA_LEN]; /**< Socket address (variable length data) */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implementation based socket address table.
|
* @brief Implementation based socket address table.
|
||||||
|
* @extends struct sockaddr
|
||||||
*/
|
*/
|
||||||
struct __attribute__((packed)) sockaddr_storage {
|
struct sockaddr_storage {
|
||||||
sa_family_t ss_family; ///< Address family
|
sa_family_t ss_family; /**< Address family */
|
||||||
char ss_data[14]; ///< address data
|
uint8_t ss_data[SOCKADDR_MAX_DATA_LEN]; /**< Socket address */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Omitted from original specification for now are struct msghdr,
|
|
||||||
* struct cmesghdr, and struct linger and all related defines
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *level* value for getsockopt() or setsockopt().
|
|
||||||
*/
|
|
||||||
#define SOL_SOCKET 1 ///< Options to be accessed at socket level, not
|
|
||||||
///< protocol level.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_ACCEPTCONN 1 ///< Socket is accepting connections.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_BROADCAST 2 ///< Transmission of broadcast messages is supported.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_DEBUG 3 ///< Debugging information is being recorded.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_DONTROUTE 4 ///< Bypass normal routing.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_ERROR 5 ///< Socket error status.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_KEEPALIVE 6 ///< Connections are kept alive with periodic messages.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_OOBINLINE 7 ///< Out-of-band data is transmitted in line.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_RCVBUF 8 ///< Receive buffer size.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_RCVLOWAT 9 ///< Receive "low water mark".
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_RCVTIMEO 10 ///< Receive timeout.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_REUSEADDR 11 ///< Reuse of local addresses is supported.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_SNDBUF 12 ///< Send buffer size.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_SNDLOWAT 13 ///< Send "low water mark".
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_SNDTIMEO 14 ///< Send timeout.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
|
||||||
*/
|
|
||||||
#define SO_TYPE 15 ///< Socket type.
|
|
||||||
|
|
||||||
#define SOMAXCONN 16 ///< Maximum *backlog* size for listen()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *how* value for shutdown()
|
|
||||||
*/
|
|
||||||
#define SHUT_WR 1 ///< Disables further send operations.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *how* value for shutdown()
|
|
||||||
*/
|
|
||||||
#define SHUT_RD 2 ///< Disables further receive operations.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief *how* value for shutdown()
|
|
||||||
*/
|
|
||||||
#define SHUT_RDWR 3 ///< Disables further send and receive operations.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Accept a new connection on a socket
|
* @brief Accept a new connection on a socket
|
||||||
@ -260,27 +212,56 @@ int bind(int socket, const struct sockaddr *address,
|
|||||||
int connect(int socket, const struct sockaddr *address, socklen_t address_len);
|
int connect(int socket, const struct sockaddr *address, socklen_t address_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the socket options.
|
* @brief Get the name of the peer socket.
|
||||||
|
* @details The getpeername() function shall retrieve the peer address of the specified socket,
|
||||||
|
* store this address in the sockaddr structure pointed to by the @p address argument,
|
||||||
|
* and store the length of this address in the object pointed to by the @p address_len
|
||||||
|
* argument.
|
||||||
*
|
*
|
||||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html">
|
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html">
|
||||||
* The Open Group Base Specification Issue 7, getsockopt
|
* The Open Group Base Specification Issue 7, getpeername
|
||||||
* </a>
|
* </a>
|
||||||
*
|
*
|
||||||
* @param[in] socket Specifies the file descriptor associated with the socket.
|
* @param[in] socket Specifies the file descriptor associated with the
|
||||||
* @param[in] level Protocol level this option applies to. Valid values
|
* socket.
|
||||||
* are defined in <sys/socket.h>, prefixed with
|
* @param[out] address Points to a sockaddr structure containing the peer
|
||||||
* ``SOL_``.
|
* address. The length and format of the address depend
|
||||||
* @param[in] option_name Defines the option to get. Valid values are defined
|
* on the address family of the socket.
|
||||||
* in <sys/socket.h>, prefixed with ``SO_``.
|
* @param[in,out] address_len Specifies the length of the sockaddr structure on input and the
|
||||||
* @param[out] option_value Buffer to write the current value of the socket
|
* length of the stored address on output. If the address is greater
|
||||||
* option into.
|
* than the length of the supplied sockaddr structure, the stored
|
||||||
* @param[out] option_len Length of the option value in byte.
|
* address shal be truncated.
|
||||||
*
|
* @return Upon successful completion, getpeername() shall return 0; otherwise,
|
||||||
* @return Upon successful completion, getsockopt() shall return 0; otherwise,
|
|
||||||
* -1 shall be returned and errno set to indicate the error.
|
* -1 shall be returned and errno set to indicate the error.
|
||||||
*/
|
*/
|
||||||
int getsockopt(int socket, int level, int option_name,
|
int getpeername(int socket, struct sockaddr *__restrict address,
|
||||||
void *__restrict option_value, socklen_t *__restrict option_len);
|
socklen_t *__restrict address_len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the socket name.
|
||||||
|
* @details The getsockname() function shall retrieve the locally-bound name of the specified
|
||||||
|
* socket, store this address in the sockaddr structure pointed to by the @p address
|
||||||
|
* argument, and store the length of this address in the object pointed to by the
|
||||||
|
* @p address_len argument.
|
||||||
|
*
|
||||||
|
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html">
|
||||||
|
* The Open Group Base Specification Issue 7, getsockname
|
||||||
|
* </a>
|
||||||
|
*
|
||||||
|
* @param[in] socket Specifies the file descriptor associated with the
|
||||||
|
* socket.
|
||||||
|
* @param[out] address Points to a sockaddr structure containing the peer
|
||||||
|
* address. The length and format of the address depend
|
||||||
|
* on the address family of the socket.
|
||||||
|
* @param[in,out] address_len Specifies the length of the sockaddr structure on input and the
|
||||||
|
* length of the stored address on output. If the address is greater
|
||||||
|
* than the length of the supplied sockaddr structure, the stored
|
||||||
|
* address shal be truncated.
|
||||||
|
* @return Upon successful completion, getsockname() shall return 0; otherwise,
|
||||||
|
* -1 shall be returned and errno set to indicate the error.
|
||||||
|
*/
|
||||||
|
int getsockname(int socket, struct sockaddr *__restrict address,
|
||||||
|
socklen_t *__restrict address_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Listen for socket connections and limit the queue of incoming
|
* @brief Listen for socket connections and limit the queue of incoming
|
||||||
@ -396,9 +377,9 @@ ssize_t send(int socket, const void *buffer, size_t length, int flags);
|
|||||||
* @details Shall send a message through a connection-mode or
|
* @details Shall send a message through a connection-mode or
|
||||||
* connectionless-mode socket. If the socket is a connectionless-mode
|
* connectionless-mode socket. If the socket is a connectionless-mode
|
||||||
* socket, the message shall be sent to the address specified by
|
* socket, the message shall be sent to the address specified by
|
||||||
* *dest_addr* if no pre-specified peer address has been set. If a
|
* @p address if no pre-specified peer address has been set. If a
|
||||||
* peer address has been pre-specified, either the message shall be
|
* peer address has been pre-specified, either the message shall be
|
||||||
* sent to the address specified by *dest_addr* (overriding the
|
* sent to the address specified by @p address (overriding the
|
||||||
* pre-specified peer address), or the function shall return -1 and
|
* pre-specified peer address), or the function shall return -1 and
|
||||||
* set errno to EISCONN.
|
* set errno to EISCONN.
|
||||||
*
|
*
|
||||||
@ -406,45 +387,23 @@ ssize_t send(int socket, const void *buffer, size_t length, int flags);
|
|||||||
* The Open Group Base Specification Issue 7, sendto
|
* The Open Group Base Specification Issue 7, sendto
|
||||||
* </a>
|
* </a>
|
||||||
*
|
*
|
||||||
* @param[in] socket Specifies the socket file descriptor.
|
* @param[in] socket Specifies the socket file descriptor.
|
||||||
* @param[in] message Points to the buffer containing the message to send.
|
* @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] length Specifies the length of the message in bytes.
|
||||||
* @param[in] flags Specifies the type of message reception. Support
|
* @param[in] flags Specifies the type of message reception. Support
|
||||||
* for values other than 0 is not implemented yet.
|
* for values other than 0 is not implemented yet.
|
||||||
* @param[in] dest_addr Points to a sockaddr structure containing the
|
* @param[in] address Points to a sockaddr structure containing the
|
||||||
* destination address. The length and format of the
|
* destination address. The length and format of the
|
||||||
* address depend on the address family of the socket.
|
* address depend on the address family of the socket.
|
||||||
* @param[in] dest_len Specifies the length of the sockaddr structure pointed
|
* @param[in] address_len Specifies the length of the sockaddr structure pointed
|
||||||
* to by the *dest_addr* argument.
|
* to by the @p address argument.
|
||||||
*
|
*
|
||||||
* @return Upon successful completion, send() shall return the number of bytes
|
* @return Upon successful completion, send() shall return the number of bytes
|
||||||
* sent. Otherwise, -1 shall be returned and errno set to indicate the
|
* sent. Otherwise, -1 shall be returned and errno set to indicate the
|
||||||
* error.
|
* error.
|
||||||
*/
|
*/
|
||||||
ssize_t sendto(int socket, const void *message, size_t length, int flags,
|
ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
|
||||||
const struct sockaddr *dest_addr, socklen_t dest_len);
|
const struct sockaddr *address, socklen_t address_len);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the socket options.
|
|
||||||
*
|
|
||||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html">
|
|
||||||
* The Open Group Base Specification Issue 7, setsockopt
|
|
||||||
* </a>
|
|
||||||
*
|
|
||||||
* @param[in] socket Specifies the file descriptor associated with the socket.
|
|
||||||
* @param[in] level Protocol level this option applies to. Valid values
|
|
||||||
* are defined in <sys/socket.h>, prefixed with
|
|
||||||
* ``SOL_``.
|
|
||||||
* @param[in] option_name Defines the option to set. Valid values are defined
|
|
||||||
* in <sys/socket.h>, prefixed with ``SO_``.
|
|
||||||
* @param[in] option_value Value for the option to set.
|
|
||||||
* @param[in] option_len Length of the option value in byte.
|
|
||||||
*
|
|
||||||
* @return Upon successful completion, setsockopt() shall return 0; otherwise,
|
|
||||||
* -1 shall be returned and errno set to indicate the error.
|
|
||||||
*/
|
|
||||||
int setsockopt(int socket, int level, int option_name, const void *option_value,
|
|
||||||
socklen_t option_len);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create an endpoint for communication.
|
* @brief Create an endpoint for communication.
|
||||||
@ -469,6 +428,34 @@ int setsockopt(int socket, int level, int option_name, const void *option_value,
|
|||||||
*/
|
*/
|
||||||
int socket(int domain, int type, int protocol);
|
int socket(int domain, int type, int protocol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo implement out these functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
static inline int getsockopt(int socket, int level, int option_name, void *option_value,
|
||||||
|
socklen_t *option_len)
|
||||||
|
{
|
||||||
|
(void)socket;
|
||||||
|
(void)level;
|
||||||
|
(void)option_name;
|
||||||
|
(void)option_value;
|
||||||
|
(void)option_len;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int setsockopt(int socket, int level, int option_name, const void *option_value,
|
||||||
|
socklen_t option_len)
|
||||||
|
{
|
||||||
|
(void)socket;
|
||||||
|
(void)level;
|
||||||
|
(void)option_name;
|
||||||
|
(void)option_value;
|
||||||
|
(void)option_len;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{
|
|
||||||
* @file
|
|
||||||
* @brief Providing values for in6addr_any and in6addr_loopback.
|
|
||||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
|
||||||
*/
|
|
||||||
#include <netinet/in.h>
|
|
||||||
|
|
||||||
const struct sockaddr_in6 in6addr_any = {{AF_INET6, 0, 0, IN6ADDR_ANY_INIT}, 0};
|
|
||||||
const struct sockaddr_in6 in6addr_loopback = {{
|
|
||||||
AF_INET6, 0, 0, IN6ADDR_LOOPBACK_INIT
|
|
||||||
}, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
@ -1,154 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{
|
|
||||||
* @file
|
|
||||||
* @brief Providing implementation for POSIX socket wrapper.
|
|
||||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
|
||||||
* @todo
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sys/socket.h"
|
|
||||||
|
|
||||||
int flagless_send(int fd, const void *buf, size_t len)
|
|
||||||
{
|
|
||||||
(void)fd;
|
|
||||||
(void)buf;
|
|
||||||
(void)len;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int flagless_recv(int fd, void *buf, size_t len)
|
|
||||||
{
|
|
||||||
return (int)socket_base_recv(fd, buf, (uint32_t)len, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int socket(int domain, int type, int protocol)
|
|
||||||
{
|
|
||||||
(void)domain;
|
|
||||||
(void)type;
|
|
||||||
(void)protocol;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int accept(int socket, struct sockaddr *restrict address,
|
|
||||||
socklen_t *restrict address_len)
|
|
||||||
{
|
|
||||||
(void)socket;
|
|
||||||
(void)address;
|
|
||||||
(void)address_len;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bind(int socket, const struct sockaddr *address, socklen_t address_len)
|
|
||||||
{
|
|
||||||
(void)socket;
|
|
||||||
(void)address;
|
|
||||||
(void)address_len;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int connect(int socket, const struct sockaddr *address, socklen_t address_len)
|
|
||||||
{
|
|
||||||
(void)socket;
|
|
||||||
(void)address;
|
|
||||||
(void)address_len;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getsockopt(int socket, int level, int option_name,
|
|
||||||
void *restrict option_value, socklen_t *restrict option_len)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
(void) socket;
|
|
||||||
(void) level;
|
|
||||||
(void) option_name;
|
|
||||||
(void) option_value;
|
|
||||||
(void) option_len;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int listen(int socket, int backlog)
|
|
||||||
{
|
|
||||||
(void)socket;
|
|
||||||
(void)backlog;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t recv(int socket, void *buffer, size_t length, int flags)
|
|
||||||
{
|
|
||||||
(void)socket;
|
|
||||||
(void)buffer;
|
|
||||||
(void)length;
|
|
||||||
(void)flags;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
|
|
||||||
struct sockaddr *restrict address,
|
|
||||||
socklen_t *restrict address_len)
|
|
||||||
{
|
|
||||||
(void)socket;
|
|
||||||
(void)buffer;
|
|
||||||
(void)length;
|
|
||||||
(void)flags;
|
|
||||||
(void)address;
|
|
||||||
(void)address_len;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t send(int socket, const void *buffer, size_t length, int flags)
|
|
||||||
{
|
|
||||||
(void)socket;
|
|
||||||
(void)buffer;
|
|
||||||
(void)length;
|
|
||||||
(void)flags;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t sendto(int socket, const void *message, size_t length, int flags,
|
|
||||||
const struct sockaddr *dest_addr, socklen_t dest_len)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
(void)socket;
|
|
||||||
(void)message;
|
|
||||||
(void)length;
|
|
||||||
(void)flags;
|
|
||||||
(void)dest_addr;
|
|
||||||
(void)dest_len;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int setsockopt(int socket, int level, int option_name, const void *option_value,
|
|
||||||
socklen_t option_len)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
(void) socket;
|
|
||||||
(void) level;
|
|
||||||
(void) option_name;
|
|
||||||
(void) option_value;
|
|
||||||
(void) option_len;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
@ -1 +1,3 @@
|
|||||||
|
MODULE = posix_sockets
|
||||||
|
|
||||||
include $(RIOTBASE)/Makefile.base
|
include $(RIOTBASE)/Makefile.base
|
@ -7,8 +7,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup pnet Network related POSIX wrapper of RIOT
|
* @defgroup posix_sockets POSIX sockets
|
||||||
* @brief Network related POSIX header files
|
* @brief POSIX socket wrapper of RIOT's @ref net_conn
|
||||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/">
|
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/">
|
||||||
* The Open Group Specifications Issue 7
|
* The Open Group Specifications Issue 7
|
||||||
* </a>
|
* </a>
|
890
sys/posix/sockets/posix_sockets.c
Normal file
890
sys/posix/sockets/posix_sockets.c
Normal file
@ -0,0 +1,890 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @{
|
||||||
|
* @file
|
||||||
|
* @brief Providing implementation for POSIX socket wrapper.
|
||||||
|
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||||
|
* @todo
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "fd.h"
|
||||||
|
#include "mutex.h"
|
||||||
|
#include "net/conn.h"
|
||||||
|
#include "net/ipv4/addr.h"
|
||||||
|
#include "net/ipv6/addr.h"
|
||||||
|
#include "random.h"
|
||||||
|
|
||||||
|
#include "sys/socket.h"
|
||||||
|
#include "netinet/in.h"
|
||||||
|
|
||||||
|
#define SOCKET_POOL_SIZE (4)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unitfied connection type.
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
|
/* is not supposed to be used */
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int fd;
|
||||||
|
sa_family_t domain;
|
||||||
|
int type;
|
||||||
|
int protocol;
|
||||||
|
bool bound;
|
||||||
|
socket_conn_t conn;
|
||||||
|
} socket_t;
|
||||||
|
|
||||||
|
socket_t _pool[SOCKET_POOL_SIZE];
|
||||||
|
mutex_t _pool_mutex = MUTEX_INIT;
|
||||||
|
|
||||||
|
const struct sockaddr_in6 in6addr_any = {AF_INET6, 0, 0, IN6ADDR_ANY_INIT, 0};
|
||||||
|
const struct sockaddr_in6 in6addr_loopback = {
|
||||||
|
AF_INET6, 0, 0, IN6ADDR_LOOPBACK_INIT, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static socket_t *_get_socket(int fd)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < SOCKET_POOL_SIZE; i++) {
|
||||||
|
if (_pool[i].fd == fd) {
|
||||||
|
return &_pool[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int _choose_ipproto(int type, int protocol)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
#ifdef MODULE_CONN_TCP
|
||||||
|
case SOCK_STREAM:
|
||||||
|
if ((protocol == 0) || (protocol == IPPROTO_TCP)) {
|
||||||
|
return protocol;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errno = EPROTOTYPE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef MODULE_CONN_UDP
|
||||||
|
case SOCK_DGRAM:
|
||||||
|
if ((protocol == 0) || (protocol == IPPROTO_UDP)) {
|
||||||
|
return protocol;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errno = EPROTOTYPE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef MODULE_CONN_IP
|
||||||
|
case SOCK_RAW:
|
||||||
|
return protocol;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
(void)protocol;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
errno = EPROTONOSUPPORT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _htons_port(uint16_t *port)
|
||||||
|
{
|
||||||
|
*port = htons(*port);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
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, uint16_t *port)
|
||||||
|
{
|
||||||
|
switch (address->sa_family) {
|
||||||
|
case AF_INET:
|
||||||
|
if (address_len < sizeof(struct sockaddr_in)) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
struct sockaddr_in *in_addr = (struct sockaddr_in *)address;
|
||||||
|
*addr = &in_addr->sin_addr;
|
||||||
|
*addr_len = sizeof(ipv4_addr_t);
|
||||||
|
/* XXX sin_port is in network byteorder */
|
||||||
|
*port = ntohs(in_addr->sin_port);
|
||||||
|
break;
|
||||||
|
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);
|
||||||
|
/* XXX sin6_port is in network byteorder */
|
||||||
|
*port = ntohs(in6_addr->sin6_port);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errno = EAFNOSUPPORT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
#endif
|
||||||
|
#ifdef MODULE_CONN_TCP
|
||||||
|
case SOCK_STREAM:
|
||||||
|
conn_tcp_close(&s->conn.tcp);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
res = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
res = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s->domain = AF_UNSPEC;
|
||||||
|
mutex_unlock(&_pool_mutex);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t socket_read(int socket, void *buf, size_t n)
|
||||||
|
{
|
||||||
|
return recv(socket, buf, n, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t socket_write(int socket, const void *buf, size_t n)
|
||||||
|
{
|
||||||
|
return send(socket, buf, n, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int socket(int domain, int type, int protocol)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
socket_t *s;
|
||||||
|
mutex_lock(&_pool_mutex);
|
||||||
|
s = _get_free_socket();
|
||||||
|
if (s == NULL) {
|
||||||
|
errno = ENFILE;
|
||||||
|
mutex_unlock(&_pool_mutex);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
switch (domain) {
|
||||||
|
case AF_INET:
|
||||||
|
case AF_INET6:
|
||||||
|
s->domain = domain;
|
||||||
|
s->type = type;
|
||||||
|
if ((s->protocol = _choose_ipproto(type, protocol)) < 0) {
|
||||||
|
res = -1;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
mutex_unlock(&_pool_mutex);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int accept(int socket, struct sockaddr *restrict address,
|
||||||
|
socklen_t *restrict address_len)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
s = _get_socket(socket);
|
||||||
|
if (s == NULL) {
|
||||||
|
mutex_unlock(&_pool_mutex);
|
||||||
|
errno = ENOTSOCK;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!s->bound) {
|
||||||
|
mutex_unlock(&_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();
|
||||||
|
if (new_s == NULL) {
|
||||||
|
errno = ENFILE;
|
||||||
|
res = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((res = conn_tcp_accept(&s->conn.tcp, &new_s->conn.tcp)) < 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);
|
||||||
|
if (fd < 0) {
|
||||||
|
errno = ENFILE;
|
||||||
|
res = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
new_s->fd = res = fd;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
_htons_port(port); /* XXX: sin(6)_port is supposed to be network byte
|
||||||
|
* order */
|
||||||
|
*address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
res = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mutex_unlock(&_pool_mutex);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bind(int socket, const struct sockaddr *address, socklen_t address_len)
|
||||||
|
{
|
||||||
|
socket_t *s;
|
||||||
|
int res = 0;
|
||||||
|
void *addr;
|
||||||
|
size_t addr_len;
|
||||||
|
uint16_t port;
|
||||||
|
mutex_lock(&_pool_mutex);
|
||||||
|
s = _get_socket(socket);
|
||||||
|
mutex_unlock(&_pool_mutex);
|
||||||
|
if (s == NULL) {
|
||||||
|
errno = ENOTSOCK;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (address->sa_family != s->domain) {
|
||||||
|
errno = EAFNOSUPPORT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (_get_data_from_sockaddr(address, address_len, &addr, &addr_len, &port) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
switch (s->type) {
|
||||||
|
#ifdef MODULE_CONN_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
|
||||||
|
case SOCK_STREAM:
|
||||||
|
if ((res = conn_tcp_create(&s->conn.tcp, addr, addr_len, s->domain, port)) < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef MODULE_CONN_UDP
|
||||||
|
case SOCK_DGRAM:
|
||||||
|
if ((res = conn_udp_create(&s->conn.udp, addr, addr_len, s->domain, port)) < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
(void)addr;
|
||||||
|
(void)addr_len;
|
||||||
|
(void)port;
|
||||||
|
(void)res;
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
s->bound = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int connect(int socket, const struct sockaddr *address, socklen_t address_len)
|
||||||
|
{
|
||||||
|
socket_t *s;
|
||||||
|
int res = 0;
|
||||||
|
void *addr;
|
||||||
|
size_t addr_len;
|
||||||
|
uint16_t port;
|
||||||
|
mutex_lock(&_pool_mutex);
|
||||||
|
s = _get_socket(socket);
|
||||||
|
mutex_unlock(&_pool_mutex);
|
||||||
|
if (s == NULL) {
|
||||||
|
errno = ENOTSOCK;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!s->bound) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (address->sa_family != s->domain) {
|
||||||
|
errno = EAFNOSUPPORT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (_get_data_from_sockaddr(address, address_len, &addr, &addr_len, &port) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
switch (s->type) {
|
||||||
|
#ifdef MODULE_CONN_TCP
|
||||||
|
case SOCK_STREAM:
|
||||||
|
/* XXX sin_port is in network byteorder */
|
||||||
|
if ((res = conn_tcp_connect(&s->conn.tcp, addr, addr_len, port)) < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
(void)res;
|
||||||
|
errno = EPROTOTYPE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getpeername(int socket, struct sockaddr *__restrict address,
|
||||||
|
socklen_t *__restrict 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);
|
||||||
|
s = _get_socket(socket);
|
||||||
|
mutex_unlock(&_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 (*address_len != tmp_len) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
switch (s->type) {
|
||||||
|
#ifdef MODULE_CONN_TCP
|
||||||
|
case SOCK_STREAM:
|
||||||
|
if ((res = conn_tcp_getpeeraddr(&s->conn.tcp, addr, port)) < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
errno = ENOTCONN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tmp.ss_family = s->domain;
|
||||||
|
_htons_port(port); /* XXX: sin(6)_port is supposed to be network byte
|
||||||
|
* order */
|
||||||
|
*address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getsockname(int socket, struct sockaddr *__restrict address,
|
||||||
|
socklen_t *__restrict 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);
|
||||||
|
s = _get_socket(socket);
|
||||||
|
mutex_unlock(&_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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
#endif
|
||||||
|
#ifdef MODULE_CONN_IP
|
||||||
|
case SOCK_RAW:
|
||||||
|
if ((res = conn_ip_getlocaladdr(&s->conn.raw, addr)) < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tmp.ss_family = AF_INET;
|
||||||
|
_htons_port(port); /* XXX: sin(6)_port is supposed to be network byte
|
||||||
|
* order */
|
||||||
|
*address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int listen(int socket, int backlog)
|
||||||
|
{
|
||||||
|
socket_t *s;
|
||||||
|
int res = 0;
|
||||||
|
mutex_lock(&_pool_mutex);
|
||||||
|
s = _get_socket(socket);
|
||||||
|
mutex_unlock(&_pool_mutex);
|
||||||
|
if (!s->bound) {
|
||||||
|
errno = EINVAL;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
(void)backlog;
|
||||||
|
(void)res;
|
||||||
|
errno = EAFNOSUPPORT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t recv(int socket, void *buffer, size_t length, int flags)
|
||||||
|
{
|
||||||
|
return recvfrom(socket, buffer, length, flags, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
|
||||||
|
struct sockaddr *restrict address,
|
||||||
|
socklen_t *restrict 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;
|
||||||
|
size_t addr_len;
|
||||||
|
uint16_t *port;
|
||||||
|
socklen_t tmp_len;
|
||||||
|
(void)flags;
|
||||||
|
mutex_lock(&_pool_mutex);
|
||||||
|
s = _get_socket(socket);
|
||||||
|
mutex_unlock(&_pool_mutex);
|
||||||
|
if (s == NULL) {
|
||||||
|
errno = ENOTSOCK;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!s->bound) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
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
|
||||||
|
case SOCK_RAW:
|
||||||
|
if ((res = conn_ip_recvfrom(&s->conn.raw, buffer, length, addr, &addr_len)) < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef MODULE_CONN_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;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
(void)addr_len;
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((address != NULL) && (address_len != NULL)) {
|
||||||
|
tmp.ss_family = s->domain;
|
||||||
|
_htons_port(port); /* XXX: sin_port is supposed to be network byte
|
||||||
|
* order */
|
||||||
|
*address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
uint16_t port = 0;
|
||||||
|
(void)flags;
|
||||||
|
mutex_lock(&_pool_mutex);
|
||||||
|
s = _get_socket(socket);
|
||||||
|
mutex_unlock(&_pool_mutex);
|
||||||
|
if (s == NULL) {
|
||||||
|
errno = ENOTSOCK;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (address != NULL) {
|
||||||
|
if (address->sa_family != s->domain) {
|
||||||
|
errno = EAFNOSUPPORT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (_get_data_from_sockaddr(address, address_len, &addr, &addr_len, &port) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (s->type) {
|
||||||
|
#ifdef MODULE_CONN_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;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef MODULE_CONN_TCP
|
||||||
|
case SOCK_STREAM:
|
||||||
|
if (!s->bound) {
|
||||||
|
errno = ENOTCONN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (address != NULL) {
|
||||||
|
errno = EISCONN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((res = conn_tcp_send(&s->conn.tcp, buffer, length)) < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef MODULE_CONN_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, port);
|
||||||
|
}
|
||||||
|
else if (address != NULL) {
|
||||||
|
uint16_t sport = (uint16_t)genrand_uint32_range(1LU << 10U, 1LU << 16U);
|
||||||
|
res = conn_udp_sendto(buffer, length, NULL, 0, addr, addr_len, s->domain,
|
||||||
|
sport, port);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errno = ENOTCONN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (res < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
(void)buffer;
|
||||||
|
(void)length;
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
Loading…
Reference in New Issue
Block a user