From 3da21315f2f3a3578a714729339a97fb528ec291 Mon Sep 17 00:00:00 2001
From: Erik Boasson
The default value is: "250".
""" ] ] xsd:integer }? & [ a:documentation [ xml:lang="en" """ -This element specifies the port number for multicast meta traffic +
This element specifies the port number for multicast data traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2).
The default value is: "1".
""" ] ] element MulticastDataOffset { @@ -225,7 +225,7 @@ section 9.6.1, constant PG).The default value is: xsd:integer }? & [ a:documentation [ xml:lang="en" """ -
This element specifies the port number for unicast meta traffic (refer +
This element specifies the port number for unicast data traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3).
The default value is: "11".
""" ] ] element UnicastDataOffset { diff --git a/etc/cyclonedds.xsd b/etc/cyclonedds.xsd index 4e31f2f..4ec63e5 100644 --- a/etc/cyclonedds.xsd +++ b/etc/cyclonedds.xsd @@ -313,7 +313,7 @@ constant DG).</p><p>The default value is: "250".&lThis element specifies the base port number (refer to the DDSI 2.1 specification, section 9.6.1, constant PB).
") }, - { LEAF("DomainGain"), 1, "250", ABSOFF(port_dg), 0, uf_uint, 0, pf_uint, + { LEAF("DomainGain"), 1, "250", ABSOFF(ports.dg), 0, uf_uint, 0, pf_uint, BLURB("This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG).
") }, - { LEAF("ParticipantGain"), 1, "2", ABSOFF(port_pg), 0, uf_uint, 0, pf_uint, + { LEAF("ParticipantGain"), 1, "2", ABSOFF(ports.pg), 0, uf_uint, 0, pf_uint, BLURB("This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG).
") }, - { LEAF("MulticastMetaOffset"), 1, "0", ABSOFF(port_d0), 0, uf_uint, 0, pf_uint, + { LEAF("MulticastMetaOffset"), 1, "0", ABSOFF(ports.d0), 0, uf_uint, 0, pf_uint, BLURB("This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0).
") }, - { LEAF("UnicastMetaOffset"), 1, "10", ABSOFF(port_d1), 0, uf_uint, 0, pf_uint, + { LEAF("UnicastMetaOffset"), 1, "10", ABSOFF(ports.d1), 0, uf_uint, 0, pf_uint, BLURB("This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d1).
") }, - { LEAF("MulticastDataOffset"), 1, "1", ABSOFF(port_d2), 0, uf_uint, 0, pf_uint, - BLURB("This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2).
") }, - { LEAF("UnicastDataOffset"), 1, "11", ABSOFF(port_d3), 0, uf_uint, 0, pf_uint, - BLURB("This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3).
") }, + { LEAF("MulticastDataOffset"), 1, "1", ABSOFF(ports.d2), 0, uf_uint, 0, pf_uint, + BLURB("This element specifies the port number for multicast data traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2).
") }, + { LEAF("UnicastDataOffset"), 1, "11", ABSOFF(ports.d3), 0, uf_uint, 0, pf_uint, + BLURB("This element specifies the port number for unicast data traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3).
") }, END_MARKER }; @@ -1883,34 +1882,23 @@ static enum update_result uf_natint_255(struct cfgst *cfgst, void *parent, struc static enum update_result uf_uint (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) { - unsigned * const elem = cfg_address (cfgst, parent, cfgelem); + uint32_t * const elem = cfg_address (cfgst, parent, cfgelem); char *endptr; unsigned long v = strtoul (value, &endptr, 10); if (*value == 0 || *endptr != 0) return cfg_error (cfgst, "%s: not a decimal integer", value); - if (v != (unsigned) v) + if (v != (uint32_t) v) return cfg_error (cfgst, "%s: value out of range", value); - *elem = (unsigned) v; + *elem = (uint32_t) v; return URES_SUCCESS; } static void pf_uint (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources) { - unsigned const * const p = cfg_address (cfgst, parent, cfgelem); + uint32_t const * const p = cfg_address (cfgst, parent, cfgelem); cfg_logelem (cfgst, sources, "%u", *p); } -static enum update_result uf_port(struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) -{ - int *elem = cfg_address (cfgst, parent, cfgelem); - if (uf_uint (cfgst, parent, cfgelem, first, value) != URES_SUCCESS) - return URES_ERROR; - else if (*elem < 1 || *elem > 65535) - return cfg_error (cfgst, "%s: out of range", value); - else - return URES_SUCCESS; -} - static enum update_result uf_duration_gen (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, const char *value, int64_t def_mult, int64_t min_ns, int64_t max_ns) { return uf_natint64_unit (cfgst, cfg_address (cfgst, parent, cfgelem), value, unittab_duration, def_mult, min_ns, max_ns); diff --git a/src/core/ddsi/src/q_debmon.c b/src/core/ddsi/src/q_debmon.c index 58c8971..b4f6c29 100644 --- a/src/core/ddsi/src/q_debmon.c +++ b/src/core/ddsi/src/q_debmon.c @@ -346,10 +346,11 @@ static uint32_t debmon_main (void *vdm) return 0; } -struct debug_monitor *new_debug_monitor (struct q_globals *gv, int port) +struct debug_monitor *new_debug_monitor (struct q_globals *gv, int32_t port) { struct debug_monitor *dm; + /* negative port number means the feature is disabled */ if (gv->config.monitor_port < 0) return NULL; @@ -362,7 +363,14 @@ struct debug_monitor *new_debug_monitor (struct q_globals *gv, int port) dm->plugins = NULL; if ((dm->tran_factory = ddsi_factory_find (gv, "tcp")) == NULL) dm->tran_factory = ddsi_factory_find (gv, "tcp6"); - dm->servsock = ddsi_factory_create_listener (dm->tran_factory, port, NULL); + + if (!ddsi_is_valid_port (dm->tran_factory, (uint32_t) port)) + { + GVERROR ("debug monitor port number %"PRId32" is invalid\n", port); + goto err_invalid_port; + } + + dm->servsock = ddsi_factory_create_listener (dm->tran_factory, (uint32_t) port, NULL); if (dm->servsock == NULL) { GVWARNING ("debmon: can't create socket\n"); @@ -389,6 +397,7 @@ err_listen: ddsrt_mutex_destroy(&dm->lock); ddsi_listener_free(dm->servsock); err_servsock: +err_invalid_port: ddsrt_free(dm); return NULL; } diff --git a/src/core/ddsi/src/q_init.c b/src/core/ddsi/src/q_init.c index c73a39e..04d94ba 100644 --- a/src/core/ddsi/src/q_init.c +++ b/src/core/ddsi/src/q_init.c @@ -71,36 +71,30 @@ static void add_peer_addresses (const struct q_globals *gv, struct addrset *as, } } -static int make_uc_sockets (struct q_globals *gv, uint32_t * pdisc, uint32_t * pdata, int ppid) +enum make_uc_sockets_ret { + MUSRET_SUCCESS, + MUSRET_INVALID_PORTS, + MUSRET_NOSOCKET +}; + +static enum make_uc_sockets_ret make_uc_sockets (struct q_globals *gv, uint32_t * pdisc, uint32_t * pdata, int ppid) { if (gv->config.many_sockets_mode == MSM_NO_UNICAST) { assert (ppid == PARTICIPANT_INDEX_NONE); - *pdata = *pdisc = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId); + *pdata = *pdisc = ddsi_get_port (&gv->config.ports, DDSI_PORT_MULTI_DISC, gv->config.domainId, ppid); if (gv->config.allowMulticast) { /* FIXME: ugly hack - but we'll fix up after creating the multicast sockets */ - return 0; + return MUSRET_SUCCESS; } } - if (ppid >= 0) - { - /* FIXME: verify port numbers are in range instead of truncating them like this */ - uint32_t base = gv->config.port_base + (gv->config.port_dg * gv->config.domainId) + ((uint32_t) ppid * gv->config.port_pg); - *pdisc = base + gv->config.port_d1; - *pdata = base + gv->config.port_d3; - } - else if (ppid == PARTICIPANT_INDEX_NONE) - { - *pdata = 0; - *pdisc = 0; - } - else - { - DDS_FATAL ("make_uc_sockets: invalid participant index %d\n", ppid); - return -1; - } + *pdisc = ddsi_get_port (&gv->config.ports, DDSI_PORT_UNI_DISC, gv->config.domainId, ppid); + *pdata = ddsi_get_port (&gv->config.ports, DDSI_PORT_UNI_DATA, gv->config.domainId, ppid); + + if (!ddsi_is_valid_port (gv->m_factory, *pdisc) || !ddsi_is_valid_port (gv->m_factory, *pdata)) + return MUSRET_INVALID_PORTS; gv->disc_conn_uc = ddsi_factory_create_conn (gv->m_factory, *pdisc, NULL); if (gv->disc_conn_uc) @@ -123,13 +117,12 @@ static int make_uc_sockets (struct q_globals *gv, uint32_t * pdisc, uint32_t * p else { /* Set unicast locators */ - ddsi_conn_locator (gv->disc_conn_uc, &gv->loc_meta_uc); ddsi_conn_locator (gv->data_conn_uc, &gv->loc_default_uc); } } - return gv->data_conn_uc ? 0 : -1; + return gv->data_conn_uc ? MUSRET_SUCCESS : MUSRET_NOSOCKET; } static void make_builtin_endpoint_xqos (dds_qos_t *q, const dds_qos_t *template) @@ -286,7 +279,7 @@ static int string_to_default_locator (const struct q_globals *gv, nn_locator_t * static int set_spdp_address (struct q_globals *gv) { - const uint32_t port = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId + gv->config.port_d0); + const uint32_t port = ddsi_get_port (&gv->config.ports, DDSI_PORT_MULTI_DISC, gv->config.domainId, 0); int rc = 0; /* FIXME: FIXME: FIXME: */ gv->loc_spdp_mc.kind = NN_LOCATOR_KIND_INVALID; @@ -318,7 +311,7 @@ static int set_spdp_address (struct q_globals *gv) static int set_default_mc_address (struct q_globals *gv) { - const uint32_t port = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId + gv->config.port_d2); + const uint32_t port = ddsi_get_port (&gv->config.ports, DDSI_PORT_MULTI_DATA, gv->config.domainId, 0); int rc; if (!gv->config.defaultMulticastAddressString) gv->loc_default_mc = gv->loc_spdp_mc; @@ -459,6 +452,25 @@ int rtps_config_prep (struct q_globals *gv, struct cfgst *cfgst) unsigned num_channel_threads = 0; #endif + { + char message[256]; + int32_t ppidx; + if (gv->config.participantIndex >= 0 || gv->config.participantIndex == PARTICIPANT_INDEX_NONE) + ppidx = gv->config.participantIndex; + else if (gv->config.participantIndex == PARTICIPANT_INDEX_AUTO) + ppidx = gv->config.maxAutoParticipantIndex; + else + { + assert (0); + ppidx = 0; + } + if (!ddsi_valid_portmapping (&gv->config.ports, gv->config.domainId, ppidx, message, sizeof (message))) + { + DDS_ILOG (DDS_LC_ERROR, gv->config.domainId, "Invalid port mapping: %s\n", message); + goto err_config_late_error; + } + } + /* retry_on_reject_duration default is dependent on late_ack_mode and responsiveness timeout, so fix up */ if (gv->config.whc_init_highwater_mark.isdefault) gv->config.whc_init_highwater_mark.value = gv->config.whc_lowwater_mark; @@ -646,8 +658,13 @@ int create_multicast_sockets (struct q_globals *gv) uint32_t port; qos->m_multicast = 1; - /* FIXME: should check for overflow */ - port = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId + gv->config.port_d0); + port = ddsi_get_port (&gv->config.ports, DDSI_PORT_MULTI_DISC, gv->config.domainId, 0); + if (!ddsi_is_valid_port (gv->m_factory, port)) + { + GVERROR ("Failed to create discovery multicast socket for domain %"PRIu32": resulting port number (%"PRIu32") is out of range\n", + gv->config.domainId, port); + goto err_disc; + } if ((disc = ddsi_factory_create_conn (gv->m_factory, port, qos)) == NULL) goto err_disc; if (gv->config.many_sockets_mode == MSM_NO_UNICAST) @@ -657,16 +674,24 @@ int create_multicast_sockets (struct q_globals *gv) } else { - port = (uint32_t) (gv->config.port_base + gv->config.port_dg * gv->config.domainId + gv->config.port_d2); + port = ddsi_get_port (&gv->config.ports, DDSI_PORT_MULTI_DATA, gv->config.domainId, 0); + if (!ddsi_is_valid_port (gv->m_factory, port)) + { + GVERROR ("Failed to create data multicast socket for domain %"PRIu32": resulting port number (%"PRIu32") is out of range\n", + gv->config.domainId, port); + goto err_disc; + } if ((data = ddsi_factory_create_conn (gv->m_factory, port, qos)) == NULL) + { goto err_data; + } } ddsi_tran_free_qos (qos); gv->disc_conn_mc = disc; gv->data_conn_mc = data; - GVTRACE ("Multicast Ports: discovery %"PRIu32" data %"PRIu32" \n", - ddsi_conn_port (gv->disc_conn_mc), ddsi_conn_port (gv->data_conn_mc)); + GVLOG (DDS_LC_CONFIG, "Multicast Ports: discovery %"PRIu32" data %"PRIu32" \n", + ddsi_conn_port (gv->disc_conn_mc), ddsi_conn_port (gv->data_conn_mc)); return 1; err_data: @@ -980,7 +1005,7 @@ int rtps_init (struct q_globals *gv) #ifdef DDSI_INCLUDE_NETWORK_PARTITIONS /* Convert address sets in partition mappings from string to address sets */ { - const uint32_t port = gv->config.port_base + gv->config.port_dg * gv->config.domainId + gv->config.port_d2; + const uint32_t port = ddsi_get_port (&gv->config.ports, DDSI_PORT_MULTI_DATA, gv->config.domainId, 0); struct config_networkpartition_listelem *np; for (np = gv->config.networkPartitions; np; np = np->next) { @@ -1070,33 +1095,44 @@ int rtps_init (struct q_globals *gv) { if (gv->config.participantIndex >= 0 || gv->config.participantIndex == PARTICIPANT_INDEX_NONE) { - if (make_uc_sockets (gv, &port_disc_uc, &port_data_uc, gv->config.participantIndex) < 0) + enum make_uc_sockets_ret musret = make_uc_sockets (gv, &port_disc_uc, &port_data_uc, gv->config.participantIndex); + switch (musret) { - GVERROR ("rtps_init: failed to create unicast sockets for domain %"PRId32" participant %d\n", gv->config.domainId, gv->config.participantIndex); - goto err_unicast_sockets; + case MUSRET_SUCCESS: + break; + case MUSRET_INVALID_PORTS: + GVERROR ("Failed to create unicast sockets for domain %"PRIu32" participant index %d: resulting port numbers (%"PRIu32", %"PRIu32") are out of range\n", + gv->config.domainId, gv->config.participantIndex, port_disc_uc, port_data_uc); + goto err_unicast_sockets; + case MUSRET_NOSOCKET: + GVERROR ("rtps_init: failed to create unicast sockets for domain %"PRId32" participant index %d (ports %"PRIu32", %"PRIu32")\n", gv->config.domainId, gv->config.participantIndex, port_disc_uc, port_data_uc); + goto err_unicast_sockets; } } else if (gv->config.participantIndex == PARTICIPANT_INDEX_AUTO) { /* try to find a free one, and update gv->config.participantIndex */ + enum make_uc_sockets_ret musret = MUSRET_NOSOCKET; int ppid; GVLOG (DDS_LC_CONFIG, "rtps_init: trying to find a free participant index\n"); - for (ppid = 0; ppid <= gv->config.maxAutoParticipantIndex; ppid++) + for (ppid = 0; ppid <= gv->config.maxAutoParticipantIndex && musret == MUSRET_NOSOCKET; ppid++) { - int r = make_uc_sockets (gv, &port_disc_uc, &port_data_uc, ppid); - if (r == 0) /* Success! */ - break; - else if (r == -1) /* Try next one */ - continue; - else /* Oops! */ + musret = make_uc_sockets (gv, &port_disc_uc, &port_data_uc, ppid); + switch (musret) { - GVERROR ("rtps_init: failed to create unicast sockets for domain %"PRId32" participant %d\n", gv->config.domainId, ppid); - goto err_unicast_sockets; + case MUSRET_SUCCESS: + break; + case MUSRET_INVALID_PORTS: + GVERROR ("Failed to create unicast sockets for domain %"PRIu32" participant index %d: resulting port numbers (%"PRIu32", %"PRIu32") are out of range\n", + gv->config.domainId, ppid, port_disc_uc, port_data_uc); + goto err_unicast_sockets; + case MUSRET_NOSOCKET: /* Try next one */ + break; } } if (ppid > gv->config.maxAutoParticipantIndex) { - GVERROR ("rtps_init: failed to find a free participant index for domain %"PRId32"\n", gv->config.domainId); + GVERROR ("Failed to find a free participant index for domain %"PRIu32"\n", gv->config.domainId); goto err_unicast_sockets; } gv->config.participantIndex = ppid; @@ -1107,7 +1143,7 @@ int rtps_init (struct q_globals *gv) } GVLOG (DDS_LC_CONFIG, "rtps_init: uc ports: disc %"PRIu32" data %"PRIu32"\n", port_disc_uc, port_data_uc); } - GVLOG (DDS_LC_CONFIG, "rtps_init: domainid %"PRId32" participantid %d\n", gv->config.domainId, gv->config.participantIndex); + GVLOG (DDS_LC_CONFIG, "rtps_init: domainid %"PRIu32" participantid %d\n", gv->config.domainId, gv->config.participantIndex); if (gv->config.pcap_file && *gv->config.pcap_file) { @@ -1157,9 +1193,15 @@ int rtps_init (struct q_globals *gv) /* Must have a data_conn_uc/tev_conn/transmit_conn */ gv->data_conn_uc = ddsi_factory_create_conn (gv->m_factory, 0, NULL); - if (gv->config.tcp_port != -1) + if (gv->config.tcp_port == -1) + ; /* nop */ + else if (!ddsi_is_valid_port (gv->m_factory, (uint32_t) gv->config.tcp_port)) { - gv->listener = ddsi_factory_create_listener (gv->m_factory, gv->config.tcp_port, NULL); + GVERROR ("Listener port %d is out of range for transport %s\n", gv->config.tcp_port, gv->m_factory->m_typename); + } + else + { + gv->listener = ddsi_factory_create_listener (gv->m_factory, (uint32_t) gv->config.tcp_port, NULL); if (gv->listener == NULL || ddsi_listener_listen (gv->listener) != 0) { GVERROR ("Failed to create %s listener\n", gv->m_factory->m_typename);