Merge pull request #20 from k0ekk0ek/getifaddrs

Replace os_sockQueryInterfaces by os_getifaddrs
This commit is contained in:
eboasson 2018-10-25 23:11:03 +08:00 committed by GitHub
commit 6e1df4c564
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 1140 additions and 1166 deletions

View file

@ -10,6 +10,7 @@
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause # SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
# #
PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src" PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src"
ddsi_eth.c
ddsi_ser.c ddsi_ser.c
ddsi_ssl.c ddsi_ssl.c
ddsi_tcp.c ddsi_tcp.c

View file

@ -17,7 +17,7 @@
enum ddsi_nearby_address_result ddsi_ipaddr_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, size_t ninterf, const struct nn_interface interf[]); enum ddsi_nearby_address_result ddsi_ipaddr_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, size_t ninterf, const struct nn_interface interf[]);
enum ddsi_locator_from_string_result ddsi_ipaddr_from_string (ddsi_tran_factory_t tran, nn_locator_t *loc, const char *str, int32_t kind); enum ddsi_locator_from_string_result ddsi_ipaddr_from_string (ddsi_tran_factory_t tran, nn_locator_t *loc, const char *str, int32_t kind);
char *ddsi_ipaddr_to_string (ddsi_tran_factory_t tran, char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port); char *ddsi_ipaddr_to_string (ddsi_tran_factory_t tran, char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port);
void ddsi_ipaddr_to_loc (nn_locator_t *dst, const os_sockaddr_storage *src, int32_t kind); void ddsi_ipaddr_to_loc (nn_locator_t *dst, const os_sockaddr *src, int32_t kind);
void ddsi_ipaddr_from_loc (os_sockaddr_storage *dst, const nn_locator_t *src); void ddsi_ipaddr_from_loc (os_sockaddr_storage *dst, const nn_locator_t *src);
#endif #endif

View file

@ -75,7 +75,7 @@ typedef enum ddsi_locator_from_string_result (*ddsi_locator_from_string_fn_t) (d
typedef char * (*ddsi_locator_to_string_fn_t) (ddsi_tran_factory_t tran, char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port); typedef char * (*ddsi_locator_to_string_fn_t) (ddsi_tran_factory_t tran, char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port);
typedef int (*ddsi_enumerate_interfaces_fn_t) (ddsi_tran_factory_t tran, int max, struct os_ifAttributes_s *interfs); typedef int (*ddsi_enumerate_interfaces_fn_t) (ddsi_tran_factory_t tran, os_ifaddrs_t **interfs);
/* Data types */ /* Data types */
@ -237,7 +237,7 @@ enum ddsi_locator_from_string_result ddsi_locator_from_string (nn_locator_t *loc
char *ddsi_locator_to_string (char *dst, size_t sizeof_dst, const nn_locator_t *loc); char *ddsi_locator_to_string (char *dst, size_t sizeof_dst, const nn_locator_t *loc);
char *ddsi_locator_to_string_no_port (char *dst, size_t sizeof_dst, const nn_locator_t *loc); char *ddsi_locator_to_string_no_port (char *dst, size_t sizeof_dst, const nn_locator_t *loc);
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, int max, struct os_ifAttributes_s *interfs); int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, os_ifaddrs_t **interfs);
#define ddsi_listener_locator(s,l) (ddsi_tran_locator (&(s)->m_base,(l))) #define ddsi_listener_locator(s,l) (ddsi_tran_locator (&(s)->m_base,(l)))
ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener); ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener);

View file

@ -0,0 +1,29 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include "ddsi_eth.h"
int ddsi_eth_enumerate_interfaces(ddsi_tran_factory_t fact, os_ifaddrs_t **ifs)
{
int afs[] = { AF_INET, OS_AF_NULL };
(void)fact;
#if OS_SOCKET_HAVE_IPV6
if (config.transport_selector == TRANS_TCP6 ||
config.transport_selector == TRANS_UDP6)
{
afs[0] = AF_INET6;
}
#endif /* OS_SOCKET_HAVE_IPV6 */
return -os_getifaddrs(ifs, afs);
}

View file

@ -0,0 +1,20 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#ifndef DDSI_ETH_H
#define DDSI_ETH_H
#include "ddsi/ddsi_tran.h"
#include "os/os.h"
int ddsi_eth_enumerate_interfaces(ddsi_tran_factory_t fact, os_ifaddrs_t **ifs);
#endif /* DDSI_ETH_H */

View file

@ -29,7 +29,7 @@ enum ddsi_nearby_address_result ddsi_ipaddr_is_nearby_address (ddsi_tran_factory
ddsi_ipaddr_from_loc(&ownip, &gv.ownloc); ddsi_ipaddr_from_loc(&ownip, &gv.ownloc);
if (os_sockaddrSameSubnet ((os_sockaddr *) &tmp, (os_sockaddr *) &iftmp, (os_sockaddr *) &nmtmp)) if (os_sockaddrSameSubnet ((os_sockaddr *) &tmp, (os_sockaddr *) &iftmp, (os_sockaddr *) &nmtmp))
{ {
if (os_sockaddrIPAddressEqual ((os_sockaddr*) &iftmp, (os_sockaddr*) &ownip)) if (os_sockaddr_compare((os_sockaddr *)&iftmp, (os_sockaddr *)&ownip) == 0)
return DNAR_SAME; return DNAR_SAME;
else else
return DNAR_LOCAL; return DNAR_LOCAL;
@ -49,7 +49,7 @@ enum ddsi_locator_from_string_result ddsi_ipaddr_from_string (ddsi_tran_factory_
return AFSR_INVALID; return AFSR_INVALID;
if ((ipv4 && tmpaddr.ss_family != AF_INET) || (!ipv4 && tmpaddr.ss_family != AF_INET6)) if ((ipv4 && tmpaddr.ss_family != AF_INET) || (!ipv4 && tmpaddr.ss_family != AF_INET6))
return AFSR_MISMATCH; return AFSR_MISMATCH;
ddsi_ipaddr_to_loc (loc, &tmpaddr, kind); ddsi_ipaddr_to_loc (loc, (os_sockaddr *)&tmpaddr, kind);
/* This is just an address, so there is no valid value for port, other than INVALID. /* This is just an address, so there is no valid value for port, other than INVALID.
Without a guarantee that tmpaddr has port 0, best is to set it explicitly here */ Without a guarantee that tmpaddr has port 0, best is to set it explicitly here */
loc->port = NN_LOCATOR_PORT_INVALID; loc->port = NN_LOCATOR_PORT_INVALID;
@ -94,10 +94,10 @@ char *ddsi_ipaddr_to_string (ddsi_tran_factory_t tran, char *dst, size_t sizeof_
return dst; return dst;
} }
void ddsi_ipaddr_to_loc (nn_locator_t *dst, const os_sockaddr_storage *src, int32_t kind) void ddsi_ipaddr_to_loc (nn_locator_t *dst, const os_sockaddr *src, int32_t kind)
{ {
dst->kind = kind; dst->kind = kind;
switch (src->ss_family) switch (src->sa_family)
{ {
case AF_INET: case AF_INET:
{ {
@ -137,7 +137,7 @@ void ddsi_ipaddr_to_loc (nn_locator_t *dst, const os_sockaddr_storage *src, int3
} }
#endif #endif
default: default:
NN_FATAL ("nn_address_to_loc: family %d unsupported\n", (int) src->ss_family); NN_FATAL ("nn_address_to_loc: family %d unsupported\n", (int) src->sa_family);
} }
} }

View file

@ -347,43 +347,13 @@ static void ddsi_raweth_deinit(void)
} }
} }
static int ddsi_raweth_enumerate_interfaces (ddsi_tran_factory_t factory, int max, struct os_ifAttributes_s *interfs) static int ddsi_raweth_enumerate_interfaces (ddsi_tran_factory_t factory, os_ifaddrs_t **interfs)
{ {
struct ifaddrs *ifaddr, *ifa; int afs[] = { AF_PACKET, OS_AF_NULL };
int cnt = 0;
(void)factory; (void)factory;
if (getifaddrs (&ifaddr) == -1)
return -errno; return -os_getifaddrs(interfs, afs);
for (ifa = ifaddr; ifa && cnt < max; ifa = ifa->ifa_next)
{
struct os_ifAttributes_s *f = &interfs[cnt];
struct sockaddr_ll *x;
if (ifa->ifa_addr == NULL)
continue;
if (ifa->ifa_addr->sa_family != AF_PACKET)
continue;
if ((ifa->ifa_flags & (IFF_UP | IFF_BROADCAST)) != (IFF_UP | IFF_BROADCAST))
continue;
strncpy(f->name, ifa->ifa_name, sizeof(f->name));
f->name[sizeof(f->name)-1] = 0;
f->flags = ifa->ifa_flags;
f->interfaceIndexNo = if_nametoindex(f->name);
x = (struct sockaddr_ll *)&f->address;
memcpy(x, ifa->ifa_addr, sizeof (*x));
x = (struct sockaddr_ll *)&f->network_mask;
if (ifa->ifa_netmask)
memcpy(x, ifa->ifa_netmask, sizeof (*x));
else
memset(x, 0, sizeof(*x));
x = (struct sockaddr_ll *)&f->broadcast_address;
if (ifa->ifa_broadaddr)
memcpy(x, ifa->ifa_broadaddr, sizeof (*x));
else
memset(x, 0, sizeof(*x));
cnt++;
}
freeifaddrs (ifaddr);
return cnt;
} }
int ddsi_raweth_init (void) int ddsi_raweth_init (void)

View file

@ -13,6 +13,7 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ddsi_eth.h"
#include "ddsi/ddsi_tran.h" #include "ddsi/ddsi_tran.h"
#include "ddsi/ddsi_tcp.h" #include "ddsi/ddsi_tcp.h"
#include "ddsi/ddsi_ipaddr.h" #include "ddsi/ddsi_ipaddr.h"
@ -82,43 +83,16 @@ static void nn_trace_tcp (const char *fmt, ...)
#define TRACE_TCP(args) ((config.enabled_logcats & LC_TCP) ? (nn_trace_tcp args) : (void) 0) #define TRACE_TCP(args) ((config.enabled_logcats & LC_TCP) ? (nn_trace_tcp args) : (void) 0)
static unsigned short sockaddr_get_port (const os_sockaddr_storage *addr)
{
if (addr->ss_family == AF_INET)
return ntohs (((os_sockaddr_in *) addr)->sin_port);
#if OS_SOCKET_HAS_IPV6
else
return ntohs (((os_sockaddr_in6 *) addr)->sin6_port);
#endif
}
static int ddsi_tcp_cmp_conn (const ddsi_tcp_conn_t c1, const ddsi_tcp_conn_t c2) static int ddsi_tcp_cmp_conn (const ddsi_tcp_conn_t c1, const ddsi_tcp_conn_t c2)
{ {
const os_sockaddr_storage *a1s = &c1->m_peer_addr; const os_sockaddr *a1s = (os_sockaddr *)&c1->m_peer_addr;
const os_sockaddr_storage *a2s = &c2->m_peer_addr; const os_sockaddr *a2s = (os_sockaddr *)&c2->m_peer_addr;
if (a1s->ss_family != a2s->ss_family) if (a1s->sa_family != a2s->sa_family)
return (a1s->ss_family < a2s->ss_family) ? -1 : 1; return (a1s->sa_family < a2s->sa_family) ? -1 : 1;
else if (c1->m_peer_port != c2->m_peer_port) else if (c1->m_peer_port != c2->m_peer_port)
return (c1->m_peer_port < c2->m_peer_port) ? -1 : 1; return (c1->m_peer_port < c2->m_peer_port) ? -1 : 1;
else if (a1s->ss_family == AF_INET)
{ return os_sockaddr_compare(a1s, a2s);
const os_sockaddr_in *a1 = (const os_sockaddr_in *) a1s;
const os_sockaddr_in *a2 = (const os_sockaddr_in *) a2s;
return (a1->sin_addr.s_addr == a2->sin_addr.s_addr) ? 0 : (a1->sin_addr.s_addr < a2->sin_addr.s_addr) ? -1 : 1;
}
#if OS_SOCKET_HAS_IPV6
else if (a1s->ss_family == AF_INET6)
{
const os_sockaddr_in6 *a1 = (const os_sockaddr_in6 *) a1s;
const os_sockaddr_in6 *a2 = (const os_sockaddr_in6 *) a2s;
return memcmp (&a1->sin6_addr, &a2->sin6_addr, 16);
}
#endif
else
{
assert (0);
return 0;
}
} }
typedef struct ddsi_tcp_node typedef struct ddsi_tcp_node
@ -140,12 +114,12 @@ static os_mutex ddsi_tcp_cache_lock_g;
static ut_avlTree_t ddsi_tcp_cache_g; static ut_avlTree_t ddsi_tcp_cache_g;
static struct ddsi_tran_factory ddsi_tcp_factory_g; static struct ddsi_tran_factory ddsi_tcp_factory_g;
static ddsi_tcp_conn_t ddsi_tcp_new_conn (os_socket, bool, os_sockaddr_storage *); static ddsi_tcp_conn_t ddsi_tcp_new_conn (os_socket, bool, os_sockaddr *);
static char *sockaddr_to_string_with_port (char *dst, size_t sizeof_dst, const os_sockaddr_storage *src) static char *sockaddr_to_string_with_port (char *dst, size_t sizeof_dst, const os_sockaddr *src)
{ {
nn_locator_t loc; nn_locator_t loc;
ddsi_ipaddr_to_loc(&loc, src, src->ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6); ddsi_ipaddr_to_loc(&loc, src, src->sa_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
ddsi_locator_to_string(dst, sizeof_dst, &loc); ddsi_locator_to_string(dst, sizeof_dst, &loc);
return dst; return dst;
} }
@ -185,7 +159,7 @@ static unsigned short get_socket_port (os_socket socket)
NN_ERROR ("ddsi_tcp_get_socket_port: getsockname errno %d\n", err); NN_ERROR ("ddsi_tcp_get_socket_port: getsockname errno %d\n", err);
return 0; return 0;
} }
return sockaddr_get_port(&addr); return os_sockaddr_get_port((os_sockaddr *)&addr);
} }
static void ddsi_tcp_conn_set_socket (ddsi_tcp_conn_t conn, os_socket sock) static void ddsi_tcp_conn_set_socket (ddsi_tcp_conn_t conn, os_socket sock)
@ -257,7 +231,7 @@ static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const struct msghdr * m
} }
#endif #endif
sockaddr_to_string_with_port(buff, sizeof(buff), (const os_sockaddr_storage *) msg->msg_name); sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *) msg->msg_name);
nn_log (LC_INFO, "%s connect socket %"PRIsock" port %u to %s\n", ddsi_name, sock, get_socket_port (sock), buff); nn_log (LC_INFO, "%s connect socket %"PRIsock" port %u to %s\n", ddsi_name, sock, get_socket_port (sock), buff);
/* Also may need to receive on connection so add to waitset */ /* Also may need to receive on connection so add to waitset */
@ -305,7 +279,7 @@ static void ddsi_tcp_cache_add (ddsi_tcp_conn_t conn, ut_avlIPath_t * path)
} }
} }
sockaddr_to_string_with_port(buff, sizeof(buff), &conn->m_peer_addr); sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&conn->m_peer_addr);
nn_log (LC_INFO, "%s cache %s %s socket %"PRIsock" to %s\n", ddsi_name, action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff); nn_log (LC_INFO, "%s cache %s %s socket %"PRIsock" to %s\n", ddsi_name, action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
} }
@ -319,7 +293,7 @@ static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn)
node = ut_avlLookupDPath (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, conn, &path); node = ut_avlLookupDPath (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, conn, &path);
if (node) if (node)
{ {
sockaddr_to_string_with_port(buff, sizeof(buff), &conn->m_peer_addr); sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&conn->m_peer_addr);
nn_log (LC_INFO, "%s cache removed socket %"PRIsock" to %s\n", ddsi_name, conn->m_sock, buff); nn_log (LC_INFO, "%s cache removed socket %"PRIsock" to %s\n", ddsi_name, conn->m_sock, buff);
ut_avlDeleteDPath (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, node, &path); ut_avlDeleteDPath (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, node, &path);
ddsi_tcp_node_free (node); ddsi_tcp_node_free (node);
@ -340,7 +314,7 @@ static ddsi_tcp_conn_t ddsi_tcp_cache_find (const struct msghdr * msg)
ddsi_tcp_conn_t ret = NULL; ddsi_tcp_conn_t ret = NULL;
memset (&key, 0, sizeof (key)); memset (&key, 0, sizeof (key));
key.m_peer_port = sockaddr_get_port (msg->msg_name); key.m_peer_port = os_sockaddr_get_port (msg->msg_name);
memcpy (&key.m_peer_addr, msg->msg_name, msg->msg_namelen); memcpy (&key.m_peer_addr, msg->msg_name, msg->msg_namelen);
/* Check cache for existing connection to target */ /* Check cache for existing connection to target */
@ -361,7 +335,7 @@ static ddsi_tcp_conn_t ddsi_tcp_cache_find (const struct msghdr * msg)
} }
if (ret == NULL) if (ret == NULL)
{ {
ret = ddsi_tcp_new_conn (Q_INVALID_SOCKET, false, &key.m_peer_addr); ret = ddsi_tcp_new_conn (Q_INVALID_SOCKET, false, (os_sockaddr *)&key.m_peer_addr);
ddsi_tcp_cache_add (ret, &path); ddsi_tcp_cache_add (ret, &path);
} }
os_mutexUnlock (&ddsi_tcp_cache_lock_g); os_mutexUnlock (&ddsi_tcp_cache_lock_g);
@ -452,7 +426,7 @@ static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
{ {
if (srcloc) if (srcloc)
{ {
ddsi_ipaddr_to_loc(srcloc, &tcp->m_peer_addr, tcp->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6); ddsi_ipaddr_to_loc(srcloc, (os_sockaddr *)&tcp->m_peer_addr, tcp->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
} }
return (ssize_t) pos; return (ssize_t) pos;
} }
@ -586,7 +560,7 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
memset(&msg, 0, sizeof(msg)); memset(&msg, 0, sizeof(msg));
set_msghdr_iov (&msg, (ddsi_iovec_t *) iov, niov); set_msghdr_iov (&msg, (ddsi_iovec_t *) iov, niov);
msg.msg_name = &dstaddr; msg.msg_name = &dstaddr;
msg.msg_namelen = (socklen_t) os_sockaddrSizeof((os_sockaddr *) &dstaddr); msg.msg_namelen = (socklen_t) os_sockaddr_get_size((os_sockaddr *) &dstaddr);
#if SYSDEPS_MSGHDR_FLAGS #if SYSDEPS_MSGHDR_FLAGS
msg.msg_flags = (int) flags; msg.msg_flags = (int) flags;
#endif #endif
@ -822,7 +796,7 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
if (sock == Q_INVALID_SOCKET) if (sock == Q_INVALID_SOCKET)
{ {
getsockname (tl->m_sock, (struct sockaddr *) &addr, &addrlen); getsockname (tl->m_sock, (struct sockaddr *) &addr, &addrlen);
sockaddr_to_string_with_port(buff, sizeof(buff), &addr); sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&addr);
nn_log ((err == 0) ? LC_ERROR : LC_FATAL, "%s accept failed on socket %"PRIsock" at %s errno %d\n", ddsi_name, tl->m_sock, buff, err); nn_log ((err == 0) ? LC_ERROR : LC_FATAL, "%s accept failed on socket %"PRIsock" at %s errno %d\n", ddsi_name, tl->m_sock, buff, err);
} }
else if (getpeername (sock, (struct sockaddr *) &addr, &addrlen) == -1) else if (getpeername (sock, (struct sockaddr *) &addr, &addrlen) == -1)
@ -832,11 +806,11 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
} }
else else
{ {
sockaddr_to_string_with_port(buff, sizeof(buff), &addr); sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&addr);
nn_log (LC_INFO, "%s accept new socket %"PRIsock" on socket %"PRIsock" from %s\n", ddsi_name, sock, tl->m_sock, buff); nn_log (LC_INFO, "%s accept new socket %"PRIsock" on socket %"PRIsock" from %s\n", ddsi_name, sock, tl->m_sock, buff);
os_sockSetNonBlocking (sock, true); os_sockSetNonBlocking (sock, true);
tcp = ddsi_tcp_new_conn (sock, true, &addr); tcp = ddsi_tcp_new_conn (sock, true, (os_sockaddr *)&addr);
#ifdef DDSI_INCLUDE_SSL #ifdef DDSI_INCLUDE_SSL
tcp->m_ssl = ssl; tcp->m_ssl = ssl;
#endif #endif
@ -869,7 +843,7 @@ static void ddsi_tcp_conn_peer_locator (ddsi_tran_conn_t conn, nn_locator_t * lo
char buff[DDSI_LOCSTRLEN]; char buff[DDSI_LOCSTRLEN];
ddsi_tcp_conn_t tc = (ddsi_tcp_conn_t) conn; ddsi_tcp_conn_t tc = (ddsi_tcp_conn_t) conn;
assert (tc->m_sock != Q_INVALID_SOCKET); assert (tc->m_sock != Q_INVALID_SOCKET);
ddsi_ipaddr_to_loc (loc, &tc->m_peer_addr, tc->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6); ddsi_ipaddr_to_loc (loc, (os_sockaddr *)&tc->m_peer_addr, tc->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
ddsi_locator_to_string(buff, sizeof(buff), loc); ddsi_locator_to_string(buff, sizeof(buff), loc);
TRACE (("(%s EP:%s)", ddsi_name, buff)); TRACE (("(%s EP:%s)", ddsi_name, buff));
} }
@ -885,7 +859,7 @@ static void ddsi_tcp_base_init (struct ddsi_tran_conn * base)
base->m_peer_locator_fn = ddsi_tcp_conn_peer_locator; base->m_peer_locator_fn = ddsi_tcp_conn_peer_locator;
} }
static ddsi_tcp_conn_t ddsi_tcp_new_conn (os_socket sock, bool server, os_sockaddr_storage * peer) static ddsi_tcp_conn_t ddsi_tcp_new_conn (os_socket sock, bool server, os_sockaddr * peer)
{ {
ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) os_malloc (sizeof (*conn)); ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) os_malloc (sizeof (*conn));
@ -893,8 +867,8 @@ static ddsi_tcp_conn_t ddsi_tcp_new_conn (os_socket sock, bool server, os_sockad
ddsi_tcp_base_init (&conn->m_base); ddsi_tcp_base_init (&conn->m_base);
os_mutexInit (&conn->m_mutex); os_mutexInit (&conn->m_mutex);
conn->m_sock = Q_INVALID_SOCKET; conn->m_sock = Q_INVALID_SOCKET;
conn->m_peer_addr = *peer; (void)memcpy(&conn->m_peer_addr, peer, os_sockaddr_get_size(peer));
conn->m_peer_port = sockaddr_get_port (peer); conn->m_peer_port = os_sockaddr_get_port (peer);
conn->m_base.m_server = server; conn->m_base.m_server = server;
conn->m_base.m_base.m_port = INVALID_PORT; conn->m_base.m_base.m_port = INVALID_PORT;
ddsi_tcp_conn_set_socket (conn, sock); ddsi_tcp_conn_set_socket (conn, sock);
@ -939,7 +913,7 @@ static ddsi_tran_listener_t ddsi_tcp_create_listener (int port, ddsi_tran_qos_t
return NULL; return NULL;
} }
sockaddr_to_string_with_port(buff, sizeof(buff), &addr); sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&addr);
nn_log (LC_INFO, "%s create listener socket %"PRIsock" on %s\n", ddsi_name, sock, buff); nn_log (LC_INFO, "%s create listener socket %"PRIsock" on %s\n", ddsi_name, sock, buff);
} }
@ -949,7 +923,7 @@ static ddsi_tran_listener_t ddsi_tcp_create_listener (int port, ddsi_tran_qos_t
static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn) static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
{ {
char buff[DDSI_LOCSTRLEN]; char buff[DDSI_LOCSTRLEN];
sockaddr_to_string_with_port(buff, sizeof(buff), &conn->m_peer_addr); sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&conn->m_peer_addr);
nn_log (LC_INFO, "%s free %s connnection on socket %"PRIsock" to %s\n", ddsi_name, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff); nn_log (LC_INFO, "%s free %s connnection on socket %"PRIsock" to %s\n", ddsi_name, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
#ifdef DDSI_INCLUDE_SSL #ifdef DDSI_INCLUDE_SSL
@ -973,10 +947,10 @@ static void ddsi_tcp_close_conn (ddsi_tran_conn_t tc)
char buff[DDSI_LOCSTRLEN]; char buff[DDSI_LOCSTRLEN];
nn_locator_t loc; nn_locator_t loc;
ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) tc; ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) tc;
sockaddr_to_string_with_port(buff, sizeof(buff), &conn->m_peer_addr); sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&conn->m_peer_addr);
nn_log (LC_INFO, "%s close %s connnection on socket %"PRIsock" to %s\n", ddsi_name, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff); nn_log (LC_INFO, "%s close %s connnection on socket %"PRIsock" to %s\n", ddsi_name, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
(void) shutdown (conn->m_sock, 2); (void) shutdown (conn->m_sock, 2);
ddsi_ipaddr_to_loc(&loc, &conn->m_peer_addr, conn->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6); ddsi_ipaddr_to_loc(&loc, (os_sockaddr *)&conn->m_peer_addr, conn->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
loc.port = conn->m_peer_port; loc.port = conn->m_peer_port;
purge_proxy_participants (&loc, conn->m_base.m_server); purge_proxy_participants (&loc, conn->m_base.m_server);
} }
@ -1035,13 +1009,13 @@ static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener)
} }
do do
{ {
ret = connect (sock, (struct sockaddr *) &addr, (unsigned) os_sockaddrSizeof((os_sockaddr *)&addr)); ret = connect (sock, (struct sockaddr *) &addr, (unsigned) os_sockaddr_get_size((os_sockaddr *)&addr));
} }
while ((ret == -1) && (os_getErrno() == os_sockEINTR)); while ((ret == -1) && (os_getErrno() == os_sockEINTR));
if (ret == -1) if (ret == -1)
{ {
char buff[DDSI_LOCSTRLEN]; char buff[DDSI_LOCSTRLEN];
sockaddr_to_string_with_port(buff, sizeof(buff), &addr); sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&addr);
nn_log (LC_WARNING, "%s failed to connect to own listener (%s) error %d\n", ddsi_name, buff, os_getErrno()); nn_log (LC_WARNING, "%s failed to connect to own listener (%s) error %d\n", ddsi_name, buff, os_getErrno());
} }
} }
@ -1093,6 +1067,7 @@ int ddsi_tcp_init (void)
ddsi_tcp_factory_g.m_free_fn = ddsi_tcp_release_factory; ddsi_tcp_factory_g.m_free_fn = ddsi_tcp_release_factory;
ddsi_tcp_factory_g.m_locator_from_string_fn = ddsi_tcp_address_from_string; ddsi_tcp_factory_g.m_locator_from_string_fn = ddsi_tcp_address_from_string;
ddsi_tcp_factory_g.m_locator_to_string_fn = ddsi_ipaddr_to_string; ddsi_tcp_factory_g.m_locator_to_string_fn = ddsi_ipaddr_to_string;
ddsi_tcp_factory_g.m_enumerate_interfaces_fn = ddsi_eth_enumerate_interfaces;
ddsi_factory_add (&ddsi_tcp_factory_g); ddsi_factory_add (&ddsi_tcp_factory_g);
#if OS_SOCKET_HAS_IPV6 #if OS_SOCKET_HAS_IPV6

View file

@ -332,10 +332,7 @@ char *ddsi_locator_to_string_no_port (char *dst, size_t sizeof_dst, const nn_loc
return dst; return dst;
} }
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, int max, struct os_ifAttributes_s *interfs) int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, os_ifaddrs_t **interfs)
{ {
/* FIXME: HACK */ return factory->m_enumerate_interfaces_fn (factory, interfs);
if (factory->m_enumerate_interfaces_fn == 0)
return 0;
return factory->m_enumerate_interfaces_fn (factory, max, interfs);
} }

View file

@ -13,6 +13,7 @@
#include <string.h> #include <string.h>
#include "os/os.h" #include "os/os.h"
#include "os/os_atomics.h" #include "os/os_atomics.h"
#include "ddsi_eth.h"
#include "ddsi/ddsi_tran.h" #include "ddsi/ddsi_tran.h"
#include "ddsi/ddsi_udp.h" #include "ddsi/ddsi_udp.h"
#include "ddsi/ddsi_ipaddr.h" #include "ddsi/ddsi_ipaddr.h"
@ -79,7 +80,7 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
if (ret > 0) if (ret > 0)
{ {
if (srcloc) if (srcloc)
ddsi_ipaddr_to_loc(srcloc, &src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6); ddsi_ipaddr_to_loc(srcloc, (os_sockaddr *)&src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
/* Check for udp packet truncation */ /* Check for udp packet truncation */
if ((((size_t) ret) > len) if ((((size_t) ret) > len)
@ -90,7 +91,7 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
{ {
char addrbuf[DDSI_LOCSTRLEN]; char addrbuf[DDSI_LOCSTRLEN];
nn_locator_t tmp; nn_locator_t tmp;
ddsi_ipaddr_to_loc(&tmp, &src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6); ddsi_ipaddr_to_loc(&tmp, (os_sockaddr *)&src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
ddsi_locator_to_string(addrbuf, sizeof(addrbuf), &tmp); ddsi_locator_to_string(addrbuf, sizeof(addrbuf), &tmp);
NN_WARNING ("%s => %d truncated to %d\n", addrbuf, (int)ret, (int)len); NN_WARNING ("%s => %d truncated to %d\n", addrbuf, (int)ret, (int)len);
} }
@ -120,7 +121,7 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *d
ddsi_ipaddr_from_loc(&dstaddr, dst); ddsi_ipaddr_from_loc(&dstaddr, dst);
set_msghdr_iov (&msg, (ddsi_iovec_t *) iov, niov); set_msghdr_iov (&msg, (ddsi_iovec_t *) iov, niov);
msg.msg_name = &dstaddr; msg.msg_name = &dstaddr;
msg.msg_namelen = (socklen_t) os_sockaddrSizeof((os_sockaddr *) &dstaddr); msg.msg_namelen = (socklen_t) os_sockaddr_get_size((os_sockaddr *) &dstaddr);
#if !defined(__sun) || defined(_XPG4_2) #if !defined(__sun) || defined(_XPG4_2)
msg.msg_control = NULL; msg.msg_control = NULL;
msg.msg_controllen = 0; msg.msg_controllen = 0;
@ -200,16 +201,6 @@ static int ddsi_udp_conn_locator (ddsi_tran_base_t base, nn_locator_t *loc)
return ret; return ret;
} }
static unsigned short sockaddr_get_port (const os_sockaddr_storage *addr)
{
if (addr->ss_family == AF_INET)
return ntohs (((os_sockaddr_in *) addr)->sin_port);
#if OS_SOCKET_HAS_IPV6
else
return ntohs (((os_sockaddr_in6 *) addr)->sin6_port);
#endif
}
static unsigned short get_socket_port (os_socket socket) static unsigned short get_socket_port (os_socket socket)
{ {
os_sockaddr_storage addr; os_sockaddr_storage addr;
@ -220,7 +211,8 @@ static unsigned short get_socket_port (os_socket socket)
NN_ERROR ("ddsi_udp_get_socket_port: getsockname errno %d\n", err); NN_ERROR ("ddsi_udp_get_socket_port: getsockname errno %d\n", err);
return 0; return 0;
} }
return sockaddr_get_port(&addr);
return os_sockaddr_get_port((os_sockaddr *)&addr);
} }
static ddsi_tran_conn_t ddsi_udp_create_conn static ddsi_tran_conn_t ddsi_udp_create_conn
@ -531,6 +523,7 @@ int ddsi_udp_init (void)
ddsi_udp_factory_g.m_is_nearby_address_fn = ddsi_ipaddr_is_nearby_address; ddsi_udp_factory_g.m_is_nearby_address_fn = ddsi_ipaddr_is_nearby_address;
ddsi_udp_factory_g.m_locator_from_string_fn = ddsi_udp_address_from_string; ddsi_udp_factory_g.m_locator_from_string_fn = ddsi_udp_address_from_string;
ddsi_udp_factory_g.m_locator_to_string_fn = ddsi_udp_locator_to_string; ddsi_udp_factory_g.m_locator_to_string_fn = ddsi_udp_locator_to_string;
ddsi_udp_factory_g.m_enumerate_interfaces_fn = ddsi_eth_enumerate_interfaces;
#if OS_SOCKET_HAS_IPV6 #if OS_SOCKET_HAS_IPV6
if (config.transport_selector == TRANS_UDP6) if (config.transport_selector == TRANS_UDP6)
{ {

View file

@ -455,63 +455,33 @@ int find_own_ip (const char *requested_address)
const char *sep = " "; const char *sep = " ";
char last_if_name[80] = ""; char last_if_name[80] = "";
int quality = -1; int quality = -1;
os_result res;
int i; int i;
unsigned int nif; os_ifaddrs_t *ifa, *ifa_root = NULL;
os_ifAttributes *ifs;
int maxq_list[MAX_INTERFACES]; int maxq_list[MAX_INTERFACES];
int maxq_count = 0; int maxq_count = 0;
size_t maxq_strlen = 0; size_t maxq_strlen = 0;
int selected_idx = -1; int selected_idx = -1;
char addrbuf[DDSI_LOCSTRLEN]; char addrbuf[DDSI_LOCSTRLEN];
ifs = os_malloc (MAX_INTERFACES * sizeof (*ifs));
nn_log (LC_CONFIG, "interfaces:"); nn_log (LC_CONFIG, "interfaces:");
{ {
int retcode; int ret;
nif = 0; ret = ddsi_enumerate_interfaces(gv.m_factory, &ifa_root);
retcode = ddsi_enumerate_interfaces(gv.m_factory, (int)(MAX_INTERFACES - nif), ifs); if (ret < 0) {
if (retcode > 0) NN_ERROR("ddsi_enumerate_interfaces(%s): %d\n", gv.m_factory->m_typename, ret);
{
nif = (unsigned)retcode;
res = os_resultSuccess;
}
else if (retcode < 0)
{
NN_ERROR ("ddsi_enumerate_interfaces(%s): %d\n", gv.m_factory->m_typename, retcode);
res = os_resultFail;
}
else
{
if (config.transport_selector == TRANS_TCP6 || config.transport_selector == TRANS_UDP6)
res = os_sockQueryIPv6Interfaces (ifs, MAX_INTERFACES, &nif);
else if (config.transport_selector == TRANS_TCP || config.transport_selector == TRANS_UDP)
res = os_sockQueryInterfaces (ifs, MAX_INTERFACES, &nif);
else
{
NN_ERROR ("ddsi_enumerate_interfaces(%s): no go but neither UDP[46] nor TCP[46]\n", gv.m_factory->m_typename);
res = os_resultFail;
}
}
if (res != os_resultSuccess)
{
NN_ERROR ("os_sockQueryInterfaces: %d\n", (int) res);
os_free (ifs);
return 0; return 0;
} }
} }
gv.n_interfaces = 0; gv.n_interfaces = 0;
last_if_name[0] = 0; last_if_name[0] = 0;
for (i = 0; i < (int) nif; i++, sep = ", ") for (ifa = ifa_root; ifa != NULL; ifa = ifa->next)
{ {
os_sockaddr_storage tmpip, tmpmask;
char if_name[sizeof (last_if_name)]; char if_name[sizeof (last_if_name)];
int q = 0; int q = 0;
strncpy (if_name, ifs[i].name, sizeof (if_name) - 1); strncpy (if_name, ifa->name, sizeof (if_name) - 1);
if_name[sizeof (if_name) - 1] = 0; if_name[sizeof (if_name) - 1] = 0;
if (strcmp (if_name, last_if_name)) if (strcmp (if_name, last_if_name))
@ -519,46 +489,46 @@ int find_own_ip (const char *requested_address)
strcpy (last_if_name, if_name); strcpy (last_if_name, if_name);
/* interface must be up */ /* interface must be up */
if ((ifs[i].flags & IFF_UP) == 0) if ((ifa->flags & IFF_UP) == 0) {
{
nn_log (LC_CONFIG, " (interface down)"); nn_log (LC_CONFIG, " (interface down)");
continue; continue;
} else if (os_sockaddr_is_unspecified(ifa->addr)) {
nn_log (LC_CONFIG, " (address unspecified)");
continue;
} }
tmpip = ifs[i].address;
tmpmask = ifs[i].network_mask;
#ifdef __linux #ifdef __linux
if (tmpip.ss_family == AF_PACKET) if (ifa->addr->sa_family == AF_PACKET)
{ {
/* FIXME: weirdo warning warranted */ /* FIXME: weirdo warning warranted */
nn_locator_t *l = &gv.interfaces[gv.n_interfaces].loc; nn_locator_t *l = &gv.interfaces[gv.n_interfaces].loc;
l->kind = NN_LOCATOR_KIND_RAWETH; l->kind = NN_LOCATOR_KIND_RAWETH;
l->port = NN_LOCATOR_PORT_INVALID; l->port = NN_LOCATOR_PORT_INVALID;
memset(l->address, 0, 10); memset(l->address, 0, 10);
memcpy(l->address + 10, ((struct sockaddr_ll *)&tmpip)->sll_addr, 6); memcpy(l->address + 10, ((struct sockaddr_ll *)ifa->addr)->sll_addr, 6);
} }
else else
#endif #endif
{ {
ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].loc, &tmpip, gv.m_factory->m_kind); ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].loc, ifa->addr, gv.m_factory->m_kind);
} }
ddsi_locator_to_string_no_port(addrbuf, sizeof(addrbuf), &gv.interfaces[gv.n_interfaces].loc); ddsi_locator_to_string_no_port(addrbuf, sizeof(addrbuf), &gv.interfaces[gv.n_interfaces].loc);
nn_log (LC_CONFIG, " %s(", addrbuf); nn_log (LC_CONFIG, " %s(", addrbuf);
if (!(ifs[i].flags & IFF_MULTICAST) && multicast_override (if_name)) if (!(ifa->flags & IFF_MULTICAST) && multicast_override (if_name))
{ {
nn_log (LC_CONFIG, "assume-mc:"); nn_log (LC_CONFIG, "assume-mc:");
ifs[i].flags |= IFF_MULTICAST; ifa->flags |= IFF_MULTICAST;
} }
if (ifs[i].flags & IFF_LOOPBACK) if (ifa->flags & IFF_LOOPBACK)
{ {
/* Loopback device has the lowest priority of every interface /* Loopback device has the lowest priority of every interface
available, because the other interfaces at least in principle available, because the other interfaces at least in principle
allow communicating with other machines. */ allow communicating with other machines. */
q += 0; q += 0;
#if OS_SOCKET_HAS_IPV6 #if OS_SOCKET_HAS_IPV6
if (!(tmpip.ss_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL (&((os_sockaddr_in6 *) &tmpip)->sin6_addr))) if (!(ifa->addr->sa_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL (&((os_sockaddr_in6 *)ifa->addr)->sin6_addr)))
q += 1; q += 1;
#endif #endif
} }
@ -575,16 +545,16 @@ int find_own_ip (const char *requested_address)
which it was received. But that means proper multi-homing which it was received. But that means proper multi-homing
support and has quite an impact in various places, not least of support and has quite an impact in various places, not least of
which is the abstraction layer. */ which is the abstraction layer. */
if (!(tmpip.ss_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL (&((os_sockaddr_in6 *) &tmpip)->sin6_addr))) if (!(ifa->addr->sa_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL (&((os_sockaddr_in6 *)ifa->addr)->sin6_addr)))
q += 5; q += 5;
#endif #endif
/* We strongly prefer a multicast capable interface, if that's /* We strongly prefer a multicast capable interface, if that's
not available anything that's not point-to-point, or else we not available anything that's not point-to-point, or else we
hope IP routing will take care of the issues. */ hope IP routing will take care of the issues. */
if (ifs[i].flags & IFF_MULTICAST) if (ifa->flags & IFF_MULTICAST)
q += 4; q += 4;
else if (!(ifs[i].flags & IFF_POINTOPOINT)) else if (!(ifa->flags & IFF_POINTOPOINT))
q += 3; q += 3;
else else
q += 2; q += 2;
@ -604,10 +574,9 @@ int find_own_ip (const char *requested_address)
/* FIXME: HACK HACK */ /* FIXME: HACK HACK */
//ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].loc, &tmpip, gv.m_factory->m_kind); //ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].loc, &tmpip, gv.m_factory->m_kind);
if (tmpip.ss_family == AF_INET || tmpip.ss_family == AF_INET6) if (ifa->addr->sa_family == AF_INET || ifa->addr->sa_family == AF_INET6)
{ {
tmpmask.ss_family = tmpip.ss_family; ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].netmask, ifa->netmask, gv.m_factory->m_kind);
ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].netmask, &tmpmask, gv.m_factory->m_kind);
} }
else else
{ {
@ -615,14 +584,14 @@ int find_own_ip (const char *requested_address)
gv.interfaces[gv.n_interfaces].netmask.port = NN_LOCATOR_PORT_INVALID; gv.interfaces[gv.n_interfaces].netmask.port = NN_LOCATOR_PORT_INVALID;
memset(&gv.interfaces[gv.n_interfaces].netmask.address, 0, sizeof(gv.interfaces[gv.n_interfaces].netmask.address)); memset(&gv.interfaces[gv.n_interfaces].netmask.address, 0, sizeof(gv.interfaces[gv.n_interfaces].netmask.address));
} }
gv.interfaces[gv.n_interfaces].mc_capable = ((ifs[i].flags & IFF_MULTICAST) != 0); gv.interfaces[gv.n_interfaces].mc_capable = ((ifa->flags & IFF_MULTICAST) != 0);
gv.interfaces[gv.n_interfaces].point_to_point = ((ifs[i].flags & IFF_POINTOPOINT) != 0); gv.interfaces[gv.n_interfaces].point_to_point = ((ifa->flags & IFF_POINTOPOINT) != 0);
gv.interfaces[gv.n_interfaces].if_index = ifs[i].interfaceIndexNo; gv.interfaces[gv.n_interfaces].if_index = ifa->index;
gv.interfaces[gv.n_interfaces].name = os_strdup (if_name); gv.interfaces[gv.n_interfaces].name = os_strdup (if_name);
gv.n_interfaces++; gv.n_interfaces++;
} }
nn_log (LC_CONFIG, "\n"); nn_log (LC_CONFIG, "\n");
os_free (ifs); os_freeifaddrs (ifa_root);
if (requested_address == NULL) if (requested_address == NULL)
{ {

View file

@ -17,10 +17,10 @@ IF(${platform} IN_LIST posix_platforms)
set(platform posix) set(platform posix)
ENDIF() ENDIF()
PREPEND(srcs_platform ${platform} os_platform_errno.c os_platform_heap.c os_platform_init.c os_platform_process.c os_platform_socket.c os_platform_stdlib.c os_platform_sync.c os_platform_thread.c os_platform_time.c) PREPEND(srcs_platform ${platform} os_platform_errno.c os_platform_heap.c os_platform_init.c os_platform_process.c os_platform_ifaddrs.c os_platform_socket.c os_platform_stdlib.c os_platform_sync.c os_platform_thread.c os_platform_time.c)
include (GenerateExportHeader) include (GenerateExportHeader)
PREPEND(srcs_os "${CMAKE_CURRENT_SOURCE_DIR}/src" os_atomics.c os_init.c os_report.c os_socket.c os_thread.c os_time.c os_errno.c os_iter.c ${srcs_platform}) PREPEND(srcs_os "${CMAKE_CURRENT_SOURCE_DIR}/src" os_atomics.c os_init.c os_report.c os_ifaddrs.c os_socket.c os_thread.c os_time.c os_errno.c os_iter.c ${srcs_platform})
add_library(OSAPI ${srcs_os}) add_library(OSAPI ${srcs_os})
configure_file( configure_file(

View file

@ -15,12 +15,6 @@
#ifndef OS_SOCKET_HAS_IPV6 #ifndef OS_SOCKET_HAS_IPV6
#error "OS_SOCKET_HAS_IPV6 should have been defined by os_platform_socket.h" #error "OS_SOCKET_HAS_IPV6 should have been defined by os_platform_socket.h"
#endif #endif
#ifndef OS_IFNAMESIZE
#error "OS_IFNAMESIZE should have been defined by os_platform_socket.h"
#endif
#ifndef OS_SOCKET_HAS_SA_LEN
#error "OS_SOCKET_HAS_SA_LEN should have been defined by os_platform_socket.h"
#endif
#ifndef OS_NO_SIOCGIFINDEX #ifndef OS_NO_SIOCGIFINDEX
#error "OS_NO_SIOCGIFINDEX should have been defined by os_platform_socket.h" #error "OS_NO_SIOCGIFINDEX should have been defined by os_platform_socket.h"
#endif #endif
@ -94,11 +88,7 @@ extern "C" {
typedef struct ipv6_mreq os_ipv6_mreq; typedef struct ipv6_mreq os_ipv6_mreq;
typedef struct in6_addr os_in6_addr; typedef struct in6_addr os_in6_addr;
#if defined (OSPL_VXWORKS653)
typedef struct sockaddr_in os_sockaddr_storage;
#else
typedef struct sockaddr_storage os_sockaddr_storage; typedef struct sockaddr_storage os_sockaddr_storage;
#endif
typedef struct sockaddr_in6 os_sockaddr_in6; typedef struct sockaddr_in6 os_sockaddr_in6;
#endif #endif
@ -120,59 +110,49 @@ extern "C" {
#define SD_FLAG_IS_SET(flags, flag) ((((uint32_t)(flags) & (uint32_t)(flag))) != 0U) #define SD_FLAG_IS_SET(flags, flag) ((((uint32_t)(flags) & (uint32_t)(flag))) != 0U)
/** #define OS_AF_NULL (-1)
* Structure to hold a network interface's attributes
*/ /** Network interface attributes */
typedef struct os_ifAttributes_s { typedef struct os_ifaddrs_s {
/** struct os_ifaddrs_s *next;
* The network interface name (or at least OS_IFNAMESIZE - 1 charcaters thereof) char *name;
*/ uint32_t index;
char name[OS_IFNAMESIZE];
/**
* Iff the interface is IPv4 holds the ioctl query result flags for this interface.
*/
uint32_t flags; uint32_t flags;
/** os_sockaddr *addr;
* The network interface address of this interface. os_sockaddr *netmask;
*/ os_sockaddr *broadaddr;
os_sockaddr_storage address; } os_ifaddrs_t;
/**
* Iff this is an IPv4 interface, holds the broadcast address for the sub-network this
* interface is connected to.
*/
os_sockaddr_storage broadcast_address;
/**
* Iff this is an IPv4 interface, holds the subnet mast for this interface
*/
os_sockaddr_storage network_mask;
/**
* Holds the interface index for this interface.
*/
unsigned interfaceIndexNo;
} os_ifAttributes;
OSAPI_EXPORT os_result
os_sockQueryInterfaces(
os_ifAttributes *ifList,
uint32_t listSize,
uint32_t *validElements);
/** /**
* Fill-in a pre-allocated list of os_ifAttributes_s with details of * @brief Get interface addresses
* the available IPv6 network interfaces. *
* @param listSize Number of elements there is space for in the list. * Retrieve network interfaces available on the local system and store
* @param ifList Pointer to head of list * them in a linked list of os_ifaddrs_t structures.
* @param validElements Out param to hold the number of interfaces found *
* whose detauils have been returned. * The data returned by os_getifaddrs() is dynamically allocated and should
* @return os_resultSuccess if 0 or more interfaces were found, os_resultFail if * be freed using os_freeifaddrs when no longer needed.
* an error occurred. *
* @see os_sockQueryInterfaces * @param[in,out] ifap Address of first os_ifaddrs_t structure in the list.
* @param[in] afs NULL-terminated array of address families (AF_xyz) to
* restrict resulting set of network interfaces too. NULL to
* return all network interfaces for all supported address
* families. Terminate the array with OS_AF_NULL.
*
* @returns Returns zero on success or a valid errno value on error.
*/ */
OSAPI_EXPORT os_result OSAPI_EXPORT _Success_(return == 0) int
os_sockQueryIPv6Interfaces( os_getifaddrs(
os_ifAttributes *ifList, _Inout_ os_ifaddrs_t **ifap,
uint32_t listSize, _In_opt_ const int *afs);
uint32_t *validElements);
/**
* @brief Free os_ifaddrs_t structure list allocated by os_getifaddrs()
*
* @param[in] Address of first os_ifaddrs_t structure in the list.
*/
OSAPI_EXPORT void
os_freeifaddrs(
_Pre_maybenull_ _Post_ptr_invalid_ os_ifaddrs_t *ifa);
OSAPI_EXPORT os_socket OSAPI_EXPORT os_socket
os_sockNew( os_sockNew(
@ -271,20 +251,53 @@ extern "C" {
os_time *timeout); os_time *timeout);
#endif /* WIN32 */ #endif /* WIN32 */
/* docced in implementation file */ /**
OSAPI_EXPORT os_result * Returns size of socket address.
os_sockaddrInit(os_sockaddr* sa, * @param sa Socket address to return the size for.
bool isIPv4); /* IPvX is poorly abstracted; this is temporary */ * @return Size of the socket address based on the address family, or 0 if
* the address family is unknown.
* @pre sa is a valid os_sockaddr pointer.
*/
OSAPI_EXPORT size_t
os_sockaddr_get_size(
const os_sockaddr *const sa) __nonnull_all__;
/* docced in implementation file */ /**
OSAPI_EXPORT bool * Retrieve port number from the given socket address.
os_sockaddrIPAddressEqual(const os_sockaddr* this_sock, * @param sa Socket address to retrieve the port from.
const os_sockaddr* that_sock); * @return Port number in host order.
* @pre sa is a valid os_sockaddr pointer.
*/
OSAPI_EXPORT uint16_t
os_sockaddr_get_port(const os_sockaddr *const sa) __nonnull_all__;
/**
* Compare two IP addresses for equality - does not consider port number.
* This is a 'straight' compare i.e. family must match and address bytes
* must correspond. It does not consider the possibility of IPv6 mapped
* IPv4 addresses or anything arcane like that.
* @param sa1 First socket address
* @param sa2 Second socket address.
* @return true if equal, false otherwise.
* @return Integer less than, equal to, or greater than zero if sa1 is
* found, respectively, to be less than, to match, or be greater
* than sa2.
* @pre both sa1 and sa2 are valid os_sockaddr pointers.
*/
OSAPI_EXPORT int OSAPI_EXPORT int
os_sockaddrIpAddressCompare(const os_sockaddr* addr1, os_sockaddr_compare(
const os_sockaddr* addr2) __nonnull_all__ const os_sockaddr *const sa1,
__attribute_pure__; const os_sockaddr *const sa2) __nonnull_all__ __attribute_pure__;
/**
* Check if IP address of given socket address is unspecified.
* @param sa Socket address
* @return true if unspecified, false otherwise.
* @pre sa is a valid os_sockaddr pointer.
*/
OSAPI_EXPORT int
os_sockaddr_is_unspecified(
const os_sockaddr *const sa) __nonnull_all__;
/* docced in implementation file */ /* docced in implementation file */
OSAPI_EXPORT bool OSAPI_EXPORT bool
@ -303,20 +316,6 @@ extern "C" {
os_sockaddrAddressToString(const os_sockaddr* sa, os_sockaddrAddressToString(const os_sockaddr* sa,
char* buffer, size_t buflen); char* buffer, size_t buflen);
/**
* Convert a socket address to a string format representation including the
* portnumber.
* @param sa The socket address struct.
* @param buffer A character buffer to hold the string rep of the address.
* @param buflen The (max) size of the buffer
* @return Pointer to start of string
*/
OSAPI_EXPORT char*
os_sockaddrAddressPortToString(
const os_sockaddr* sa,
char* buffer,
size_t buflen);
/** /**
* Convert the provided addressString into a os_sockaddr. * Convert the provided addressString into a os_sockaddr.
* *
@ -342,16 +341,6 @@ extern "C" {
OSAPI_EXPORT bool OSAPI_EXPORT bool
os_sockaddrIsLoopback(const os_sockaddr* thisSock); os_sockaddrIsLoopback(const os_sockaddr* thisSock);
/**
* Returns sizeof(sa) based on the family of the actual content.
* @param sa the sockaddr to get the actual size for
* @return The actual size sa based on the family. If the family is
* unknown 0 will be returned.
* @pre sa is a valid sockaddr pointer
*/
OSAPI_EXPORT size_t
os_sockaddrSizeof(const os_sockaddr* sa);
/** /**
* Sets the address of the sockaddr to the special IN_ADDR_ANY value. * Sets the address of the sockaddr to the special IN_ADDR_ANY value.
* @param sa the sockaddr to set the address for * @param sa the sockaddr to set the address for
@ -361,26 +350,6 @@ extern "C" {
OSAPI_EXPORT void OSAPI_EXPORT void
os_sockaddrSetInAddrAny(os_sockaddr* sa); os_sockaddrSetInAddrAny(os_sockaddr* sa);
/**
* Sets the port number in the supplied sockaddr.
* @param sa the sockaddr to set the port in
* @param port the port number to be set in network byte order
* @pre sa is a valid sockaddr pointer
* @post Port number of sa is set to port
*/
OSAPI_EXPORT void
os_sockaddrSetPort(os_sockaddr* sa, uint16_t port);
/**
* Retrieves the port number from the supplied sockaddr.
* @param sa the sockaddr to retrieve the port from
* @return The port number stored in the supplied sockaddr (hence in network byte order)
* @pre sa is a valid sockaddr pointer
*/
OSAPI_EXPORT uint16_t
os_sockaddrGetPort(const os_sockaddr* const sa);
/** /**
* @} * @}
*/ */

View file

@ -262,6 +262,9 @@ extern "C" {
__attribute_returns_nonnull__ __attribute_returns_nonnull__
__attribute_warn_unused_result__; __attribute_warn_unused_result__;
void *
os_memdup(const void *src, size_t n);
/** \brief os_strsep wrapper /** \brief os_strsep wrapper
* *
* See strsep() * See strsep()
@ -271,6 +274,14 @@ extern "C" {
char **stringp, char **stringp,
const char *delim); const char *delim);
/** \brief write a formatted string to a newly allocated buffer
*/
OSAPI_EXPORT int
os_asprintf(
char **strp,
const char *fmt,
...);
/** \brief os_vsnprintf wrapper /** \brief os_vsnprintf wrapper
* *
* Microsoft generates deprected warnings for vsnprintf, * Microsoft generates deprected warnings for vsnprintf,

View file

@ -39,7 +39,6 @@ extern "C" {
/* Keep defines before common header */ /* Keep defines before common header */
#define OS_SOCKET_HAS_IPV6 1 #define OS_SOCKET_HAS_IPV6 1
#define OS_IFNAMESIZE IF_NAMESIZE
#define OS_SOCKET_HAS_SA_LEN 1 #define OS_SOCKET_HAS_SA_LEN 1
#define OS_NO_SIOCGIFINDEX 1 #define OS_NO_SIOCGIFINDEX 1
#define OS_NO_NETLINK 1 #define OS_NO_NETLINK 1

View file

@ -25,7 +25,6 @@ extern "C" {
/* Keep defines before common header */ /* Keep defines before common header */
#define OS_SOCKET_HAS_IPV6 1 #define OS_SOCKET_HAS_IPV6 1
#define OS_IFNAMESIZE 128
#define OS_SOCKET_HAS_SA_LEN 0 #define OS_SOCKET_HAS_SA_LEN 0
#define OS_NO_SIOCGIFINDEX 1 #define OS_NO_SIOCGIFINDEX 1
#define OS_NO_NETLINK 1 #define OS_NO_NETLINK 1

29
src/os/src/os_ifaddrs.c Normal file
View file

@ -0,0 +1,29 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include "os/os.h"
void
os_freeifaddrs(os_ifaddrs_t *ifa)
{
os_ifaddrs_t *next;
while (ifa != NULL) {
next = ifa->next;
os_free(ifa->name);
os_free(ifa->addr);
os_free(ifa->netmask);
os_free(ifa->broadaddr);
os_free(ifa);
ifa = next;
}
}

View file

@ -20,6 +20,11 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#ifdef __linux
#include <linux/if_packet.h> /* sockaddr_ll */
#endif /* __linux */
#include "os/os.h" #include "os/os.h"
#if (OS_SOCKET_HAS_IPV6 == 1) #if (OS_SOCKET_HAS_IPV6 == 1)
@ -40,180 +45,125 @@ const os_in6_addr os_in6addr_loopback = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
#define OS_INET_PTON inet_pton #define OS_INET_PTON inet_pton
#endif #endif
static const int afs[] = {
void os__sockaddrInit4(os_sockaddr* sa) #ifdef __linux
AF_PACKET,
#endif /* __linux */
#if OS_SOCKET_HAS_IPV6
AF_INET6,
#endif /* OS_SOCKET_HAS_IPV6 */
AF_INET,
OS_AF_NULL /* Terminator */
};
const int *const os_supp_afs = afs;
size_t
os_sockaddr_get_size(const os_sockaddr *const sa)
{ {
assert(sa); size_t sz;
/* 0 is a valid value for all members besides sa_family */
memset(sa, 0, sizeof(os_sockaddr_in));
sa->sa_family = AF_INET;
}
assert(sa != NULL);
#if (OS_SOCKET_HAS_IPV6 == 1) switch(sa->sa_family) {
static #if OS_SOCKET_HAS_IPV6
void os__sockaddrInit6(os_sockaddr* sa) case AF_INET6:
{ sz = sizeof(os_sockaddr_in6);
assert(sa); break;
/* 0 is a valid value for all members besides sa_family */ #endif /* OS_SOCKET_HAS_IPV6 */
memset(sa, 0, sizeof(os_sockaddr_in6)); #ifdef __linux
sa->sa_family = AF_INET6; case AF_PACKET:
} sz = sizeof(struct sockaddr_ll);
#endif break;
#endif /* __linux */
default:
/** assert(sa->sa_family == AF_INET);
* Initialises the memory pointed to by sa. The address family sz = sizeof(os_sockaddr_in);
* will be set correctly according to isIPv4. break;
* @param sa Pointer to the os_sockaddr to be initialised
* @param isIPv4 Flag indicating whether *sa will be IPv4 or IPv6. If
* IPv6 is not supported but this flag is FALSE, sa will be initialised
* as IPv4 and an API-warning is logged.
* @pre sa != NULL
* @return os_resultSuccess on successful initialisation, os_resultInvalid
* if isIPv4 was FALSE but IPv6 is not supported.
* @post sa is initialised
* @note Please be aware that the memory will be memset; make sure that
* enough memory for the requested address kind is available. Allocating
* os_sockaddr_storage always suffices.
*/
os_result
os_sockaddrInit(os_sockaddr* sa,
bool isIPv4)
{
os_result result = os_resultSuccess;
assert(sa);
if (!isIPv4)
{
#if (OS_SOCKET_HAS_IPV6 == 1)
os__sockaddrInit6(sa);
#else
OS_ERROR("os_sockaddrInit", 0,
"Unsupported parameter value: IPV6 address requested but not supported by this platform");
os__sockaddrInit4(sa);
result = os_resultInvalid;
#endif
}
else
{
os__sockaddrInit4(sa);
} }
return result; return sz;
} }
uint16_t os_sockaddr_get_port(const os_sockaddr *const sa)
/**
* Compare two socket IP host addresses for equality - does not consider the port number.
* This is a 'straight' equal i.e. family must match and address bytes
* must correspond. So it will not consider the possibility of IPv6 mapped
* IPv4 addresses or anything arcane like that.
* @param thisSock First address
* @param thatSock Second address.
* @return true if equal, false otherwise.
*/
bool
os_sockaddrIPAddressEqual(const os_sockaddr* thisSock,
const os_sockaddr* thatSock)
{ {
bool result = false; unsigned short port = 0;
#if (OS_SOCKET_HAS_IPV6 == 1)
os_sockaddr_in6 * thisV6, * thatV6;
#endif
if (thisSock->sa_family == thatSock->sa_family) switch(sa->sa_family) {
{ #if OS_SOCKET_HAS_IPV6
if (thisSock->sa_family == AF_INET) case AF_INET6:
{ port = ntohs(((os_sockaddr_in6 *)sa)->sin6_port);
/* IPv4 */ break;
result = (((os_sockaddr_in*)thisSock)->sin_addr.s_addr == #endif /* OS_SOCKET_HAS_IPV6 */
((os_sockaddr_in*)thatSock)->sin_addr.s_addr ? default:
true: false); assert(sa->sa_family == AF_INET);
} port = ntohs(((os_sockaddr_in *)sa)->sin_port);
#if (OS_SOCKET_HAS_IPV6 == 1) break;
else
{
/* IPv6 */
thisV6 = (os_sockaddr_in6*) thisSock;
thatV6 = (os_sockaddr_in6*) thatSock;
result = (memcmp(&thisV6->sin6_addr.s6_addr, &thatV6->sin6_addr.s6_addr, sizeof(unsigned char) * 16) ?
false : true);
}
#endif
} }
return result;
return port;
} }
int int os_sockaddr_compare(
os_sockaddrIpAddressCompare(const os_sockaddr* addr1, const os_sockaddr *const sa1,
const os_sockaddr* addr2) const os_sockaddr *const sa2)
{ {
int result = -1; int eq;
uint16_t port1, port2; size_t sz;
int r;
if ((eq = sa1->sa_family - sa2->sa_family) == 0) {
switch(sa1->sa_family) {
#if (OS_SOCKET_HAS_IPV6 == 1) #if (OS_SOCKET_HAS_IPV6 == 1)
os_sockaddr_in6 * thisV6, * thatV6; case AF_INET6:
#endif {
os_sockaddr_in6 *sin61, *sin62;
if (addr1->sa_family == addr2->sa_family) sin61 = (os_sockaddr_in6 *)sa1;
{ sin62 = (os_sockaddr_in6 *)sa2;
if (addr1->sa_family == AF_INET) sz = sizeof(sin61->sin6_addr);
{ eq = memcmp(&sin61->sin6_addr, &sin62->sin6_addr, sz);
/* IPv4 */
if (((os_sockaddr_in*)addr1)->sin_addr.s_addr ==
((os_sockaddr_in*)addr2)->sin_addr.s_addr) {
port1 = os_sockaddrGetPort(addr1);
port2 = os_sockaddrGetPort(addr2);
if (port1 == port2) {
result = 0;
} else {
if (port1 > port2) {
result = 1;
} else {
result = -1;
}
}
} else {
if (((os_sockaddr_in*)addr1)->sin_addr.s_addr >
((os_sockaddr_in*)addr2)->sin_addr.s_addr) {
result = 1;
} else {
result = -1;
}
} }
} break;
#if (OS_SOCKET_HAS_IPV6 == 1) #endif /* OS_SOCKET_HAS_IPV6 */
else #ifdef __linux
{ case AF_PACKET:
/* IPv6 */ {
thisV6 = (os_sockaddr_in6*) addr1; struct sockaddr_ll *sll1, *sll2;
thatV6 = (os_sockaddr_in6*) addr2; sll1 = (struct sockaddr_ll *)sa1;
r = memcmp(&thisV6->sin6_addr.s6_addr, &thatV6->sin6_addr.s6_addr, sizeof(unsigned char) * 16); sll2 = (struct sockaddr_ll *)sa2;
if (r == 0) { sz = sizeof(sll1->sll_addr);
port1 = os_sockaddrGetPort(addr1); eq = memcmp(sll1->sll_addr, sll2->sll_addr, sz);
port2 = os_sockaddrGetPort(addr2);
if (port1 == port2) {
result = 0;
} else {
if (port1 > port2) {
result = 1;
} else {
result = -1;
}
}
} else {
if (r > 0) {
result = 1;
} else {
result = -1;
}
} }
break;
#endif /* __linux */
default:
{
assert(sa1->sa_family == AF_INET);
os_sockaddr_in *sin1, *sin2;
sin1 = (os_sockaddr_in *)sa1;
sin2 = (os_sockaddr_in *)sa2;
sz = sizeof(sin1->sin_addr);
eq = memcmp(sin1, sin2, sizeof(*sin1));
}
break;
} }
#endif
} }
return result;
return eq;
}
int os_sockaddr_is_unspecified(const os_sockaddr *const sa)
{
int unspec = 0;
assert(sa != NULL);
if (sa->sa_family == AF_INET6) {
unspec = IN6_IS_ADDR_UNSPECIFIED(&((os_sockaddr_in6 *)sa)->sin6_addr);
} else if (sa->sa_family == AF_INET) {
unspec = (((os_sockaddr_in *)sa)->sin_addr.s_addr == 0);
}
return unspec;
} }
/** /**
@ -342,7 +292,7 @@ os_sockaddrIsLoopback(const os_sockaddr* thisSock)
if (thisSock->sa_family == AF_INET6) if (thisSock->sa_family == AF_INET6)
{ {
result = IN6_IS_ADDR_LOOPBACK(&((os_sockaddr_in6*)thisSock)->sin6_addr) || result = IN6_IS_ADDR_LOOPBACK(&((os_sockaddr_in6*)thisSock)->sin6_addr) ||
os_sockaddrIPAddressEqual(thisSock, linkLocalLoopbackPtr) ? true : false; os_sockaddr_compare(thisSock, linkLocalLoopbackPtr) == 0 ? true : false;
} }
else else
#endif #endif
@ -354,38 +304,6 @@ os_sockaddrIsLoopback(const os_sockaddr* thisSock)
return result; return result;
} }
size_t
os_sockaddrSizeof(
const os_sockaddr* sa)
{
size_t result;
assert(sa);
switch(sa->sa_family){
#if (OS_SOCKET_HAS_IPV6 == 1)
case AF_INET6:
result = sizeof(os_sockaddr_in6);
break;
#endif
case AF_INET:
result = sizeof(os_sockaddr_in);
break;
default:
#if (OS_SOCKET_HAS_IPV6 == 1)
OS_ERROR("os_sockaddrSizeof", 0,
"Unkown address family specified: %d. Should be AF_INET (%d) or AF_INET6 (%d)",
(int)sa->sa_family, AF_INET, AF_INET6);
#else
OS_ERROR("os_sockaddrSizeof", 0,
"Unkown address family specified: %d. Should be AF_INET (%d)",
(int)sa->sa_family, AF_INET);
#endif
result = 0;
break;
}
return result;
}
void void
os_sockaddrSetInAddrAny( os_sockaddrSetInAddrAny(
os_sockaddr* sa) os_sockaddr* sa)
@ -406,54 +324,6 @@ os_sockaddrSetInAddrAny(
} }
} }
void
os_sockaddrSetPort(
os_sockaddr* sa,
uint16_t port /* network byte order */)
{
assert(sa);
#if (OS_SOCKET_HAS_IPV6 == 1)
assert(sa->sa_family == AF_INET6 || sa->sa_family == AF_INET);
if (sa->sa_family == AF_INET6)
{
((os_sockaddr_in6*)sa)->sin6_port = port;
}
else
#else
assert(sa->sa_family == AF_INET);
#endif
if (sa->sa_family == AF_INET)
{
((os_sockaddr_in*)sa)->sin_port = port;
}
}
uint16_t /* network byte order */
os_sockaddrGetPort(
const os_sockaddr* const sa)
{
uint16_t port = 0;
assert(sa);
#if (OS_SOCKET_HAS_IPV6 == 1)
assert(sa->sa_family == AF_INET6 || sa->sa_family == AF_INET);
if (sa->sa_family == AF_INET6)
{
port = (uint16_t)((os_sockaddr_in6*)sa)->sin6_port;
}
else
#else
assert(sa->sa_family == AF_INET);
#endif
if (sa->sa_family == AF_INET)
{
port = (uint16_t)((os_sockaddr_in*)sa)->sin_port;
}
return port;
}
char* char*
os_sockaddrAddressToString(const os_sockaddr* sa, os_sockaddrAddressToString(const os_sockaddr* sa,
char* buffer, size_t buflen) char* buffer, size_t buflen)
@ -478,34 +348,3 @@ os_sockaddrAddressToString(const os_sockaddr* sa,
return buffer; return buffer;
} }
char*
os_sockaddrAddressPortToString(
const os_sockaddr* sa,
char* buffer,
size_t buflen)
{
size_t pos;
switch (sa->sa_family)
{
case AF_INET:
os_sockaddrAddressToString (sa, buffer, buflen);
pos = strlen (buffer);
(void) snprintf (buffer + pos, buflen - pos, ":%hu", ntohs (((os_sockaddr_in *) sa)->sin_port));
break;
#if OS_SOCKET_HAS_IPV6
case AF_INET6:
if(buflen){
buffer[0] = '[';
os_sockaddrAddressToString (sa, buffer + 1, buflen - 1);
pos = strlen (buffer);
(void) snprintf (buffer + pos, buflen - pos, "]:%hu", ntohs (((os_sockaddr_in6 *) sa)->sin6_port));
}
break;
#endif
default:
(void) snprintf(buffer, buflen, "Unknown address family");
break;
}
return buffer;
}

View file

@ -0,0 +1,114 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <assert.h>
#include <string.h>
#include "os/os.h"
extern const int *const os_supp_afs;
static int
copyaddr(os_ifaddrs_t **ifap, const struct ifaddrs *sys_ifa)
{
int err = 0;
os_ifaddrs_t *ifa;
size_t sz;
assert(ifap != NULL);
assert(sys_ifa != NULL);
sz = os_sockaddr_get_size(sys_ifa->ifa_addr);
ifa = os_calloc_s(1, sizeof(*ifa));
if (ifa == NULL) {
err = errno;
} else {
ifa->index = if_nametoindex(sys_ifa->ifa_name);
ifa->flags = sys_ifa->ifa_flags;
if ((ifa->name = os_strdup(sys_ifa->ifa_name)) == NULL ||
(ifa->addr = os_memdup(sys_ifa->ifa_addr, sz)) == NULL ||
(sys_ifa->ifa_netmask != NULL &&
(ifa->netmask = os_memdup(sys_ifa->ifa_netmask, sz)) == NULL) ||
(sys_ifa->ifa_broadaddr != NULL &&
(sys_ifa->ifa_flags & IFF_BROADCAST) &&
(ifa->broadaddr = os_memdup(sys_ifa->ifa_broadaddr, sz)) == NULL))
{
err = errno;
}
}
if (err == 0) {
*ifap = ifa;
} else {
os_freeifaddrs(ifa);
}
return err;
}
_Success_(return == 0) int
os_getifaddrs(
_Inout_ os_ifaddrs_t **ifap,
_In_opt_ const int *afs)
{
int err = 0;
int use;
os_ifaddrs_t *ifa, *ifa_root, *ifa_next;
struct ifaddrs *sys_ifa, *sys_ifa_root;
struct sockaddr *sa;
assert(ifap != NULL);
if (afs == NULL) {
afs = os_supp_afs;
}
if (getifaddrs(&sys_ifa_root) == -1) {
err = errno;
} else {
ifa = ifa_root = NULL;
for (sys_ifa = sys_ifa_root;
sys_ifa != NULL && err == 0;
sys_ifa = sys_ifa->ifa_next)
{
sa = sys_ifa->ifa_addr;
if (sa != NULL) {
use = 0;
for (int i = 0; !use && afs[i] != OS_AF_NULL; i++) {
use = (sa->sa_family == afs[i]);
}
if (use) {
err = copyaddr(&ifa_next, sys_ifa);
if (err == 0) {
if (ifa == NULL) {
ifa = ifa_root = ifa_next;
} else {
ifa->next = ifa_next;
ifa = ifa_next;
}
}
}
}
}
freeifaddrs(sys_ifa_root);
if (err == 0) {
*ifap = ifa_root;
} else {
os_freeifaddrs(ifa_root);
}
}
return err;
}

View file

@ -230,98 +230,3 @@ os_sockSelect(
return r; return r;
} }
_Check_return_
static os_result
os_queryInterfaceAttributesIPv4 (_In_ const struct ifaddrs *ifa, _Inout_ os_ifAttributes *ifElement)
{
os_result result = os_resultSuccess;
strncpy (ifElement->name, ifa->ifa_name, OS_IFNAMESIZE);
ifElement->name[OS_IFNAMESIZE - 1] = '\0';
memcpy (&ifElement->address, ifa->ifa_addr, sizeof (os_sockaddr_in));
ifElement->flags = ifa->ifa_flags;
if (ifElement->flags & IFF_BROADCAST)
memcpy (&ifElement->broadcast_address, ifa->ifa_broadaddr, sizeof (os_sockaddr_in));
else
memset (&ifElement->broadcast_address, 0, sizeof (ifElement->broadcast_address));
memcpy (&ifElement->network_mask, ifa->ifa_netmask, sizeof (os_sockaddr_in));
ifElement->interfaceIndexNo = (unsigned) if_nametoindex (ifa->ifa_name);
return result;
}
_Check_return_
static os_result
os_queryInterfaceAttributesIPv6 (_In_ const struct ifaddrs *ifa, _Inout_ os_ifAttributes *ifElement)
{
os_result result = os_resultSuccess;
strncpy (ifElement->name, ifa->ifa_name, OS_IFNAMESIZE);
ifElement->name[OS_IFNAMESIZE - 1] = '\0';
memcpy (&ifElement->address, ifa->ifa_addr, sizeof (os_sockaddr_in6));
ifElement->flags = ifa->ifa_flags;
memset (&ifElement->broadcast_address, 0, sizeof (ifElement->broadcast_address));
memset (&ifElement->network_mask, 0, sizeof (ifElement->network_mask));
ifElement->interfaceIndexNo = (unsigned) if_nametoindex (ifa->ifa_name);
return result;
}
os_result os_sockQueryInterfaces (os_ifAttributes *ifList, uint32_t listSize, uint32_t *validElements)
{
os_result result = os_resultSuccess;
unsigned int listIndex;
struct ifaddrs *ifa_first, *ifa;
if (getifaddrs (&ifa_first) != 0)
{
perror ("getifaddrs");
return os_resultFail;
}
listIndex = 0;
for (ifa = ifa_first; ifa && listIndex < listSize; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr && ((struct sockaddr_in *) ifa->ifa_addr)->sin_family == AF_INET)
{
/* Get other interface attributes */
result = os_queryInterfaceAttributesIPv4 (ifa, &ifList[listIndex]);
if (result == os_resultSuccess)
listIndex++;
}
if (result == os_resultSuccess)
*validElements = listIndex;
}
freeifaddrs (ifa_first);
return result;
}
os_result os_sockQueryIPv6Interfaces (os_ifAttributes *ifList, uint32_t listSize, uint32_t *validElements)
{
struct ifaddrs* interfaceList = NULL;
struct ifaddrs* nextInterface = NULL;
unsigned int listIndex = 0;
*validElements = 0;
if (getifaddrs (&interfaceList) != 0)
{
return os_resultFail;
}
nextInterface = interfaceList;
while (nextInterface != NULL && listIndex < listSize)
{
if (nextInterface->ifa_addr && nextInterface->ifa_addr->sa_family == AF_INET6)
{
os_sockaddr_in6 *v6Address = (os_sockaddr_in6 *) nextInterface->ifa_addr;
if (!IN6_IS_ADDR_UNSPECIFIED (&v6Address->sin6_addr))
{
os_result result = os_resultSuccess;
result = os_queryInterfaceAttributesIPv6 (nextInterface, &ifList[listIndex]);
if (result == os_resultSuccess)
listIndex++;
}
}
nextInterface = nextInterface->ifa_next;
}
*validElements = listIndex;
freeifaddrs(interfaceList);
return os_resultSuccess;
}

View file

@ -21,8 +21,13 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "os_stdlib_strsep.c" #include "os_stdlib_strsep.c"
#include "os_stdlib_memdup.c"
#include "os_stdlib_rindex.c"
#include "os_stdlib_asprintf.c"
#include "os_stdlib_strcasecmp.c"
#include "os_stdlib_strncasecmp.c"
#include "os_stdlib_strdup.c"
_Ret_opt_z_ const char * _Ret_opt_z_ const char *
os_getenv( os_getenv(
@ -79,38 +84,6 @@ os_access(
return result; return result;
} }
char *
os_rindex(
const char *s,
int c)
{
char *last = NULL;
while (*s) {
if (*s == c) {
last = (char *)s;
}
s++;
}
return last;
}
_Ret_z_
_Check_return_
char *
os_strdup(
_In_z_ const char *s1)
{
size_t len;
char *dup;
len = strlen(s1) + 1;
dup = os_malloc(len);
memcpy(dup, s1, len);
return dup;
}
int int
os_vsnprintf( os_vsnprintf(
char *str, char *str,
@ -157,48 +130,6 @@ os_vfprintfnosigpipe(
return result; return result;
} }
int
os_strcasecmp(
const char *s1,
const char *s2)
{
int cr;
while (*s1 && *s2) {
cr = tolower(*s1) - tolower(*s2);
if (cr) {
return cr;
}
s1++;
s2++;
}
cr = tolower(*s1) - tolower(*s2);
return cr;
}
int
os_strncasecmp(
const char *s1,
const char *s2,
size_t n)
{
int cr = 0;
while (*s1 && *s2 && n) {
cr = tolower(*s1) - tolower(*s2);
if (cr) {
return cr;
}
s1++;
s2++;
n--;
}
if (n) {
cr = tolower(*s1) - tolower(*s2);
}
return cr;
}
os_result os_result
os_stat( os_stat(
const char *path, const char *path,

View file

@ -0,0 +1,48 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include "os/os.h"
int
os_asprintf(
char **strp,
const char *fmt,
...)
{
int ret;
unsigned int len;
char buf[1] = { '\0' };
char *str = NULL;
va_list args1, args2;
assert(strp != NULL);
assert(fmt != NULL);
va_start(args1, fmt);
va_copy(args2, args1); /* va_list cannot be reused */
if ((ret = os_vsnprintf(buf, sizeof(buf), fmt, args1)) >= 0) {
len = (unsigned int)ret; /* +1 for null byte */
if ((str = os_malloc(len + 1)) == NULL) {
ret = -1;
} else if ((ret = os_vsnprintf(str, len + 1, fmt, args2)) >= 0) {
assert(((unsigned int)ret) == len);
*strp = str;
} else {
os_free(str);
}
}
va_end(args1);
va_end(args2);
return ret;
}

View file

@ -0,0 +1,24 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include "os/os.h"
void *
os_memdup(const void *src, size_t n)
{
void *dest = NULL;
if (n != 0 && (dest = os_malloc_s(n)) != NULL) {
memcpy(dest, src, n);
}
return dest;
}

View file

@ -0,0 +1,28 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <stddef.h>
char *
os_rindex(
const char *s,
int c)
{
char *last = NULL;
while (*s) {
if (*s == c) {
last = (char *)s;
}
s++;
}
return last;
}

View file

@ -0,0 +1,34 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include "os/os.h"
#ifdef _MSC_VER
#pragma warning( default : 4996 )
#endif /* _MSC_VER */
int
os_strcasecmp(
const char *s1,
const char *s2)
{
int cr;
while (*s1 && *s2) {
cr = tolower(*s1) - tolower(*s2);
if (cr) {
return cr;
}
s1++;
s2++;
}
cr = tolower(*s1) - tolower(*s2);
return cr;
}

View file

@ -0,0 +1,23 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include "os/os.h"
_Ret_z_
_Check_return_
char *
os_strdup(
_In_z_ const char *str)
{
assert(str != NULL);
return os_memdup(str, strlen(str) + 1);
}

View file

@ -0,0 +1,35 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include "os/os.h"
int
os_strncasecmp(
const char *s1,
const char *s2,
size_t n)
{
int cr = 0;
while (*s1 && *s2 && n) {
cr = tolower(*s1) - tolower(*s2);
if (cr) {
return cr;
}
s1++;
s2++;
n--;
}
if (n) {
cr = tolower(*s1) - tolower(*s2);
}
return cr;
}

View file

@ -0,0 +1,269 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#include "os/os.h"
extern const int *const os_supp_afs;
static int
getifaces(PIP_ADAPTER_ADDRESSES *ptr)
{
int err = ERANGE;
PIP_ADAPTER_ADDRESSES buf = NULL;
ULONG bufsz = 0; /* Size is determined on first iteration. */
ULONG ret;
size_t i;
static const size_t max = 2;
static const ULONG filter = GAA_FLAG_INCLUDE_PREFIX |
GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_MULTICAST |
GAA_FLAG_SKIP_DNS_SERVER;
assert(ptr != NULL);
for (i = 0; err == ERANGE && i < max; i++) {
ret = GetAdaptersAddresses(AF_UNSPEC, filter, NULL, buf, &bufsz);
assert(ret != ERROR_INVALID_PARAMETER);
switch (ret) {
case ERROR_BUFFER_OVERFLOW:
err = ERANGE;
os_free(buf);
if ((buf = (IP_ADAPTER_ADDRESSES *)os_malloc(bufsz)) == NULL) {
err = ENOMEM;
}
break;
case ERROR_NOT_ENOUGH_MEMORY:
err = ENOMEM;
break;
case ERROR_SUCCESS:
case ERROR_ADDRESS_NOT_ASSOCIATED: /* No address associated yet. */
case ERROR_NO_DATA: /* No adapters that match the filter. */
default:
err = 0;
break;
}
}
if (err == 0) {
*ptr = buf;
}
return err;
}
static int
getaddrtable(PMIB_IPADDRTABLE *ptr)
{
int err = ERANGE;
PMIB_IPADDRTABLE buf = NULL;
ULONG bufsz = 0;
DWORD ret;
size_t i;
static const size_t max = 2;
assert(ptr != NULL);
for (i = 0; err == ERANGE && i < max; i++) {
ret = GetIpAddrTable(buf, &bufsz, 0);
assert(ret != ERROR_INVALID_PARAMETER &&
ret != ERROR_NOT_SUPPORTED);
switch (ret) {
case ERROR_INSUFFICIENT_BUFFER:
err = ERANGE;
os_free(buf);
if ((buf = (PMIB_IPADDRTABLE)os_malloc(bufsz)) == NULL) {
err = ENOMEM;
}
break;
case ERROR_SUCCESS:
default:
err = GetLastError();
break;
}
}
if (err == 0) {
*ptr = buf;
} else {
os_free(buf);
}
return err;
}
static uint32_t
getflags(const PIP_ADAPTER_ADDRESSES iface)
{
uint32_t flags = 0;
if (iface->OperStatus == IfOperStatusUp) {
flags |= IFF_UP;
}
if (iface->IfType == IF_TYPE_SOFTWARE_LOOPBACK) {
flags |= IFF_LOOPBACK;
}
if (!(iface->Flags & IP_ADAPTER_NO_MULTICAST)) {
flags |= IFF_MULTICAST;
}
/* FIXME: Shouldn't IFF_LOOPBACK be included here? */
switch (iface->IfType) {
case IF_TYPE_ETHERNET_CSMACD:
case IF_TYPE_IEEE80211:
case IF_TYPE_IEEE1394:
case IF_TYPE_ISO88025_TOKENRING:
flags |= IFF_BROADCAST;
break;
default:
flags |= IFF_POINTTOPOINT;
break;
}
return flags;
}
static int
copyaddr(
os_ifaddrs_t **ifap,
const PIP_ADAPTER_ADDRESSES iface,
const PMIB_IPADDRTABLE addrtable,
const PIP_ADAPTER_UNICAST_ADDRESS addr)
{
int err = 0;
int eq = 0;
os_ifaddrs_t *ifa;
DWORD i;
struct sockaddr *sa = (struct sockaddr *)addr->Address.lpSockaddr;
size_t size;
assert(iface != NULL);
assert(addrtable != NULL);
assert(addr != NULL);
if ((ifa = os_calloc_s(1, sizeof(*ifa))) == NULL) {
err = ENOMEM;
} else {
ifa->flags = getflags(iface);
(void)os_asprintf(&ifa->name, "%wS", iface->FriendlyName);
if (ifa->name == NULL) {
err = ENOMEM;
} else {
ifa->addr = os_memdup(sa, addr->Address.iSockaddrLength);
if (ifa->addr == NULL) {
err = ENOMEM;
} else if (ifa->addr->sa_family == AF_INET) {
size = sizeof(struct sockaddr_in);
struct sockaddr_in netmask, broadaddr;
memset(&netmask, 0, size);
memset(&broadaddr, 0, size);
netmask.sin_family = broadaddr.sin_family = AF_INET;
for (i = 0; !eq && i < addrtable->dwNumEntries; i++) {
eq = (((struct sockaddr_in *)sa)->sin_addr.s_addr ==
addrtable->table[i].dwAddr);
if (eq) {
ifa->index = addrtable->table[i].dwIndex;
netmask.sin_addr.s_addr = addrtable->table[i].dwMask;
broadaddr.sin_addr.s_addr =
((struct sockaddr_in *)sa)->sin_addr.s_addr | ~(netmask.sin_addr.s_addr);
}
}
assert(eq != 0);
if ((ifa->netmask = os_memdup(&netmask, size)) == NULL ||
(ifa->broadaddr = os_memdup(&broadaddr, size)) == NULL)
{
err = ENOMEM;
}
} else {
ifa->index = iface->Ipv6IfIndex;
}
}
}
if (err == 0) {
*ifap = ifa;
} else {
os_free(ifa);
}
return err;
}
_Success_(return == 0) int
os_getifaddrs(
_Inout_ os_ifaddrs_t **ifap,
_In_opt_ const int *afs)
{
int err = 0;
int use;
PIP_ADAPTER_ADDRESSES ifaces = NULL, iface;
PIP_ADAPTER_UNICAST_ADDRESS addr = NULL;
PMIB_IPADDRTABLE addrtable = NULL;
os_ifaddrs_t *ifa, *ifa_root, *ifa_next;
struct sockaddr *sa;
assert(ifap != NULL);
if (afs == NULL) {
afs = os_supp_afs;
}
ifa = ifa_root = ifa_next = NULL;
if ((err = getifaces(&ifaces)) == 0 &&
(err = getaddrtable(&addrtable)) == 0)
{
for (iface = ifaces; !err && iface != NULL; iface = iface->Next) {
for (addr = iface->FirstUnicastAddress;
addr != NULL;
addr = addr->Next)
{
sa = (struct sockaddr *)addr->Address.lpSockaddr;
use = 0;
for (int i = 0; !use && afs[i] != OS_AF_NULL; i++) {
use = (afs[i] == sa->sa_family);
}
if (use) {
err = copyaddr(&ifa_next, iface, addrtable, addr);
if (err == 0) {
if (ifa == NULL) {
ifa = ifa_root = ifa_next;
} else {
ifa->next = ifa_next;
ifa = ifa_next;
}
}
}
}
}
}
os_free(ifaces);
os_free(addrtable);
if (err == 0) {
*ifap = ifa_root;
} else {
os_freeifaddrs(ifa_root);
}
return err;
}

View file

@ -19,9 +19,6 @@
#include <assert.h> #include <assert.h>
#define WORKING_BUFFER_SIZE 15000
#define MAX_TRIES 3
typedef BOOL (WINAPI *qwaveQOSCreateHandleFuncT) (_In_ PQOS_VERSION Version, _Out_ PHANDLE QOSHandle); typedef BOOL (WINAPI *qwaveQOSCreateHandleFuncT) (_In_ PQOS_VERSION Version, _Out_ PHANDLE QOSHandle);
typedef BOOL (WINAPI *qwaveQOSCloseHandleFuncT) (_In_ HANDLE QOSHandle); typedef BOOL (WINAPI *qwaveQOSCloseHandleFuncT) (_In_ HANDLE QOSHandle);
typedef BOOL (WINAPI *qwaveQOSAddSocketToFlowFuncT) ( typedef BOOL (WINAPI *qwaveQOSAddSocketToFlowFuncT) (
@ -558,341 +555,3 @@ os__sockSelect(
return r; return r;
} }
static unsigned int
getInterfaceFlags(PIP_ADAPTER_ADDRESSES pAddr)
{
unsigned int flags = 0;
if (pAddr->OperStatus == IfOperStatusUp) {
flags |= IFF_UP;
}
if (pAddr->IfType == IF_TYPE_SOFTWARE_LOOPBACK) {
flags |= IFF_LOOPBACK;
}
if (!(pAddr->Flags & IP_ADAPTER_NO_MULTICAST)) {
flags |= IFF_MULTICAST;
}
switch (pAddr->IfType) {
case IF_TYPE_ETHERNET_CSMACD:
case IF_TYPE_IEEE80211:
case IF_TYPE_IEEE1394:
case IF_TYPE_ISO88025_TOKENRING:
flags |= IFF_BROADCAST;
break;
default:
flags |= IFF_POINTTOPOINT;
break;
}
return flags;
}
static os_result
addressToIndexAndMask(struct sockaddr *addr, unsigned int *ifIndex, struct sockaddr *mask )
{
os_result result = os_resultSuccess;
bool found = FALSE;
PMIB_IPADDRTABLE pIPAddrTable = NULL;
DWORD dwSize = 0;
DWORD i;
int errNo;
if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
pIPAddrTable = (MIB_IPADDRTABLE *) os_malloc(dwSize);
if (pIPAddrTable != NULL) {
if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) != NO_ERROR) {
errNo = os_getErrno();
OS_ERROR("addressToIndexAndMask", 0, "GetIpAddrTable failed: %d", errNo);
result = os_resultFail;
}
} else {
OS_ERROR("addressToIndexAndMask", 0, "Failed to allocate %lu bytes for IP address table", dwSize);
result = os_resultFail;
}
} else {
errNo = os_getErrno();
OS_ERROR("addressToIndexAndMask", 0, "GetIpAddrTable failed: %d", errNo);
result = os_resultFail;
}
if (result == os_resultSuccess) {
for (i = 0; !found && i < pIPAddrTable->dwNumEntries; i++ ) {
if (((struct sockaddr_in* ) addr )->sin_addr.s_addr == pIPAddrTable->table[i].dwAddr) {
*ifIndex = pIPAddrTable->table[i].dwIndex;
((struct sockaddr_in*) mask)->sin_addr.s_addr= pIPAddrTable->table[i].dwMask;
found = TRUE;
}
}
}
if (pIPAddrTable) {
os_free(pIPAddrTable);
}
if (!found) {
result = os_resultFail;
}
return result;
}
#define MAX_INTERFACES 64
#define INTF_MAX_NAME_LEN 16
os_result
os_sockQueryInterfaces(
os_ifAttributes *ifList,
unsigned int listSize,
unsigned int *validElements)
{
os_result result = os_resultSuccess;
DWORD filter;
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
PIP_ADAPTER_ADDRESSES pCurrAddress = NULL;
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
unsigned long outBufLen = WORKING_BUFFER_SIZE;
int retVal;
int iterations = 0;
int listIndex = 0;
filter = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
do {
pAddresses = (IP_ADAPTER_ADDRESSES *) os_malloc(outBufLen);
if (!pAddresses) {
OS_ERROR("os_sockQueryInterfaces", 0, "Failed to allocate %lu bytes for Adapter addresses", outBufLen);
return os_resultFail;
}
retVal = GetAdaptersAddresses(AF_INET, filter, NULL, pAddresses, &outBufLen);
if (retVal == ERROR_BUFFER_OVERFLOW) {
os_free(pAddresses);
pAddresses = NULL;
outBufLen <<= 1; /* double the buffer just to be save.*/
} else {
break;
}
iterations++;
} while ((retVal == ERROR_BUFFER_OVERFLOW) && (iterations < MAX_TRIES));
if (retVal != ERROR_SUCCESS) {
if (pAddresses) {
os_free(pAddresses);
pAddresses = NULL;
}
OS_ERROR("os_sockQueryInterfaces", 0, "Failed to GetAdaptersAddresses");
return os_resultFail;
}
for (pCurrAddress = pAddresses; pCurrAddress; pCurrAddress = pCurrAddress->Next) {
IP_ADAPTER_PREFIX *firstPrefix = NULL;
if (pCurrAddress->Length >= sizeof(IP_ADAPTER_ADDRESSES)) {
firstPrefix = pCurrAddress->FirstPrefix;
}
if (pCurrAddress->OperStatus != IfOperStatusUp) {
continue;
}
for (pUnicast = pCurrAddress->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
unsigned int ipv4Index;
struct sockaddr_in ipv4Netmask;
if (pUnicast->Address.lpSockaddr->sa_family != AF_INET) {
continue;
}
ipv4Index = 0;
memset(&ipv4Netmask, 0, sizeof(ipv4Netmask));
if (addressToIndexAndMask((struct sockaddr *) pUnicast->Address.lpSockaddr,
&ipv4Index, (struct sockaddr *) &ipv4Netmask) != os_resultSuccess) {
continue;
}
(void)snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddress->FriendlyName);
/* Get interface flags. */
ifList[listIndex].flags = getInterfaceFlags(pCurrAddress);
ifList[listIndex].interfaceIndexNo = ipv4Index;
memcpy(&ifList[listIndex].address, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength);
memcpy(&ifList[listIndex].broadcast_address, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength);
memcpy(&ifList[listIndex].network_mask, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength);
((struct sockaddr_in *)(&(ifList[listIndex].broadcast_address)))->sin_addr.s_addr =
((struct sockaddr_in *)(&(ifList[listIndex].address)))->sin_addr.s_addr | ~(ipv4Netmask.sin_addr.s_addr);
((struct sockaddr_in *)&(ifList[listIndex].network_mask))->sin_addr.s_addr = ipv4Netmask.sin_addr.s_addr;
listIndex++;
}
}
for (pCurrAddress = pAddresses; pCurrAddress; pCurrAddress = pCurrAddress->Next) {
if (pCurrAddress->OperStatus != IfOperStatusUp) {
(void)snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddress->FriendlyName);
/* Get interface flags. */
ifList[listIndex].flags = getInterfaceFlags(pCurrAddress);
ifList[listIndex].interfaceIndexNo = 0;
memset (&ifList[listIndex].address, 0, sizeof(ifList[listIndex].address));
memset (&ifList[listIndex].broadcast_address, 0, sizeof (ifList[listIndex].broadcast_address));
memset (&ifList[listIndex].network_mask, 0, sizeof (ifList[listIndex].network_mask));
listIndex++;
}
}
if (pAddresses) {
os_free(pAddresses);
}
*validElements = listIndex;
return result;
}
os_result
os_sockQueryIPv6Interfaces (
os_ifAttributes *ifList,
unsigned int listSize,
unsigned int *validElements)
{
os_result result = os_resultSuccess;
ULONG filter;
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
PIP_ADAPTER_ADDRESSES pCurrAddress = NULL;
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
ULONG outBufLen = WORKING_BUFFER_SIZE;
ULONG retVal;
int iterations = 0;
int listIndex = 0;
filter = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
do {
pAddresses = (IP_ADAPTER_ADDRESSES *) os_malloc(outBufLen);
if (!pAddresses) {
OS_ERROR("os_sockQueryIPv6Interfaces", 0, "Failed to allocate %lu bytes for Adapter addresses", outBufLen);
return os_resultFail;
}
retVal = GetAdaptersAddresses(AF_INET6, filter, NULL, pAddresses, &outBufLen);
if (retVal == ERROR_BUFFER_OVERFLOW) {
os_free(pAddresses);
pAddresses = NULL;
outBufLen <<= 1; /* double the buffer just to be save.*/
} else {
break;
}
iterations++;
} while ((retVal == ERROR_BUFFER_OVERFLOW) && (iterations < MAX_TRIES));
if (retVal != ERROR_SUCCESS) {
if (pAddresses) {
os_free(pAddresses);
pAddresses = NULL;
}
OS_ERROR("os_sockQueryIPv6Interfaces", 0, "Failed to GetAdaptersAddresses");
return os_resultFail;
}
for (pCurrAddress = pAddresses; pCurrAddress; pCurrAddress = pCurrAddress->Next) {
DWORD ipv6IfIndex = 0;
IP_ADAPTER_PREFIX *firstPrefix = NULL;
if (pCurrAddress->Length >= sizeof(IP_ADAPTER_ADDRESSES)) {
ipv6IfIndex = pCurrAddress->Ipv6IfIndex;
firstPrefix = pCurrAddress->FirstPrefix;
}
if (((ipv6IfIndex == 1) && (pCurrAddress->IfType != IF_TYPE_SOFTWARE_LOOPBACK)) || (pCurrAddress->IfType == IF_TYPE_TUNNEL)) {
continue;
}
if (pCurrAddress->OperStatus != IfOperStatusUp) {
continue;
}
for (pUnicast = pCurrAddress->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
IP_ADAPTER_PREFIX *prefix;
IN6_ADDR mask;
struct sockaddr_in6 *sa6;
struct sockaddr_in6 ipv6Netmask;
if (pUnicast->Address.lpSockaddr->sa_family != AF_INET6) {
continue;
}
(void)snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddress->FriendlyName);
/* Get interface flags. */
ifList[listIndex].flags = getInterfaceFlags(pCurrAddress);
ifList[listIndex].interfaceIndexNo = (uint32_t) pCurrAddress->Ipv6IfIndex;
memcpy(&ifList[listIndex].address, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength);
memcpy(&ifList[listIndex].broadcast_address, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength);
memcpy(&ifList[listIndex].network_mask, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength);
sa6 = (struct sockaddr_in6 *)&ifList[listIndex].network_mask;
memset(&sa6->sin6_addr.s6_addr, 0xFF, sizeof(sa6->sin6_addr.s6_addr));
for (prefix = firstPrefix; prefix; prefix = prefix->Next) {
unsigned int l, i;
if ((prefix->PrefixLength == 0) || (prefix->PrefixLength > 128) ||
(pUnicast->Address.iSockaddrLength != prefix->Address.iSockaddrLength) ||
(memcmp(pUnicast->Address.lpSockaddr, prefix->Address.lpSockaddr, pUnicast->Address.iSockaddrLength) == 0)){
continue;
}
memset(&ipv6Netmask, 0, sizeof(ipv6Netmask));
ipv6Netmask.sin6_family = AF_INET6;
l = prefix->PrefixLength;
for (i = 0; l > 0; l -= 8, i++) {
ipv6Netmask.sin6_addr.s6_addr[i] = (l >= 8) ? 0xFF : ((0xFF << (8-l)) & 0xFF);
}
for (i = 0; i < 16; i++) {
mask.s6_addr[i] =
((struct sockaddr_in6 *)pUnicast->Address.lpSockaddr)->sin6_addr.s6_addr[i] & ipv6Netmask.sin6_addr.s6_addr[i];
}
if (memcmp(((struct sockaddr_in6 *)prefix->Address.lpSockaddr)->sin6_addr.s6_addr,
mask.s6_addr, sizeof(ipv6Netmask.sin6_addr)) == 0) {
memcpy(&sa6->sin6_addr.s6_addr, &ipv6Netmask.sin6_addr.s6_addr, sizeof(sa6->sin6_addr.s6_addr));
}
}
listIndex++;
}
}
for (pCurrAddress = pAddresses; pCurrAddress; pCurrAddress = pCurrAddress->Next) {
if (pCurrAddress->OperStatus != IfOperStatusUp) {
(void) snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddress->FriendlyName);
/* Get interface flags. */
ifList[listIndex].flags = getInterfaceFlags(pCurrAddress);
ifList[listIndex].interfaceIndexNo = 0;
memset (&ifList[listIndex].address, 0, sizeof(ifList[listIndex].address));
memset (&ifList[listIndex].broadcast_address, 0, sizeof (ifList[listIndex].broadcast_address));
memset (&ifList[listIndex].network_mask, 0, sizeof (ifList[listIndex].network_mask));
listIndex++;
}
}
if (pAddresses) {
os_free(pAddresses);
}
*validElements = listIndex;
return result;
}
#undef MAX_INTERFACES

View file

@ -18,7 +18,13 @@
#include "../snippets/code/os_stdlib_strtod.c" #include "../snippets/code/os_stdlib_strtod.c"
#include "../snippets/code/os_stdlib_strtol.c" #include "../snippets/code/os_stdlib_strtol.c"
#include "../snippets/code/os_stdlib_strtok_r.c" #include "../snippets/code/os_stdlib_strtok_r.c"
#include "../snippets/code/os_stdlib_strsep.c"
#include "../snippets/code/os_stdlib_strdup.c"
#include "../snippets/code/os_stdlib_memdup.c"
#include "../snippets/code/os_stdlib_asprintf.c"
#include "../snippets/code/os_stdlib_rindex.c"
#include "../snippets/code/os_stdlib_strcasecmp.c"
#include "../snippets/code/os_stdlib_strncasecmp.c"
static int32_t static int32_t
os__ensurePathExists( os__ensurePathExists(
@ -140,55 +146,6 @@ os_access(
return result; return result;
} }
char *
os_rindex(
const char *s,
int c)
{
char *last = NULL;
while (*s) {
if (*s == c) {
last = (char *)s;
}
s++;
}
return last;
}
_Ret_z_
_Check_return_
char *
os_strdup(
_In_z_ const char *s1)
{
size_t len;
char *dup;
len = strlen(s1) + 1;
dup = os_malloc(len);
memcpy(dup, s1, len);
return dup;
}
char *
os_strsep(char **str, const char *sep)
{
char *ret;
if (**str == '\0')
return 0;
ret = *str;
while (**str && strchr(sep, **str) == 0)
(*str)++;
if (**str != '\0')
{
**str = '\0';
(*str)++;
}
return ret;
}
#pragma warning( disable : 4996 ) #pragma warning( disable : 4996 )
int int
os_vfprintfnosigpipe( os_vfprintfnosigpipe(
@ -199,49 +156,6 @@ os_vfprintfnosigpipe(
return vfprintf(file, format, args); return vfprintf(file, format, args);
} }
#pragma warning( default : 4996 )
int
os_strcasecmp(
const char *s1,
const char *s2)
{
int cr;
while (*s1 && *s2) {
cr = tolower(*s1) - tolower(*s2);
if (cr) {
return cr;
}
s1++;
s2++;
}
cr = tolower(*s1) - tolower(*s2);
return cr;
}
int
os_strncasecmp(
const char *s1,
const char *s2,
size_t n)
{
int cr = 0;
while (*s1 && *s2 && n) {
cr = tolower(*s1) - tolower(*s2);
if (cr) {
return cr;
}
s1++;
s2++;
n--;
}
if (n) {
cr = tolower(*s1) - tolower(*s2);
}
return cr;
}
os_result os_result
os_stat( os_stat(
const char *path, const char *path,

190
src/os/tests/ifaddrs.c Normal file
View file

@ -0,0 +1,190 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include "CUnit/Runner.h"
#include "os/os.h"
/* FIXME: It's not possible to predict what network interfaces are available
on a given host. To properly test all combinations the abstracted
operating system functions must be mocked. */
/* FIXME: It's possible that IPv6 is available in the network stack, but
disabled in the kernel. Travis CI for example has build environments
that do not have IPv6 enabled. */
#ifdef OS_SOCKET_HAS_IPV6
static int ipv6_enabled = 1;
#endif
CUnit_Suite_Initialize(os_getifaddrs)
{
os_osInit();
#ifdef OS_SOCKET_HAS_IPV6
#ifdef __linux
FILE *fh;
const char *const *path;
static const char *const paths[] = {
"/proc/sys/net/ipv6/conf/all/disable_ipv6",
"/proc/sys/net/ipv6/conf/default/disable_ipv6",
NULL
};
for (path = paths; ipv6_enabled == 1 && *path != NULL; path++) {
if ((fh = fopen(*path, "r")) != NULL) {
ipv6_enabled = (fgetc(fh) == '0');
fclose(fh);
fh = NULL;
}
}
#endif /* __linux */
#endif /* OS_SOCKET_HAS_IPV6 */
return 0;
}
CUnit_Suite_Cleanup(os_getifaddrs)
{
os_osExit();
return 0;
}
/* Assume every test machine has at least one IPv4 enabled interface. This
simple test verifies an interface can at least be found and that the
IFF_LOOPBACK flags are properly set. */
CUnit_Test(os_getifaddrs, ipv4)
{
int err;
int seen = 0;
os_ifaddrs_t *ifa_root, *ifa;
const int afs[] = { AF_INET, OS_AF_NULL };
err = os_getifaddrs(&ifa_root, afs);
CU_ASSERT_EQUAL_FATAL(err, 0);
for (ifa = ifa_root; ifa; ifa = ifa->next) {
CU_ASSERT_PTR_NOT_EQUAL_FATAL(ifa->addr, NULL);
CU_ASSERT_EQUAL(ifa->addr->sa_family, AF_INET);
if (ifa->addr->sa_family == AF_INET) {
if (ifa->flags & IFF_LOOPBACK) {
CU_ASSERT(os_sockaddrIsLoopback(ifa->addr));
} else {
CU_ASSERT(!os_sockaddrIsLoopback(ifa->addr));
}
seen = 1;
}
}
CU_ASSERT_EQUAL(seen, 1);
os_freeifaddrs(ifa_root);
}
CUnit_Test(os_getifaddrs, null_filter)
{
int err;
int cnt = 0;
os_ifaddrs_t *ifa_root, *ifa;
err = os_getifaddrs(&ifa_root, NULL);
CU_ASSERT_EQUAL_FATAL(err, 0);
for (ifa = ifa_root; ifa; ifa = ifa->next) {
CU_ASSERT_PTR_NOT_EQUAL_FATAL(ifa->addr, NULL);
cnt++;
}
CU_ASSERT(cnt > 0);
os_freeifaddrs(ifa_root);
}
CUnit_Test(os_getifaddrs, empty_filter)
{
int err;
os_ifaddrs_t *ifa_root;
const int afs[] = { OS_AF_NULL };
err = os_getifaddrs(&ifa_root, afs);
CU_ASSERT_EQUAL_FATAL(err, 0);
CU_ASSERT_PTR_EQUAL(ifa_root, NULL);
os_freeifaddrs(ifa_root);
}
#ifdef OS_SOCKET_HAS_IPV6
CUnit_Test(os_getifaddrs, ipv6)
{
if (ipv6_enabled == 1) {
int err;
int have_ipv6 = 0;
os_ifaddrs_t *ifa_root, *ifa;
const int afs[] = { AF_INET6, OS_AF_NULL };
err = os_getifaddrs(&ifa_root, afs);
CU_ASSERT_EQUAL_FATAL(err, 0);
for (ifa = ifa_root; ifa; ifa = ifa->next) {
CU_ASSERT_PTR_NOT_EQUAL_FATAL(ifa->addr, NULL);
CU_ASSERT_EQUAL(ifa->addr->sa_family, AF_INET6);
if (ifa->addr->sa_family == AF_INET6) {
have_ipv6 = 1;
if (ifa->flags & IFF_LOOPBACK) {
CU_ASSERT(os_sockaddrIsLoopback(ifa->addr));
} else {
CU_ASSERT(!os_sockaddrIsLoopback(ifa->addr));
}
}
}
CU_ASSERT_EQUAL(have_ipv6, 1);
os_freeifaddrs(ifa_root);
CU_PASS("IPv6 enabled in test environment");
} else {
CU_PASS("IPv6 disabled in test environment");
}
}
/* Assume at least one IPv4 and one IPv6 interface are available when IPv6 is
available on the platform. */
CUnit_Test(os_getifaddrs, ipv4_n_ipv6)
{
if (ipv6_enabled == 1) {
int err;
int have_ipv4 = 0;
int have_ipv6 = 0;
os_ifaddrs_t *ifa_root, *ifa;
const int afs[] = { AF_INET, AF_INET6, OS_AF_NULL };
err = os_getifaddrs(&ifa_root, afs);
CU_ASSERT_EQUAL_FATAL(err, 0);
for (ifa = ifa_root; ifa; ifa = ifa->next) {
CU_ASSERT_PTR_NOT_EQUAL_FATAL(ifa->addr, NULL);
CU_ASSERT(ifa->addr->sa_family == AF_INET ||
ifa->addr->sa_family == AF_INET6);
if (ifa->addr->sa_family == AF_INET) {
have_ipv4 = 1;
} else if (ifa->addr->sa_family == AF_INET6) {
have_ipv6 = 1;
}
}
CU_ASSERT_EQUAL(have_ipv4, 1);
CU_ASSERT_EQUAL(have_ipv6, 1);
os_freeifaddrs(ifa_root);
CU_PASS("IPv6 enabled in test environment");
} else {
CU_PASS("IPv6 disabled in test environment");
}
}
#endif /* OS_SOCKET_HAS_IPV6 */

0
src/os/tests/iter.c Executable file → Normal file
View file

0
src/os/tests/stdlib.c Executable file → Normal file
View file