Minor cleanup of UDP, TCP support code
Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
0b9ab17018
commit
e1201e678d
10 changed files with 517 additions and 479 deletions
|
@ -60,8 +60,8 @@ typedef void (*ddsi_tran_free_fn_t) (ddsi_tran_factory_t);
|
|||
typedef void (*ddsi_tran_peer_locator_fn_t) (ddsi_tran_conn_t, nn_locator_t *);
|
||||
typedef void (*ddsi_tran_disable_multiplexing_fn_t) (ddsi_tran_conn_t);
|
||||
typedef ddsi_tran_conn_t (*ddsi_tran_accept_fn_t) (ddsi_tran_listener_t);
|
||||
typedef ddsi_tran_conn_t (*ddsi_tran_create_conn_fn_t) (ddsi_tran_factory_t fact, uint32_t, const struct ddsi_tran_qos *);
|
||||
typedef ddsi_tran_listener_t (*ddsi_tran_create_listener_fn_t) (ddsi_tran_factory_t fact, uint32_t port, const struct ddsi_tran_qos *);
|
||||
typedef dds_return_t (*ddsi_tran_create_conn_fn_t) (ddsi_tran_conn_t *conn, ddsi_tran_factory_t fact, uint32_t, const struct ddsi_tran_qos *);
|
||||
typedef dds_return_t (*ddsi_tran_create_listener_fn_t) (ddsi_tran_listener_t *listener, ddsi_tran_factory_t fact, uint32_t port, const struct ddsi_tran_qos *);
|
||||
typedef void (*ddsi_tran_release_conn_fn_t) (ddsi_tran_conn_t);
|
||||
typedef void (*ddsi_tran_close_conn_fn_t) (ddsi_tran_conn_t);
|
||||
typedef void (*ddsi_tran_unblock_listener_fn_t) (ddsi_tran_listener_t);
|
||||
|
@ -214,15 +214,17 @@ inline bool ddsi_factory_supports (const struct ddsi_tran_factory *factory, int3
|
|||
inline int ddsi_is_valid_port (ddsi_tran_factory_t factory, uint32_t port) {
|
||||
return factory->m_is_valid_port_fn (factory, port);
|
||||
}
|
||||
inline ddsi_tran_conn_t ddsi_factory_create_conn (ddsi_tran_factory_t factory, uint32_t port, const struct ddsi_tran_qos *qos) {
|
||||
inline dds_return_t ddsi_factory_create_conn (ddsi_tran_conn_t *conn, ddsi_tran_factory_t factory, uint32_t port, const struct ddsi_tran_qos *qos) {
|
||||
*conn = NULL;
|
||||
if (!ddsi_is_valid_port (factory, port))
|
||||
return NULL;
|
||||
return factory->m_create_conn_fn (factory, port, qos);
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
return factory->m_create_conn_fn (conn, factory, port, qos);
|
||||
}
|
||||
inline ddsi_tran_listener_t ddsi_factory_create_listener (ddsi_tran_factory_t factory, uint32_t port, const struct ddsi_tran_qos *qos) {
|
||||
inline dds_return_t ddsi_factory_create_listener (ddsi_tran_listener_t *listener, ddsi_tran_factory_t factory, uint32_t port, const struct ddsi_tran_qos *qos) {
|
||||
*listener = NULL;
|
||||
if (!ddsi_is_valid_port (factory, port))
|
||||
return NULL;
|
||||
return factory->m_create_listener_fn (factory, port, qos);
|
||||
return DDS_RETCODE_BAD_PARAMETER;
|
||||
return factory->m_create_listener_fn (listener, factory, port, qos);
|
||||
}
|
||||
|
||||
void ddsi_tran_free (ddsi_tran_base_t base);
|
||||
|
|
|
@ -21,7 +21,7 @@ extern "C" {
|
|||
|
||||
struct msghdr;
|
||||
|
||||
FILE * new_pcap_file (const struct ddsrt_log_cfg *logcfg, const char *name);
|
||||
FILE * new_pcap_file (struct ddsi_domaingv *gv, const char *name);
|
||||
|
||||
void write_pcap_received (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const struct sockaddr_storage *src, const struct sockaddr_storage *dst, unsigned char *buf, size_t sz);
|
||||
void write_pcap_sent (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const struct sockaddr_storage *src,
|
||||
|
|
|
@ -174,7 +174,7 @@ static int ddsi_raweth_conn_locator (ddsi_tran_factory_t fact, ddsi_tran_base_t
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ddsi_tran_conn_t ddsi_raweth_create_conn (ddsi_tran_factory_t fact, uint32_t port, const struct ddsi_tran_qos *qos)
|
||||
static dds_return_t ddsi_raweth_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_factory_t fact, uint32_t port, const struct ddsi_tran_qos *qos)
|
||||
{
|
||||
ddsrt_socket_t sock;
|
||||
dds_return_t rc;
|
||||
|
@ -187,14 +187,14 @@ static ddsi_tran_conn_t ddsi_raweth_create_conn (ddsi_tran_factory_t fact, uint3
|
|||
if (port == 0 || port > 65535)
|
||||
{
|
||||
DDS_CERROR (&fact->gv->logconfig, "ddsi_raweth_create_conn %s port %u - using port number as ethernet type, %u won't do\n", mcast ? "multicast" : "unicast", port, port);
|
||||
return NULL;
|
||||
return DDS_RETCODE_ERROR;
|
||||
}
|
||||
|
||||
rc = ddsrt_socket(&sock, PF_PACKET, SOCK_DGRAM, htons((uint16_t)port));
|
||||
if (rc != DDS_RETCODE_OK)
|
||||
{
|
||||
DDS_CERROR (&fact->gv->logconfig, "ddsi_raweth_create_conn %s port %u failed ... retcode = %d\n", mcast ? "multicast" : "unicast", port, rc);
|
||||
return NULL;
|
||||
return DDS_RETCODE_ERROR;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
@ -207,13 +207,13 @@ static ddsi_tran_conn_t ddsi_raweth_create_conn (ddsi_tran_factory_t fact, uint3
|
|||
{
|
||||
ddsrt_close(sock);
|
||||
DDS_CERROR (&fact->gv->logconfig, "ddsi_raweth_create_conn %s bind port %u failed ... retcode = %d\n", mcast ? "multicast" : "unicast", port, rc);
|
||||
return NULL;
|
||||
return DDS_RETCODE_ERROR;
|
||||
}
|
||||
|
||||
if ((uc = (ddsi_raweth_conn_t) ddsrt_malloc (sizeof (*uc))) == NULL)
|
||||
{
|
||||
ddsrt_close(sock);
|
||||
return NULL;
|
||||
return DDS_RETCODE_ERROR;
|
||||
}
|
||||
|
||||
memset (uc, 0, sizeof (*uc));
|
||||
|
@ -230,7 +230,8 @@ static ddsi_tran_conn_t ddsi_raweth_create_conn (ddsi_tran_factory_t fact, uint3
|
|||
uc->m_base.m_disable_multiplexing_fn = 0;
|
||||
|
||||
DDS_CTRACE (&fact->gv->logconfig, "ddsi_raweth_create_conn %s socket %d port %u\n", mcast ? "multicast" : "unicast", uc->m_sock, uc->m_base.m_base.m_port);
|
||||
return &uc->m_base;
|
||||
*conn_out = &uc->m_base;
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static int isbroadcast(const nn_locator_t *loc)
|
||||
|
|
|
@ -39,9 +39,15 @@
|
|||
wait set that manages their lifecycle.
|
||||
*/
|
||||
|
||||
union addr {
|
||||
struct sockaddr a;
|
||||
struct sockaddr_in a4;
|
||||
struct sockaddr_in6 a6;
|
||||
};
|
||||
|
||||
typedef struct ddsi_tcp_conn {
|
||||
struct ddsi_tran_conn m_base;
|
||||
struct sockaddr_storage m_peer_addr;
|
||||
union addr m_peer_addr;
|
||||
uint32_t m_peer_port;
|
||||
ddsrt_mutex_t m_mutex;
|
||||
ddsrt_socket_t m_sock;
|
||||
|
@ -70,8 +76,8 @@ struct ddsi_tran_factory_tcp {
|
|||
|
||||
static int ddsi_tcp_cmp_conn (const struct ddsi_tcp_conn *c1, const struct ddsi_tcp_conn *c2)
|
||||
{
|
||||
const struct sockaddr *a1s = (struct sockaddr *)&c1->m_peer_addr;
|
||||
const struct sockaddr *a2s = (struct sockaddr *)&c2->m_peer_addr;
|
||||
const struct sockaddr *a1s = &c1->m_peer_addr.a;
|
||||
const struct sockaddr *a2s = &c2->m_peer_addr.a;
|
||||
if (a1s->sa_family != a2s->sa_family)
|
||||
return (a1s->sa_family < a2s->sa_family) ? -1 : 1;
|
||||
else if (c1->m_peer_port != c2->m_peer_port)
|
||||
|
@ -132,114 +138,91 @@ static void ddsi_tcp_cache_dump (void)
|
|||
}
|
||||
*/
|
||||
|
||||
static unsigned short get_socket_port (struct ddsrt_log_cfg *logcfg, ddsrt_socket_t socket)
|
||||
static uint16_t get_socket_port (struct ddsi_domaingv const * const gv, ddsrt_socket_t socket)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
union addr addr;
|
||||
socklen_t addrlen = sizeof (addr);
|
||||
dds_return_t ret;
|
||||
|
||||
ret = ddsrt_getsockname(socket, (struct sockaddr *)&addr, &addrlen);
|
||||
ret = ddsrt_getsockname(socket, &addr.a, &addrlen);
|
||||
if (ret != DDS_RETCODE_OK) {
|
||||
DDS_CERROR (logcfg, "ddsi_tcp_get_socket_port: ddsrt_getsockname retcode %"PRId32"\n", ret);
|
||||
GVERROR ("ddsi_tcp_get_socket_port: ddsrt_getsockname retcode %"PRId32"\n", ret);
|
||||
return 0;
|
||||
}
|
||||
return ddsrt_sockaddr_get_port((struct sockaddr *)&addr);
|
||||
return ddsrt_sockaddr_get_port (&addr.a);
|
||||
}
|
||||
|
||||
static void ddsi_tcp_conn_set_socket (ddsi_tcp_conn_t conn, ddsrt_socket_t sock)
|
||||
{
|
||||
struct ddsi_domaingv const * const gv = conn->m_base.m_base.gv;
|
||||
conn->m_sock = sock;
|
||||
conn->m_base.m_base.m_port = (sock == DDSRT_INVALID_SOCKET) ? INVALID_PORT : get_socket_port (&conn->m_base.m_base.gv->logconfig, sock);
|
||||
conn->m_base.m_base.m_port = (sock == DDSRT_INVALID_SOCKET) ? INVALID_PORT : get_socket_port (gv, sock);
|
||||
}
|
||||
|
||||
static void ddsi_tcp_sock_free (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t sock, const char *msg)
|
||||
static void ddsi_tcp_sock_free (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, const char *msg)
|
||||
{
|
||||
if (sock != DDSRT_INVALID_SOCKET)
|
||||
{
|
||||
if (msg)
|
||||
{
|
||||
DDS_CLOG (DDS_LC_TCP, logcfg, "tcp %s free socket %"PRIdSOCK"\n", msg, sock);
|
||||
}
|
||||
GVLOG (DDS_LC_TCP, "tcp %s free socket %"PRIdSOCK"\n", msg, sock);
|
||||
ddsrt_close (sock);
|
||||
}
|
||||
}
|
||||
|
||||
static dds_return_t ddsi_tcp_sock_new (struct ddsi_tran_factory_tcp * const fact, ddsrt_socket_t *sock, uint16_t port)
|
||||
{
|
||||
struct ddsi_domaingv * const gv = fact->fact.gv;
|
||||
struct ddsi_domaingv const * const gv = fact->fact.gv;
|
||||
const int one = 1;
|
||||
union addr socketname;
|
||||
dds_return_t rc;
|
||||
|
||||
memset (&socketname, 0, sizeof (socketname));
|
||||
switch (fact->fact.m_kind)
|
||||
{
|
||||
int af = AF_UNSPEC;
|
||||
switch (fact->fact.m_kind)
|
||||
{
|
||||
case NN_LOCATOR_KIND_TCPv4:
|
||||
af = AF_INET;
|
||||
break;
|
||||
case NN_LOCATOR_KIND_TCPv4:
|
||||
socketname.a4.sin_family = AF_INET;
|
||||
socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||
socketname.a4.sin_port = htons (port);
|
||||
break;
|
||||
#if DDSRT_HAVE_IPV6
|
||||
case NN_LOCATOR_KIND_TCPv6:
|
||||
af = AF_INET6;
|
||||
break;
|
||||
case NN_LOCATOR_KIND_TCPv6:
|
||||
socketname.a6.sin6_family = AF_INET6;
|
||||
socketname.a6.sin6_addr = ddsrt_in6addr_any;
|
||||
socketname.a6.sin6_port = htons (port);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DDS_FATAL ("ddsi_tcp_sock_new: unsupported kind %"PRId32"\n", fact->fact.m_kind);
|
||||
}
|
||||
assert (af != AF_UNSPEC);
|
||||
if ((rc = ddsrt_socket (sock, af, SOCK_STREAM, 0)) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_tcp_sock_new: failed to create socket: %s\n", dds_strretcode (rc));
|
||||
goto fail;
|
||||
}
|
||||
default:
|
||||
DDS_FATAL ("ddsi_tcp_sock_new: unsupported kind %"PRId32"\n", fact->fact.m_kind);
|
||||
}
|
||||
if ((rc = ddsrt_socket (sock, socketname.a.sa_family, SOCK_STREAM, 0)) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_tcp_sock_new: failed to create socket: %s\n", dds_strretcode (rc));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* REUSEADDR if we're binding to a port number */
|
||||
if (port && (rc = ddsrt_setsockopt (*sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof (one))) != DDS_RETCODE_OK)
|
||||
if (port && (rc = ddsrt_setsockopt (*sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (one))) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_tcp_sock_new: failed to enable address reuse: %s\n", dds_strretcode (rc));
|
||||
goto fail_w_socket;
|
||||
}
|
||||
|
||||
if ((rc = ddsrt_bind (*sock, &socketname.a, ddsrt_sockaddr_get_size (&socketname.a))) != DDS_RETCODE_OK)
|
||||
{
|
||||
union {
|
||||
struct sockaddr_storage x;
|
||||
struct sockaddr_in a4;
|
||||
struct sockaddr_in6 a6;
|
||||
} socketname;
|
||||
memset (&socketname.x, 0, sizeof (socketname.x));
|
||||
switch (fact->fact.m_kind)
|
||||
{
|
||||
case NN_LOCATOR_KIND_TCPv4:
|
||||
socketname.a4.sin_family = AF_INET;
|
||||
socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||
socketname.a4.sin_port = htons (port);
|
||||
break;
|
||||
#if DDSRT_HAVE_IPV6
|
||||
case NN_LOCATOR_KIND_TCPv6:
|
||||
socketname.a4.sin_family = AF_INET6;
|
||||
socketname.a6.sin6_addr = ddsrt_in6addr_any;
|
||||
socketname.a6.sin6_port = htons (port);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DDS_FATAL ("ddsi_tcp_sock_new: unsupported kind %"PRId32"\n", fact->fact.m_kind);
|
||||
}
|
||||
if ((rc = ddsrt_bind (*sock, (struct sockaddr *) &socketname, ddsrt_sockaddr_get_size ((struct sockaddr *) &socketname))) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_tcp_sock_new: failed to bind to ANY:%"PRIu16": %s\n", port, dds_strretcode (rc));
|
||||
goto fail_w_socket;
|
||||
}
|
||||
GVERROR ("ddsi_tcp_sock_new: failed to bind to ANY:%"PRIu16": %s\n", port,
|
||||
(rc == DDS_RETCODE_PRECONDITION_NOT_MET) ? "address in use" : dds_strretcode (rc));
|
||||
goto fail_w_socket;
|
||||
}
|
||||
|
||||
#ifdef SO_NOSIGPIPE
|
||||
if (ddsrt_setsockopt (*sock, SOL_SOCKET, SO_NOSIGPIPE, (char *) &one, sizeof (one)) != DDS_RETCODE_OK)
|
||||
if (ddsrt_setsockopt (*sock, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof (one)) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_tcp_sock_new: failed to set NOSIGPIPE: %s\n", dds_strretcode (rc));
|
||||
goto fail_w_socket;
|
||||
}
|
||||
#endif
|
||||
#ifdef TCP_NODELAY
|
||||
if (gv->config.tcp_nodelay && (rc = ddsrt_setsockopt (*sock, IPPROTO_TCP, TCP_NODELAY, (char*) &one, sizeof (one))) != DDS_RETCODE_OK)
|
||||
if (gv->config.tcp_nodelay && (rc = ddsrt_setsockopt (*sock, IPPROTO_TCP, TCP_NODELAY, &one, sizeof (one))) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_tcp_sock_new: failed to set NODELAY: %s\n", dds_strretcode (rc));
|
||||
goto fail_w_socket;
|
||||
|
@ -264,52 +247,57 @@ static void ddsi_tcp_node_free (void * ptr)
|
|||
static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const ddsrt_msghdr_t * msg)
|
||||
{
|
||||
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory;
|
||||
struct ddsi_domaingv const * const gv = fact->fact.gv;
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
ddsrt_socket_t sock;
|
||||
dds_return_t ret;
|
||||
|
||||
if (ddsi_tcp_sock_new (fact, &sock, 0) == DDS_RETCODE_OK)
|
||||
if (ddsi_tcp_sock_new (fact, &sock, 0) != DDS_RETCODE_OK)
|
||||
{
|
||||
/* Attempt to connect, expected that may fail */
|
||||
do {
|
||||
ret = ddsrt_connect(sock, msg->msg_name, msg->msg_namelen);
|
||||
} while (ret == DDS_RETCODE_INTERRUPTED);
|
||||
/* error messages are logged by ddsi_tcp_sock_new */
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret != DDS_RETCODE_OK)
|
||||
{
|
||||
ddsi_tcp_sock_free (&conn->m_base.m_base.gv->logconfig, sock, NULL);
|
||||
return;
|
||||
}
|
||||
ddsi_tcp_conn_set_socket (conn, sock);
|
||||
/* Attempt to connect, expected that may fail */
|
||||
do {
|
||||
ret = ddsrt_connect(sock, msg->msg_name, msg->msg_namelen);
|
||||
} while (ret == DDS_RETCODE_INTERRUPTED);
|
||||
if (ret != DDS_RETCODE_OK)
|
||||
goto fail_w_socket;
|
||||
|
||||
ddsi_tcp_conn_set_socket (conn, sock);
|
||||
#ifdef DDSI_INCLUDE_SSL
|
||||
if (fact->ddsi_tcp_ssl_plugin.connect)
|
||||
if (fact->ddsi_tcp_ssl_plugin.connect)
|
||||
{
|
||||
conn->m_ssl = (fact->ddsi_tcp_ssl_plugin.connect) (conn->m_base.m_base.gv, sock);
|
||||
if (conn->m_ssl == NULL)
|
||||
{
|
||||
conn->m_ssl = (fact->ddsi_tcp_ssl_plugin.connect) (conn->m_base.m_base.gv, sock);
|
||||
if (conn->m_ssl == NULL)
|
||||
{
|
||||
ddsi_tcp_conn_set_socket (conn, DDSRT_INVALID_SOCKET);
|
||||
return;
|
||||
}
|
||||
ddsi_tcp_conn_set_socket (conn, DDSRT_INVALID_SOCKET);
|
||||
goto fail_w_socket;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *) msg->msg_name);
|
||||
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp connect socket %"PRIdSOCK" port %u to %s\n", sock, get_socket_port (&conn->m_base.m_base.gv->logconfig, sock), buff);
|
||||
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *) msg->msg_name);
|
||||
GVLOG (DDS_LC_TCP, "tcp connect socket %"PRIdSOCK" port %u to %s\n", sock, get_socket_port (gv, sock), buff);
|
||||
|
||||
/* Also may need to receive on connection so add to waitset */
|
||||
/* Also may need to receive on connection so add to waitset */
|
||||
|
||||
(void)ddsrt_setsocknonblocking(conn->m_sock, true);
|
||||
(void)ddsrt_setsocknonblocking(conn->m_sock, true);
|
||||
|
||||
assert (conn->m_base.m_base.gv->n_recv_threads > 0);
|
||||
assert (conn->m_base.m_base.gv->recv_threads[0].arg.mode == RTM_MANY);
|
||||
os_sockWaitsetAdd (conn->m_base.m_base.gv->recv_threads[0].arg.u.many.ws, &conn->m_base);
|
||||
os_sockWaitsetTrigger (conn->m_base.m_base.gv->recv_threads[0].arg.u.many.ws);
|
||||
}
|
||||
assert (conn->m_base.m_base.gv->n_recv_threads > 0);
|
||||
assert (conn->m_base.m_base.gv->recv_threads[0].arg.mode == RTM_MANY);
|
||||
os_sockWaitsetAdd (conn->m_base.m_base.gv->recv_threads[0].arg.u.many.ws, &conn->m_base);
|
||||
os_sockWaitsetTrigger (conn->m_base.m_base.gv->recv_threads[0].arg.u.many.ws);
|
||||
return;
|
||||
|
||||
fail_w_socket:
|
||||
ddsi_tcp_sock_free (gv, sock, NULL);
|
||||
}
|
||||
|
||||
static void ddsi_tcp_cache_add (struct ddsi_tran_factory_tcp *fact, ddsi_tcp_conn_t conn, ddsrt_avl_ipath_t * path)
|
||||
{
|
||||
struct ddsi_domaingv * const gv = fact->fact.gv;
|
||||
const char * action = "added";
|
||||
ddsi_tcp_node_t node;
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
|
@ -342,13 +330,14 @@ static void ddsi_tcp_cache_add (struct ddsi_tran_factory_tcp *fact, ddsi_tcp_con
|
|||
}
|
||||
}
|
||||
|
||||
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
|
||||
DDS_CLOG (DDS_LC_TCP, &fact->fact.gv->logconfig, "tcp cache %s %s socket %"PRIdSOCK" to %s\n", action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
sockaddr_to_string_with_port(fact, buff, sizeof(buff), &conn->m_peer_addr.a);
|
||||
GVLOG (DDS_LC_TCP, "tcp cache %s %s socket %"PRIdSOCK" to %s\n", action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
}
|
||||
|
||||
static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn)
|
||||
{
|
||||
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory;
|
||||
struct ddsi_domaingv * const gv = fact->fact.gv;
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
ddsi_tcp_node_t node;
|
||||
ddsrt_avl_dpath_t path;
|
||||
|
@ -357,8 +346,8 @@ static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn)
|
|||
node = ddsrt_avl_lookup_dpath (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, conn, &path);
|
||||
if (node)
|
||||
{
|
||||
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
|
||||
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp cache removed socket %"PRIdSOCK" to %s\n", conn->m_sock, buff);
|
||||
sockaddr_to_string_with_port(fact, buff, sizeof(buff), &conn->m_peer_addr.a);
|
||||
GVLOG (DDS_LC_TCP, "tcp cache removed socket %"PRIdSOCK" to %s\n", conn->m_sock, buff);
|
||||
ddsrt_avl_delete_dpath (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, node, &path);
|
||||
ddsi_tcp_node_free (node);
|
||||
}
|
||||
|
@ -399,7 +388,7 @@ static ddsi_tcp_conn_t ddsi_tcp_cache_find (struct ddsi_tran_factory_tcp *fact,
|
|||
}
|
||||
if (ret == NULL)
|
||||
{
|
||||
ret = ddsi_tcp_new_conn (fact, DDSRT_INVALID_SOCKET, false, (struct sockaddr *)&key.m_peer_addr);
|
||||
ret = ddsi_tcp_new_conn (fact, DDSRT_INVALID_SOCKET, false, &key.m_peer_addr.a);
|
||||
ddsi_tcp_cache_add (fact, ret, &path);
|
||||
}
|
||||
ddsrt_mutex_unlock (&fact->ddsi_tcp_cache_lock_g);
|
||||
|
@ -425,7 +414,7 @@ static ssize_t ddsi_tcp_conn_read_ssl (ddsi_tcp_conn_t tcp, void * buf, size_t l
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool ddsi_tcp_select (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t sock, bool read, size_t pos, int64_t timeout)
|
||||
static bool ddsi_tcp_select (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, bool read, size_t pos, int64_t timeout)
|
||||
{
|
||||
dds_return_t rc;
|
||||
fd_set fds;
|
||||
|
@ -443,22 +432,29 @@ static bool ddsi_tcp_select (const struct ddsrt_log_cfg *logcfg, ddsrt_socket_t
|
|||
DDSRT_WARNING_GNUC_ON(sign-conversion)
|
||||
#endif
|
||||
|
||||
DDS_CLOG (DDS_LC_TCP, logcfg, "tcp blocked %s: sock %d\n", read ? "read" : "write", (int) sock);
|
||||
GVLOG (DDS_LC_TCP, "tcp blocked %s: sock %d\n", read ? "read" : "write", (int) sock);
|
||||
do {
|
||||
rc = ddsrt_select (sock + 1, rdset, wrset, NULL, tval, &ready);
|
||||
} while (rc == DDS_RETCODE_INTERRUPTED);
|
||||
|
||||
if (rc != DDS_RETCODE_OK)
|
||||
{
|
||||
DDS_CWARNING (logcfg, "tcp abandoning %s on blocking socket %d after %"PRIuSIZE" bytes\n", read ? "read" : "write", (int) sock, pos);
|
||||
GVWARNING ("tcp abandoning %s on blocking socket %d after %"PRIuSIZE" bytes\n", read ? "read" : "write", (int) sock, pos);
|
||||
}
|
||||
|
||||
return (ready > 0);
|
||||
}
|
||||
|
||||
static int32_t addrfam_to_locator_kind (int af)
|
||||
{
|
||||
assert (af == AF_INET || af == AF_INET6);
|
||||
return (af == AF_INET) ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6;
|
||||
}
|
||||
|
||||
static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, size_t len, bool allow_spurious, nn_locator_t *srcloc)
|
||||
{
|
||||
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_factory;
|
||||
struct ddsi_domaingv const * const gv = fact->fact.gv;
|
||||
dds_return_t rc;
|
||||
ddsi_tcp_conn_t tcp = (ddsi_tcp_conn_t) conn;
|
||||
ssize_t (*rd) (ddsi_tcp_conn_t, void *, size_t, dds_return_t * err) = ddsi_tcp_conn_read_plain;
|
||||
|
@ -482,14 +478,15 @@ static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, si
|
|||
{
|
||||
if (srcloc)
|
||||
{
|
||||
ddsi_ipaddr_to_loc(&fact->fact, srcloc, (struct sockaddr *)&tcp->m_peer_addr, tcp->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
|
||||
const int32_t kind = addrfam_to_locator_kind (tcp->m_peer_addr.a.sa_family);
|
||||
ddsi_ipaddr_to_loc(&fact->fact, srcloc, &tcp->m_peer_addr.a, kind);
|
||||
}
|
||||
return (ssize_t) pos;
|
||||
}
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
DDS_CLOG (DDS_LC_TCP, &conn->m_base.gv->logconfig, "tcp read: sock %"PRIdSOCK" closed-by-peer\n", tcp->m_sock);
|
||||
GVLOG (DDS_LC_TCP, "tcp read: sock %"PRIdSOCK" closed-by-peer\n", tcp->m_sock);
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -500,13 +497,13 @@ static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, si
|
|||
{
|
||||
if (allow_spurious && pos == 0)
|
||||
return 0;
|
||||
const int64_t timeout = conn->m_base.gv->config.tcp_read_timeout;
|
||||
if (ddsi_tcp_select (&conn->m_base.gv->logconfig, tcp->m_sock, true, pos, timeout) == false)
|
||||
const int64_t timeout = gv->config.tcp_read_timeout;
|
||||
if (ddsi_tcp_select (gv, tcp->m_sock, true, pos, timeout) == false)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
DDS_CLOG (DDS_LC_TCP, &conn->m_base.gv->logconfig, "tcp read: sock %"PRIdSOCK" error %"PRId32"\n", tcp->m_sock, rc);
|
||||
GVLOG (DDS_LC_TCP, "tcp read: sock %"PRIdSOCK" error %"PRId32"\n", tcp->m_sock, rc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -542,6 +539,7 @@ static ssize_t ddsi_tcp_block_write (ssize_t (*wr) (ddsi_tcp_conn_t, const void
|
|||
{
|
||||
/* Write all bytes of buf even in the presence of signals,
|
||||
partial writes and blocking (typically write buffer full) */
|
||||
struct ddsi_domaingv const * const gv = conn->m_base.m_base.gv;
|
||||
dds_return_t rc;
|
||||
size_t pos = 0;
|
||||
ssize_t n = -1;
|
||||
|
@ -559,15 +557,15 @@ static ssize_t ddsi_tcp_block_write (ssize_t (*wr) (ddsi_tcp_conn_t, const void
|
|||
{
|
||||
if (rc == DDS_RETCODE_TRY_AGAIN)
|
||||
{
|
||||
const int64_t timeout = conn->m_base.m_base.gv->config.tcp_write_timeout;
|
||||
if (ddsi_tcp_select (&conn->m_base.m_base.gv->logconfig, conn->m_sock, false, pos, timeout) == false)
|
||||
const int64_t timeout = gv->config.tcp_write_timeout;
|
||||
if (ddsi_tcp_select (gv, conn->m_sock, false, pos, timeout) == false)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp write: sock %"PRIdSOCK" error %"PRId32"\n", conn->m_sock, rc);
|
||||
GVLOG (DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" error %"PRId32"\n", conn->m_sock, rc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -594,6 +592,7 @@ static void set_msghdr_iov (ddsrt_msghdr_t *mhdr, ddsrt_iovec_t *iov, size_t iov
|
|||
static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *dst, size_t niov, const ddsrt_iovec_t *iov, uint32_t flags)
|
||||
{
|
||||
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) base->m_factory;
|
||||
struct ddsi_domaingv const * const gv = fact->fact.gv;
|
||||
#ifdef DDSI_INCLUDE_SSL
|
||||
char msgbuf[4096]; /* stack buffer for merging smallish writes without requiring allocations */
|
||||
ddsrt_iovec_t iovec; /* iovec used for msgbuf */
|
||||
|
@ -604,13 +603,16 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
|
|||
int piecewise;
|
||||
bool connect = false;
|
||||
ddsrt_msghdr_t msg;
|
||||
struct sockaddr_storage dstaddr;
|
||||
union {
|
||||
struct sockaddr_storage x;
|
||||
union addr a;
|
||||
} dstaddr;
|
||||
assert(niov <= INT_MAX);
|
||||
ddsi_ipaddr_from_loc(&dstaddr, dst);
|
||||
ddsi_ipaddr_from_loc(&dstaddr.x, dst);
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
set_msghdr_iov (&msg, (ddsrt_iovec_t *) iov, niov);
|
||||
msg.msg_name = &dstaddr;
|
||||
msg.msg_namelen = (socklen_t) ddsrt_sockaddr_get_size((struct sockaddr *) &dstaddr);
|
||||
msg.msg_namelen = ddsrt_sockaddr_get_size(&dstaddr.a.a);
|
||||
#if DDSRT_MSGHDR_FLAGS
|
||||
msg.msg_flags = (int) flags;
|
||||
#endif
|
||||
|
@ -643,13 +645,13 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
|
|||
|
||||
if (!connect && ((flags & DDSI_TRAN_ON_CONNECT) != 0))
|
||||
{
|
||||
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp write: sock %"PRIdSOCK" message filtered\n", conn->m_sock);
|
||||
GVLOG (DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" message filtered\n", conn->m_sock);
|
||||
ddsrt_mutex_unlock (&conn->m_mutex);
|
||||
return (ssize_t) len;
|
||||
}
|
||||
|
||||
#ifdef DDSI_INCLUDE_SSL
|
||||
if (base->m_base.gv->config.ssl_enable)
|
||||
if (gv->config.ssl_enable)
|
||||
{
|
||||
/* SSL doesn't have sendmsg, ret = 0 so writing starts at first byte.
|
||||
Rumor is that it is much better to merge small writes, which do here
|
||||
|
@ -702,11 +704,11 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
|
|||
{
|
||||
case DDS_RETCODE_NO_CONNECTION:
|
||||
case DDS_RETCODE_ILLEGAL_OPERATION:
|
||||
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp write: sock %"PRIdSOCK" DDS_RETCODE_NO_CONNECTION\n", conn->m_sock);
|
||||
GVLOG (DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" DDS_RETCODE_NO_CONNECTION\n", conn->m_sock);
|
||||
break;
|
||||
default:
|
||||
if (! conn->m_base.m_closed && (conn->m_sock != DDSRT_INVALID_SOCKET))
|
||||
DDS_CWARNING (&conn->m_base.m_base.gv->logconfig, "tcp write failed on socket %"PRIdSOCK" with errno %"PRId32"\n", conn->m_sock, rc);
|
||||
GVWARNING ("tcp write failed on socket %"PRIdSOCK" with errno %"PRId32"\n", conn->m_sock, rc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -715,7 +717,7 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
|
|||
{
|
||||
if (ret == 0)
|
||||
{
|
||||
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp write: sock %"PRIdSOCK" eof\n", conn->m_sock);
|
||||
GVLOG (DDS_LC_TCP, "tcp write: sock %"PRIdSOCK" eof\n", conn->m_sock);
|
||||
}
|
||||
piecewise = (ret > 0 && (size_t) ret < len);
|
||||
}
|
||||
|
@ -783,12 +785,13 @@ static int ddsi_tcp_locator (struct ddsi_tran_factory *fact_cmn, ddsi_tran_base_
|
|||
return 0;
|
||||
}
|
||||
|
||||
static ddsi_tran_conn_t ddsi_tcp_create_conn (struct ddsi_tran_factory *fact_cmn, uint32_t port, const struct ddsi_tran_qos *qos)
|
||||
static dds_return_t ddsi_tcp_create_conn (ddsi_tran_conn_t *conn_out, struct ddsi_tran_factory *fact_cmn, uint32_t port, const struct ddsi_tran_qos *qos)
|
||||
{
|
||||
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) fact_cmn;
|
||||
(void) qos;
|
||||
(void) port;
|
||||
return &fact->ddsi_tcp_conn_client.m_base;
|
||||
*conn_out = &fact->ddsi_tcp_conn_client.m_base;
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static int ddsi_tcp_listen (ddsi_tran_listener_t listener)
|
||||
|
@ -812,10 +815,11 @@ static int ddsi_tcp_listen (ddsi_tran_listener_t listener)
|
|||
static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
|
||||
{
|
||||
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory;
|
||||
struct ddsi_domaingv const * const gv = fact->fact.gv;
|
||||
ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener;
|
||||
ddsi_tcp_conn_t tcp = NULL;
|
||||
ddsrt_socket_t sock = DDSRT_INVALID_SOCKET;
|
||||
struct sockaddr_storage addr;
|
||||
union addr addr;
|
||||
socklen_t addrlen = sizeof (addr);
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
dds_return_t rc = DDS_RETCODE_OK;
|
||||
|
@ -839,31 +843,31 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
|
|||
{
|
||||
rc = ddsrt_accept(tl->m_sock, NULL, NULL, &sock);
|
||||
}
|
||||
if (!ddsrt_atomic_ld32(&listener->m_base.gv->rtps_keepgoing))
|
||||
if (!ddsrt_atomic_ld32(&gv->rtps_keepgoing))
|
||||
{
|
||||
ddsi_tcp_sock_free (&listener->m_base.gv->logconfig, sock, NULL);
|
||||
ddsi_tcp_sock_free (gv, sock, NULL);
|
||||
return NULL;
|
||||
}
|
||||
} while (rc == DDS_RETCODE_INTERRUPTED || rc == DDS_RETCODE_TRY_AGAIN);
|
||||
|
||||
if (sock == DDSRT_INVALID_SOCKET)
|
||||
{
|
||||
(void)ddsrt_getsockname (tl->m_sock, (struct sockaddr *) &addr, &addrlen);
|
||||
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *)&addr);
|
||||
DDS_CLOG ((rc == DDS_RETCODE_OK) ? DDS_LC_ERROR : DDS_LC_FATAL, &listener->m_base.gv->logconfig, "tcp accept failed on socket %"PRIdSOCK" at %s retcode %"PRId32"\n", tl->m_sock, buff, rc);
|
||||
(void)ddsrt_getsockname (tl->m_sock, &addr.a, &addrlen);
|
||||
sockaddr_to_string_with_port(fact, buff, sizeof(buff), &addr.a);
|
||||
GVLOG ((rc == DDS_RETCODE_OK) ? DDS_LC_ERROR : DDS_LC_FATAL, "tcp accept failed on socket %"PRIdSOCK" at %s retcode %"PRId32"\n", tl->m_sock, buff, rc);
|
||||
}
|
||||
else if (getpeername (sock, (struct sockaddr *) &addr, &addrlen) == -1)
|
||||
else if (getpeername (sock, &addr.a, &addrlen) == -1)
|
||||
{
|
||||
DDS_CWARNING (&listener->m_base.gv->logconfig, "tcp accepted new socket %"PRIdSOCK" on socket %"PRIdSOCK" but no peer address, errno %"PRId32"\n", sock, tl->m_sock, rc);
|
||||
GVWARNING ("tcp accepted new socket %"PRIdSOCK" on socket %"PRIdSOCK" but no peer address, errno %"PRId32"\n", sock, tl->m_sock, rc);
|
||||
ddsrt_close (sock);
|
||||
}
|
||||
else
|
||||
{
|
||||
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *)&addr);
|
||||
DDS_CLOG (DDS_LC_TCP, &listener->m_base.gv->logconfig, "tcp accept new socket %"PRIdSOCK" on socket %"PRIdSOCK" from %s\n", sock, tl->m_sock, buff);
|
||||
sockaddr_to_string_with_port(fact, buff, sizeof(buff), &addr.a);
|
||||
GVLOG (DDS_LC_TCP, "tcp accept new socket %"PRIdSOCK" on socket %"PRIdSOCK" from %s\n", sock, tl->m_sock, buff);
|
||||
|
||||
(void)ddsrt_setsocknonblocking (sock, true);
|
||||
tcp = ddsi_tcp_new_conn (fact, sock, true, (struct sockaddr *)&addr);
|
||||
tcp = ddsi_tcp_new_conn (fact, sock, true, &addr.a);
|
||||
#ifdef DDSI_INCLUDE_SSL
|
||||
tcp->m_ssl = ssl;
|
||||
#endif
|
||||
|
@ -891,14 +895,20 @@ static ddsrt_socket_t ddsi_tcp_listener_handle (ddsi_tran_base_t base)
|
|||
caller (supporting call back over NAT).
|
||||
*/
|
||||
|
||||
static void addr_to_loc (const struct ddsi_tran_factory *fact, nn_locator_t *loc, const union addr *addr)
|
||||
{
|
||||
ddsi_ipaddr_to_loc (fact, loc, &addr->a, addrfam_to_locator_kind (addr->a.sa_family));
|
||||
}
|
||||
|
||||
static void ddsi_tcp_conn_peer_locator (ddsi_tran_conn_t conn, nn_locator_t * loc)
|
||||
{
|
||||
struct ddsi_domaingv const * const gv = conn->m_base.gv;
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
ddsi_tcp_conn_t tc = (ddsi_tcp_conn_t) conn;
|
||||
assert (tc->m_sock != DDSRT_INVALID_SOCKET);
|
||||
ddsi_ipaddr_to_loc (conn->m_factory, loc, (struct sockaddr *)&tc->m_peer_addr, tc->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
|
||||
addr_to_loc (conn->m_factory, loc, &tc->m_peer_addr);
|
||||
ddsi_locator_to_string(buff, sizeof(buff), loc);
|
||||
DDS_CLOG (DDS_LC_TCP, &conn->m_base.gv->logconfig, "(tcp EP:%s)", buff);
|
||||
GVLOG (DDS_LC_TCP, "(tcp EP:%s)", buff);
|
||||
}
|
||||
|
||||
static void ddsi_tcp_base_init (const struct ddsi_tran_factory_tcp *fact, struct ddsi_tran_conn *base)
|
||||
|
@ -915,7 +925,7 @@ static void ddsi_tcp_base_init (const struct ddsi_tran_factory_tcp *fact, struct
|
|||
|
||||
static ddsi_tcp_conn_t ddsi_tcp_new_conn (struct ddsi_tran_factory_tcp *fact, ddsrt_socket_t sock, bool server, struct sockaddr * peer)
|
||||
{
|
||||
ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) ddsrt_malloc (sizeof (*conn));
|
||||
ddsi_tcp_conn_t conn = ddsrt_malloc (sizeof (*conn));
|
||||
|
||||
memset (conn, 0, sizeof (*conn));
|
||||
ddsi_tcp_base_init (fact, &conn->m_base);
|
||||
|
@ -930,19 +940,30 @@ static ddsi_tcp_conn_t ddsi_tcp_new_conn (struct ddsi_tran_factory_tcp *fact, dd
|
|||
return conn;
|
||||
}
|
||||
|
||||
static ddsi_tran_listener_t ddsi_tcp_create_listener (ddsi_tran_factory_t fact, uint32_t port, const struct ddsi_tran_qos *qos)
|
||||
static dds_return_t ddsi_tcp_create_listener (ddsi_tran_listener_t *listener_out, ddsi_tran_factory_t fact, uint32_t port, const struct ddsi_tran_qos *qos)
|
||||
{
|
||||
struct ddsi_tran_factory_tcp * const fact_tcp = (struct ddsi_tran_factory_tcp *) fact;
|
||||
struct ddsi_domaingv * const gv = fact_tcp->fact.gv;
|
||||
struct ddsi_domaingv const * const gv = fact_tcp->fact.gv;
|
||||
ddsrt_socket_t sock;
|
||||
|
||||
(void) qos;
|
||||
|
||||
if (ddsi_tcp_sock_new (fact_tcp, &sock, (unsigned short) port) != DDS_RETCODE_OK)
|
||||
return NULL;
|
||||
if (ddsi_tcp_sock_new (fact_tcp, &sock, (uint16_t) port) != DDS_RETCODE_OK)
|
||||
return DDS_RETCODE_ERROR;
|
||||
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
union addr addr;
|
||||
socklen_t addrlen = sizeof (addr);
|
||||
dds_return_t ret;
|
||||
ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) ddsrt_malloc (sizeof (*tl));
|
||||
if ((ret = ddsrt_getsockname (sock, &addr.a, &addrlen)) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_tcp_create_listener: ddsrt_getsockname returned %"PRId32"\n", ret);
|
||||
ddsi_tcp_sock_free (gv, sock, NULL);
|
||||
return DDS_RETCODE_ERROR;
|
||||
}
|
||||
sockaddr_to_string_with_port (fact_tcp, buff, sizeof (buff), &addr.a);
|
||||
GVLOG (DDS_LC_TCP, "tcp create listener socket %"PRIdSOCK" on %s\n", sock, buff);
|
||||
|
||||
ddsi_tcp_listener_t tl = ddsrt_malloc (sizeof (*tl));
|
||||
memset (tl, 0, sizeof (*tl));
|
||||
|
||||
tl->m_sock = sock;
|
||||
|
@ -952,33 +973,21 @@ static ddsi_tran_listener_t ddsi_tcp_create_listener (ddsi_tran_factory_t fact,
|
|||
tl->m_base.m_accept_fn = ddsi_tcp_accept;
|
||||
tl->m_base.m_factory = fact;
|
||||
|
||||
tl->m_base.m_base.m_port = get_socket_port (&fact->gv->logconfig, sock);
|
||||
tl->m_base.m_base.m_port = get_socket_port (gv, sock);
|
||||
tl->m_base.m_base.m_trantype = DDSI_TRAN_LISTENER;
|
||||
tl->m_base.m_base.m_handle_fn = ddsi_tcp_listener_handle;
|
||||
tl->m_base.m_locator_fn = ddsi_tcp_locator;
|
||||
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen = sizeof (addr);
|
||||
if ((ret = ddsrt_getsockname (sock, (struct sockaddr *) &addr, &addrlen)) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_tcp_create_listener: ddsrt_getsockname returned %"PRId32"\n", ret);
|
||||
ddsi_tcp_sock_free (&fact->gv->logconfig, sock, NULL);
|
||||
ddsrt_free (tl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
sockaddr_to_string_with_port (fact_tcp, buff, sizeof (buff), (struct sockaddr *) &addr);
|
||||
GVLOG (DDS_LC_TCP, "tcp create listener socket %"PRIdSOCK" on %s\n", sock, buff);
|
||||
return &tl->m_base;
|
||||
*listener_out = &tl->m_base;
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
|
||||
{
|
||||
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) conn->m_base.m_factory;
|
||||
struct ddsi_domaingv const * const gv = fact->fact.gv;
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
sockaddr_to_string_with_port(fact, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
|
||||
DDS_CLOG (DDS_LC_TCP, &conn->m_base.m_base.gv->logconfig, "tcp free %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
sockaddr_to_string_with_port(fact, buff, sizeof(buff), &conn->m_peer_addr.a);
|
||||
GVLOG (DDS_LC_TCP, "tcp free %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
|
||||
#ifdef DDSI_INCLUDE_SSL
|
||||
if (fact->ddsi_tcp_ssl_plugin.ssl_free)
|
||||
|
@ -988,7 +997,7 @@ static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
ddsi_tcp_sock_free (&conn->m_base.m_base.gv->logconfig, conn->m_sock, "connection");
|
||||
ddsi_tcp_sock_free (gv, conn->m_sock, "connection");
|
||||
}
|
||||
ddsrt_mutex_destroy (&conn->m_mutex);
|
||||
ddsrt_free (conn);
|
||||
|
@ -997,17 +1006,18 @@ static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
|
|||
static void ddsi_tcp_close_conn (ddsi_tran_conn_t tc)
|
||||
{
|
||||
struct ddsi_tran_factory_tcp * const fact_tcp = (struct ddsi_tran_factory_tcp *) tc->m_factory;
|
||||
struct ddsi_domaingv * const gv = fact_tcp->fact.gv;
|
||||
if (tc != &fact_tcp->ddsi_tcp_conn_client.m_base)
|
||||
{
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
nn_locator_t loc;
|
||||
ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) tc;
|
||||
sockaddr_to_string_with_port(fact_tcp, buff, sizeof(buff), (struct sockaddr *)&conn->m_peer_addr);
|
||||
DDS_CLOG (DDS_LC_TCP, &tc->m_base.gv->logconfig, "tcp close %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
sockaddr_to_string_with_port(fact_tcp, buff, sizeof(buff), &conn->m_peer_addr.a);
|
||||
GVLOG (DDS_LC_TCP, "tcp close %s connnection on socket %"PRIdSOCK" to %s\n", conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
(void) shutdown (conn->m_sock, 2);
|
||||
ddsi_ipaddr_to_loc(&fact_tcp->fact, &loc, (struct 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(&fact_tcp->fact, &loc, &conn->m_peer_addr.a, addrfam_to_locator_kind(conn->m_peer_addr.a.sa_family));
|
||||
loc.port = conn->m_peer_port;
|
||||
purge_proxy_participants (conn->m_base.m_base.gv, &loc, conn->m_base.m_server);
|
||||
purge_proxy_participants (gv, &loc, conn->m_base.m_server);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1023,7 +1033,7 @@ static void ddsi_tcp_release_conn (ddsi_tran_conn_t conn)
|
|||
static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener)
|
||||
{
|
||||
struct ddsi_tran_factory_tcp * const fact_tcp = (struct ddsi_tran_factory_tcp *) listener->m_factory;
|
||||
struct ddsi_domaingv * const gv = fact_tcp->fact.gv;
|
||||
struct ddsi_domaingv const * const gv = fact_tcp->fact.gv;
|
||||
ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener;
|
||||
ddsrt_socket_t sock;
|
||||
dds_return_t ret;
|
||||
|
@ -1032,44 +1042,40 @@ static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener)
|
|||
if (ddsi_tcp_sock_new (fact_tcp, &sock, 0) != DDS_RETCODE_OK)
|
||||
goto fail;
|
||||
|
||||
struct sockaddr_storage addr;
|
||||
union addr addr;
|
||||
socklen_t addrlen = sizeof (addr);
|
||||
if ((ret = ddsrt_getsockname (tl->m_sock, (struct sockaddr *) &addr, &addrlen)) != DDS_RETCODE_OK)
|
||||
if ((ret = ddsrt_getsockname (tl->m_sock, &addr.a, &addrlen)) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVWARNING ("tcp failed to get listener address error %"PRId32"\n", ret);
|
||||
goto fail_w_socket;
|
||||
}
|
||||
switch (addr.ss_family)
|
||||
switch (addr.a.sa_family)
|
||||
{
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *socketname = (struct sockaddr_in *) &addr;
|
||||
if (socketname->sin_addr.s_addr == htonl (INADDR_ANY))
|
||||
socketname->sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||
case AF_INET:
|
||||
if (addr.a4.sin_addr.s_addr == htonl (INADDR_ANY))
|
||||
addr.a4.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||
break;
|
||||
}
|
||||
#if DDSRT_HAVE_IPV6
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *socketname = (struct sockaddr_in6 *) &addr;
|
||||
if (memcmp (&socketname->sin6_addr, &ddsrt_in6addr_any, sizeof (socketname->sin6_addr)) == 0)
|
||||
socketname->sin6_addr = ddsrt_in6addr_loopback;
|
||||
case AF_INET6:
|
||||
if (memcmp (&addr.a6.sin6_addr, &ddsrt_in6addr_any, sizeof (addr.a6.sin6_addr)) == 0)
|
||||
addr.a6.sin6_addr = ddsrt_in6addr_loopback;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
do {
|
||||
ret = ddsrt_connect (sock, (struct sockaddr *) &addr, ddsrt_sockaddr_get_size ((struct sockaddr *) &addr));
|
||||
ret = ddsrt_connect (sock, &addr.a, ddsrt_sockaddr_get_size (&addr.a));
|
||||
} while (ret == DDS_RETCODE_INTERRUPTED);
|
||||
if (ret != DDS_RETCODE_OK)
|
||||
{
|
||||
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory;
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
sockaddr_to_string_with_port (fact, buff, sizeof (buff), (struct sockaddr *) &addr);
|
||||
sockaddr_to_string_with_port (fact, buff, sizeof (buff), &addr.a);
|
||||
GVWARNING ("tcp failed to connect to own listener (%s) error %"PRId32"\n", buff, ret);
|
||||
}
|
||||
|
||||
fail_w_socket:
|
||||
ddsi_tcp_sock_free (&listener->m_base.gv->logconfig, sock, NULL);
|
||||
ddsi_tcp_sock_free (gv, sock, NULL);
|
||||
fail:
|
||||
return;
|
||||
}
|
||||
|
@ -1077,6 +1083,7 @@ fail:
|
|||
static void ddsi_tcp_release_listener (ddsi_tran_listener_t listener)
|
||||
{
|
||||
ddsi_tcp_listener_t tl = (ddsi_tcp_listener_t) listener;
|
||||
struct ddsi_domaingv const * const gv = tl->m_base.m_base.gv;
|
||||
#ifdef DDSI_INCLUDE_SSL
|
||||
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) listener->m_factory;
|
||||
if (fact->ddsi_tcp_ssl_plugin.bio_vfree)
|
||||
|
@ -1084,13 +1091,14 @@ static void ddsi_tcp_release_listener (ddsi_tran_listener_t listener)
|
|||
(fact->ddsi_tcp_ssl_plugin.bio_vfree) (tl->m_bio);
|
||||
}
|
||||
#endif
|
||||
ddsi_tcp_sock_free (&listener->m_base.gv->logconfig, tl->m_sock, "listener");
|
||||
ddsi_tcp_sock_free (gv, tl->m_sock, "listener");
|
||||
ddsrt_free (tl);
|
||||
}
|
||||
|
||||
static void ddsi_tcp_release_factory (struct ddsi_tran_factory *fact_cmn)
|
||||
{
|
||||
struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) fact_cmn;
|
||||
struct ddsi_domaingv const * const gv = fact->fact.gv;
|
||||
ddsrt_avl_free (&ddsi_tcp_treedef, &fact->ddsi_tcp_cache_g, ddsi_tcp_node_free);
|
||||
ddsrt_mutex_destroy (&fact->ddsi_tcp_cache_lock_g);
|
||||
#ifdef DDSI_INCLUDE_SSL
|
||||
|
@ -1099,7 +1107,7 @@ static void ddsi_tcp_release_factory (struct ddsi_tran_factory *fact_cmn)
|
|||
(fact->ddsi_tcp_ssl_plugin.fini) ();
|
||||
}
|
||||
#endif
|
||||
DDS_CLOG (DDS_LC_CONFIG, &fact_cmn->gv->logconfig, "tcp de-initialized\n");
|
||||
GVLOG (DDS_LC_CONFIG, "tcp de-initialized\n");
|
||||
ddsrt_free (fact);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,13 +24,13 @@
|
|||
|
||||
extern inline uint32_t ddsi_conn_type (ddsi_tran_conn_t conn);
|
||||
extern inline uint32_t ddsi_conn_port (ddsi_tran_conn_t conn);
|
||||
extern inline ddsi_tran_listener_t ddsi_factory_create_listener (ddsi_tran_factory_t factory, uint32_t port, const struct ddsi_tran_qos *qos);
|
||||
extern inline dds_return_t ddsi_factory_create_listener (ddsi_tran_listener_t *listener, ddsi_tran_factory_t factory, uint32_t port, const struct ddsi_tran_qos *qos);
|
||||
extern inline bool ddsi_factory_supports (const struct ddsi_tran_factory *factory, int32_t kind);
|
||||
extern inline int ddsi_is_valid_port (ddsi_tran_factory_t factory, uint32_t port);
|
||||
extern inline ddsrt_socket_t ddsi_conn_handle (ddsi_tran_conn_t conn);
|
||||
extern inline int ddsi_conn_locator (ddsi_tran_conn_t conn, nn_locator_t * loc);
|
||||
extern inline ddsrt_socket_t ddsi_tran_handle (ddsi_tran_base_t base);
|
||||
extern inline ddsi_tran_conn_t ddsi_factory_create_conn (ddsi_tran_factory_t factory, uint32_t port, const struct ddsi_tran_qos *qos);
|
||||
extern inline dds_return_t ddsi_factory_create_conn (ddsi_tran_conn_t *conn, ddsi_tran_factory_t factory, uint32_t port, const struct ddsi_tran_qos *qos);
|
||||
extern inline int ddsi_listener_locator (ddsi_tran_listener_t listener, nn_locator_t * loc);
|
||||
extern inline int ddsi_listener_listen (ddsi_tran_listener_t listener);
|
||||
extern inline ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener);
|
||||
|
|
|
@ -26,6 +26,13 @@
|
|||
#include "dds/ddsi/q_pcap.h"
|
||||
#include "dds/ddsi/ddsi_domaingv.h"
|
||||
|
||||
union addr {
|
||||
struct sockaddr_storage x;
|
||||
struct sockaddr a;
|
||||
struct sockaddr_in a4;
|
||||
struct sockaddr_in6 a6;
|
||||
};
|
||||
|
||||
typedef struct ddsi_udp_conn {
|
||||
struct ddsi_tran_conn m_base;
|
||||
ddsrt_socket_t m_sock;
|
||||
|
@ -35,20 +42,27 @@ typedef struct ddsi_udp_conn {
|
|||
int m_diffserv;
|
||||
} *ddsi_udp_conn_t;
|
||||
|
||||
static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, size_t len, bool allow_spurious, nn_locator_t *srcloc)
|
||||
static void addr_to_loc (const struct ddsi_tran_factory *tran, nn_locator_t *dst, const union addr *src)
|
||||
{
|
||||
ddsi_ipaddr_to_loc (tran, dst, &src->a, (src->a.sa_family == AF_INET) ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
|
||||
}
|
||||
|
||||
static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn_cmn, unsigned char * buf, size_t len, bool allow_spurious, nn_locator_t *srcloc)
|
||||
{
|
||||
ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
|
||||
struct ddsi_domaingv * const gv = conn->m_base.m_base.gv;
|
||||
dds_return_t rc;
|
||||
ssize_t ret = 0;
|
||||
ddsrt_msghdr_t msghdr;
|
||||
struct sockaddr_storage src;
|
||||
union addr src;
|
||||
ddsrt_iovec_t msg_iov;
|
||||
socklen_t srclen = (socklen_t) sizeof (src);
|
||||
(void) allow_spurious;
|
||||
|
||||
msg_iov.iov_base = (void*) buf;
|
||||
msg_iov.iov_len = (ddsrt_iov_len_t)len; /* Windows uses unsigned, POSIX (except Linux) int */
|
||||
msg_iov.iov_base = (void *) buf;
|
||||
msg_iov.iov_len = (ddsrt_iov_len_t) len; /* Windows uses unsigned, POSIX (except Linux) int */
|
||||
|
||||
msghdr.msg_name = &src;
|
||||
msghdr.msg_name = &src.x;
|
||||
msghdr.msg_namelen = srclen;
|
||||
msghdr.msg_iov = &msg_iov;
|
||||
msghdr.msg_iovlen = 1;
|
||||
|
@ -61,65 +75,67 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
|
|||
#endif
|
||||
|
||||
do {
|
||||
rc = ddsrt_recvmsg(((ddsi_udp_conn_t) conn)->m_sock, &msghdr, 0, &ret);
|
||||
rc = ddsrt_recvmsg (conn->m_sock, &msghdr, 0, &ret);
|
||||
} while (rc == DDS_RETCODE_INTERRUPTED);
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
if (srcloc)
|
||||
ddsi_ipaddr_to_loc(conn->m_factory, srcloc, (struct sockaddr *)&src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
|
||||
addr_to_loc (conn->m_base.m_factory, srcloc, &src);
|
||||
|
||||
if(conn->m_base.gv->pcap_fp)
|
||||
if (gv->pcap_fp)
|
||||
{
|
||||
struct sockaddr_storage dest;
|
||||
union addr dest;
|
||||
socklen_t dest_len = sizeof (dest);
|
||||
if (ddsrt_getsockname (((ddsi_udp_conn_t) conn)->m_sock, (struct sockaddr *) &dest, &dest_len) != DDS_RETCODE_OK)
|
||||
memset(&dest, 0, sizeof(dest));
|
||||
write_pcap_received(conn->m_base.gv, ddsrt_time_wallclock(), &src, &dest, buf, (size_t) ret);
|
||||
if (ddsrt_getsockname (conn->m_sock, &dest.a, &dest_len) != DDS_RETCODE_OK)
|
||||
memset (&dest, 0, sizeof (dest));
|
||||
write_pcap_received (gv, ddsrt_time_wallclock (), &src.x, &dest.x, buf, (size_t) ret);
|
||||
}
|
||||
|
||||
/* Check for udp packet truncation */
|
||||
if ((((size_t) ret) > len)
|
||||
#if DDSRT_MSGHDR_FLAGS
|
||||
|| (msghdr.msg_flags & MSG_TRUNC)
|
||||
const bool trunc_flag = (msghdr.msg_flags & MSG_TRUNC) != 0;
|
||||
#else
|
||||
const bool trunc_flag = false;
|
||||
#endif
|
||||
)
|
||||
if ((size_t) ret > len || trunc_flag)
|
||||
{
|
||||
char addrbuf[DDSI_LOCSTRLEN];
|
||||
nn_locator_t tmp;
|
||||
ddsi_ipaddr_to_loc(conn->m_factory, &tmp, (struct sockaddr *)&src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
|
||||
ddsi_locator_to_string(addrbuf, sizeof(addrbuf), &tmp);
|
||||
DDS_CWARNING(&conn->m_base.gv->logconfig, "%s => %d truncated to %d\n", addrbuf, (int)ret, (int)len);
|
||||
addr_to_loc (conn->m_base.m_factory, &tmp, &src);
|
||||
ddsi_locator_to_string (addrbuf, sizeof (addrbuf), &tmp);
|
||||
GVWARNING ("%s => %d truncated to %d\n", addrbuf, (int) ret, (int) len);
|
||||
}
|
||||
}
|
||||
else if (rc != DDS_RETCODE_BAD_PARAMETER &&
|
||||
rc != DDS_RETCODE_NO_CONNECTION)
|
||||
else if (rc != DDS_RETCODE_BAD_PARAMETER && rc != DDS_RETCODE_NO_CONNECTION)
|
||||
{
|
||||
DDS_CERROR(&conn->m_base.gv->logconfig, "UDP recvmsg sock %d: ret %d retcode %"PRId32"\n", (int) ((ddsi_udp_conn_t) conn)->m_sock, (int) ret, rc);
|
||||
GVERROR ("UDP recvmsg sock %d: ret %d retcode %"PRId32"\n", (int) conn->m_sock, (int) ret, rc);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void set_msghdr_iov (ddsrt_msghdr_t *mhdr, ddsrt_iovec_t *iov, size_t iovlen)
|
||||
static void set_msghdr_iov (ddsrt_msghdr_t *mhdr, const ddsrt_iovec_t *iov, size_t iovlen)
|
||||
{
|
||||
mhdr->msg_iov = iov;
|
||||
mhdr->msg_iovlen = (ddsrt_msg_iovlen_t)iovlen;
|
||||
mhdr->msg_iov = (ddsrt_iovec_t *) iov;
|
||||
mhdr->msg_iovlen = (ddsrt_msg_iovlen_t) iovlen;
|
||||
}
|
||||
|
||||
static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *dst, size_t niov, const ddsrt_iovec_t *iov, uint32_t flags)
|
||||
static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn_cmn, const nn_locator_t *dst, size_t niov, const ddsrt_iovec_t *iov, uint32_t flags)
|
||||
{
|
||||
ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
|
||||
struct ddsi_domaingv * const gv = conn->m_base.m_base.gv;
|
||||
dds_return_t rc;
|
||||
ssize_t ret = -1;
|
||||
unsigned retry = 2;
|
||||
int sendflags = 0;
|
||||
ddsrt_msghdr_t msg;
|
||||
struct sockaddr_storage dstaddr;
|
||||
assert(niov <= INT_MAX);
|
||||
ddsi_ipaddr_from_loc(&dstaddr, dst);
|
||||
set_msghdr_iov (&msg, (ddsrt_iovec_t *) iov, niov);
|
||||
msg.msg_name = &dstaddr;
|
||||
msg.msg_namelen = (socklen_t) ddsrt_sockaddr_get_size((struct sockaddr *) &dstaddr);
|
||||
union addr dstaddr;
|
||||
assert (niov <= INT_MAX);
|
||||
ddsi_ipaddr_from_loc (&dstaddr.x, dst);
|
||||
set_msghdr_iov (&msg, iov, niov);
|
||||
msg.msg_name = &dstaddr.x;
|
||||
msg.msg_namelen = (socklen_t) ddsrt_sockaddr_get_size (&dstaddr.a);
|
||||
#if defined(__sun) && !defined(_XPG4_2)
|
||||
msg.msg_accrights = NULL;
|
||||
msg.msg_accrightslen = 0;
|
||||
|
@ -130,56 +146,53 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *d
|
|||
#if DDSRT_MSGHDR_FLAGS
|
||||
msg.msg_flags = (int) flags;
|
||||
#else
|
||||
DDSRT_UNUSED_ARG(flags);
|
||||
DDSRT_UNUSED_ARG (flags);
|
||||
#endif
|
||||
#if MSG_NOSIGNAL && !LWIP_SOCKET
|
||||
sendflags |= MSG_NOSIGNAL;
|
||||
#endif
|
||||
do {
|
||||
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) conn;
|
||||
rc = ddsrt_sendmsg (uc->m_sock, &msg, sendflags, &ret);
|
||||
rc = ddsrt_sendmsg (conn->m_sock, &msg, sendflags, &ret);
|
||||
#if defined _WIN32 && !defined WINCE
|
||||
if (rc == DDS_RETCODE_TRY_AGAIN) {
|
||||
if (rc == DDS_RETCODE_TRY_AGAIN)
|
||||
{
|
||||
WSANETWORKEVENTS ev;
|
||||
WaitForSingleObject(uc->m_sockEvent, INFINITE);
|
||||
WSAEnumNetworkEvents(uc->m_sock, uc->m_sockEvent, &ev);
|
||||
WaitForSingleObject (conn->m_sockEvent, INFINITE);
|
||||
WSAEnumNetworkEvents (conn->m_sock, conn->m_sockEvent, &ev);
|
||||
}
|
||||
#endif
|
||||
} while ((rc == DDS_RETCODE_INTERRUPTED) ||
|
||||
(rc == DDS_RETCODE_TRY_AGAIN) ||
|
||||
(rc == DDS_RETCODE_NOT_ALLOWED && retry-- > 0));
|
||||
if (ret > 0 && conn->m_base.gv->pcap_fp)
|
||||
} while (rc == DDS_RETCODE_INTERRUPTED || rc == DDS_RETCODE_TRY_AGAIN || (rc == DDS_RETCODE_NOT_ALLOWED && retry-- > 0));
|
||||
if (ret > 0 && gv->pcap_fp)
|
||||
{
|
||||
struct sockaddr_storage sa;
|
||||
union addr sa;
|
||||
socklen_t alen = sizeof (sa);
|
||||
if (ddsrt_getsockname (((ddsi_udp_conn_t) conn)->m_sock, (struct sockaddr *) &sa, &alen) != DDS_RETCODE_OK)
|
||||
if (ddsrt_getsockname (conn->m_sock, &sa.a, &alen) != DDS_RETCODE_OK)
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
write_pcap_sent (conn->m_base.gv, ddsrt_time_wallclock (), &sa, &msg, (size_t) ret);
|
||||
write_pcap_sent (gv, ddsrt_time_wallclock (), &sa.x, &msg, (size_t) ret);
|
||||
}
|
||||
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)
|
||||
{
|
||||
DDS_CERROR(&conn->m_base.gv->logconfig, "ddsi_udp_conn_write failed with retcode %"PRId32"\n", rc);
|
||||
GVERROR ("ddsi_udp_conn_write failed with retcode %"PRId32"\n", rc);
|
||||
}
|
||||
return (rc == DDS_RETCODE_OK ? ret : -1);
|
||||
return (rc == DDS_RETCODE_OK) ? ret : -1;
|
||||
}
|
||||
|
||||
static void ddsi_udp_disable_multiplexing (ddsi_tran_conn_t base)
|
||||
static void ddsi_udp_disable_multiplexing (ddsi_tran_conn_t conn_cmn)
|
||||
{
|
||||
#if defined _WIN32 && !defined WINCE
|
||||
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) base;
|
||||
ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
|
||||
uint32_t zero = 0, dummy;
|
||||
WSAEventSelect(uc->m_sock, 0, 0);
|
||||
WSAIoctl(uc->m_sock, FIONBIO, &zero,sizeof(zero), NULL,0, &dummy, NULL,NULL);
|
||||
WSAEventSelect (conn->m_sock, 0, 0);
|
||||
WSAIoctl (conn->m_sock, FIONBIO, &zero,sizeof(zero), NULL,0, &dummy, NULL,NULL);
|
||||
#else
|
||||
(void)base;
|
||||
(void) conn_cmn;
|
||||
#endif
|
||||
}
|
||||
|
||||
static ddsrt_socket_t ddsi_udp_conn_handle (ddsi_tran_base_t base)
|
||||
static ddsrt_socket_t ddsi_udp_conn_handle (ddsi_tran_base_t conn_cmn)
|
||||
{
|
||||
return ((ddsi_udp_conn_t) base)->m_sock;
|
||||
ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
|
||||
return conn->m_sock;
|
||||
}
|
||||
|
||||
static bool ddsi_udp_supports (const struct ddsi_tran_factory *fact, int32_t kind)
|
||||
|
@ -187,162 +200,171 @@ static bool ddsi_udp_supports (const struct ddsi_tran_factory *fact, int32_t kin
|
|||
return kind == fact->m_kind || (kind == NN_LOCATOR_KIND_UDPv4MCGEN && fact->m_kind == NN_LOCATOR_KIND_UDPv4);
|
||||
}
|
||||
|
||||
static int ddsi_udp_conn_locator (ddsi_tran_factory_t fact, ddsi_tran_base_t base, nn_locator_t *loc)
|
||||
static int ddsi_udp_conn_locator (ddsi_tran_factory_t fact, ddsi_tran_base_t conn_cmn, nn_locator_t *loc)
|
||||
{
|
||||
ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
|
||||
int ret = -1;
|
||||
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) base;
|
||||
if (uc->m_sock != DDSRT_INVALID_SOCKET)
|
||||
if (conn->m_sock != DDSRT_INVALID_SOCKET)
|
||||
{
|
||||
loc->kind = fact->m_kind;
|
||||
loc->port = uc->m_base.m_base.m_port;
|
||||
memcpy(loc->address, uc->m_base.m_base.gv->extloc.address, sizeof (loc->address));
|
||||
loc->port = conn->m_base.m_base.m_port;
|
||||
memcpy (loc->address, conn->m_base.m_base.gv->extloc.address, sizeof (loc->address));
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint16_t get_socket_port (struct ddsi_domaingv * const gv, ddsrt_socket_t sock)
|
||||
static uint16_t get_socket_port (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock)
|
||||
{
|
||||
dds_return_t ret;
|
||||
struct sockaddr_storage addr;
|
||||
union addr addr;
|
||||
socklen_t addrlen = sizeof (addr);
|
||||
|
||||
ret = ddsrt_getsockname (sock, (struct sockaddr *)&addr, &addrlen);
|
||||
ret = ddsrt_getsockname (sock, &addr.a, &addrlen);
|
||||
if (ret != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_udp_get_socket_port: getsockname returned %"PRId32"\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ddsrt_sockaddr_get_port ((struct sockaddr *)&addr);
|
||||
return ddsrt_sockaddr_get_port (&addr.a);
|
||||
}
|
||||
|
||||
static dds_return_t set_dont_route (struct ddsi_domaingv * const gv, ddsrt_socket_t socket, bool ipv6)
|
||||
static dds_return_t set_dont_route (struct ddsi_domaingv const * const gv, ddsrt_socket_t socket, bool ipv6)
|
||||
{
|
||||
dds_return_t rc;
|
||||
#if DDSRT_HAVE_IPV6
|
||||
if (ipv6)
|
||||
{
|
||||
const unsigned ipv6Flag = 1;
|
||||
if ((rc = ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ipv6Flag, sizeof (ipv6Flag))) != DDS_RETCODE_OK)
|
||||
const unsigned uone = 1;
|
||||
if ((rc = ddsrt_setsockopt (socket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &uone, sizeof (uone))) != DDS_RETCODE_OK)
|
||||
GVERROR ("ddsi_udp_create_conn: set IPV6_UNICAST_HOPS = 1 failed: %s\n", dds_strretcode (rc));
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
(void) ipv6;
|
||||
#endif
|
||||
const int one = 1;
|
||||
if ((rc = ddsrt_setsockopt (socket, SOL_SOCKET, SO_DONTROUTE, (char *) &one, sizeof (one))) != DDS_RETCODE_OK)
|
||||
if ((rc = ddsrt_setsockopt (socket, SOL_SOCKET, SO_DONTROUTE, &one, sizeof (one))) != DDS_RETCODE_OK)
|
||||
GVERROR ("ddsi_udp_create_conn: set SO_DONTROUTE = 1 failed: %s\n", dds_strretcode (rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
static dds_return_t set_rcvbuf (struct ddsi_domaingv * const gv, ddsrt_socket_t sock, const struct config_maybe_uint32 *min_size)
|
||||
static dds_return_t set_rcvbuf (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, const struct config_maybe_uint32 *min_size)
|
||||
{
|
||||
uint32_t ReceiveBufferSize;
|
||||
socklen_t optlen = (socklen_t) sizeof (ReceiveBufferSize);
|
||||
uint32_t size;
|
||||
socklen_t optlen = (socklen_t) sizeof (size);
|
||||
uint32_t socket_min_rcvbuf_size;
|
||||
dds_return_t rc;
|
||||
|
||||
if (min_size->isdefault)
|
||||
socket_min_rcvbuf_size = 1048576;
|
||||
else
|
||||
socket_min_rcvbuf_size = min_size->value;
|
||||
rc = ddsrt_getsockopt (sock, SOL_SOCKET, SO_RCVBUF, (char *) &ReceiveBufferSize, &optlen);
|
||||
socket_min_rcvbuf_size = min_size->isdefault ? 1048576 : min_size->value;
|
||||
rc = ddsrt_getsockopt (sock, SOL_SOCKET, SO_RCVBUF, &size, &optlen);
|
||||
if (rc == DDS_RETCODE_BAD_PARAMETER)
|
||||
{
|
||||
/* not all stacks support getting/setting RCVBUF */
|
||||
GVLOG (DDS_LC_CONFIG, "cannot retrieve socket receive buffer size\n");
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
if (rc != DDS_RETCODE_OK)
|
||||
else if (rc != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_udp_create_conn: get SO_RCVBUF failed: %s\n", dds_strretcode (rc));
|
||||
goto fail;
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ReceiveBufferSize < socket_min_rcvbuf_size)
|
||||
if (size < socket_min_rcvbuf_size)
|
||||
{
|
||||
/* make sure the receive buffersize is at least the minimum required */
|
||||
ReceiveBufferSize = socket_min_rcvbuf_size;
|
||||
(void) ddsrt_setsockopt (sock, SOL_SOCKET, SO_RCVBUF, (const char *) &ReceiveBufferSize, sizeof (ReceiveBufferSize));
|
||||
size = socket_min_rcvbuf_size;
|
||||
(void) ddsrt_setsockopt (sock, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size));
|
||||
|
||||
/* We don't check the return code from setsockopt, because some O/Ss tend
|
||||
to silently cap the buffer size. The only way to make sure is to read
|
||||
the option value back and check it is now set correctly. */
|
||||
if ((rc = ddsrt_getsockopt (sock, SOL_SOCKET, SO_RCVBUF, (char *) &ReceiveBufferSize, &optlen)) != DDS_RETCODE_OK)
|
||||
if ((rc = ddsrt_getsockopt (sock, SOL_SOCKET, SO_RCVBUF, &size, &optlen)) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_udp_create_conn: get SO_RCVBUF failed: %s\n", dds_strretcode (rc));
|
||||
goto fail;
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ReceiveBufferSize >= socket_min_rcvbuf_size)
|
||||
GVLOG (DDS_LC_CONFIG, "socket receive buffer size set to %"PRIu32" bytes\n", ReceiveBufferSize);
|
||||
if (size >= socket_min_rcvbuf_size)
|
||||
GVLOG (DDS_LC_CONFIG, "socket receive buffer size set to %"PRIu32" bytes\n", size);
|
||||
else if (min_size->isdefault)
|
||||
GVLOG (DDS_LC_CONFIG,
|
||||
"failed to increase socket receive buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n",
|
||||
socket_min_rcvbuf_size, size);
|
||||
else
|
||||
GVLOG (min_size->isdefault ? DDS_LC_CONFIG : DDS_LC_ERROR,
|
||||
"failed to increase socket receive buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n",
|
||||
socket_min_rcvbuf_size, ReceiveBufferSize);
|
||||
{
|
||||
/* If the configuration states it must be >= X, then error out if the
|
||||
kernel doesn't give us at least X */
|
||||
GVLOG (DDS_LC_CONFIG | DDS_LC_ERROR,
|
||||
"failed to increase socket receive buffer size to %"PRIu32" bytes, maximum is %"PRIu32" bytes\n",
|
||||
socket_min_rcvbuf_size, size);
|
||||
rc = DDS_RETCODE_NOT_ENOUGH_SPACE;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static dds_return_t set_sndbuf (struct ddsi_domaingv * const gv, ddsrt_socket_t sock, uint32_t min_size)
|
||||
static dds_return_t set_sndbuf (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, uint32_t min_size)
|
||||
{
|
||||
unsigned SendBufferSize;
|
||||
socklen_t optlen = (socklen_t) sizeof(SendBufferSize);
|
||||
unsigned size;
|
||||
socklen_t optlen = (socklen_t) sizeof(size);
|
||||
dds_return_t rc;
|
||||
|
||||
rc = ddsrt_getsockopt(sock, SOL_SOCKET, SO_SNDBUF,(char *)&SendBufferSize, &optlen);
|
||||
rc = ddsrt_getsockopt (sock, SOL_SOCKET, SO_SNDBUF, &size, &optlen);
|
||||
if (rc == DDS_RETCODE_BAD_PARAMETER)
|
||||
{
|
||||
/* not all stacks support getting/setting SNDBUF */
|
||||
GVLOG (DDS_LC_CONFIG, "cannot retrieve socket send buffer size\n");
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
if (rc != DDS_RETCODE_OK)
|
||||
else if (rc != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_udp_create_conn: get SO_SNDBUF failed: %s\n", dds_strretcode (rc));
|
||||
goto fail;
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (SendBufferSize < min_size)
|
||||
if (size < min_size)
|
||||
{
|
||||
/* make sure the send buffersize is at least the minimum required */
|
||||
SendBufferSize = min_size;
|
||||
if ((rc = ddsrt_setsockopt (sock, SOL_SOCKET, SO_SNDBUF, (const char *) &SendBufferSize, sizeof (SendBufferSize))) != DDS_RETCODE_OK)
|
||||
size = min_size;
|
||||
if ((rc = ddsrt_setsockopt (sock, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size))) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_udp_create_conn: set SO_SNDBUF failed: %s\n", dds_strretcode (rc));
|
||||
goto fail;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
return rc;
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static dds_return_t set_mc_options_transmit_ipv6 (struct ddsi_domaingv * const gv, ddsrt_socket_t sock)
|
||||
static dds_return_t set_mc_options_transmit_ipv6 (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock)
|
||||
{
|
||||
/* Function is a never-called no-op if IPv6 is not supported to keep the call-site a bit cleaner */
|
||||
#if DDSRT_HAVE_IPV6
|
||||
const unsigned interfaceNo = gv->interfaceNo;
|
||||
const unsigned ifno = gv->interfaceNo;
|
||||
const unsigned ttl = (unsigned) gv->config.multicast_ttl;
|
||||
const unsigned loop = (unsigned) !!gv->config.enableMulticastLoopback;
|
||||
dds_return_t rc;
|
||||
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &interfaceNo, sizeof (interfaceNo))) != DDS_RETCODE_OK)
|
||||
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifno, sizeof (ifno))) != DDS_RETCODE_OK) {
|
||||
GVERROR ("ddsi_udp_create_conn: set IPV6_MULTICAST_IF failed: %s\n", dds_strretcode (rc));
|
||||
else if ((rc = ddsrt_setsockopt (sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &ttl, sizeof (ttl))) != DDS_RETCODE_OK)
|
||||
return rc;
|
||||
}
|
||||
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof (ttl))) != DDS_RETCODE_OK) {
|
||||
GVERROR ("ddsi_udp_create_conn: set IPV6_MULTICAST_HOPS failed: %s\n", dds_strretcode (rc));
|
||||
else if ((rc = ddsrt_setsockopt (sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof (loop))) != DDS_RETCODE_OK)
|
||||
return rc;
|
||||
}
|
||||
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof (loop))) != DDS_RETCODE_OK) {
|
||||
GVERROR ("ddsi_udp_create_conn: set IPV6_MULTICAST_LOOP failed: %s\n", dds_strretcode (rc));
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
return DDS_RETCODE_OK;
|
||||
#else
|
||||
(void) gv; (void) sock;
|
||||
return DDS_RETCODE_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv * const gv, ddsrt_socket_t sock)
|
||||
static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock)
|
||||
{
|
||||
#if (defined(__linux) || defined(__APPLE__)) && !LWIP_SOCKET
|
||||
if (gv->config.use_multicast_if_mreqn)
|
||||
|
@ -362,23 +384,29 @@ static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv * cons
|
|||
return ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, gv->ownloc.address + 12, 4);
|
||||
}
|
||||
|
||||
static dds_return_t set_mc_options_transmit_ipv4 (struct ddsi_domaingv * const gv, ddsrt_socket_t sock)
|
||||
static dds_return_t set_mc_options_transmit_ipv4 (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock)
|
||||
{
|
||||
const unsigned char ttl = (unsigned char) gv->config.multicast_ttl;
|
||||
const unsigned char loop = (unsigned char) !!gv->config.enableMulticastLoopback;
|
||||
dds_return_t rc;
|
||||
if ((rc = set_mc_options_transmit_ipv4_if (gv, sock)) != DDS_RETCODE_OK)
|
||||
if ((rc = set_mc_options_transmit_ipv4_if (gv, sock)) != DDS_RETCODE_OK) {
|
||||
GVERROR ("ddsi_udp_create_conn: set IP_MULTICAST_IF failed: %s\n", dds_strretcode (rc));
|
||||
else if ((rc = ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &ttl, sizeof (ttl))) != DDS_RETCODE_OK)
|
||||
return rc;
|
||||
}
|
||||
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof (ttl))) != DDS_RETCODE_OK) {
|
||||
GVERROR ("ddsi_udp_create_conn: set IP_MULTICAST_TTL failed: %s\n", dds_strretcode (rc));
|
||||
else if ((rc = ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof (loop))) != DDS_RETCODE_OK)
|
||||
return rc;
|
||||
}
|
||||
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof (loop))) != DDS_RETCODE_OK) {
|
||||
GVERROR ("ddsi_udp_create_conn: set IP_MULTICAST_LOOP failed: %s\n", dds_strretcode (rc));
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
return DDS_RETCODE_OK;
|
||||
}
|
||||
|
||||
static ddsi_tran_conn_t ddsi_udp_create_conn (ddsi_tran_factory_t fact, uint32_t port, const ddsi_tran_qos_t *qos)
|
||||
static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_factory_t fact, uint32_t port, const ddsi_tran_qos_t *qos)
|
||||
{
|
||||
struct ddsi_domaingv * const gv = fact->gv;
|
||||
struct ddsi_domaingv const * const gv = fact->gv;
|
||||
const int one = 1;
|
||||
|
||||
dds_return_t rc;
|
||||
|
@ -406,31 +434,37 @@ static ddsi_tran_conn_t ddsi_udp_create_conn (ddsi_tran_factory_t fact, uint32_t
|
|||
}
|
||||
assert (purpose_str != NULL);
|
||||
|
||||
union addr socketname;
|
||||
nn_locator_t ownloc_w_port = gv->ownloc;
|
||||
assert (ownloc_w_port.port == NN_LOCATOR_PORT_INVALID);
|
||||
if (port) {
|
||||
/* PORT_INVALID maps to 0 in ipaddr_from_loc */
|
||||
ownloc_w_port.port = port;
|
||||
}
|
||||
ddsi_ipaddr_from_loc (&socketname.x, &ownloc_w_port);
|
||||
switch (fact->m_kind)
|
||||
{
|
||||
int af = AF_UNSPEC;
|
||||
switch (fact->m_kind)
|
||||
{
|
||||
case NN_LOCATOR_KIND_UDPv4:
|
||||
af = AF_INET;
|
||||
break;
|
||||
case NN_LOCATOR_KIND_UDPv4:
|
||||
if (bind_to_any)
|
||||
socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||
break;
|
||||
#if DDSRT_HAVE_IPV6
|
||||
case NN_LOCATOR_KIND_UDPv6:
|
||||
af = AF_INET6;
|
||||
ipv6 = true;
|
||||
break;
|
||||
case NN_LOCATOR_KIND_UDPv6:
|
||||
ipv6 = true;
|
||||
if (bind_to_any)
|
||||
socketname.a6.sin6_addr = ddsrt_in6addr_any;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DDS_FATAL ("ddsi_udp_create_conn: unsupported kind %"PRId32"\n", fact->m_kind);
|
||||
}
|
||||
assert (af != AF_UNSPEC);
|
||||
if ((rc = ddsrt_socket (&sock, af, SOCK_DGRAM, 0)) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_udp_create_conn: failed to create socket: %s\n", dds_strretcode (rc));
|
||||
goto fail;
|
||||
}
|
||||
default:
|
||||
DDS_FATAL ("ddsi_udp_create_conn: unsupported kind %"PRId32"\n", fact->m_kind);
|
||||
}
|
||||
if ((rc = ddsrt_socket (&sock, socketname.a.sa_family, SOCK_DGRAM, 0)) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_udp_create_conn: failed to create socket: %s\n", dds_strretcode (rc));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (reuse_addr && (rc = ddsrt_setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof (one))) != DDS_RETCODE_OK)
|
||||
if (reuse_addr && (rc = ddsrt_setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (one))) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_udp_create_conn: failed to enable address reuse: %s\n", dds_strretcode (rc));
|
||||
if (rc != DDS_RETCODE_BAD_PARAMETER)
|
||||
|
@ -448,45 +482,21 @@ static ddsi_tran_conn_t ddsi_udp_create_conn (ddsi_tran_factory_t fact, uint32_t
|
|||
if (gv->config.dontRoute && (rc = set_dont_route (gv, sock, ipv6)) != DDS_RETCODE_OK)
|
||||
goto fail_w_socket;
|
||||
|
||||
if ((rc = ddsrt_bind (sock, &socketname.a, ddsrt_sockaddr_get_size (&socketname.a))) != DDS_RETCODE_OK)
|
||||
{
|
||||
union {
|
||||
struct sockaddr_storage x;
|
||||
struct sockaddr_in a4;
|
||||
struct sockaddr_in6 a6;
|
||||
} socketname;
|
||||
nn_locator_t ownloc_w_port = gv->ownloc;
|
||||
assert (ownloc_w_port.port == NN_LOCATOR_PORT_INVALID);
|
||||
if (port) {
|
||||
/* PORT_INVALID maps to 0 in ipaddr_from_loc */
|
||||
ownloc_w_port.port = port;
|
||||
}
|
||||
ddsi_ipaddr_from_loc (&socketname.x, &ownloc_w_port);
|
||||
/* PRECONDITION_NOT_MET (= EADDRINUSE) is expected if reuse_addr isn't set, should be handled at
|
||||
a higher level and therefore needs to return a specific error message */
|
||||
if (!reuse_addr && rc == DDS_RETCODE_PRECONDITION_NOT_MET)
|
||||
goto fail_addrinuse;
|
||||
|
||||
char buf[DDSI_LOCATORSTRLEN];
|
||||
if (bind_to_any)
|
||||
{
|
||||
switch (fact->m_kind)
|
||||
{
|
||||
case NN_LOCATOR_KIND_UDPv4:
|
||||
socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||
break;
|
||||
#if DDSRT_HAVE_IPV6
|
||||
case NN_LOCATOR_KIND_UDPv6:
|
||||
socketname.a6.sin6_addr = ddsrt_in6addr_any;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DDS_FATAL ("ddsi_udp_create_conn: unsupported kind %"PRId32"\n", fact->m_kind);
|
||||
}
|
||||
}
|
||||
if ((rc = ddsrt_bind (sock, (struct sockaddr *) &socketname, ddsrt_sockaddr_get_size ((struct sockaddr *) &socketname))) != DDS_RETCODE_OK)
|
||||
{
|
||||
char buf[DDSI_LOCATORSTRLEN];
|
||||
if (bind_to_any)
|
||||
snprintf (buf, sizeof (buf), "ANY:%"PRIu32, port);
|
||||
else
|
||||
ddsi_locator_to_string (buf, sizeof (buf), &ownloc_w_port);
|
||||
GVERROR ("ddsi_udp_create_conn: failed to bind to %s: %s\n", buf, dds_strretcode (rc));
|
||||
goto fail_w_socket;
|
||||
}
|
||||
snprintf (buf, sizeof (buf), "ANY:%"PRIu32, port);
|
||||
else
|
||||
ddsi_locator_to_string (buf, sizeof (buf), &ownloc_w_port);
|
||||
GVERROR ("ddsi_udp_create_conn: failed to bind to %s: %s\n", buf,
|
||||
(rc == DDS_RETCODE_PRECONDITION_NOT_MET) ? "address in use" : dds_strretcode (rc));
|
||||
goto fail_w_socket;
|
||||
}
|
||||
|
||||
rc = ipv6 ? set_mc_options_transmit_ipv6 (gv, sock) : set_mc_options_transmit_ipv4 (gv, sock);
|
||||
|
@ -494,9 +504,9 @@ static ddsi_tran_conn_t ddsi_udp_create_conn (ddsi_tran_factory_t fact, uint32_t
|
|||
goto fail_w_socket;
|
||||
|
||||
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
|
||||
if ((qos->m_diffserv != 0) && (fact->m_kind == NN_LOCATOR_KIND_UDPv4))
|
||||
if (qos->m_diffserv != 0 && fact->m_kind == NN_LOCATOR_KIND_UDPv4)
|
||||
{
|
||||
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IP, IP_TOS, (char *) &qos->m_diffserv, sizeof (qos->m_diffserv))) != DDS_RETCODE_OK)
|
||||
if ((rc = ddsrt_setsockopt (sock, IPPROTO_IP, IP_TOS, &qos->m_diffserv, sizeof (qos->m_diffserv))) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("ddsi_udp_create_conn: set diffserv retcode %"PRId32"\n", rc);
|
||||
goto fail_w_socket;
|
||||
|
@ -504,49 +514,52 @@ static ddsi_tran_conn_t ddsi_udp_create_conn (ddsi_tran_factory_t fact, uint32_t
|
|||
}
|
||||
#endif
|
||||
|
||||
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) ddsrt_malloc (sizeof (*uc));
|
||||
memset (uc, 0, sizeof (*uc));
|
||||
ddsi_udp_conn_t conn = ddsrt_malloc (sizeof (*conn));
|
||||
memset (conn, 0, sizeof (*conn));
|
||||
|
||||
uc->m_sock = sock;
|
||||
uc->m_diffserv = qos->m_diffserv;
|
||||
conn->m_sock = sock;
|
||||
conn->m_diffserv = qos->m_diffserv;
|
||||
#if defined _WIN32 && !defined WINCE
|
||||
uc->m_sockEvent = WSACreateEvent();
|
||||
WSAEventSelect(uc->m_sock, uc->m_sockEvent, FD_WRITE);
|
||||
conn->m_sockEvent = WSACreateEvent ();
|
||||
WSAEventSelect (conn->m_sock, conn->m_sockEvent, FD_WRITE);
|
||||
#endif
|
||||
|
||||
ddsi_factory_conn_init (fact, &uc->m_base);
|
||||
uc->m_base.m_base.m_port = get_socket_port (gv, sock);
|
||||
uc->m_base.m_base.m_trantype = DDSI_TRAN_CONN;
|
||||
uc->m_base.m_base.m_multicast = (qos->m_purpose == DDSI_TRAN_QOS_RECV_MC);
|
||||
uc->m_base.m_base.m_handle_fn = ddsi_udp_conn_handle;
|
||||
ddsi_factory_conn_init (fact, &conn->m_base);
|
||||
conn->m_base.m_base.m_port = get_socket_port (gv, sock);
|
||||
conn->m_base.m_base.m_trantype = DDSI_TRAN_CONN;
|
||||
conn->m_base.m_base.m_multicast = (qos->m_purpose == DDSI_TRAN_QOS_RECV_MC);
|
||||
conn->m_base.m_base.m_handle_fn = ddsi_udp_conn_handle;
|
||||
|
||||
uc->m_base.m_read_fn = ddsi_udp_conn_read;
|
||||
uc->m_base.m_write_fn = ddsi_udp_conn_write;
|
||||
uc->m_base.m_disable_multiplexing_fn = ddsi_udp_disable_multiplexing;
|
||||
uc->m_base.m_locator_fn = ddsi_udp_conn_locator;
|
||||
conn->m_base.m_read_fn = ddsi_udp_conn_read;
|
||||
conn->m_base.m_write_fn = ddsi_udp_conn_write;
|
||||
conn->m_base.m_disable_multiplexing_fn = ddsi_udp_disable_multiplexing;
|
||||
conn->m_base.m_locator_fn = ddsi_udp_conn_locator;
|
||||
|
||||
GVTRACE ("ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n", purpose_str, uc->m_sock, uc->m_base.m_base.m_port);
|
||||
return &uc->m_base;
|
||||
GVTRACE ("ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n", purpose_str, conn->m_sock, conn->m_base.m_base.m_port);
|
||||
*conn_out = &conn->m_base;
|
||||
return DDS_RETCODE_OK;
|
||||
|
||||
fail_w_socket:
|
||||
ddsrt_close (sock);
|
||||
fail:
|
||||
if (fact->gv->config.participantIndex != PARTICIPANT_INDEX_AUTO)
|
||||
GVERROR ("ddsi_udp_create_conn: failed for %s port %"PRIu32"\n", purpose_str, port);
|
||||
return NULL;
|
||||
return DDS_RETCODE_ERROR;
|
||||
|
||||
fail_addrinuse:
|
||||
ddsrt_close (sock);
|
||||
return DDS_RETCODE_PRECONDITION_NOT_MET;
|
||||
}
|
||||
|
||||
static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const nn_locator_t *mcloc, const struct nn_interface *interf)
|
||||
{
|
||||
dds_return_t rc;
|
||||
struct sockaddr_storage mcip;
|
||||
ddsi_ipaddr_from_loc(&mcip, mcloc);
|
||||
union addr mcip;
|
||||
ddsi_ipaddr_from_loc (&mcip.x, mcloc);
|
||||
#if DDSRT_HAVE_IPV6
|
||||
if (mcloc->kind == NN_LOCATOR_KIND_UDPv6)
|
||||
{
|
||||
struct ipv6_mreq ipv6mreq;
|
||||
memset (&ipv6mreq, 0, sizeof (ipv6mreq));
|
||||
memcpy (&ipv6mreq.ipv6mr_multiaddr, &((struct sockaddr_in6 *) &mcip)->sin6_addr, sizeof (ipv6mreq.ipv6mr_multiaddr));
|
||||
memcpy (&ipv6mreq.ipv6mr_multiaddr, &mcip.a6, sizeof (ipv6mreq.ipv6mr_multiaddr));
|
||||
ipv6mreq.ipv6mr_interface = interf ? interf->if_index : 0;
|
||||
rc = ddsrt_setsockopt (socket, IPPROTO_IPV6, join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP, &ipv6mreq, sizeof (ipv6mreq));
|
||||
}
|
||||
|
@ -554,12 +567,12 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const nn_loca
|
|||
#endif
|
||||
{
|
||||
struct ip_mreq mreq;
|
||||
mreq.imr_multiaddr = ((struct sockaddr_in *) &mcip)->sin_addr;
|
||||
mreq.imr_multiaddr = mcip.a4.sin_addr;
|
||||
if (interf)
|
||||
memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface));
|
||||
else
|
||||
mreq.imr_interface.s_addr = htonl (INADDR_ANY);
|
||||
rc = ddsrt_setsockopt (socket, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, (char *) &mreq, sizeof (mreq));
|
||||
rc = ddsrt_setsockopt (socket, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreq, sizeof (mreq));
|
||||
}
|
||||
return (rc == DDS_RETCODE_OK) ? 0 : -1;
|
||||
}
|
||||
|
@ -568,17 +581,17 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const nn_loca
|
|||
static int joinleave_ssm_mcgroup (ddsrt_socket_t socket, int join, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf)
|
||||
{
|
||||
dds_return_t rc;
|
||||
struct sockaddr_storage mcip, srcip;
|
||||
ddsi_ipaddr_from_loc(&mcip, mcloc);
|
||||
ddsi_ipaddr_from_loc(&srcip, srcloc);
|
||||
union addr mcip, srcip;
|
||||
ddsi_ipaddr_from_loc (&mcip.x, mcloc);
|
||||
ddsi_ipaddr_from_loc (&srcip.x, srcloc);
|
||||
#if DDSRT_HAVE_IPV6
|
||||
if (mcloc->kind == NN_LOCATOR_KIND_UDPv6)
|
||||
{
|
||||
struct group_source_req gsr;
|
||||
memset (&gsr, 0, sizeof (gsr));
|
||||
gsr.gsr_interface = interf ? interf->if_index : 0;
|
||||
memcpy (&gsr.gsr_group, &mcip, sizeof (gsr.gsr_group));
|
||||
memcpy (&gsr.gsr_source, &srcip, sizeof (gsr.gsr_source));
|
||||
memcpy (&gsr.gsr_group, &mcip.a6, sizeof (gsr.gsr_group));
|
||||
memcpy (&gsr.gsr_source, &srcip.a6, sizeof (gsr.gsr_source));
|
||||
rc = ddsrt_setsockopt (socket, IPPROTO_IPV6, join ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP, &gsr, sizeof (gsr));
|
||||
}
|
||||
else
|
||||
|
@ -586,8 +599,8 @@ static int joinleave_ssm_mcgroup (ddsrt_socket_t socket, int join, const nn_loca
|
|||
{
|
||||
struct ip_mreq_source mreq;
|
||||
memset (&mreq, 0, sizeof (mreq));
|
||||
mreq.imr_sourceaddr = ((struct sockaddr_in *) &srcip)->sin_addr;
|
||||
mreq.imr_multiaddr = ((struct sockaddr_in *) &mcip)->sin_addr;
|
||||
mreq.imr_sourceaddr = srcip.a4.sin_addr;
|
||||
mreq.imr_multiaddr = mcip.a4.sin_addr;
|
||||
if (interf)
|
||||
memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface));
|
||||
else
|
||||
|
@ -598,43 +611,42 @@ static int joinleave_ssm_mcgroup (ddsrt_socket_t socket, int join, const nn_loca
|
|||
}
|
||||
#endif
|
||||
|
||||
static int ddsi_udp_join_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf)
|
||||
static int ddsi_udp_join_mc (ddsi_tran_conn_t conn_cmn, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf)
|
||||
{
|
||||
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) conn;
|
||||
(void)srcloc;
|
||||
ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
|
||||
(void) srcloc;
|
||||
#ifdef DDSI_INCLUDE_SSM
|
||||
if (srcloc)
|
||||
return joinleave_ssm_mcgroup(uc->m_sock, 1, srcloc, mcloc, interf);
|
||||
return joinleave_ssm_mcgroup (conn->m_sock, 1, srcloc, mcloc, interf);
|
||||
else
|
||||
#endif
|
||||
return joinleave_asm_mcgroup(uc->m_sock, 1, mcloc, interf);
|
||||
return joinleave_asm_mcgroup (conn->m_sock, 1, mcloc, interf);
|
||||
}
|
||||
|
||||
static int ddsi_udp_leave_mc (ddsi_tran_conn_t conn, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf)
|
||||
static int ddsi_udp_leave_mc (ddsi_tran_conn_t conn_cmn, const nn_locator_t *srcloc, const nn_locator_t *mcloc, const struct nn_interface *interf)
|
||||
{
|
||||
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) conn;
|
||||
(void)srcloc;
|
||||
ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
|
||||
(void) srcloc;
|
||||
#ifdef DDSI_INCLUDE_SSM
|
||||
if (srcloc)
|
||||
return joinleave_ssm_mcgroup(uc->m_sock, 0, srcloc, mcloc, interf);
|
||||
return joinleave_ssm_mcgroup (conn->m_sock, 0, srcloc, mcloc, interf);
|
||||
else
|
||||
#endif
|
||||
return joinleave_asm_mcgroup(uc->m_sock, 0, mcloc, interf);
|
||||
return joinleave_asm_mcgroup (conn->m_sock, 0, mcloc, interf);
|
||||
}
|
||||
|
||||
static void ddsi_udp_release_conn (ddsi_tran_conn_t conn)
|
||||
static void ddsi_udp_release_conn (ddsi_tran_conn_t conn_cmn)
|
||||
{
|
||||
ddsi_udp_conn_t uc = (ddsi_udp_conn_t) conn;
|
||||
DDS_CTRACE (&conn->m_base.gv->logconfig,
|
||||
"ddsi_udp_release_conn %s socket %"PRIdSOCK" port %"PRIu32"\n",
|
||||
conn->m_base.m_multicast ? "multicast" : "unicast",
|
||||
uc->m_sock,
|
||||
uc->m_base.m_base.m_port);
|
||||
ddsrt_close (uc->m_sock);
|
||||
ddsi_udp_conn_t conn = (ddsi_udp_conn_t) conn_cmn;
|
||||
struct ddsi_domaingv const * const gv = conn->m_base.m_base.gv;
|
||||
GVTRACE ("ddsi_udp_release_conn %s socket %"PRIdSOCK" port %"PRIu32"\n",
|
||||
conn_cmn->m_base.m_multicast ? "multicast" : "unicast",
|
||||
conn->m_sock, conn->m_base.m_base.m_port);
|
||||
ddsrt_close (conn->m_sock);
|
||||
#if defined _WIN32 && !defined WINCE
|
||||
WSACloseEvent(uc->m_sockEvent);
|
||||
WSACloseEvent (conn->m_sockEvent);
|
||||
#endif
|
||||
ddsrt_free (conn);
|
||||
ddsrt_free (conn_cmn);
|
||||
}
|
||||
|
||||
static int ddsi_udp_is_mcaddr (const ddsi_tran_factory_t tran, const nn_locator_t *loc)
|
||||
|
@ -720,7 +732,8 @@ static char *ddsi_udp_locator_to_string (char *dst, size_t sizeof_dst, const nn_
|
|||
|
||||
static void ddsi_udp_fini (ddsi_tran_factory_t fact)
|
||||
{
|
||||
DDS_CLOG (DDS_LC_CONFIG, &fact->gv->logconfig, "udp finalized\n");
|
||||
struct ddsi_domaingv const * const gv = fact->gv;
|
||||
GVLOG (DDS_LC_CONFIG, "udp finalized\n");
|
||||
ddsrt_free (fact);
|
||||
}
|
||||
|
||||
|
@ -730,7 +743,7 @@ static int ddsi_udp_is_valid_port (ddsi_tran_factory_t fact, uint32_t port)
|
|||
return (port <= 65535);
|
||||
}
|
||||
|
||||
int ddsi_udp_init (struct ddsi_domaingv *gv)
|
||||
int ddsi_udp_init (struct ddsi_domaingv*gv)
|
||||
{
|
||||
struct ddsi_tran_factory *fact = ddsrt_malloc (sizeof (*fact));
|
||||
memset (fact, 0, sizeof (*fact));
|
||||
|
|
|
@ -369,8 +369,7 @@ struct debug_monitor *new_debug_monitor (struct ddsi_domaingv *gv, int32_t port)
|
|||
goto err_invalid_port;
|
||||
}
|
||||
|
||||
dm->servsock = ddsi_factory_create_listener (dm->tran_factory, (uint32_t) port, NULL);
|
||||
if (dm->servsock == NULL)
|
||||
if (ddsi_factory_create_listener (&dm->servsock, dm->tran_factory, (uint32_t) port, NULL) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVWARNING ("debmon: can't create socket\n");
|
||||
goto err_servsock;
|
||||
|
|
|
@ -587,6 +587,7 @@ dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct ddsi_domain
|
|||
struct participant *pp;
|
||||
ddsi_guid_t subguid, group_guid;
|
||||
struct whc_writer_info *wrinfo;
|
||||
ddsi_tran_conn_t ppconn;
|
||||
|
||||
/* no reserved bits may be set */
|
||||
assert ((flags & ~(RTPS_PF_NO_BUILTIN_READERS | RTPS_PF_NO_BUILTIN_WRITERS | RTPS_PF_PRIVILEGED_PP | RTPS_PF_IS_DDSI2_PP | RTPS_PF_ONLY_LOCAL)) == 0);
|
||||
|
@ -603,6 +604,18 @@ dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct ddsi_domain
|
|||
if (entidx_lookup_participant_guid (gv->entity_index, ppguid) != NULL)
|
||||
return DDS_RETCODE_PRECONDITION_NOT_MET;
|
||||
|
||||
if (gv->config.many_sockets_mode != MSM_MANY_UNICAST)
|
||||
ppconn = NULL;
|
||||
else
|
||||
{
|
||||
const ddsi_tran_qos_t qos = { .m_purpose = DDSI_TRAN_QOS_RECV_UC, .m_diffserv = 0 };
|
||||
if (ddsi_factory_create_conn (&ppconn, gv->m_factory, 0, &qos) != DDS_RETCODE_OK)
|
||||
{
|
||||
GVERROR ("new_participant("PGUIDFMT", %x) failed: could not create network endpoint\n", PGUID (*ppguid), flags);
|
||||
return DDS_RETCODE_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
if (gv->config.max_participants == 0)
|
||||
{
|
||||
ddsrt_mutex_lock (&gv->participant_set_lock);
|
||||
|
@ -621,6 +634,8 @@ dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct ddsi_domain
|
|||
{
|
||||
ddsrt_mutex_unlock (&gv->participant_set_lock);
|
||||
GVERROR ("new_participant("PGUIDFMT", %x) failed: max participants reached\n", PGUID (*ppguid), flags);
|
||||
if (ppconn)
|
||||
ddsi_conn_free (ppconn);
|
||||
return DDS_RETCODE_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
@ -649,16 +664,9 @@ dds_return_t new_participant_guid (const ddsi_guid_t *ppguid, struct ddsi_domain
|
|||
GVLOGDISC ("}\n");
|
||||
}
|
||||
|
||||
pp->m_conn = ppconn;
|
||||
if (gv->config.many_sockets_mode == MSM_MANY_UNICAST)
|
||||
{
|
||||
const ddsi_tran_qos_t qos = { .m_purpose = DDSI_TRAN_QOS_RECV_UC, .m_diffserv = 0 };
|
||||
pp->m_conn = ddsi_factory_create_conn (gv->m_factory, 0, &qos);
|
||||
ddsi_conn_locator (pp->m_conn, &pp->m_locator);
|
||||
}
|
||||
else
|
||||
{
|
||||
pp->m_conn = NULL;
|
||||
}
|
||||
|
||||
ddsrt_fibheap_init (&lease_fhdef_pp, &pp->leaseheap_man);
|
||||
ddsrt_atomic_stvoidp (&pp->minl_man, NULL);
|
||||
|
|
|
@ -72,13 +72,16 @@ static void add_peer_addresses (const struct ddsi_domaingv *gv, struct addrset *
|
|||
}
|
||||
|
||||
enum make_uc_sockets_ret {
|
||||
MUSRET_SUCCESS,
|
||||
MUSRET_INVALID_PORTS,
|
||||
MUSRET_NOSOCKET
|
||||
MUSRET_SUCCESS, /* unicast socket(s) created */
|
||||
MUSRET_INVALID_PORTS, /* specified port numbers are invalid */
|
||||
MUSRET_PORTS_IN_USE, /* ports were in use, keep trying */
|
||||
MUSRET_ERROR /* generic error, no use continuing */
|
||||
};
|
||||
|
||||
static enum make_uc_sockets_ret make_uc_sockets (struct ddsi_domaingv *gv, uint32_t * pdisc, uint32_t * pdata, int ppid)
|
||||
{
|
||||
dds_return_t rc;
|
||||
|
||||
if (gv->config.many_sockets_mode == MSM_NO_UNICAST)
|
||||
{
|
||||
assert (ppid == PARTICIPANT_INDEX_NONE);
|
||||
|
@ -97,33 +100,29 @@ static enum make_uc_sockets_ret make_uc_sockets (struct ddsi_domaingv *gv, uint3
|
|||
return MUSRET_INVALID_PORTS;
|
||||
|
||||
const ddsi_tran_qos_t qos = { .m_purpose = DDSI_TRAN_QOS_RECV_UC, .m_diffserv = 0 };
|
||||
gv->disc_conn_uc = ddsi_factory_create_conn (gv->m_factory, *pdisc, &qos);
|
||||
if (gv->disc_conn_uc)
|
||||
rc = ddsi_factory_create_conn (&gv->disc_conn_uc, gv->m_factory, *pdisc, &qos);
|
||||
if (rc != DDS_RETCODE_OK)
|
||||
goto fail_disc;
|
||||
|
||||
if (*pdata == 0 || *pdata == *pdisc)
|
||||
gv->data_conn_uc = gv->disc_conn_uc;
|
||||
else
|
||||
{
|
||||
/* Check not configured to use same unicast port for data and discovery */
|
||||
|
||||
if (*pdata != 0 && (*pdata != *pdisc))
|
||||
{
|
||||
gv->data_conn_uc = ddsi_factory_create_conn (gv->m_factory, *pdata, &qos);
|
||||
}
|
||||
else
|
||||
{
|
||||
gv->data_conn_uc = gv->disc_conn_uc;
|
||||
}
|
||||
if (gv->data_conn_uc == NULL)
|
||||
{
|
||||
ddsi_conn_free (gv->disc_conn_uc);
|
||||
gv->disc_conn_uc = NULL;
|
||||
}
|
||||
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);
|
||||
}
|
||||
rc = ddsi_factory_create_conn (&gv->data_conn_uc, gv->m_factory, *pdata, &qos);
|
||||
if (rc != DDS_RETCODE_OK)
|
||||
goto fail_data;
|
||||
}
|
||||
ddsi_conn_locator (gv->disc_conn_uc, &gv->loc_meta_uc);
|
||||
ddsi_conn_locator (gv->data_conn_uc, &gv->loc_default_uc);
|
||||
return MUSRET_SUCCESS;
|
||||
|
||||
return gv->data_conn_uc ? MUSRET_SUCCESS : MUSRET_NOSOCKET;
|
||||
fail_data:
|
||||
ddsi_conn_free (gv->disc_conn_uc);
|
||||
gv->disc_conn_uc = NULL;
|
||||
fail_disc:
|
||||
if (rc == DDS_RETCODE_PRECONDITION_NOT_MET)
|
||||
return MUSRET_PORTS_IN_USE;
|
||||
return MUSRET_ERROR;
|
||||
}
|
||||
|
||||
static void make_builtin_endpoint_xqos (dds_qos_t *q, const dds_qos_t *template)
|
||||
|
@ -675,7 +674,7 @@ int create_multicast_sockets (struct ddsi_domaingv *gv)
|
|||
gv->config.extDomainId.value, port);
|
||||
goto err_disc;
|
||||
}
|
||||
if ((disc = ddsi_factory_create_conn (gv->m_factory, port, &qos)) == NULL)
|
||||
if (ddsi_factory_create_conn (&disc, gv->m_factory, port, &qos) != DDS_RETCODE_OK)
|
||||
goto err_disc;
|
||||
if (gv->config.many_sockets_mode == MSM_NO_UNICAST)
|
||||
{
|
||||
|
@ -691,10 +690,8 @@ int create_multicast_sockets (struct ddsi_domaingv *gv)
|
|||
gv->config.extDomainId.value, port);
|
||||
goto err_disc;
|
||||
}
|
||||
if ((data = ddsi_factory_create_conn (gv->m_factory, port, &qos)) == NULL)
|
||||
{
|
||||
if (ddsi_factory_create_conn (&data, gv->m_factory, port, &qos) != DDS_RETCODE_OK)
|
||||
goto err_data;
|
||||
}
|
||||
}
|
||||
|
||||
gv->disc_conn_mc = disc;
|
||||
|
@ -1192,18 +1189,21 @@ int rtps_init (struct ddsi_domaingv *gv)
|
|||
GVERROR ("Failed to create unicast sockets for domain %"PRIu32" participant index %d: resulting port numbers (%"PRIu32", %"PRIu32") are out of range\n",
|
||||
gv->config.extDomainId.value, gv->config.participantIndex, port_disc_uc, port_data_uc);
|
||||
goto err_unicast_sockets;
|
||||
case MUSRET_NOSOCKET:
|
||||
case MUSRET_PORTS_IN_USE:
|
||||
GVERROR ("rtps_init: failed to create unicast sockets for domain %"PRId32" participant index %d (ports %"PRIu32", %"PRIu32")\n", gv->config.extDomainId.value, gv->config.participantIndex, port_disc_uc, port_data_uc);
|
||||
goto err_unicast_sockets;
|
||||
case MUSRET_ERROR:
|
||||
/* something bad happened; assume make_uc_sockets logged the error */
|
||||
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;
|
||||
enum make_uc_sockets_ret musret = MUSRET_PORTS_IN_USE;
|
||||
int ppid;
|
||||
GVLOG (DDS_LC_CONFIG, "rtps_init: trying to find a free participant index\n");
|
||||
for (ppid = 0; ppid <= gv->config.maxAutoParticipantIndex && musret == MUSRET_NOSOCKET; ppid++)
|
||||
for (ppid = 0; ppid <= gv->config.maxAutoParticipantIndex && musret == MUSRET_PORTS_IN_USE; ppid++)
|
||||
{
|
||||
musret = make_uc_sockets (gv, &port_disc_uc, &port_data_uc, ppid);
|
||||
switch (musret)
|
||||
|
@ -1214,8 +1214,11 @@ int rtps_init (struct ddsi_domaingv *gv)
|
|||
GVERROR ("Failed to create unicast sockets for domain %"PRIu32" participant index %d: resulting port numbers (%"PRIu32", %"PRIu32") are out of range\n",
|
||||
gv->config.extDomainId.value, ppid, port_disc_uc, port_data_uc);
|
||||
goto err_unicast_sockets;
|
||||
case MUSRET_NOSOCKET: /* Try next one */
|
||||
case MUSRET_PORTS_IN_USE: /* Try next one */
|
||||
break;
|
||||
case MUSRET_ERROR:
|
||||
/* something bad happened; assume make_uc_sockets logged the error */
|
||||
goto err_unicast_sockets;
|
||||
}
|
||||
}
|
||||
if (ppid > gv->config.maxAutoParticipantIndex)
|
||||
|
@ -1235,7 +1238,7 @@ int rtps_init (struct ddsi_domaingv *gv)
|
|||
|
||||
if (gv->config.pcap_file && *gv->config.pcap_file)
|
||||
{
|
||||
gv->pcap_fp = new_pcap_file (&gv->logconfig, gv->config.pcap_file);
|
||||
gv->pcap_fp = new_pcap_file (gv, gv->config.pcap_file);
|
||||
if (gv->pcap_fp)
|
||||
{
|
||||
ddsrt_mutex_init (&gv->pcap_lock);
|
||||
|
@ -1286,8 +1289,9 @@ int rtps_init (struct ddsi_domaingv *gv)
|
|||
}
|
||||
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)
|
||||
dds_return_t rc;
|
||||
rc = ddsi_factory_create_listener (&gv->listener, gv->m_factory, (uint32_t) gv->config.tcp_port, NULL);
|
||||
if (rc != DDS_RETCODE_OK || ddsi_listener_listen (gv->listener) != 0)
|
||||
{
|
||||
GVERROR ("Failed to create %s listener\n", gv->m_factory->m_typename);
|
||||
if (gv->listener)
|
||||
|
@ -1308,7 +1312,10 @@ int rtps_init (struct ddsi_domaingv *gv)
|
|||
/* Create shared transmit connection */
|
||||
{
|
||||
const ddsi_tran_qos_t qos = { .m_purpose = DDSI_TRAN_QOS_XMIT, .m_diffserv = 0 };
|
||||
gv->xmit_conn = ddsi_factory_create_conn (gv->m_factory, 0, &qos);
|
||||
dds_return_t rc;
|
||||
rc = ddsi_factory_create_conn (&gv->xmit_conn, gv->m_factory, 0, &qos);
|
||||
if (rc != DDS_RETCODE_OK)
|
||||
goto err_mc_conn;
|
||||
}
|
||||
|
||||
#ifdef DDSI_INCLUDE_NETWORK_CHANNELS
|
||||
|
|
|
@ -76,7 +76,7 @@ static const ipv4_hdr_t ipv4_hdr_template = {
|
|||
#define IPV4_HDR_SIZE 20
|
||||
#define UDP_HDR_SIZE 8
|
||||
|
||||
FILE *new_pcap_file (const struct ddsrt_log_cfg *logcfg, const char *name)
|
||||
FILE *new_pcap_file (struct ddsi_domaingv *gv, const char *name)
|
||||
{
|
||||
DDSRT_WARNING_MSVC_OFF(4996);
|
||||
FILE *fp;
|
||||
|
@ -84,7 +84,7 @@ FILE *new_pcap_file (const struct ddsrt_log_cfg *logcfg, const char *name)
|
|||
|
||||
if ((fp = fopen (name, "wb")) == NULL)
|
||||
{
|
||||
DDS_CWARNING (logcfg, "packet capture disabled: file %s could not be opened for writing\n", name);
|
||||
GVWARNING ("packet capture disabled: file %s could not be opened for writing\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue