Remove IPv4/IPv6-specific code in adding peers
This removes the special handling of IP addresses in adding peer locators from the configuration, instead relying on the general string-to-locator conversion routines. * This extends the common IP handling to code to handle the optional presence of a port and the use of brackets, allowing them always for IPv6 addresses, but requiring them only when needed for disambiguating numerical IPv6 addresses when a port is present. * The "multicast generator" format is now handled in UDPv4 code. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
e005c89240
commit
fe89d216a5
8 changed files with 628 additions and 117 deletions
|
@ -203,8 +203,8 @@ struct ddsi_tran_qos
|
||||||
|
|
||||||
void ddsi_tran_factories_fini (struct ddsi_domaingv *gv);
|
void ddsi_tran_factories_fini (struct ddsi_domaingv *gv);
|
||||||
void ddsi_factory_add (struct ddsi_domaingv *gv, ddsi_tran_factory_t factory);
|
void ddsi_factory_add (struct ddsi_domaingv *gv, ddsi_tran_factory_t factory);
|
||||||
void ddsi_factory_free (ddsi_tran_factory_t factory);
|
DDS_EXPORT void ddsi_factory_free (ddsi_tran_factory_t factory);
|
||||||
ddsi_tran_factory_t ddsi_factory_find (const struct ddsi_domaingv *gv, const char * type);
|
DDS_EXPORT ddsi_tran_factory_t ddsi_factory_find (const struct ddsi_domaingv *gv, const char * type);
|
||||||
ddsi_tran_factory_t ddsi_factory_find_supported_kind (const struct ddsi_domaingv *gv, int32_t kind);
|
ddsi_tran_factory_t ddsi_factory_find_supported_kind (const struct ddsi_domaingv *gv, int32_t kind);
|
||||||
void ddsi_factory_conn_init (const struct ddsi_tran_factory *factory, ddsi_tran_conn_t conn);
|
void ddsi_factory_conn_init (const struct ddsi_tran_factory *factory, ddsi_tran_conn_t conn);
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ int ddsi_is_mcaddr (const struct ddsi_domaingv *gv, const nn_locator_t *loc);
|
||||||
int ddsi_is_ssm_mcaddr (const struct ddsi_domaingv *gv, const nn_locator_t *loc);
|
int ddsi_is_ssm_mcaddr (const struct ddsi_domaingv *gv, const nn_locator_t *loc);
|
||||||
enum ddsi_nearby_address_result ddsi_is_nearby_address (const nn_locator_t *loc, const nn_locator_t *ownloc, size_t ninterf, const struct nn_interface *interf);
|
enum ddsi_nearby_address_result ddsi_is_nearby_address (const nn_locator_t *loc, const nn_locator_t *ownloc, size_t ninterf, const struct nn_interface *interf);
|
||||||
|
|
||||||
enum ddsi_locator_from_string_result ddsi_locator_from_string (const struct ddsi_domaingv *gv, nn_locator_t *loc, const char *str, ddsi_tran_factory_t default_factory);
|
DDS_EXPORT enum ddsi_locator_from_string_result ddsi_locator_from_string (const struct ddsi_domaingv *gv, nn_locator_t *loc, const char *str, ddsi_tran_factory_t default_factory);
|
||||||
|
|
||||||
/* 8 for transport/
|
/* 8 for transport/
|
||||||
1 for [
|
1 for [
|
||||||
|
|
|
@ -24,7 +24,7 @@ typedef struct nn_udpv4mcgen_address {
|
||||||
uint8_t idx; /* must be last: then sorting will put them consecutively */
|
uint8_t idx; /* must be last: then sorting will put them consecutively */
|
||||||
} nn_udpv4mcgen_address_t;
|
} nn_udpv4mcgen_address_t;
|
||||||
|
|
||||||
int ddsi_udp_init (struct ddsi_domaingv *gv);
|
DDS_EXPORT int ddsi_udp_init (struct ddsi_domaingv *gv);
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,8 @@ enum ddsi_nearby_address_result ddsi_ipaddr_is_nearby_address (const nn_locator_
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
DDSRT_WARNING_MSVC_OFF(4996);
|
||||||
|
char copy[264];
|
||||||
int af = AF_INET;
|
int af = AF_INET;
|
||||||
struct sockaddr_storage tmpaddr;
|
struct sockaddr_storage tmpaddr;
|
||||||
|
|
||||||
|
@ -94,28 +96,101 @@ enum ddsi_locator_from_string_result ddsi_ipaddr_from_string (ddsi_tran_factory_
|
||||||
return AFSR_MISMATCH;
|
return AFSR_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)tran;
|
// IPv6: we format numeric ones surrounded by brackets and we want to
|
||||||
if (ddsrt_sockaddrfromstr(af, str, (struct sockaddr *) &tmpaddr) != 0) {
|
// parse port numbers, so a copy is the most pragamatic approach. POSIX
|
||||||
#if DDSRT_HAVE_DNS
|
// hostnames seem to be limited to 255 characters, add a port of max 5
|
||||||
/* Not a valid IP address. User may have specified a hostname instead. */
|
// digits and a colon, and so 262 should be enough. (Numerical addresses
|
||||||
ddsrt_hostent_t *hent = NULL;
|
// add a few other characters, but even so this ought to be plenty.)
|
||||||
if (ddsrt_gethostbyname(str, af, &hent) != 0) {
|
const size_t len = strlen(str);
|
||||||
return AFSR_UNKNOWN;
|
if (len == 0 || len >= sizeof(copy))
|
||||||
}
|
return AFSR_INVALID;
|
||||||
memcpy(&tmpaddr, &hent->addrs[0], sizeof(hent->addrs[0]));
|
memcpy(copy, str, len + 1);
|
||||||
ddsrt_free (hent);
|
char *ipstr = copy;
|
||||||
#else
|
char *portstr = strrchr(copy, ':');
|
||||||
|
if (af == AF_INET6 && portstr != strchr(copy, ':') && ipstr[0] != '[')
|
||||||
|
{
|
||||||
|
// IPv6 numerical addresses contain colons, so if there are multiple
|
||||||
|
// colons, we require disambiguation by enclosing the IP part in
|
||||||
|
// brackets and hence consider "portstr" only if the first character
|
||||||
|
// is '['
|
||||||
|
portstr = NULL;
|
||||||
|
}
|
||||||
|
uint16_t port = 0;
|
||||||
|
if (portstr) {
|
||||||
|
unsigned tmpport;
|
||||||
|
int pos;
|
||||||
|
if (sscanf (portstr + 1, "%u%n", &tmpport, &pos) == 1 && portstr[1 + pos] == 0)
|
||||||
|
{
|
||||||
|
if (tmpport < 1 || tmpport > 65535)
|
||||||
|
return AFSR_INVALID;
|
||||||
|
*portstr = 0;
|
||||||
|
port = (uint16_t) tmpport;
|
||||||
|
}
|
||||||
|
else if (af == AF_INET)
|
||||||
|
{
|
||||||
|
// no colons in IPv4 addresses
|
||||||
return AFSR_INVALID;
|
return AFSR_INVALID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// allow for IPv6 address embedding IPv4 ones, like ff02::ffff:239.255.0.1
|
||||||
|
portstr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DDSRT_HAVE_IPV6
|
||||||
|
if (af == AF_INET6)
|
||||||
|
{
|
||||||
|
if (copy[0] == '[') {
|
||||||
|
// strip brackets: last character before the port must be a ']',
|
||||||
|
// in the absence of a port, the last character in the string.
|
||||||
|
ipstr = copy + 1;
|
||||||
|
if (portstr == NULL) {
|
||||||
|
if (copy[len - 1] != ']')
|
||||||
|
return AFSR_INVALID;
|
||||||
|
copy[len - 1] = 0;
|
||||||
|
} else {
|
||||||
|
assert (portstr > copy);
|
||||||
|
if (portstr[-1] != ']')
|
||||||
|
return AFSR_INVALID;
|
||||||
|
portstr[-1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ddsrt_sockaddrfromstr(af, ipstr, (struct sockaddr *) &tmpaddr) != 0) {
|
||||||
|
#if DDSRT_HAVE_DNS
|
||||||
|
/* Not a valid IP address. User may have specified a hostname instead. */
|
||||||
|
ddsrt_hostent_t *hent = NULL;
|
||||||
|
if (ddsrt_gethostbyname(ipstr, af, &hent) != 0) {
|
||||||
|
return AFSR_UNKNOWN;
|
||||||
|
}
|
||||||
|
memcpy(&tmpaddr, &hent->addrs[0], sizeof(hent->addrs[0]));
|
||||||
|
ddsrt_free (hent);
|
||||||
|
#else
|
||||||
|
return AFSR_INVALID;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
// patch in port (sin_port/sin6_port is undefined at this point and must always be set
|
||||||
|
// before calling ddsi_ipaddr_to_loc
|
||||||
if (tmpaddr.ss_family != af) {
|
if (tmpaddr.ss_family != af) {
|
||||||
return AFSR_MISMATCH;
|
return AFSR_MISMATCH;
|
||||||
|
} else if (af == AF_INET) {
|
||||||
|
struct sockaddr_in *x = (struct sockaddr_in *) &tmpaddr;
|
||||||
|
x->sin_port = htons (port);
|
||||||
|
} else {
|
||||||
|
#if DDSRT_HAVE_IPV6
|
||||||
|
assert (af == AF_INET6);
|
||||||
|
struct sockaddr_in6 *x = (struct sockaddr_in6 *) &tmpaddr;
|
||||||
|
x->sin6_port = htons (port);
|
||||||
|
#else
|
||||||
|
abort ();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
ddsi_ipaddr_to_loc (tran, loc, (struct sockaddr *)&tmpaddr, kind);
|
ddsi_ipaddr_to_loc (tran, loc, (struct 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;
|
|
||||||
return AFSR_OK;
|
return AFSR_OK;
|
||||||
|
DDSRT_WARNING_MSVC_ON(4996);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ddsi_ipaddr_to_string (char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port)
|
char *ddsi_ipaddr_to_string (char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port)
|
||||||
|
|
|
@ -274,7 +274,7 @@ int find_own_ip (struct ddsi_domaingv *gv, const char *requested_address)
|
||||||
if (i < gv->n_interfaces)
|
if (i < gv->n_interfaces)
|
||||||
selected_idx = i;
|
selected_idx = i;
|
||||||
else
|
else
|
||||||
GVERROR ("%s: does not match an available interface\n", gv->config.networkAddressString);
|
GVERROR ("%s: does not match an available interface supporting %s\n", gv->config.networkAddressString, gv->m_factory->m_typename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected_idx < 0)
|
if (selected_idx < 0)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "dds/ddsrt/log.h"
|
#include "dds/ddsrt/log.h"
|
||||||
#include "dds/ddsrt/misc.h"
|
#include "dds/ddsrt/misc.h"
|
||||||
#include "dds/ddsrt/sockets.h"
|
#include "dds/ddsrt/sockets.h"
|
||||||
|
#include "dds/ddsrt/string.h"
|
||||||
#include "ddsi_eth.h"
|
#include "ddsi_eth.h"
|
||||||
#include "dds/ddsi/ddsi_tran.h"
|
#include "dds/ddsi/ddsi_tran.h"
|
||||||
#include "dds/ddsi/ddsi_udp.h"
|
#include "dds/ddsi/ddsi_udp.h"
|
||||||
|
@ -174,7 +175,8 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn_cmn, const nn_locator_
|
||||||
}
|
}
|
||||||
else if (rc != DDS_RETCODE_OK && rc != DDS_RETCODE_NOT_ALLOWED && rc != DDS_RETCODE_NO_CONNECTION)
|
else if (rc != DDS_RETCODE_OK && rc != DDS_RETCODE_NOT_ALLOWED && rc != DDS_RETCODE_NO_CONNECTION)
|
||||||
{
|
{
|
||||||
GVERROR ("ddsi_udp_conn_write failed with retcode %"PRId32"\n", rc);
|
char locbuf[DDSI_LOCSTRLEN];
|
||||||
|
GVERROR ("ddsi_udp_conn_write to %s failed with retcode %"PRId32"\n", ddsi_locator_to_string (locbuf, sizeof (locbuf), dst), rc);
|
||||||
}
|
}
|
||||||
return (rc == DDS_RETCODE_OK) ? ret : -1;
|
return (rc == DDS_RETCODE_OK) ? ret : -1;
|
||||||
}
|
}
|
||||||
|
@ -699,9 +701,61 @@ static int ddsi_udp_is_ssm_mcaddr (const ddsi_tran_factory_t tran, const nn_loca
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static enum ddsi_locator_from_string_result mcgen_address_from_string (ddsi_tran_factory_t tran, nn_locator_t *loc, const char *str)
|
||||||
|
{
|
||||||
|
// check for UDPv4MCGEN string, be lazy and refuse to recognize as a MCGEN form if there's anything "wrong" with it
|
||||||
|
DDSRT_WARNING_MSVC_OFF(4996);
|
||||||
|
char ipstr[280];
|
||||||
|
unsigned base, count, idx;
|
||||||
|
int ipstrlen, pos;
|
||||||
|
if (strlen (str) + 10 >= sizeof (ipstr)) // + 6 for appending a port
|
||||||
|
return AFSR_INVALID;
|
||||||
|
else if (sscanf (str, "%255[^;]%n;%u;%u;%u%n", ipstr, &ipstrlen, &base, &count, &idx, &pos) != 4)
|
||||||
|
return AFSR_INVALID;
|
||||||
|
else if (str[pos] != 0 && str[pos] != ':')
|
||||||
|
return AFSR_INVALID;
|
||||||
|
else if (!(count > 0 && base < 28 && count < 28 && base + count < 28 && idx < count))
|
||||||
|
return AFSR_INVALID;
|
||||||
|
if (str[pos] == ':')
|
||||||
|
{
|
||||||
|
unsigned port;
|
||||||
|
int pos2;
|
||||||
|
if (sscanf (str + pos, ":%u%n", &port, &pos2) != 1 || str[pos + pos2] != 0)
|
||||||
|
return AFSR_INVALID;
|
||||||
|
// append port to IP component so that ddsi_ipaddr_from_string can do all of the work
|
||||||
|
// except for filling the specials
|
||||||
|
assert (ipstrlen >= 0 && (size_t) ipstrlen < sizeof (ipstr));
|
||||||
|
assert (pos2 >= 0 && (size_t) pos2 < sizeof (ipstr) - (size_t) ipstrlen);
|
||||||
|
ddsrt_strlcpy (ipstr + ipstrlen, str + pos, sizeof (ipstr) - (size_t) ipstrlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ddsi_locator_from_string_result res = ddsi_ipaddr_from_string (tran, loc, ipstr, tran->m_kind);
|
||||||
|
if (res != AFSR_OK)
|
||||||
|
return res;
|
||||||
|
assert (loc->kind == NN_LOCATOR_KIND_UDPv4);
|
||||||
|
if (!ddsi_udp_is_mcaddr (tran, loc))
|
||||||
|
return AFSR_INVALID;
|
||||||
|
|
||||||
|
nn_udpv4mcgen_address_t x;
|
||||||
|
DDSRT_STATIC_ASSERT (sizeof (x) <= sizeof (loc->address));
|
||||||
|
memset (&x, 0, sizeof(x));
|
||||||
|
memcpy (&x.ipv4, loc->address + 12, 4);
|
||||||
|
x.base = (unsigned char) base;
|
||||||
|
x.count = (unsigned char) count;
|
||||||
|
x.idx = (unsigned char) idx;
|
||||||
|
memset (loc->address, 0, sizeof (loc->address));
|
||||||
|
memcpy (loc->address, &x, sizeof (x));
|
||||||
|
loc->kind = NN_LOCATOR_KIND_UDPv4MCGEN;
|
||||||
|
return AFSR_OK;
|
||||||
|
DDSRT_WARNING_MSVC_ON(4996);
|
||||||
|
}
|
||||||
|
|
||||||
static enum ddsi_locator_from_string_result ddsi_udp_address_from_string (ddsi_tran_factory_t tran, nn_locator_t *loc, const char *str)
|
static enum ddsi_locator_from_string_result ddsi_udp_address_from_string (ddsi_tran_factory_t tran, nn_locator_t *loc, const char *str)
|
||||||
{
|
{
|
||||||
return ddsi_ipaddr_from_string (tran, loc, str, tran->m_kind);
|
if (tran->m_kind == TRANS_UDP && mcgen_address_from_string (tran, loc, str) == AFSR_OK)
|
||||||
|
return AFSR_OK;
|
||||||
|
else
|
||||||
|
return ddsi_ipaddr_from_string (tran, loc, str, tran->m_kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *ddsi_udp_locator_to_string (char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port)
|
static char *ddsi_udp_locator_to_string (char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port)
|
||||||
|
|
|
@ -44,86 +44,46 @@ static int compare_locators_vwrap (const void *va, const void *vb);
|
||||||
static const ddsrt_avl_ctreedef_t addrset_treedef =
|
static const ddsrt_avl_ctreedef_t addrset_treedef =
|
||||||
DDSRT_AVL_CTREEDEF_INITIALIZER (offsetof (struct addrset_node, avlnode), offsetof (struct addrset_node, loc), compare_locators_vwrap, 0);
|
DDSRT_AVL_CTREEDEF_INITIALIZER (offsetof (struct addrset_node, avlnode), offsetof (struct addrset_node, loc), compare_locators_vwrap, 0);
|
||||||
|
|
||||||
static int add_addresses_to_addrset_1 (const struct ddsi_domaingv *gv, struct addrset *as, const char *ip, int port_mode, const char *msgtag, int req_mc, int mcgen_base, int mcgen_count, int mcgen_idx)
|
static int add_addresses_to_addrset_1 (const struct ddsi_domaingv *gv, struct addrset *as, nn_locator_t *loc, int port_mode, const char *msgtag)
|
||||||
{
|
{
|
||||||
char buf[DDSI_LOCSTRLEN];
|
char buf[DDSI_LOCSTRLEN];
|
||||||
nn_locator_t loc;
|
int32_t maxidx;
|
||||||
|
|
||||||
switch (ddsi_locator_from_string(gv, &loc, ip, gv->m_factory))
|
// check whether port number, address type and mode make sense, and prepare the
|
||||||
|
// locator by patching the first port number to use if none is given
|
||||||
|
if (loc->port != NN_LOCATOR_PORT_INVALID)
|
||||||
{
|
{
|
||||||
case AFSR_OK:
|
if (port_mode >= 0 && loc->port != (uint32_t) port_mode)
|
||||||
break;
|
{
|
||||||
case AFSR_INVALID:
|
GVERROR ("%s: %s: port mismatch (expecting no port or %d)\n", msgtag, ddsi_locator_to_string (buf, sizeof(buf), loc), port_mode);
|
||||||
GVERROR ("%s: %s: not a valid address\n", msgtag, ip);
|
|
||||||
return -1;
|
|
||||||
case AFSR_UNKNOWN:
|
|
||||||
GVERROR ("%s: %s: unknown address\n", msgtag, ip);
|
|
||||||
return -1;
|
|
||||||
case AFSR_MISMATCH:
|
|
||||||
GVERROR ("%s: %s: address family mismatch\n", msgtag, ip);
|
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
maxidx = 0;
|
||||||
}
|
}
|
||||||
|
else if (port_mode >= 0)
|
||||||
if (req_mc && !ddsi_is_mcaddr (gv, &loc))
|
|
||||||
{
|
{
|
||||||
GVERROR ("%s: %s: not a multicast address\n", msgtag, ip);
|
loc->port = (uint32_t) port_mode;
|
||||||
return -1;
|
maxidx = 0;
|
||||||
}
|
}
|
||||||
|
else if (ddsi_is_mcaddr (gv, loc))
|
||||||
if (mcgen_base == -1 && mcgen_count == -1 && mcgen_idx == -1)
|
|
||||||
;
|
|
||||||
else if (loc.kind == NN_LOCATOR_KIND_UDPv4 && ddsi_is_mcaddr(gv, &loc) && mcgen_base >= 0 && mcgen_count > 0 && mcgen_base + mcgen_count < 28 && mcgen_idx >= 0 && mcgen_idx < mcgen_count)
|
|
||||||
{
|
{
|
||||||
nn_udpv4mcgen_address_t x;
|
loc->port = ddsi_get_port (&gv->config, DDSI_PORT_MULTI_DISC, 0);
|
||||||
memset(&x, 0, sizeof(x));
|
maxidx = 0;
|
||||||
memcpy(&x.ipv4, loc.address + 12, 4);
|
|
||||||
x.base = (unsigned char) mcgen_base;
|
|
||||||
x.count = (unsigned char) mcgen_count;
|
|
||||||
x.idx = (unsigned char) mcgen_idx;
|
|
||||||
memset(loc.address, 0, sizeof(loc.address));
|
|
||||||
memcpy(loc.address, &x, sizeof(x));
|
|
||||||
loc.kind = NN_LOCATOR_KIND_UDPv4MCGEN;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GVERROR ("%s: %s,%d,%d,%d: IPv4 multicast address generator invalid or out of place\n",
|
loc->port = ddsi_get_port (&gv->config, DDSI_PORT_UNI_DISC, 0);
|
||||||
msgtag, ip, mcgen_base, mcgen_count, mcgen_idx);
|
maxidx = gv->config.maxAutoParticipantIndex;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (port_mode >= 0)
|
GVLOG (DDS_LC_CONFIG, "%s: add %s", msgtag, ddsi_locator_to_string (buf, sizeof (buf), loc));
|
||||||
|
add_to_addrset (gv, as, loc);
|
||||||
|
for (int32_t i = 1; i < maxidx; i++)
|
||||||
{
|
{
|
||||||
loc.port = (unsigned) port_mode;
|
loc->port = ddsi_get_port (&gv->config, DDSI_PORT_UNI_DISC, i);
|
||||||
GVLOG (DDS_LC_CONFIG, "%s: add %s", msgtag, ddsi_locator_to_string(buf, sizeof(buf), &loc));
|
GVLOG (DDS_LC_CONFIG, ", :%"PRIu32, loc->port);
|
||||||
add_to_addrset (gv, as, &loc);
|
add_to_addrset (gv, as, loc);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
GVLOG (DDS_LC_CONFIG, "%s: add ", msgtag);
|
|
||||||
if (!ddsi_is_mcaddr (gv, &loc))
|
|
||||||
{
|
|
||||||
assert (gv->config.maxAutoParticipantIndex >= 0);
|
|
||||||
for (int32_t i = 0; i <= gv->config.maxAutoParticipantIndex; i++)
|
|
||||||
{
|
|
||||||
loc.port = ddsi_get_port (&gv->config, DDSI_PORT_UNI_DISC, i);
|
|
||||||
if (i == 0)
|
|
||||||
GVLOG (DDS_LC_CONFIG, "%s", ddsi_locator_to_string(buf, sizeof(buf), &loc));
|
|
||||||
else
|
|
||||||
GVLOG (DDS_LC_CONFIG, ", :%"PRIu32, loc.port);
|
|
||||||
add_to_addrset (gv, as, &loc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (port_mode == -1)
|
|
||||||
loc.port = ddsi_get_port (&gv->config, DDSI_PORT_MULTI_DISC, 0);
|
|
||||||
else
|
|
||||||
loc.port = (uint32_t) port_mode;
|
|
||||||
GVLOG (DDS_LC_CONFIG, "%s", ddsi_locator_to_string(buf, sizeof(buf), &loc));
|
|
||||||
add_to_addrset (gv, as, &loc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GVLOG (DDS_LC_CONFIG, "\n");
|
GVLOG (DDS_LC_CONFIG, "\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -134,50 +94,43 @@ int add_addresses_to_addrset (const struct ddsi_domaingv *gv, struct addrset *as
|
||||||
port_mode >= 0 => always set port to port_mode
|
port_mode >= 0 => always set port to port_mode
|
||||||
*/
|
*/
|
||||||
DDSRT_WARNING_MSVC_OFF(4996);
|
DDSRT_WARNING_MSVC_OFF(4996);
|
||||||
char *addrs_copy, *ip, *cursor, *a;
|
char *addrs_copy, *cursor, *a;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
addrs_copy = ddsrt_strdup (addrs);
|
addrs_copy = ddsrt_strdup (addrs);
|
||||||
ip = ddsrt_malloc (strlen (addrs) + 1);
|
|
||||||
cursor = addrs_copy;
|
cursor = addrs_copy;
|
||||||
while ((a = ddsrt_strsep (&cursor, ",")) != NULL)
|
while ((a = ddsrt_strsep (&cursor, ",")) != NULL)
|
||||||
{
|
{
|
||||||
int port = 0, pos;
|
nn_locator_t loc;
|
||||||
int mcgen_base = -1, mcgen_count = -1, mcgen_idx = -1;
|
char buf[DDSI_LOCSTRLEN];
|
||||||
if (gv->config.transport_selector == TRANS_UDP || gv->config.transport_selector == TRANS_TCP)
|
|
||||||
|
switch (ddsi_locator_from_string (gv, &loc, a, gv->m_factory))
|
||||||
{
|
{
|
||||||
if (port_mode == -1 && sscanf (a, "%[^:]:%d%n", ip, &port, &pos) == 2 && a[pos] == 0)
|
case AFSR_OK:
|
||||||
; /* XYZ:PORT */
|
break;
|
||||||
else if (sscanf (a, "%[^;];%d;%d;%d%n", ip, &mcgen_base, &mcgen_count, &mcgen_idx, &pos) == 4 && a[pos] == 0)
|
case AFSR_INVALID:
|
||||||
port = port_mode; /* XYZ;BASE;COUNT;IDX for IPv4 MC address generators */
|
GVERROR ("%s: %s: not a valid address\n", msgtag, a);
|
||||||
else if (sscanf (a, "%[^:]%n", ip, &pos) == 1 && a[pos] == 0)
|
goto error;
|
||||||
port = port_mode; /* XYZ */
|
case AFSR_UNKNOWN:
|
||||||
else { /* XY:Z -- illegal, but conversion routine should flag it */
|
GVERROR ("%s: %s: unknown address\n", msgtag, a);
|
||||||
strcpy (ip, a);
|
goto error;
|
||||||
port = 0;
|
case AFSR_MISMATCH:
|
||||||
}
|
GVERROR ("%s: %s: address family mismatch\n", msgtag, a);
|
||||||
}
|
goto error;
|
||||||
else
|
|
||||||
{
|
|
||||||
if (port_mode == -1 && sscanf (a, "[%[^]]]:%d%n", ip, &port, &pos) == 2 && a[pos] == 0)
|
|
||||||
; /* [XYZ]:PORT */
|
|
||||||
else if (sscanf (a, "[%[^]]]%n", ip, &pos) == 1 && a[pos] == 0)
|
|
||||||
port = port_mode; /* [XYZ] */
|
|
||||||
else { /* XYZ -- let conversion routines handle errors */
|
|
||||||
strcpy (ip, a);
|
|
||||||
port = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((port > 0 && port <= 65535) || (port_mode == -1 && port == -1)) {
|
if (req_mc && !ddsi_is_mcaddr (gv, &loc))
|
||||||
if (add_addresses_to_addrset_1 (gv, as, ip, port, msgtag, req_mc, mcgen_base, mcgen_count, mcgen_idx) < 0)
|
{
|
||||||
goto error;
|
GVERROR ("%s: %s: not a multicast address\n", msgtag, ddsi_locator_to_string_no_port (buf, sizeof(buf), &loc));
|
||||||
} else {
|
goto error;
|
||||||
GVERROR ("%s: %s: port %d invalid\n", msgtag, a, port);
|
}
|
||||||
|
|
||||||
|
if (add_addresses_to_addrset_1 (gv, as, &loc, port_mode, msgtag) < 0)
|
||||||
|
{
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
error:
|
error:
|
||||||
ddsrt_free (ip);
|
|
||||||
ddsrt_free (addrs_copy);
|
ddsrt_free (addrs_copy);
|
||||||
return retval;
|
return retval;
|
||||||
DDSRT_WARNING_MSVC_ON(4996);
|
DDSRT_WARNING_MSVC_ON(4996);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
include(CUnit)
|
include(CUnit)
|
||||||
|
|
||||||
set(ddsi_test_sources
|
set(ddsi_test_sources
|
||||||
|
"locators.c"
|
||||||
"plist_generic.c"
|
"plist_generic.c"
|
||||||
"plist.c"
|
"plist.c"
|
||||||
"mem_ser.h")
|
"mem_ser.h")
|
||||||
|
|
428
src/core/ddsi/tests/locators.c
Normal file
428
src/core/ddsi/tests/locators.c
Normal file
|
@ -0,0 +1,428 @@
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2020 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 <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "dds/ddsrt/heap.h"
|
||||||
|
#include "dds/ddsrt/sockets.h"
|
||||||
|
#include "dds/ddsi/ddsi_tran.h"
|
||||||
|
#include "dds/ddsi/ddsi_domaingv.h"
|
||||||
|
#include "dds/ddsi/ddsi_udp.h"
|
||||||
|
#include "dds/ddsi/ddsi_tcp.h"
|
||||||
|
#include "dds/ddsi/q_config.h"
|
||||||
|
#include "dds/ddsi/q_rtps.h"
|
||||||
|
#include "CUnit/Theory.h"
|
||||||
|
|
||||||
|
static bool prefix_zero (const nn_locator_t *loc, size_t n)
|
||||||
|
{
|
||||||
|
assert (n <= sizeof (loc->address));
|
||||||
|
for (size_t i = 0; i < n; i++)
|
||||||
|
if (loc->address[i] != 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool check_ipv4_address (const nn_locator_t *loc, const uint8_t x[4])
|
||||||
|
{
|
||||||
|
return prefix_zero (loc, 12) && memcmp (loc->address + 12, x, 4) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool check_ipv64_address (const nn_locator_t *loc, const uint8_t x[4])
|
||||||
|
{
|
||||||
|
return prefix_zero (loc, 10) && loc->address[10] == 0xff && loc->address[11] == 0xff && memcmp (loc->address + 12, x, 4) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ddsi_tran_factory *init (struct ddsi_domaingv *gv, enum transport_selector tr)
|
||||||
|
{
|
||||||
|
memset (gv, 0, sizeof (*gv));
|
||||||
|
gv->config.transport_selector = tr;
|
||||||
|
ddsi_udp_init (gv);
|
||||||
|
ddsi_tcp_init (gv);
|
||||||
|
switch (tr)
|
||||||
|
{
|
||||||
|
case TRANS_UDP: return ddsi_factory_find (gv, "udp");
|
||||||
|
case TRANS_TCP: return ddsi_factory_find (gv, "tcp");
|
||||||
|
case TRANS_UDP6: return ddsi_factory_find (gv, "udp6");
|
||||||
|
case TRANS_TCP6: return ddsi_factory_find (gv, "tcp6");
|
||||||
|
default: return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fini (struct ddsi_domaingv *gv)
|
||||||
|
{
|
||||||
|
while (gv->ddsi_tran_factories)
|
||||||
|
{
|
||||||
|
struct ddsi_tran_factory *f = gv->ddsi_tran_factories;
|
||||||
|
gv->ddsi_tran_factories = f->m_factory;
|
||||||
|
ddsi_factory_free (f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CU_Test (ddsi_locator_from_string, bogusproto)
|
||||||
|
{
|
||||||
|
struct ddsi_domaingv gv;
|
||||||
|
struct ddsi_tran_factory * const fact = init (&gv, TRANS_UDP);
|
||||||
|
nn_locator_t loc;
|
||||||
|
enum ddsi_locator_from_string_result res;
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "bogusproto/xyz", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_UNKNOWN);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "bogusproto/xyz:1234", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_UNKNOWN);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "bogusproto/1.2.3.4:1234", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_UNKNOWN);
|
||||||
|
fini (&gv);
|
||||||
|
}
|
||||||
|
|
||||||
|
CU_TheoryDataPoints(ddsi_locator_from_string, ipv4_invalid) = {
|
||||||
|
CU_DataPoints(enum transport_selector, TRANS_UDP, TRANS_TCP)
|
||||||
|
};
|
||||||
|
|
||||||
|
CU_Theory ((enum transport_selector tr), ddsi_locator_from_string, ipv4_invalid)
|
||||||
|
{
|
||||||
|
struct ddsi_domaingv gv;
|
||||||
|
struct ddsi_tran_factory * const fact = init (&gv, tr);
|
||||||
|
nn_locator_t loc;
|
||||||
|
enum ddsi_locator_from_string_result res;
|
||||||
|
char astr[40];
|
||||||
|
snprintf (astr, sizeof (astr), "%s/", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID);
|
||||||
|
snprintf (astr, sizeof (astr), "%s/:", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID);
|
||||||
|
snprintf (astr, sizeof (astr), "%s/1.2:", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID);
|
||||||
|
snprintf (astr, sizeof (astr), "%s/1.2:99999", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID);
|
||||||
|
// if DNS is supported, a hostname lookup is tried whenever parsing as a numerical address fails
|
||||||
|
// which means we may get UNKNOWN
|
||||||
|
snprintf (astr, sizeof (astr), "%s/:1234", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
snprintf (astr, sizeof (astr), "%s/[1.2.3.4]", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
snprintf (astr, sizeof (astr), "%s/[1.2.3.4]:1234", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
fini (&gv);
|
||||||
|
}
|
||||||
|
|
||||||
|
CU_TheoryDataPoints(ddsi_locator_from_string, ipv4) = {
|
||||||
|
CU_DataPoints(enum transport_selector, TRANS_UDP, TRANS_TCP)
|
||||||
|
};
|
||||||
|
|
||||||
|
CU_Theory ((enum transport_selector tr), ddsi_locator_from_string, ipv4)
|
||||||
|
{
|
||||||
|
struct ddsi_domaingv gv;
|
||||||
|
struct ddsi_tran_factory * const fact = init (&gv, tr);
|
||||||
|
nn_locator_t loc;
|
||||||
|
enum ddsi_locator_from_string_result res;
|
||||||
|
char astr[40];
|
||||||
|
|
||||||
|
#if DDSRT_HAVE_DNS
|
||||||
|
{
|
||||||
|
enum ddsi_locator_from_string_result exp;
|
||||||
|
struct sockaddr_in localhost;
|
||||||
|
ddsrt_hostent_t *hent = NULL;
|
||||||
|
if (ddsrt_gethostbyname ("localhost", AF_INET, &hent) != 0)
|
||||||
|
exp = AFSR_UNKNOWN;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (hent->addrs[0].ss_family == AF_INET);
|
||||||
|
memcpy (&localhost, &hent->addrs[0], sizeof (localhost));
|
||||||
|
ddsrt_free (hent);
|
||||||
|
exp = AFSR_OK;
|
||||||
|
}
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "localhost", fact);
|
||||||
|
CU_ASSERT_FATAL (res == exp);
|
||||||
|
if (res == AFSR_OK)
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == NN_LOCATOR_PORT_INVALID);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (prefix_zero (&loc, 12) && memcmp (loc.address + 12, &localhost.sin_addr.s_addr, 4) == 0);
|
||||||
|
}
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "localhost:1234", fact);
|
||||||
|
CU_ASSERT_FATAL (res == exp);
|
||||||
|
if (res == AFSR_OK)
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == 1234);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (prefix_zero (&loc, 12) && memcmp (loc.address + 12, &localhost.sin_addr.s_addr, 4) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "1.2.3.4", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_OK);
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == NN_LOCATOR_PORT_INVALID);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (check_ipv4_address (&loc, (uint8_t[]){1,2,3,4}));
|
||||||
|
|
||||||
|
snprintf (astr, sizeof (astr), "%s/1.2.3.4", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_OK);
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == NN_LOCATOR_PORT_INVALID);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (check_ipv4_address (&loc, (uint8_t[]){1,2,3,4}));
|
||||||
|
|
||||||
|
snprintf (astr, sizeof (astr), "%s/1.2.3.4:1234", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_OK);
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == 1234);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (check_ipv4_address (&loc, (uint8_t[]){1,2,3,4}));
|
||||||
|
fini (&gv);
|
||||||
|
}
|
||||||
|
|
||||||
|
CU_Test (ddsi_locator_from_string, ipv4_cross1)
|
||||||
|
{
|
||||||
|
struct ddsi_domaingv gv;
|
||||||
|
struct ddsi_tran_factory * const fact = init (&gv, TRANS_UDP);
|
||||||
|
nn_locator_t loc;
|
||||||
|
enum ddsi_locator_from_string_result res;
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "tcp/1.2.3.4:1234", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_OK);
|
||||||
|
CU_ASSERT_FATAL (loc.kind == NN_LOCATOR_KIND_TCPv4);
|
||||||
|
CU_ASSERT_FATAL (loc.port == 1234);
|
||||||
|
CU_ASSERT_FATAL (loc.tran != fact);
|
||||||
|
CU_ASSERT_FATAL (check_ipv4_address (&loc, (uint8_t[]){1,2,3,4}));
|
||||||
|
fini (&gv);
|
||||||
|
}
|
||||||
|
|
||||||
|
CU_Test (ddsi_locator_from_string, ipv4_cross2)
|
||||||
|
{
|
||||||
|
struct ddsi_domaingv gv;
|
||||||
|
struct ddsi_tran_factory * const fact = init (&gv, TRANS_TCP);
|
||||||
|
nn_locator_t loc;
|
||||||
|
enum ddsi_locator_from_string_result res;
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "udp/1.2.3.4:1234", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_OK);
|
||||||
|
CU_ASSERT_FATAL (loc.kind == NN_LOCATOR_KIND_UDPv4);
|
||||||
|
CU_ASSERT_FATAL (loc.port == 1234);
|
||||||
|
CU_ASSERT_FATAL (loc.tran != fact);
|
||||||
|
CU_ASSERT_FATAL (check_ipv4_address (&loc, (uint8_t[]){1,2,3,4}));
|
||||||
|
fini (&gv);
|
||||||
|
}
|
||||||
|
|
||||||
|
CU_Test (ddsi_locator_from_string, udpv4mcgen)
|
||||||
|
{
|
||||||
|
struct ddsi_domaingv gv;
|
||||||
|
struct ddsi_tran_factory * const fact = init (&gv, TRANS_UDP);
|
||||||
|
nn_locator_t loc;
|
||||||
|
enum ddsi_locator_from_string_result res;
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "239.255.0.1;4;8;1:1234", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_OK);
|
||||||
|
CU_ASSERT_FATAL (loc.kind == NN_LOCATOR_KIND_UDPv4MCGEN);
|
||||||
|
CU_ASSERT_FATAL (loc.port == 1234);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (loc.address[0] == 239 && loc.address[1] == 255 && loc.address[2] == 0 && loc.address[3] == 1);
|
||||||
|
CU_ASSERT_FATAL (loc.address[4] == 4 && loc.address[5] == 8 && loc.address[6] == 1);
|
||||||
|
CU_ASSERT_FATAL (loc.address[7] == 0 && loc.address[8] == 0 && loc.address[9] == 0);
|
||||||
|
CU_ASSERT_FATAL (loc.address[10] == 0 && loc.address[11] == 0 && loc.address[12] == 0);
|
||||||
|
CU_ASSERT_FATAL (loc.address[13] == 0 && loc.address[14] == 0 && loc.address[15] == 0);
|
||||||
|
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "239.255.0.1;4;0;1:1234", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "239.255.0.1;4;0;1:2345", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "239.255.0.1;30;1;1:3456", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "239.255.0.1;4;24;1:4567", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "239.255.0.1;4;3;3:5678", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
fini (&gv);
|
||||||
|
}
|
||||||
|
|
||||||
|
CU_TheoryDataPoints(ddsi_locator_from_string, ipv6_invalid) = {
|
||||||
|
CU_DataPoints(enum transport_selector, TRANS_UDP6, TRANS_TCP6)
|
||||||
|
};
|
||||||
|
|
||||||
|
CU_Theory ((enum transport_selector tr), ddsi_locator_from_string, ipv6_invalid)
|
||||||
|
{
|
||||||
|
#if DDSRT_HAVE_IPV6
|
||||||
|
struct ddsi_domaingv gv;
|
||||||
|
struct ddsi_tran_factory * const fact = init (&gv, tr);
|
||||||
|
nn_locator_t loc;
|
||||||
|
enum ddsi_locator_from_string_result res;
|
||||||
|
char astr[40];
|
||||||
|
snprintf (astr, sizeof (astr), "%s/", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID);
|
||||||
|
// if DNS is supported, a hostname lookup is tried whenever parsing as a numerical address fails
|
||||||
|
// which means we may get UNKNOWN
|
||||||
|
snprintf (astr, sizeof (astr), "%s/::1:31415", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
snprintf (astr, sizeof (astr), "%s/:", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
snprintf (astr, sizeof (astr), "%s/1.2:", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
snprintf (astr, sizeof (astr), "%s/]:", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
snprintf (astr, sizeof (astr), "%s/[", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
snprintf (astr, sizeof (astr), "%s/[]", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
snprintf (astr, sizeof (astr), "%s/:1234", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_INVALID || res == AFSR_UNKNOWN);
|
||||||
|
fini (&gv);
|
||||||
|
#else
|
||||||
|
CU_PASS ("No IPv6 support");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CU_TheoryDataPoints(ddsi_locator_from_string, ipv6) = {
|
||||||
|
CU_DataPoints(enum transport_selector, TRANS_UDP6, TRANS_TCP6)
|
||||||
|
};
|
||||||
|
|
||||||
|
CU_Theory ((enum transport_selector tr), ddsi_locator_from_string, ipv6)
|
||||||
|
{
|
||||||
|
#if DDSRT_HAVE_IPV6
|
||||||
|
struct ddsi_domaingv gv;
|
||||||
|
struct ddsi_tran_factory * const fact = init (&gv, tr);
|
||||||
|
nn_locator_t loc;
|
||||||
|
enum ddsi_locator_from_string_result res;
|
||||||
|
char astr[40];
|
||||||
|
|
||||||
|
#if DDSRT_HAVE_DNS
|
||||||
|
{
|
||||||
|
enum ddsi_locator_from_string_result exp;
|
||||||
|
struct sockaddr_in6 localhost;
|
||||||
|
ddsrt_hostent_t *hent = NULL;
|
||||||
|
if (ddsrt_gethostbyname ("localhost", AF_INET6, &hent) != 0)
|
||||||
|
exp = AFSR_UNKNOWN;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (hent->addrs[0].ss_family == AF_INET6);
|
||||||
|
memcpy (&localhost, &hent->addrs[0], sizeof (localhost));
|
||||||
|
ddsrt_free (hent);
|
||||||
|
exp = AFSR_OK;
|
||||||
|
}
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "localhost", fact);
|
||||||
|
CU_ASSERT_FATAL (res == exp);
|
||||||
|
if (res == AFSR_OK)
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == NN_LOCATOR_PORT_INVALID);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (memcmp (loc.address, &localhost.sin6_addr.s6_addr, 16) == 0);
|
||||||
|
}
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "[localhost]", fact);
|
||||||
|
CU_ASSERT_FATAL (res == exp);
|
||||||
|
if (res == AFSR_OK)
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == NN_LOCATOR_PORT_INVALID);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (memcmp (loc.address, &localhost.sin6_addr.s6_addr, 16) == 0);
|
||||||
|
}
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "localhost:1234", fact);
|
||||||
|
CU_ASSERT_FATAL (res == exp);
|
||||||
|
if (res == AFSR_OK)
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == 1234);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (memcmp (loc.address, &localhost.sin6_addr.s6_addr, 16) == 0);
|
||||||
|
}
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "[localhost]:4567", fact);
|
||||||
|
CU_ASSERT_FATAL (res == exp);
|
||||||
|
if (res == AFSR_OK)
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == 4567);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (memcmp (loc.address, &localhost.sin6_addr.s6_addr, 16) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "1.2.3.4", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_OK || res == AFSR_UNKNOWN);
|
||||||
|
if (res == AFSR_OK)
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == NN_LOCATOR_PORT_INVALID);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (check_ipv64_address (&loc, (uint8_t[]){1,2,3,4}));
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, "[1.2.3.4]", fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_OK || res == AFSR_UNKNOWN);
|
||||||
|
if (res == AFSR_OK)
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == NN_LOCATOR_PORT_INVALID);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (check_ipv64_address (&loc, (uint8_t[]){1,2,3,4}));
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf (astr, sizeof (astr), "%s/1.2.3.4", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_OK || res == AFSR_UNKNOWN); if (res == AFSR_OK)
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == NN_LOCATOR_PORT_INVALID);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (check_ipv64_address (&loc, (uint8_t[]){1,2,3,4}));
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf (astr, sizeof (astr), "%s/1.2.3.4:6789", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_OK || res == AFSR_UNKNOWN);
|
||||||
|
if (res == AFSR_OK)
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == 6789);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (check_ipv64_address (&loc, (uint8_t[]){1,2,3,4}));
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf (astr, sizeof (astr), "%s/[1.2.3.4]:7890", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
if (res == AFSR_OK)
|
||||||
|
{
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_OK || res == AFSR_UNKNOWN);
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == 7890);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (check_ipv64_address (&loc, (uint8_t[]){1,2,3,4}));
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf (astr, sizeof (astr), "%s/[::1]:8901", fact->m_typename);
|
||||||
|
res = ddsi_locator_from_string (&gv, &loc, astr, fact);
|
||||||
|
CU_ASSERT_FATAL (res == AFSR_OK);
|
||||||
|
CU_ASSERT_FATAL (loc.kind == fact->m_kind);
|
||||||
|
CU_ASSERT_FATAL (loc.port == 8901);
|
||||||
|
CU_ASSERT_FATAL (loc.tran == fact);
|
||||||
|
CU_ASSERT_FATAL (prefix_zero (&loc, 15) && loc.address[15] == 1);
|
||||||
|
|
||||||
|
fini (&gv);
|
||||||
|
#else
|
||||||
|
CU_PASS ("No IPv6 support");
|
||||||
|
#endif
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue