337 lines
14 KiB
C
337 lines
14 KiB
C
/*
|
|
* Copyright(c) 2006 to 2021 ZettaScale Technology and others
|
|
*
|
|
* This program and the accompanying materials are made available under the
|
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
|
* v. 1.0 which is available at
|
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
|
*
|
|
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
|
*/
|
|
#ifndef _DDSI_TRAN_H_
|
|
#define _DDSI_TRAN_H_
|
|
|
|
/* DDSI Transport module */
|
|
|
|
#include "dds/ddsrt/ifaddrs.h"
|
|
#include "dds/ddsrt/atomics.h"
|
|
#include "dds/ddsi/ddsi_locator.h"
|
|
#include "dds/ddsi/ddsi_config.h"
|
|
|
|
#if defined (__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct nn_interface;
|
|
struct ddsi_domaingv;
|
|
|
|
/* Types supporting handles */
|
|
|
|
#define DDSI_TRAN_CONN 1
|
|
#define DDSI_TRAN_LISTENER 2
|
|
|
|
/* Flags */
|
|
|
|
#define DDSI_TRAN_ON_CONNECT 0x0001
|
|
|
|
/* Core types */
|
|
|
|
typedef struct ddsi_tran_base * ddsi_tran_base_t;
|
|
typedef struct ddsi_tran_conn * ddsi_tran_conn_t;
|
|
typedef struct ddsi_tran_listener * ddsi_tran_listener_t;
|
|
typedef struct ddsi_tran_factory * ddsi_tran_factory_t;
|
|
typedef struct ddsi_tran_qos ddsi_tran_qos_t;
|
|
|
|
/* Function pointer types */
|
|
|
|
typedef ssize_t (*ddsi_tran_read_fn_t) (ddsi_tran_conn_t, unsigned char *, size_t, bool, ddsi_locator_t *);
|
|
typedef ssize_t (*ddsi_tran_write_fn_t) (ddsi_tran_conn_t, const ddsi_locator_t *, size_t, const ddsrt_iovec_t *, uint32_t);
|
|
typedef int (*ddsi_tran_locator_fn_t) (ddsi_tran_factory_t, ddsi_tran_base_t, ddsi_locator_t *);
|
|
typedef bool (*ddsi_tran_supports_fn_t) (const struct ddsi_tran_factory *, int32_t);
|
|
typedef ddsrt_socket_t (*ddsi_tran_handle_fn_t) (ddsi_tran_base_t);
|
|
typedef int (*ddsi_tran_listen_fn_t) (ddsi_tran_listener_t);
|
|
typedef void (*ddsi_tran_free_fn_t) (ddsi_tran_factory_t);
|
|
typedef void (*ddsi_tran_peer_locator_fn_t) (ddsi_tran_conn_t, ddsi_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 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);
|
|
typedef void (*ddsi_tran_release_listener_fn_t) (ddsi_tran_listener_t);
|
|
typedef int (*ddsi_tran_join_mc_fn_t) (ddsi_tran_conn_t, const ddsi_locator_t *srcip, const ddsi_locator_t *mcip, const struct nn_interface *interf);
|
|
typedef int (*ddsi_tran_leave_mc_fn_t) (ddsi_tran_conn_t, const ddsi_locator_t *srcip, const ddsi_locator_t *mcip, const struct nn_interface *interf);
|
|
typedef int (*ddsi_is_loopbackaddr_fn_t) (const struct ddsi_tran_factory *tran, const ddsi_locator_t *loc);
|
|
typedef int (*ddsi_is_mcaddr_fn_t) (const struct ddsi_tran_factory *tran, const ddsi_locator_t *loc);
|
|
typedef int (*ddsi_is_ssm_mcaddr_fn_t) (const struct ddsi_tran_factory *tran, const ddsi_locator_t *loc);
|
|
typedef int (*ddsi_is_valid_port_fn_t) (const struct ddsi_tran_factory *tran, uint32_t port);
|
|
typedef uint32_t (*ddsi_receive_buffer_size_fn_t) (const struct ddsi_tran_factory *fact);
|
|
|
|
enum ddsi_nearby_address_result {
|
|
DNAR_DISTANT,
|
|
DNAR_LOCAL
|
|
};
|
|
|
|
typedef enum ddsi_nearby_address_result (*ddsi_is_nearby_address_fn_t) (const ddsi_locator_t *loc, size_t ninterf, const struct nn_interface *interf, size_t *interf_idx);
|
|
|
|
enum ddsi_locator_from_string_result {
|
|
AFSR_OK, /* conversion succeeded */
|
|
AFSR_INVALID, /* bogus input */
|
|
AFSR_UNKNOWN, /* transport or hostname lookup failure */
|
|
AFSR_MISMATCH /* recognised format, but mismatch with expected (e.g., IPv4/IPv6) */
|
|
};
|
|
|
|
typedef enum ddsi_locator_from_string_result (*ddsi_locator_from_string_fn_t) (const struct ddsi_tran_factory *tran, ddsi_locator_t *loc, const char *str);
|
|
|
|
typedef int (*ddsi_locator_from_sockaddr_fn_t) (const struct ddsi_tran_factory *tran, ddsi_locator_t *loc, const struct sockaddr *sockaddr);
|
|
|
|
typedef char * (*ddsi_locator_to_string_fn_t) (char *dst, size_t sizeof_dst, const ddsi_locator_t *loc, ddsi_tran_conn_t conn, int with_port);
|
|
|
|
typedef int (*ddsi_enumerate_interfaces_fn_t) (ddsi_tran_factory_t tran, enum ddsi_transport_selector transport_selector, ddsrt_ifaddrs_t **interfs);
|
|
|
|
/* Data types */
|
|
struct ddsi_tran_base
|
|
{
|
|
/* Data */
|
|
|
|
uint32_t m_port;
|
|
uint32_t m_trantype;
|
|
bool m_multicast;
|
|
struct ddsi_domaingv *gv;
|
|
|
|
/* Functions */
|
|
|
|
ddsi_tran_handle_fn_t m_handle_fn;
|
|
};
|
|
|
|
struct ddsi_tran_conn
|
|
{
|
|
struct ddsi_tran_base m_base;
|
|
|
|
/* Functions */
|
|
|
|
ddsi_tran_read_fn_t m_read_fn;
|
|
ddsi_tran_write_fn_t m_write_fn;
|
|
ddsi_tran_peer_locator_fn_t m_peer_locator_fn;
|
|
ddsi_tran_disable_multiplexing_fn_t m_disable_multiplexing_fn;
|
|
ddsi_tran_locator_fn_t m_locator_fn;
|
|
|
|
/* Data */
|
|
|
|
bool m_server;
|
|
bool m_connless;
|
|
bool m_stream;
|
|
bool m_closed;
|
|
ddsrt_atomic_uint32_t m_count;
|
|
|
|
/* Relationships */
|
|
|
|
const struct nn_interface *m_interf;
|
|
ddsi_tran_factory_t m_factory;
|
|
ddsi_tran_listener_t m_listener;
|
|
ddsi_tran_conn_t m_conn;
|
|
};
|
|
|
|
struct ddsi_tran_listener
|
|
{
|
|
struct ddsi_tran_base m_base;
|
|
|
|
/* Functions */
|
|
|
|
ddsi_tran_listen_fn_t m_listen_fn;
|
|
ddsi_tran_accept_fn_t m_accept_fn;
|
|
ddsi_tran_locator_fn_t m_locator_fn;
|
|
|
|
/* Relationships */
|
|
|
|
ddsi_tran_conn_t m_connections;
|
|
ddsi_tran_factory_t m_factory;
|
|
ddsi_tran_listener_t m_listener;
|
|
};
|
|
|
|
struct ddsi_tran_factory
|
|
{
|
|
/* Functions */
|
|
|
|
ddsi_tran_create_conn_fn_t m_create_conn_fn;
|
|
ddsi_tran_create_listener_fn_t m_create_listener_fn;
|
|
ddsi_tran_release_conn_fn_t m_release_conn_fn;
|
|
ddsi_tran_close_conn_fn_t m_close_conn_fn;
|
|
ddsi_tran_unblock_listener_fn_t m_unblock_listener_fn;
|
|
ddsi_tran_release_listener_fn_t m_release_listener_fn;
|
|
ddsi_tran_supports_fn_t m_supports_fn;
|
|
ddsi_tran_free_fn_t m_free_fn;
|
|
ddsi_tran_join_mc_fn_t m_join_mc_fn;
|
|
ddsi_tran_leave_mc_fn_t m_leave_mc_fn;
|
|
ddsi_is_loopbackaddr_fn_t m_is_loopbackaddr_fn;
|
|
ddsi_is_mcaddr_fn_t m_is_mcaddr_fn;
|
|
ddsi_is_ssm_mcaddr_fn_t m_is_ssm_mcaddr_fn;
|
|
ddsi_is_nearby_address_fn_t m_is_nearby_address_fn;
|
|
ddsi_locator_from_string_fn_t m_locator_from_string_fn;
|
|
ddsi_locator_to_string_fn_t m_locator_to_string_fn;
|
|
ddsi_enumerate_interfaces_fn_t m_enumerate_interfaces_fn;
|
|
ddsi_is_valid_port_fn_t m_is_valid_port_fn;
|
|
ddsi_receive_buffer_size_fn_t m_receive_buffer_size_fn;
|
|
ddsi_locator_from_sockaddr_fn_t m_locator_from_sockaddr_fn;
|
|
|
|
/* Data */
|
|
|
|
/// Transport name, also used as prefix in string representation of locator (e.g., udp/1.2.3.4)
|
|
const char *m_typename;
|
|
|
|
/// Whether this is a connection-oriented transport like TCP (false), where a socket communicates
|
|
/// with one other socket after connecting; or whether it can send to any address at any time like
|
|
/// UDP (true).
|
|
bool m_connless;
|
|
|
|
/// Whether this transport deals with byte streams (TCP, true) or with datagrams (UDP, false). A
|
|
/// byte stream forces the upper layer to do add some framing.
|
|
bool m_stream;
|
|
|
|
/// Whether this transport is enabled for DDS communications. Only locators mapping handled
|
|
/// by enabled transports are taken into account when parsing discovery data.
|
|
///
|
|
/// The usefulness of disabled transports is (currently) limited to running in UDP mode while using
|
|
/// the TCP transport code as a portable means for providing a debug interface.
|
|
bool m_enable;
|
|
|
|
/// Whether this transport should be included in SPDP advertisements. Not all transports are
|
|
/// created equally: those that only provide a representation for an integrated pub-sub messaging
|
|
/// system that can be used to by-pass RTPS should not by included in anything related to SPDP.
|
|
bool m_enable_spdp;
|
|
|
|
/// Default SPDP address for this transport (the spec only gives an UDPv4 default one), NULL if
|
|
/// no default address exists.
|
|
const char *m_default_spdp_address;
|
|
|
|
struct ddsi_domaingv *gv;
|
|
|
|
/* Relationships */
|
|
|
|
ddsi_tran_factory_t m_factory;
|
|
};
|
|
|
|
enum ddsi_tran_qos_purpose {
|
|
DDSI_TRAN_QOS_XMIT_UC, // will send unicast only
|
|
DDSI_TRAN_QOS_XMIT_MC, // may send unicast or multicast
|
|
DDSI_TRAN_QOS_RECV_UC, // will be used for receiving unicast
|
|
DDSI_TRAN_QOS_RECV_MC // will be used for receiving multicast
|
|
};
|
|
|
|
struct ddsi_tran_qos
|
|
{
|
|
enum ddsi_tran_qos_purpose m_purpose;
|
|
int m_diffserv;
|
|
struct nn_interface *m_interface; // only for purpose = XMIT
|
|
};
|
|
|
|
void ddsi_tran_factories_fini (struct ddsi_domaingv *gv);
|
|
void ddsi_factory_add (struct ddsi_domaingv *gv, ddsi_tran_factory_t factory);
|
|
DDS_EXPORT void ddsi_factory_free (ddsi_tran_factory_t factory);
|
|
DDS_EXPORT ddsi_tran_factory_t ddsi_factory_find (const struct ddsi_domaingv *gv, const char * type);
|
|
ddsi_tran_factory_t ddsi_factory_find_supported_kind (const struct ddsi_domaingv *gv, int32_t kind);
|
|
void ddsi_factory_conn_init (const struct ddsi_tran_factory *factory, const struct nn_interface *interf, ddsi_tran_conn_t conn);
|
|
|
|
DDS_INLINE_EXPORT inline bool ddsi_factory_supports (const struct ddsi_tran_factory *factory, int32_t kind) {
|
|
return factory->m_supports_fn (factory, kind);
|
|
}
|
|
DDS_INLINE_EXPORT inline int ddsi_is_valid_port (const struct ddsi_tran_factory *factory, uint32_t port) {
|
|
return factory->m_is_valid_port_fn (factory, port);
|
|
}
|
|
DDS_INLINE_EXPORT inline uint32_t ddsi_receive_buffer_size (const struct ddsi_tran_factory *factory) {
|
|
return factory->m_receive_buffer_size_fn (factory);
|
|
}
|
|
DDS_INLINE_EXPORT 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 ((qos->m_interface != NULL) != (qos->m_purpose == DDSI_TRAN_QOS_XMIT_UC || qos->m_purpose == DDSI_TRAN_QOS_XMIT_MC))
|
|
return DDS_RETCODE_BAD_PARAMETER;
|
|
if (!ddsi_is_valid_port (factory, port))
|
|
return DDS_RETCODE_BAD_PARAMETER;
|
|
return factory->m_create_conn_fn (conn, factory, port, qos);
|
|
}
|
|
DDS_INLINE_EXPORT 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 DDS_RETCODE_BAD_PARAMETER;
|
|
return factory->m_create_listener_fn (listener, factory, port, qos);
|
|
}
|
|
|
|
void ddsi_tran_free (ddsi_tran_base_t base);
|
|
DDS_INLINE_EXPORT inline ddsrt_socket_t ddsi_tran_handle (ddsi_tran_base_t base) {
|
|
return base->m_handle_fn (base);
|
|
}
|
|
DDS_INLINE_EXPORT inline ddsrt_socket_t ddsi_conn_handle (ddsi_tran_conn_t conn) {
|
|
return conn->m_base.m_handle_fn (&conn->m_base);
|
|
}
|
|
DDS_INLINE_EXPORT inline uint32_t ddsi_conn_type (const struct ddsi_tran_conn *conn) {
|
|
return conn->m_base.m_trantype;
|
|
}
|
|
DDS_INLINE_EXPORT inline uint32_t ddsi_conn_port (const struct ddsi_tran_conn *conn) {
|
|
return conn->m_base.m_port;
|
|
}
|
|
DDS_INLINE_EXPORT inline int ddsi_conn_locator (ddsi_tran_conn_t conn, ddsi_locator_t * loc) {
|
|
return conn->m_locator_fn (conn->m_factory, &conn->m_base, loc);
|
|
}
|
|
DDS_INLINE_EXPORT inline ssize_t ddsi_conn_write (ddsi_tran_conn_t conn, const ddsi_locator_t *dst, size_t niov, const ddsrt_iovec_t *iov, uint32_t flags) {
|
|
return conn->m_closed ? -1 : (conn->m_write_fn) (conn, dst, niov, iov, flags);
|
|
}
|
|
DDS_INLINE_EXPORT inline ssize_t ddsi_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, size_t len, bool allow_spurious, ddsi_locator_t *srcloc) {
|
|
return conn->m_closed ? -1 : conn->m_read_fn (conn, buf, len, allow_spurious, srcloc);
|
|
}
|
|
bool ddsi_conn_peer_locator (ddsi_tran_conn_t conn, ddsi_locator_t * loc);
|
|
void ddsi_conn_disable_multiplexing (ddsi_tran_conn_t conn);
|
|
void ddsi_conn_add_ref (ddsi_tran_conn_t conn);
|
|
void ddsi_conn_free (ddsi_tran_conn_t conn);
|
|
int ddsi_conn_join_mc (ddsi_tran_conn_t conn, const ddsi_locator_t *srcip, const ddsi_locator_t *mcip, const struct nn_interface *interf);
|
|
int ddsi_conn_leave_mc (ddsi_tran_conn_t conn, const ddsi_locator_t *srcip, const ddsi_locator_t *mcip, const struct nn_interface *interf);
|
|
void ddsi_conn_transfer_group_membership (ddsi_tran_conn_t conn, ddsi_tran_conn_t newconn);
|
|
int ddsi_conn_rejoin_transferred_mcgroups (ddsi_tran_conn_t conn);
|
|
int ddsi_is_loopbackaddr (const struct ddsi_domaingv *gv, const ddsi_locator_t *loc);
|
|
int ddsi_is_mcaddr (const struct ddsi_domaingv *gv, const ddsi_locator_t *loc);
|
|
int ddsi_is_ssm_mcaddr (const struct ddsi_domaingv *gv, const ddsi_locator_t *loc);
|
|
enum ddsi_nearby_address_result ddsi_is_nearby_address (const struct ddsi_domaingv *gv, const ddsi_locator_t *loc, size_t ninterf, const struct nn_interface *interf, size_t *interf_idx);
|
|
|
|
DDS_EXPORT enum ddsi_locator_from_string_result ddsi_locator_from_string (const struct ddsi_domaingv *gv, ddsi_locator_t *loc, const char *str, ddsi_tran_factory_t default_factory);
|
|
|
|
DDS_EXPORT int ddsi_locator_from_sockaddr (const struct ddsi_tran_factory *tran, ddsi_locator_t *loc, const struct sockaddr *sockaddr);
|
|
|
|
/* 8 for transport/
|
|
1 for [
|
|
48 for IPv6 hex digits (3*16) + separators
|
|
2 for ]:
|
|
10 for port (DDSI loc has signed 32-bit)
|
|
11 for @ifindex
|
|
1 for terminator
|
|
--
|
|
81
|
|
*/
|
|
#define DDSI_LOCSTRLEN 81
|
|
|
|
char *ddsi_xlocator_to_string (char *dst, size_t sizeof_dst, const ddsi_xlocator_t *loc);
|
|
char *ddsi_locator_to_string (char *dst, size_t sizeof_dst, const ddsi_locator_t *loc);
|
|
|
|
char *ddsi_xlocator_to_string_no_port (char *dst, size_t sizeof_dst, const ddsi_xlocator_t *loc);
|
|
char *ddsi_locator_to_string_no_port (char *dst, size_t sizeof_dst, const ddsi_locator_t *loc);
|
|
|
|
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, enum ddsi_transport_selector transport_selector, ddsrt_ifaddrs_t **interfs);
|
|
|
|
DDS_INLINE_EXPORT inline int ddsi_listener_locator (ddsi_tran_listener_t listener, ddsi_locator_t *loc) {
|
|
return listener->m_locator_fn (listener->m_factory, &listener->m_base, loc);
|
|
}
|
|
DDS_INLINE_EXPORT inline int ddsi_listener_listen (ddsi_tran_listener_t listener) {
|
|
return listener->m_listen_fn (listener);
|
|
}
|
|
DDS_INLINE_EXPORT inline ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener) {
|
|
return listener->m_accept_fn (listener);
|
|
}
|
|
void ddsi_listener_unblock (ddsi_tran_listener_t listener);
|
|
void ddsi_listener_free (ddsi_tran_listener_t listener);
|
|
|
|
#if defined (__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
#endif
|