Change socket function signatures to use os_sockaddr

* Consolidated and cleaned up some (duplicate) functions.
* Removed some unused functions that did not make sense to keep around.

Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
This commit is contained in:
Jeroen Koekkoek 2018-10-18 11:41:08 +02:00
parent ea3f5e7ff4
commit 7ba3bca087
20 changed files with 275 additions and 506 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

@ -0,0 +1,30 @@
/*
* 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 err;
int afs[] = { AF_INET, 0 };
(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;

View file

@ -350,21 +350,11 @@ static void ddsi_raweth_deinit(void)
static int ddsi_raweth_enumerate_interfaces (ddsi_tran_factory_t factory, os_ifaddrs_t **interfs) static int ddsi_raweth_enumerate_interfaces (ddsi_tran_factory_t factory, os_ifaddrs_t **interfs)
{ {
int err = 0; int err = 0;
int cnt = 0; int afs[] = { AF_PACKET, 0 };
os_ifaddrs_t *ifa;
os_ifaddr_filter_t filt = { .af_packet = 1 };
(void)factory; (void)factory;
if ((err = os_getifaddrs(interfs, &filt)) == 0) { return -os_getifaddrs(interfs, afs);
for (ifa = *interfs; ifa != NULL; ifa = ifa->next, cnt++) {
/* do nothing */
}
} else {
return -err;
}
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, (const os_sockaddr *)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);
@ -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_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
@ -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_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,7 +947,7 @@ 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, (os_sockaddr *)&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);
@ -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_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

@ -334,8 +334,5 @@ char *ddsi_locator_to_string_no_port (char *dst, size_t sizeof_dst, const nn_loc
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, os_ifaddrs_t **interfs) int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, os_ifaddrs_t **interfs)
{ {
/* FIXME: HACK */
if (factory->m_enumerate_interfaces_fn == 0)
return 0;
return factory->m_enumerate_interfaces_fn (factory, interfs); return factory->m_enumerate_interfaces_fn (factory, 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"
@ -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_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

@ -466,28 +466,10 @@ int find_own_ip (const char *requested_address)
nn_log (LC_CONFIG, "interfaces:"); nn_log (LC_CONFIG, "interfaces:");
{ {
int retcode; int ret;
retcode = ddsi_enumerate_interfaces(gv.m_factory, &ifa_root); ret = ddsi_enumerate_interfaces(gv.m_factory, &ifa_root);
if (retcode < 0) { if (ret < 0) {
NN_ERROR("ddsi_enumerate_interfaces(%s): %d\n", gv.m_factory->m_typename, retcode); NN_ERROR("ddsi_enumerate_interfaces(%s): %d\n", gv.m_factory->m_typename, ret);
} else if (retcode == 0) {
int err;
const os_ifaddr_filter_t fltr = {
.af_inet = (config.transport_selector == TRANS_TCP || config.transport_selector == TRANS_UDP),
.af_inet6 = (config.transport_selector == TRANS_TCP6 || config.transport_selector == TRANS_UDP6)
};
if ((err = os_getifaddrs(&ifa_root, &fltr)) != 0) {
NN_ERROR("os_getifaddrs: %s\n", os_strerror(err));
retcode = -1;
} else if (ifa_root == NULL) {
NN_ERROR("ddsi_enumerate_interfaces(%s): no go but neither UDP[46] nor TCP[46]\n", gv.m_factory->m_typename);
retcode = -1;
}
}
if (retcode < 0) {
os_freeifaddrs(ifa_root);
return 0; return 0;
} }
} }
@ -507,10 +489,12 @@ 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 ((ifa->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;
} }
#ifdef __linux #ifdef __linux

View file

@ -110,12 +110,6 @@ 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)
typedef struct {
uint8_t af_inet : 1;
uint8_t af_inet6 : 1;
uint8_t af_packet : 1;
} os_ifaddr_filter_t;
/** Network interface attributes */ /** Network interface attributes */
typedef struct os_ifaddrs_s { typedef struct os_ifaddrs_s {
struct os_ifaddrs_s *next; struct os_ifaddrs_s *next;
@ -137,14 +131,17 @@ extern "C" {
* be freed using os_freeifaddrs when no longer needed. * be freed using os_freeifaddrs when no longer needed.
* *
* @param[in,out] ifap Address of first os_ifaddrs_t structure in the list. * @param[in,out] ifap Address of first os_ifaddrs_t structure in the list.
* @param[in] ifilt FIXME: comment * @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.
* *
* @returns Returns zero on success or a valid errno value on error. * @returns Returns zero on success or a valid errno value on error.
*/ */
OSAPI_EXPORT _Success_(return == 0) int OSAPI_EXPORT _Success_(return == 0) int
os_getifaddrs( os_getifaddrs(
_Inout_ os_ifaddrs_t **ifap, _Inout_ os_ifaddrs_t **ifap,
_In_ const os_ifaddr_filter_t *ifilt); _In_opt_ const int *const afs);
/** /**
* @brief Free os_ifaddrs_t structure list allocated by os_getifaddrs() * @brief Free os_ifaddrs_t structure list allocated by os_getifaddrs()
@ -252,20 +249,46 @@ extern "C" {
os_time *timeout); os_time *timeout);
#endif /* WIN32 */ #endif /* WIN32 */
/* docced in implementation file */ /**
OSAPI_EXPORT os_result * Returns sizeof(sa) based on the family of the actual content.
os_sockaddrInit(os_sockaddr* sa, * @param sa the sockaddr to get the actual size for
bool isIPv4); /* IPvX is poorly abstracted; this is temporary */ * @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_sockaddr_size(
const os_sockaddr *const sa) __nonnull_all__;
/* docced in implementation file */ /**
OSAPI_EXPORT bool * Retrieves the port number from the supplied sockaddr.
os_sockaddrIPAddressEqual(const os_sockaddr* this_sock, * @param sa the sockaddr to retrieve the port from
const os_sockaddr* that_sock); * @return The port number stored in the supplied sockaddr convert to host order
* @pre sa is a valid sockaddr pointer
*/
OSAPI_EXPORT uint16_t
os_sockaddr_get_port(const os_sockaddr *const sa) __nonnull_all__;
/**
* 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.
*/
OSAPI_EXPORT int OSAPI_EXPORT int
os_sockaddrIpAddressCompare(const os_sockaddr* addr1, os_sockaddr_compare(
const os_sockaddr* addr2) __nonnull_all__ const os_sockaddr *sa1,
__attribute_pure__; const os_sockaddr *sa2) __nonnull_all__ __attribute_pure__;
/**
* FIXME: comment
*/
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
@ -284,20 +307,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.
* *
@ -323,16 +332,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
@ -342,26 +341,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

@ -263,7 +263,7 @@ extern "C" {
__attribute_warn_unused_result__; __attribute_warn_unused_result__;
void * void *
os_memdup(void *src, size_t n); os_memdup(const void *src, size_t n);
/** \brief os_strsep wrapper /** \brief os_strsep wrapper
* *

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,113 @@ 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 size_t
void os__sockaddrInit4(os_sockaddr* sa) os_sockaddr_size(const os_sockaddr *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);
switch(sa->sa_family) {
#if (OS_SOCKET_HAS_IPV6 == 1) #if (OS_SOCKET_HAS_IPV6 == 1)
static case AF_INET6:
void os__sockaddrInit6(os_sockaddr* sa) sz = sizeof(os_sockaddr_in6);
{ break;
assert(sa); #endif /* OS_SOCKET_HAS_IPV6 */
/* 0 is a valid value for all members besides sa_family */ #ifdef __linux
memset(sa, 0, sizeof(os_sockaddr_in6)); case AF_PACKET:
sa->sa_family = AF_INET6; sz = sizeof(struct sockaddr_ll);
} break;
#endif #endif /* __linux */
default:
assert(sa->sa_family == AF_INET);
/** sz = sizeof(os_sockaddr_in);
* Initialises the memory pointed to by sa. The address family break;
* will be set correctly according to isIPv4.
* @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 *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(const os_sockaddr *sa1, const os_sockaddr *sa2)
os_sockaddrIpAddressCompare(const os_sockaddr* addr1,
const os_sockaddr* addr2)
{ {
int result = -1; int eq;
uint16_t port1, port2; size_t sz;
int r;
assert(sa1 != 0);
assert(sa2 != 0);
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 +280,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 +292,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 +312,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 +336,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

@ -12,57 +12,37 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#if defined(__linux)
#include <linux/if_packet.h> /* sockaddr_ll */
#endif /* __linux */
#include "os/os.h" #include "os/os.h"
static int static int
copy_ifaddrs(os_ifaddrs_t **ifap, const struct ifaddrs *sys_ifa) copyaddr(os_ifaddrs_t **ifap, const struct ifaddrs *sys_ifa)
{ {
int err = 0; int err = 0;
os_ifaddrs_t *ifa; os_ifaddrs_t *ifa;
size_t size; ssize_t sz;
assert(ifap != NULL); assert(ifap != NULL);
assert(sys_ifa != NULL); assert(sys_ifa != NULL);
assert(sys_ifa->ifa_addr->sa_family == AF_INET
#ifdef __linux
|| sys_ifa->ifa_addr->sa_family == AF_PACKET
#endif /* __linux */
|| sys_ifa->ifa_addr->sa_family == AF_INET6);
ifa = os_malloc(sizeof(*ifa)); sz = os_sockaddr_size(sys_ifa->ifa_addr);
ifa = os_calloc_s(1, sizeof(*ifa));
if (ifa == NULL) { if (ifa == NULL) {
err = errno; err = errno;
} else { } else {
(void)memset(ifa, 0, sizeof(*ifa));
ifa->index = if_nametoindex(sys_ifa->ifa_name); ifa->index = if_nametoindex(sys_ifa->ifa_name);
ifa->flags = sys_ifa->ifa_flags; ifa->flags = sys_ifa->ifa_flags;
if ((ifa->name = os_strdup(sys_ifa->ifa_name)) == NULL) { if ((ifa->name = os_strdup(sys_ifa->ifa_name)) == NULL) {
err = errno; err = errno;
} else if (sys_ifa->ifa_addr->sa_family == AF_INET6) { } else if (sys_ifa->ifa_addr->sa_family == AF_INET6) {
size = sizeof(struct sockaddr_in6); if (!(ifa->addr = os_memdup(sys_ifa->ifa_addr, sz))) {
if (!(ifa->addr = os_memdup(sys_ifa->ifa_addr, size))) { err = errno;
err = errno;
}
} else {
if (sys_ifa->ifa_addr->sa_family == AF_INET) {
size = sizeof(struct sockaddr_in);
#ifdef __linux
} else {
assert(sys_ifa->ifa_addr->sa_family == AF_PACKET);
size = sizeof(struct sockaddr_ll);
#endif /* __linux */
} }
} else {
if (!(ifa->addr = os_memdup(sys_ifa->ifa_addr, size)) || assert(sys_ifa->ifa_netmask != NULL);
(sys_ifa->ifa_netmask && if (!(ifa->addr = os_memdup(sys_ifa->ifa_addr, sz)) ||
!(ifa->netmask = os_memdup(sys_ifa->ifa_netmask, size))) || !(ifa->netmask = os_memdup(sys_ifa->ifa_netmask, sz)) ||
(sys_ifa->ifa_broadaddr && ((sys_ifa->ifa_flags & IFF_BROADCAST) &&
!(ifa->broadaddr = os_memdup(sys_ifa->ifa_broadaddr, size)))) !(ifa->broadaddr = os_memdup(sys_ifa->ifa_broadaddr, sz))))
{ {
err = errno; err = errno;
} }
@ -81,15 +61,15 @@ copy_ifaddrs(os_ifaddrs_t **ifap, const struct ifaddrs *sys_ifa)
_Success_(return == 0) int _Success_(return == 0) int
os_getifaddrs( os_getifaddrs(
_Inout_ os_ifaddrs_t **ifap, _Inout_ os_ifaddrs_t **ifap,
_In_opt_ const os_ifaddr_filter_t *ifltr) _In_opt_ const int *const afs)
{ {
int err = 0; int err = 0;
int use;
os_ifaddrs_t *ifa, *ifa_root, *ifa_next; os_ifaddrs_t *ifa, *ifa_root, *ifa_next;
struct ifaddrs *sys_ifa, *sys_ifa_root; struct ifaddrs *sys_ifa, *sys_ifa_root;
struct sockaddr *addr; struct sockaddr *sa;
assert(ifap != NULL); assert(ifap != NULL);
assert(ifltr != NULL);
if (getifaddrs(&sys_ifa_root) == -1) { if (getifaddrs(&sys_ifa_root) == -1) {
err = errno; err = errno;
@ -97,19 +77,17 @@ os_getifaddrs(
ifa = ifa_root = NULL; ifa = ifa_root = NULL;
for (sys_ifa = sys_ifa_root; for (sys_ifa = sys_ifa_root;
sys_ifa != NULL && err == 0; sys_ifa != NULL && sys_ifa->ifa_addr != NULL && err == 0;
sys_ifa = sys_ifa->ifa_next) sys_ifa = sys_ifa->ifa_next)
{ {
addr = sys_ifa->ifa_addr; sa = sys_ifa->ifa_addr;
if ((addr->sa_family == AF_INET && ifltr->af_inet) use = (afs == NULL);
#ifdef __linux for (int i = 0; !use && afs[i] != 0; i++) {
|| (addr->sa_family == AF_PACKET && ifltr->af_packet) use = (sa->sa_family == afs[i]);
#endif /* __linux */ }
|| (addr->sa_family == AF_INET6 && ifltr->af_inet6 &&
!IN6_IS_ADDR_UNSPECIFIED( if (use) {
&((struct sockaddr_in6 *)addr)->sin6_addr))) err = copyaddr(&ifa_next, sys_ifa);
{
err = copy_ifaddrs(&ifa_next, sys_ifa);
if (err == 0) { if (err == 0) {
if (ifa == NULL) { if (ifa == NULL) {
ifa = ifa_root = ifa_next; ifa = ifa_root = ifa_next;

View file

@ -12,11 +12,11 @@
#include "os/os.h" #include "os/os.h"
void * void *
os_memdup(void *src, size_t n) os_memdup(const void *src, size_t n)
{ {
void *dest; void *dest = NULL;
if ((dest = os_malloc_s(n)) != NULL) { if (n != 0 && (dest = os_malloc_s(n)) != NULL) {
memcpy(dest, src, n); memcpy(dest, src, n);
} }

View file

@ -15,14 +15,9 @@ _Ret_z_
_Check_return_ _Check_return_
char * char *
os_strdup( os_strdup(
_In_z_ const char *s1) _In_z_ const char *str)
{ {
size_t len; assert(str != NULL);
char *dup;
len = strlen(s1) + 1; return os_memdup(str, strlen(str) + 1);
dup = os_malloc(len);
memcpy(dup, s1, len);
return dup;
} }

View file

@ -23,7 +23,7 @@ getifaces(PIP_ADAPTER_ADDRESSES *ptr)
ULONG ret; ULONG ret;
size_t i; size_t i;
static const size_t max = 3; static const size_t max = 2;
static const ULONG filter = GAA_FLAG_INCLUDE_PREFIX | static const ULONG filter = GAA_FLAG_INCLUDE_PREFIX |
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_MULTICAST |
@ -207,9 +207,10 @@ copyaddr(
_Success_(return == 0) int _Success_(return == 0) int
os_getifaddrs( os_getifaddrs(
_Inout_ os_ifaddrs_t **ifap, _Inout_ os_ifaddrs_t **ifap,
_In_opt_ const os_ifaddr_filter_t *ifltr) _In_opt_ const int *const afs)
{ {
int err = 0; int err = 0;
int use;
PIP_ADAPTER_ADDRESSES ifaces = NULL, iface; PIP_ADAPTER_ADDRESSES ifaces = NULL, iface;
PIP_ADAPTER_UNICAST_ADDRESS addr = NULL; PIP_ADAPTER_UNICAST_ADDRESS addr = NULL;
PMIB_IPADDRTABLE addrtable = NULL; PMIB_IPADDRTABLE addrtable = NULL;
@ -217,7 +218,6 @@ os_getifaddrs(
struct sockaddr *sa; struct sockaddr *sa;
assert(ifap != NULL); assert(ifap != NULL);
assert(ifltr != NULL);
ifa = ifa_root = ifa_next = NULL; ifa = ifa_root = ifa_next = NULL;
@ -230,9 +230,12 @@ os_getifaddrs(
addr = addr->Next) addr = addr->Next)
{ {
sa = (struct sockaddr *)addr->Address.lpSockaddr; sa = (struct sockaddr *)addr->Address.lpSockaddr;
if ((sa->sa_family == AF_INET && ifltr->af_inet) || use = (afs == NULL);
(sa->sa_family == AF_INET6 && ifltr->af_inet6)) for (int i = 0; !use && afs[i] != 0; i++) {
{ use = (afs[i] == sa->sa_family);
}
if (use) {
err = copyaddr(&ifa_next, iface, addrtable, addr); err = copyaddr(&ifa_next, iface, addrtable, addr);
if (err == 0) { if (err == 0) {
if (ifa == NULL) { if (ifa == NULL) {

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

View file

@ -36,9 +36,9 @@ CUnit_Test(os_getifaddrs, ipv4)
int err; int err;
int seen = 0; int seen = 0;
os_ifaddrs_t *ifa_root, *ifa; os_ifaddrs_t *ifa_root, *ifa;
os_ifaddr_filter_t ifltr = { .af_inet = 1 }; const int afs[] = { AF_INET, 0 };
err = os_getifaddrs(&ifa_root, &ifltr); err = os_getifaddrs(&ifa_root, afs);
CU_ASSERT_EQUAL_FATAL(err, 0); CU_ASSERT_EQUAL_FATAL(err, 0);
for (ifa = ifa_root; ifa; ifa = ifa->next) { for (ifa = ifa_root; ifa; ifa = ifa->next) {
CU_ASSERT_EQUAL(ifa->addr->sa_family, AF_INET); CU_ASSERT_EQUAL(ifa->addr->sa_family, AF_INET);
@ -62,9 +62,9 @@ CUnit_Test(os_getifaddrs, non_local_ipv6)
{ {
int err; int err;
os_ifaddrs_t *ifa_root, *ifa; os_ifaddrs_t *ifa_root, *ifa;
os_ifaddr_filter_t ifltr = { .af_inet6 = 1 }; const int afs[] = { AF_INET6, 0 };
err = os_getifaddrs(&ifa_root, &ifltr); err = os_getifaddrs(&ifa_root, afs);
CU_ASSERT_EQUAL_FATAL(err, 0); CU_ASSERT_EQUAL_FATAL(err, 0);
for (ifa = ifa_root; ifa; ifa = ifa->next) { for (ifa = ifa_root; ifa; ifa = ifa->next) {
CU_ASSERT_EQUAL(ifa->addr->sa_family, AF_INET6); CU_ASSERT_EQUAL(ifa->addr->sa_family, AF_INET6);

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

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