Replace os_sockQueryInterfaces by os_getifaddrs

Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
This commit is contained in:
Jeroen Koekkoek 2018-09-19 19:25:58 +02:00
parent 2fc4cac1a7
commit 458b1df3f7
23 changed files with 696 additions and 597 deletions

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_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);
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);
#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 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 */
@ -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_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)))
ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener);

View file

@ -49,7 +49,7 @@ enum ddsi_locator_from_string_result ddsi_ipaddr_from_string (ddsi_tran_factory_
return AFSR_INVALID;
if ((ipv4 && tmpaddr.ss_family != AF_INET) || (!ipv4 && tmpaddr.ss_family != AF_INET6))
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.
Without a guarantee that tmpaddr has port 0, best is to set it explicitly here */
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;
}
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;
switch (src->ss_family)
switch (src->sa_family)
{
case AF_INET:
{
@ -137,7 +137,7 @@ void ddsi_ipaddr_to_loc (nn_locator_t *dst, const os_sockaddr_storage *src, int3
}
#endif
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,42 +347,23 @@ 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 err = 0;
int cnt = 0;
os_ifaddrs_t *ifa;
os_ifaddr_filter_t filt = { .af_packet = 1 };
(void)factory;
if (getifaddrs (&ifaddr) == -1)
return -errno;
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++;
if ((err = os_getifaddrs(interfs, &filt)) == 0) {
for (ifa = *interfs; ifa != NULL; ifa = ifa->next, cnt++) {
/* do nothing */
}
} else {
return -err;
}
freeifaddrs (ifaddr);
return cnt;
}

View file

@ -145,7 +145,7 @@ static ddsi_tcp_conn_t ddsi_tcp_new_conn (os_socket, bool, os_sockaddr_storage *
static char *sockaddr_to_string_with_port (char *dst, size_t sizeof_dst, const os_sockaddr_storage *src)
{
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, (const os_sockaddr *)src, src->ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
ddsi_locator_to_string(dst, sizeof_dst, &loc);
return dst;
}
@ -452,7 +452,7 @@ static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
{
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;
}
@ -869,7 +869,7 @@ static void ddsi_tcp_conn_peer_locator (ddsi_tran_conn_t conn, nn_locator_t * lo
char buff[DDSI_LOCSTRLEN];
ddsi_tcp_conn_t tc = (ddsi_tcp_conn_t) conn;
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);
TRACE (("(%s EP:%s)", ddsi_name, buff));
}
@ -976,7 +976,7 @@ static void ddsi_tcp_close_conn (ddsi_tran_conn_t tc)
sockaddr_to_string_with_port(buff, sizeof(buff), &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);
(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;
purge_proxy_participants (&loc, conn->m_base.m_server);
}

View file

@ -332,10 +332,10 @@ char *ddsi_locator_to_string_no_port (char *dst, size_t sizeof_dst, const nn_loc
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 */
if (factory->m_enumerate_interfaces_fn == 0)
return 0;
return factory->m_enumerate_interfaces_fn (factory, max, interfs);
return factory->m_enumerate_interfaces_fn (factory, interfs);
}

View file

@ -79,7 +79,7 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
if (ret > 0)
{
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 */
if ((((size_t) ret) > len)
@ -90,7 +90,7 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
{
char addrbuf[DDSI_LOCSTRLEN];
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);
NN_WARNING ("%s => %d truncated to %d\n", addrbuf, (int)ret, (int)len);
}

View file

@ -455,63 +455,51 @@ int find_own_ip (const char *requested_address)
const char *sep = " ";
char last_if_name[80] = "";
int quality = -1;
os_result res;
int i;
unsigned int nif;
os_ifAttributes *ifs;
os_ifaddrs_t *ifa, *ifa_root = NULL;
int maxq_list[MAX_INTERFACES];
int maxq_count = 0;
size_t maxq_strlen = 0;
int selected_idx = -1;
char addrbuf[DDSI_LOCSTRLEN];
ifs = os_malloc (MAX_INTERFACES * sizeof (*ifs));
nn_log (LC_CONFIG, "interfaces:");
{
int retcode;
nif = 0;
retcode = ddsi_enumerate_interfaces(gv.m_factory, (int)(MAX_INTERFACES - nif), ifs);
if (retcode > 0)
{
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;
retcode = ddsi_enumerate_interfaces(gv.m_factory, &ifa_root);
if (retcode < 0) {
NN_ERROR("ddsi_enumerate_interfaces(%s): %d\n", gv.m_factory->m_typename, retcode);
} 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 (res != os_resultSuccess)
{
NN_ERROR ("os_sockQueryInterfaces: %d\n", (int) res);
os_free (ifs);
if (retcode < 0) {
os_freeifaddrs(ifa_root);
return 0;
}
}
gv.n_interfaces = 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)];
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 (strcmp (if_name, last_if_name))
@ -519,46 +507,44 @@ int find_own_ip (const char *requested_address)
strcpy (last_if_name, if_name);
/* interface must be up */
if ((ifs[i].flags & IFF_UP) == 0)
if ((ifa->flags & IFF_UP) == 0)
{
nn_log (LC_CONFIG, " (interface down)");
continue;
}
tmpip = ifs[i].address;
tmpmask = ifs[i].network_mask;
#ifdef __linux
if (tmpip.ss_family == AF_PACKET)
if (ifa->addr->sa_family == AF_PACKET)
{
/* FIXME: weirdo warning warranted */
nn_locator_t *l = &gv.interfaces[gv.n_interfaces].loc;
l->kind = NN_LOCATOR_KIND_RAWETH;
l->port = NN_LOCATOR_PORT_INVALID;
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
#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);
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:");
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
available, because the other interfaces at least in principle
allow communicating with other machines. */
q += 0;
#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;
#endif
}
@ -575,16 +561,16 @@ int find_own_ip (const char *requested_address)
which it was received. But that means proper multi-homing
support and has quite an impact in various places, not least of
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;
#endif
/* We strongly prefer a multicast capable interface, if that's
not available anything that's not point-to-point, or else we
hope IP routing will take care of the issues. */
if (ifs[i].flags & IFF_MULTICAST)
if (ifa->flags & IFF_MULTICAST)
q += 4;
else if (!(ifs[i].flags & IFF_POINTOPOINT))
else if (!(ifa->flags & IFF_POINTOPOINT))
q += 3;
else
q += 2;
@ -604,10 +590,9 @@ int find_own_ip (const char *requested_address)
/* FIXME: HACK HACK */
//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, &tmpmask, gv.m_factory->m_kind);
ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].netmask, ifa->netmask, gv.m_factory->m_kind);
}
else
{
@ -615,14 +600,14 @@ int find_own_ip (const char *requested_address)
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));
}
gv.interfaces[gv.n_interfaces].mc_capable = ((ifs[i].flags & IFF_MULTICAST) != 0);
gv.interfaces[gv.n_interfaces].point_to_point = ((ifs[i].flags & IFF_POINTOPOINT) != 0);
gv.interfaces[gv.n_interfaces].if_index = ifs[i].interfaceIndexNo;
gv.interfaces[gv.n_interfaces].mc_capable = ((ifa->flags & IFF_MULTICAST) != 0);
gv.interfaces[gv.n_interfaces].point_to_point = ((ifa->flags & IFF_POINTOPOINT) != 0);
gv.interfaces[gv.n_interfaces].if_index = ifa->index;
gv.interfaces[gv.n_interfaces].name = os_strdup (if_name);
gv.n_interfaces++;
}
nn_log (LC_CONFIG, "\n");
os_free (ifs);
os_freeifaddrs (ifa_root);
if (requested_address == NULL)
{