Make ICE dual-satck (IPv46) more versatile

This commit is contained in:
Mamadou DIOP 2016-05-24 00:11:39 +02:00
parent aff961eb23
commit 3383de3026
16 changed files with 212 additions and 84 deletions

View File

@ -102,7 +102,7 @@ static int _tdav_session_bfcp_set(tmedia_session_t* p_self, const tmedia_param_t
else if (tsk_striequals(param->key, "local-ip")) {
tsk_strupdate(&p_bfcp->p_local_ip, param->value);
}
else if (tsk_striequals(param->key, "local-ipver")) {
else if (tsk_striequals(param->key, "use-ipv6")) {
p_bfcp->b_use_ipv6 = tsk_striequals(param->value, "ipv6");
}
}

View File

@ -370,7 +370,7 @@ int tdav_session_msrp_set(tmedia_session_t* self, const tmedia_param_t* param)
else if(tsk_striequals(param->key, "local-ip")) {
tsk_strupdate(&msrp->local_ip, param->value);
}
else if(tsk_striequals(param->key, "local-ipver")) {
else if(tsk_striequals(param->key, "use-ipv6")) {
msrp->useIPv6 = tsk_striequals(param->value, "ipv6");
}
else if(tsk_striequals(param->key, "accept-types")) {

View File

@ -305,7 +305,7 @@ tsk_bool_t tdav_session_av_set(tdav_session_av_t* self, const tmedia_param_t* pa
tsk_strupdate(&self->local_ip, (const char*)param->value);
return tsk_true;
}
else if(tsk_striequals(param->key, "local-ipver")) {
else if(tsk_striequals(param->key, "use-ipv6")) {
self->use_ipv6 = tsk_striequals(param->value, "ipv6");
return tsk_true;
}
@ -876,11 +876,11 @@ const tsdp_header_M_t* tdav_session_av_get_lo(tdav_session_av_t* self, tsk_bool_
*updated = (base->ro_changed || !base->M.lo);
if(!base->M.lo) {
if((base->M.lo = tsdp_header_M_create(base->plugin->media, self->rtp_manager->rtp.public_port, "RTP/AVP"))) {
if((base->M.lo = tsdp_header_M_create(base->plugin->media, self->rtp_manager->rtp.public_addr.port, "RTP/AVP"))) {
/* If NATT is active, do not rely on the global IP address Connection line */
if(self->natt_ctx) {
tsdp_header_M_add_headers(base->M.lo,
TSDP_HEADER_C_VA_ARGS("IN", self->use_ipv6 ? "IP6" : "IP4", self->rtp_manager->rtp.public_ip),
TSDP_HEADER_C_VA_ARGS("IN", TNET_SOCKET_TYPE_IS_IPV6(self->rtp_manager->rtp.public_addr.type) ? "IP6" : "IP4", self->rtp_manager->rtp.public_addr.ip),
tsk_null);
}
/* 3GPP TS 24.229 - 6.1.1 General
@ -1337,10 +1337,10 @@ const tsdp_header_M_t* tdav_session_av_get_lo(tdav_session_av_t* self, tsk_bool_
}
else {
if(base->M.lo->C) {
tsk_strupdate(&base->M.lo->C->addr, self->rtp_manager->rtp.public_ip);
tsk_strupdate(&base->M.lo->C->addrtype, (self->use_ipv6 ? "IP6" : "IP4"));
tsk_strupdate(&base->M.lo->C->addr, self->rtp_manager->rtp.public_addr.ip);
tsk_strupdate(&base->M.lo->C->addrtype, (TNET_SOCKET_TYPE_IS_IPV6(self->rtp_manager->rtp.public_addr.type) ? "IP6" : "IP4"));
}
base->M.lo->port = self->rtp_manager->rtp.public_port;
base->M.lo->port = self->rtp_manager->rtp.public_addr.port;
}
if(self->media_type & tmedia_audio) {

View File

@ -306,10 +306,12 @@ typedef struct tmedia_session_mgr_s {
tsk_bool_t offerer;
//! local IP address or FQDN
char* addr;
tnet_socket_type_t addr_type;
//! public IP address or FQDN
char* public_addr;
//! whether the @a addr is IPv6 or not (useful when @addr is a FQDN)
tsk_bool_t ipv6;
tnet_socket_type_t public_addr_type;
//! whether to enable IPv6
tsk_bool_t use_ipv6;
struct {
uint32_t lo_ver;
@ -538,7 +540,7 @@ tmedia_session_param_type_t;
//#define TMEDIA_SESSION_SET_QOS(TYPE_ENUM, STRENGTH_ENUM) tmedia_sptype_qos, (tmedia_qos_stype_t)TYPE_ENUM, (tmedia_qos_strength_t)STRENGTH_ENUM
TINYMEDIA_API tmedia_session_mgr_t* tmedia_session_mgr_create(tmedia_type_t type, const char* addr, tsk_bool_t ipv6, tsk_bool_t offerer);
TINYMEDIA_API tmedia_session_mgr_t* tmedia_session_mgr_create(tmedia_type_t type, const char* addr, tsk_bool_t use_ipv6, tsk_bool_t offerer);
TINYMEDIA_API int tmedia_session_mgr_set_media_type(tmedia_session_mgr_t* self, tmedia_type_t type);
TINYMEDIA_API int tmedia_session_mgr_set_media_type_2(tmedia_session_mgr_t* self, tmedia_type_t type, tsk_bool_t force);
TINYMEDIA_API int tmedia_session_mgr_set_codecs_supported(tmedia_session_mgr_t* self, tmedia_codec_id_t codecs_supported);

View File

@ -31,6 +31,8 @@
#include "ice/tnet_ice_ctx.h"
#include "tnet_utils.h"
#include "tsk_memory.h"
#include "tsk_debug.h"
@ -816,7 +818,7 @@ filter_neg_codecs:
* will create an audio/video session.
* @retval new @ref tmedia_session_mgr_t object
*/
tmedia_session_mgr_t* tmedia_session_mgr_create(tmedia_type_t type, const char* addr, tsk_bool_t ipv6, tsk_bool_t offerer)
tmedia_session_mgr_t* tmedia_session_mgr_create(tmedia_type_t type, const char* addr, tsk_bool_t use_ipv6, tsk_bool_t offerer)
{
tmedia_session_mgr_t* mgr;
@ -828,7 +830,10 @@ tmedia_session_mgr_t* tmedia_session_mgr_create(tmedia_type_t type, const char*
/* init */
mgr->type = type;
mgr->addr = tsk_strdup(addr);
mgr->ipv6 = ipv6;
mgr->addr_type = tsk_strempty(mgr->addr)
? (use_ipv6 ? tnet_socket_type_udp_ipv6 : tnet_socket_type_udp_ipv4)
: (tnet_is_ipv6(mgr->addr, 0) ? tnet_socket_type_udp_ipv6 : tnet_socket_type_udp_ipv4);
mgr->use_ipv6 = use_ipv6;
/* load sessions (will allow us to generate lo) */
if (offerer) {
@ -913,6 +918,7 @@ int tmedia_session_mgr_set_natt_ctx(tmedia_session_mgr_t* self, struct tnet_nat_
TSK_OBJECT_SAFE_FREE(self->natt_ctx);
self->natt_ctx = tsk_object_ref(natt_ctx);
tsk_strupdate(&self->public_addr, public_addr);
tnet_nat_get_socket_type(natt_ctx, &self->public_addr_type);
tmedia_session_mgr_set(self,
TMEDIA_SESSION_SET_POBJECT(self->type, "natt-ctx", self->natt_ctx),
@ -2211,7 +2217,7 @@ static int _tmedia_session_mgr_load_sessions(tmedia_session_mgr_t* self)
TMEDIA_SESSION_SET_POBJECT(tmedia_bfcp_video, "ice-ctx", self->ice.ctx_bfcpvid),
TMEDIA_SESSION_SET_STR(self->type, "local-ip", self->addr),
TMEDIA_SESSION_SET_STR(self->type, "local-ipver", self->ipv6 ? "ipv6" : "ipv4"),
TMEDIA_SESSION_SET_STR(self->type, "use-ipv6", self->use_ipv6 ? "ipv6" : "ipv4"),
TMEDIA_SESSION_SET_INT32(self->type, "bandwidth-level", self->bl),
TMEDIA_SESSION_SET_NULL());
// set callback functions
@ -2350,10 +2356,12 @@ static const tsdp_message_t* _tmedia_session_mgr_get_lo(tmedia_session_mgr_t* se
goto bail;
}
else {
if ((self->sdp.lo = tsdp_message_create_empty(self->public_addr ? self->public_addr : self->addr, self->ipv6, new_ver_num))) {
const char* addr = self->public_addr ? self->public_addr : self->addr;
tsk_bool_t ipv6 = self->public_addr ? TNET_SOCKET_TYPE_IS_IPV6(self->public_addr_type) : TNET_SOCKET_TYPE_IS_IPV6(self->addr_type);
if ((self->sdp.lo = tsdp_message_create_empty(addr, ipv6, new_ver_num))) {
/* Set connection "c=" */
tsdp_message_add_headers(self->sdp.lo,
TSDP_HEADER_C_VA_ARGS("IN", self->ipv6 ? "IP6" : "IP4", self->public_addr ? self->public_addr : self->addr),
TSDP_HEADER_C_VA_ARGS("IN", ipv6 ? "IP6" : "IP4", addr),
tsk_null);
if (inc_ver) {
++self->sdp.lo_ver;

View File

@ -80,6 +80,8 @@
#define kIcePairsBuildingTimeMax 2500 // maximum time to build pairs
#define kIceDefaultDualStack tsk_true
typedef tsk_list_t tnet_ice_servers_L_t;
static const char* foundation_default = tsk_null;
@ -194,6 +196,12 @@ static tnet_ice_server_t* tnet_ice_server_create(
TSK_DEBUG_ERROR("Invalid server address (host=%s, port=%d, transport=%d)", str_server_addr, u_server_port, e_transport);
return tsk_null;
}
if (obj_server_addr.ss_family == AF_INET6) {
TNET_SOCKET_TYPE_SET_IPV6Only(e_transport);
}
else {
TNET_SOCKET_TYPE_SET_IPV4Only(e_transport);
}
if ((ice_server = tsk_object_new(&tnet_ice_server_def_s))) {
ice_server->e_proto = e_proto;
@ -218,6 +226,7 @@ typedef struct tnet_ice_ctx_s {
tnet_ice_callback_f callback;
const void* userdata;
tsk_bool_t use_ipv6;
tsk_bool_t dual_stack;
tsk_bool_t use_rtcp;
tsk_bool_t use_rtcpmux;
tsk_bool_t is_video;
@ -400,6 +409,8 @@ static tsk_object_t* tnet_ice_ctx_ctor(tsk_object_t * self, va_list * app)
*/
ctx->Rc = kIceDefaultRC;
ctx->dual_stack = kIceDefaultDualStack;
ctx->tie_breaker = ((tsk_time_now() << 32) ^ tsk_time_now());
ctx->is_ice_jingle = tsk_false;
ctx->is_stun_enabled = kIceDefaultStunEnabled;
@ -595,6 +606,15 @@ int tnet_ice_ctx_add_server(
TSK_DEBUG_ERROR("'%s' not a valid transport proto", transport_proto);
return -1;
}
if (self->dual_stack) {
TNET_SOCKET_TYPE_SET_IPV46(socket_type);
}
else if (self->use_ipv6) {
TNET_SOCKET_TYPE_SET_IPV6Only(socket_type);
}
else {
TNET_SOCKET_TYPE_SET_IPV4Only(socket_type);
}
return _tnet_ice_ctx_server_add(self, e_proto,
socket_type, server_addr, server_port,
kStunSoftware,
@ -1117,7 +1137,7 @@ bail:
// Started -> (GatherHostCandidates) -> (GatheringHostCandidates)
static int _tnet_ice_ctx_fsm_Started_2_GatheringHostCandidates_X_GatherHostCandidates(va_list *app)
{
int ret = 0;
int ret = 0, i;
tnet_ice_ctx_t* self;
tnet_addresses_L_t* addresses;
const tsk_list_item_t *item;
@ -1129,21 +1149,42 @@ static int _tnet_ice_ctx_fsm_Started_2_GatheringHostCandidates_X_GatherHostCandi
uint16_t local_pref, curr_local_pref;
tnet_ip_t best_local_ip;
tsk_bool_t check_best_local_ip;
int af_inets[2] = { AF_UNSPEC, AF_UNSPEC };
static const tsk_bool_t dnsserver = tsk_false;
static const long if_index_any = -1; // any interface
static const char* destination = "doubango.org";
self = va_arg(*app, tnet_ice_ctx_t *);
socket_type = self->use_ipv6 ? tnet_socket_type_udp_ipv6 : tnet_socket_type_udp_ipv4;
addresses = tnet_get_addresses((self->use_ipv6 ? AF_INET6 : AF_INET), self->unicast, self->anycast, self->multicast, dnsserver, if_index_any);
if (!addresses || TSK_LIST_IS_EMPTY(addresses)) {
TSK_DEBUG_ERROR("Failed to get addresses");
socket_type = self->dual_stack
? tnet_socket_type_udp_ipv46
: (self->use_ipv6 ? tnet_socket_type_udp_ipv6 : tnet_socket_type_udp_ipv4);
// Create list of addresses
if (!(addresses = tsk_list_create())) {
TSK_DEBUG_ERROR("Failed to create addresses-list");
ret = -1;
goto bail;
}
}
// Set IPv4 flag
if (TNET_SOCKET_TYPE_IS_IPV4(socket_type)) {
af_inets[0] = AF_INET;
}
// Set IPv6 flag
if (TNET_SOCKET_TYPE_IS_IPV6(socket_type)) {
af_inets[1] = AF_INET6;
}
/* IPv4/IPv6 addresses */
for (i = 0; i < sizeof(af_inets)/sizeof(af_inets[0]); ++i) {
if (af_inets[i] != AF_UNSPEC) {
tnet_addresses_L_t* list = tnet_get_addresses(af_inets[i], self->unicast, self->anycast, self->multicast, dnsserver, if_index_any);
if (list && !TSK_LIST_IS_EMPTY(list)) {
tsk_list_pushback_list(addresses, list);
}
TSK_OBJECT_SAFE_FREE(list);
}
}
check_best_local_ip = (tnet_getbestsource(destination, 5060, socket_type, &best_local_ip) == 0);
curr_local_pref = local_pref = check_best_local_ip ? 0xFFFE : 0xFFFF;
@ -1163,7 +1204,7 @@ static int _tnet_ice_ctx_fsm_Started_2_GatheringHostCandidates_X_GatherHostCandi
}
// host candidates
ret = tnet_ice_utils_create_sockets(socket_type,
ret = tnet_ice_utils_create_sockets((address->family == AF_INET6) ? tnet_socket_type_udp_ipv6 : tnet_socket_type_udp_ipv4,
address->ip, &socket_rtp,
self->use_rtcp ? &socket_rtcp : tsk_null);
if (ret == 0) {
@ -1371,7 +1412,7 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidatesDone_2_GatheringReflexiveCan
if (!(candidate = (tnet_ice_candidate_t*)item->data)) {
continue;
}
if (candidate->socket && tsk_strnullORempty(candidate->stun.srflx_addr)) {
if (candidate->socket && candidate->transport_e == ice_server->e_transport && tsk_strnullORempty(candidate->stun.srflx_addr)) {
ret = tnet_ice_candidate_send_stun_bind_request(candidate, &ice_server->obj_server_addr, ice_server->str_username, ice_server->str_password);
}
}
@ -2759,8 +2800,9 @@ static int _tnet_ice_ctx_server_add(struct tnet_ice_ctx_s* self, enum tnet_ice_s
const char* str_software,
const char* str_username, const char* str_password)
{
struct tnet_ice_server_s* ice_server;
int ret = -1;
struct tnet_ice_server_s* ice_server = tsk_null;
enum tnet_socket_type_e e_transports[2] = { tnet_socket_type_invalid, tnet_socket_type_invalid};
int ret = -1, i;
if (!self || !e_proto || !str_server_addr || !u_server_port) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
@ -2782,12 +2824,38 @@ static int _tnet_ice_ctx_server_add(struct tnet_ice_ctx_s* self, enum tnet_ice_s
ret = 0; // Not an error
goto bail;
}
if (!(ice_server = tnet_ice_server_create(e_proto, e_transport, str_server_addr, u_server_port, str_software, str_username, str_password))) {
TSK_DEBUG_ERROR("Failed to create ICE server(proto=%d, transport=%d, addr=%s, port=%hu)", e_proto, e_transport, str_server_addr, u_server_port);
goto bail;
}
tsk_list_push_back_data(self->servers, (void**)&ice_server);
TSK_OBJECT_SAFE_FREE(ice_server);
// Guess the supported IP versions from the server address
if (self->dual_stack) {
enum tnet_socket_type_e server_addr_type = tnet_get_type(str_server_addr, u_server_port);
if (TNET_SOCKET_TYPE_IS_IPV4(server_addr_type)) {
e_transports[0] = e_transport;
TNET_SOCKET_TYPE_SET_IPV4Only(e_transports[0]);
}
if (TNET_SOCKET_TYPE_IS_IPV6(server_addr_type)) {
e_transports[1] = e_transport;
TNET_SOCKET_TYPE_SET_IPV6Only(e_transports[1]);
}
}
else {
e_transports[0] = e_transport;
if (self->use_ipv6) {
TNET_SOCKET_TYPE_SET_IPV6Only(e_transports[0]);
}
else {
TNET_SOCKET_TYPE_SET_IPV4Only(e_transports[0]);
}
}
// Add the ICE servers
for (i = 0; i < sizeof(e_transports)/sizeof(e_transports[0]); ++i) {
if (TNET_SOCKET_TYPE_IS_VALID(e_transports[i])) {
if (!(ice_server = tnet_ice_server_create(e_proto, e_transports[i], str_server_addr, u_server_port, str_software, str_username, str_password))) {
TSK_DEBUG_ERROR("Failed to create ICE server(proto=%d, transport=%d, addr=%s, port=%hu)", e_proto, e_transport, str_server_addr, u_server_port);
goto bail;
}
tsk_list_push_back_data(self->servers, (void**)&ice_server);
TSK_OBJECT_SAFE_FREE(ice_server);
}
}
ret = 0;
bail:

View File

@ -129,6 +129,16 @@ int tnet_nat_set_server_address(struct tnet_nat_ctx_s* p_self, const char* pc_se
return 0;
}
int tnet_nat_get_socket_type(const struct tnet_nat_ctx_s* p_self, enum tnet_socket_type_e* type)
{
if (!p_self || !type) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
*type = p_self->socket_type;
return 0;
}
/**@ingroup tnet_nat_group
*
* Sets the address and port of the STUN/TURN server.

View File

@ -30,6 +30,7 @@ struct tnet_nat_ctx_s;
struct tnet_stun_binding_s;
enum tnet_socket_type_e;
TINYNET_API int tnet_nat_get_socket_type(const struct tnet_nat_ctx_s* p_self, enum tnet_socket_type_e* type);
TINYNET_API int tnet_nat_set_server_address(struct tnet_nat_ctx_s* p_self, const char* pc_srv_addr);
TINYNET_API int tnet_nat_set_server(struct tnet_nat_ctx_s* p_self, const char* pc_srv_addr, tnet_port_t u_srv_port);
TINYNET_API tnet_stun_binding_id_t tnet_nat_stun_bind(const struct tnet_nat_ctx_s* p_self, const tnet_fd_t localFD);

View File

@ -132,6 +132,7 @@ tnet_socket_type_t;
#define TNET_SOCKET_TYPE_SET_IPV4Only(type) (type = TNET_SOCKET_TYPE_IS_IPV6(type) ? (type ^TNET_SOCKET_TYPE_IPV6)|TNET_SOCKET_TYPE_IPV4 : type)
#define TNET_SOCKET_TYPE_SET_IPV6(type) (type |= TNET_SOCKET_TYPE_IPV6)
#define TNET_SOCKET_TYPE_SET_IPV6Only(type) (type = TNET_SOCKET_TYPE_IS_IPV4(type) ? (type ^TNET_SOCKET_TYPE_IPV4)|TNET_SOCKET_TYPE_IPV6 : type)
#define TNET_SOCKET_TYPE_SET_IPV46(type) (type |= TNET_SOCKET_TYPE_IPV46)
#define TNET_SOCKET_TYPE_SET_IPSEC(type) (type |=TNET_SOCKET_TYPE_IPSEC)

View File

@ -157,6 +157,7 @@ tnet_transport_t* tnet_transport_create(const char* host, tnet_port_t port, tnet
if ((transport->master = tnet_socket_create(transport->local_host, transport->req_local_port, transport->type))) {
transport->local_ip = tsk_strdup(transport->master->ip);
transport->bind_local_port = transport->master->port;
transport->type = transport->master->type;
}
else {
TSK_DEBUG_ERROR("Failed to create master socket");

View File

@ -837,7 +837,7 @@ int tnet_getbestsource(const char* destination, tnet_port_t port, tnet_socket_ty
tnet_addresses_L_t* addresses = tsk_null;
const tsk_list_item_t* item;
if (!(addresses = tnet_get_addresses(TNET_SOCKET_TYPE_IS_IPV6(type) ? AF_INET6 : AF_INET, tsk_true, tsk_false, tsk_false, tsk_false, dwBestIfIndex))) {
if (!(addresses = tnet_get_addresses(destAddr.ss_family, tsk_true, tsk_false, tsk_false, tsk_false, dwBestIfIndex))) {
ret = -2;
TSK_DEBUG_ERROR("Failed to retrieve addresses.");
goto bail;
@ -1053,34 +1053,50 @@ int tnet_getpeername(tnet_fd_t fd, struct sockaddr_storage *result)
return -1;
}
/**@ingroup tnet_utils_group
* Retrieves the socket type of a File Descriptor.
* @param fd The File descriptor for which to retrive the type.
* @retval @ref tnet_socket_type_t.
*/
tnet_socket_type_t tnet_get_socket_type(tnet_fd_t fd)
tnet_socket_type_t tnet_get_type(const char* host, tnet_port_t port)
{
tnet_socket_type_t type = tnet_socket_type_invalid;
tnet_socket_type_t ret = TNET_SOCKET_TYPE_UDP;
if (host) {
int status;
tsk_istr_t srv;
struct addrinfo *result = tsk_null;
struct addrinfo hints;
const struct addrinfo *ptr = tsk_null;
/*if(fd >0)
{
struct sockaddr_storage ss;
if(!tnet_get_sockaddr(fd, &ss))
{
if(((struct sockaddr *)&ss)->sa_family == AF_INET)
{
TNET_SOCKET_TYPE_AS_IPV4(type);
}
else if(((struct sockaddr *)&ss)->sa_family == AF_INET6)
{
TNET_SOCKET_TYPE_AS_IPV6(type);
}
}
}*/
/* set the port: used as the default service */
if (port) {
tsk_itoa(port, &srv);
}
else {
memset(srv, '\0', sizeof(srv));
}
return type;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
if ((status = tnet_getaddrinfo(host, srv, &hints, &result))) {
TNET_PRINT_LAST_ERROR("getaddrinfo(%s:%d) failed", host, port);
goto done;
}
for (ptr = result; ptr; ptr = ptr->ai_next) {
if (ptr->ai_family == AF_INET) {
TNET_SOCKET_TYPE_SET_IPV4(ret);
}
else if (ptr->ai_family == AF_INET6) {
TNET_SOCKET_TYPE_SET_IPV6(ret);
}
}
done:
tnet_freeaddrinfo(result);
}
return ret;
}
/**@ingroup tnet_utils_group
* Gets the IP family of the @a host (e.g. "google.com" or "192.168.16.104" or "::1").
* If the @a host is FQDN associated with both IPv4 and IPv6 then the result is unpredictable.
@ -1127,6 +1143,12 @@ done:
return ret;
}
tsk_bool_t tnet_is_ipv6(const char* host, tnet_port_t port)
{
tnet_socket_type_t type = tnet_get_type(host, port);
return TNET_SOCKET_TYPE_IS_IPV6(type);
}
/**@ingroup tnet_utils_group
* Gets the IP address and the Port of a @b sockaddr object.
* @param addr [in] A pointer to @b sockaddr structure for which to retrieve the IP address and port.

View File

@ -93,8 +93,9 @@ TINYNET_API int tnet_getaddrinfo(const char *node, const char *service, const st
TINYNET_API void tnet_freeaddrinfo(struct addrinfo *ai);
TINYNET_API int tnet_getsockname(tnet_fd_t fd, struct sockaddr_storage *result);
TINYNET_API int tnet_getpeername(tnet_fd_t fd, struct sockaddr_storage *result);
TINYNET_API tnet_socket_type_t tnet_get_socket_type(tnet_fd_t fd);
TINYNET_API tnet_family_t tnet_get_family(const char* host, tnet_port_t port);
TINYNET_API tnet_socket_type_t tnet_get_type(const char* host, tnet_port_t port);
TINYNET_API tsk_bool_t tnet_is_ipv6(const char* host, tnet_port_t port);
TINYNET_API int tnet_get_ip_n_port(tnet_fd_t fd, tsk_bool_t getlocal, tnet_ip_t *ip, tnet_port_t *port);
TINYNET_API int tnet_get_sockip_n_port(const struct sockaddr *addr, tnet_ip_t *ip, tnet_port_t *port);
TINYNET_API int tnet_get_peerip_n_port(tnet_fd_t localFD, tnet_ip_t *ip, tnet_port_t *port);

View File

@ -90,8 +90,11 @@ typedef struct trtp_manager_s {
tnet_port_t remote_port;
struct sockaddr_storage remote_addr;
char* public_ip;
tnet_port_t public_port;
struct {
char* ip;
tnet_port_t port;
tnet_socket_type_t type;
} public_addr;
struct {
uint32_t local;
@ -117,8 +120,11 @@ typedef struct trtp_manager_s {
struct sockaddr_storage remote_addr;
tnet_socket_t* local_socket;
char* public_ip;
tnet_port_t public_port;
struct {
char* ip;
tnet_port_t port;
tnet_socket_type_t type;
} public_addr;
struct {
const void* usrdata;

View File

@ -833,8 +833,8 @@ static int _trtp_manager_ice_init(trtp_manager_t* self)
if (candidate_answer_dest) { // could be "null" if remote peer is ICE-lite
tsk_strupdate(&self->rtp.remote_ip, candidate_answer_dest->connection_addr);
self->rtp.remote_port = candidate_answer_dest->port;
tsk_strupdate(&self->rtp.public_ip, candidate_offer->connection_addr);
self->rtp.public_port = candidate_offer->port;
tsk_strupdate(&self->rtp.public_addr.ip, candidate_offer->connection_addr);
self->rtp.public_addr.port = candidate_offer->port;
}
// get rtp nominated symetric candidates
@ -845,8 +845,8 @@ static int _trtp_manager_ice_init(trtp_manager_t* self)
// set rtp local and remote IPs and ports
tsk_strupdate(&self->rtcp.remote_ip, candidate_answer_dest->connection_addr);
self->rtcp.remote_port = candidate_answer_dest->port;
tsk_strupdate(&self->rtcp.public_ip, candidate_offer->connection_addr);
self->rtcp.public_port = candidate_offer->port;
tsk_strupdate(&self->rtcp.public_addr.ip, candidate_offer->connection_addr);
self->rtcp.public_addr.port = candidate_offer->port;
TSK_OBJECT_SAFE_FREE(self->rtcp.local_socket);
// Get RTCP socket
if (self->is_ice_turn_active && candidate_offer->turn.ss) {
@ -918,6 +918,7 @@ int trtp_manager_prepare(trtp_manager_t* self)
{
const char *rtp_local_ip = tsk_null, *rtcp_local_ip = tsk_null;
tnet_port_t rtp_local_port = 0, rtcp_local_port = 0;
tnet_socket_type_t socket_type = self->use_ipv6 ? tnet_socket_type_udp_ipv6 : tnet_socket_type_udp_ipv4;
if(!self) {
TSK_DEBUG_ERROR("Invalid parameter");
@ -939,7 +940,12 @@ int trtp_manager_prepare(trtp_manager_t* self)
#define __retry_count_max 5
#define __retry_count_max_minus1 (__retry_count_max - 1)
uint8_t retry_count = __retry_count_max;
tnet_socket_type_t socket_type = self->use_ipv6 ? tnet_socket_type_udp_ipv6 : tnet_socket_type_udp_ipv4;
tnet_socket_type_t socket_type = tnet_socket_type_invalid;
// If local IP is defined then check its address family
if (!tsk_strempty(self->local_ip)) {
socket_type = tnet_get_type(self->local_ip, rtp_local_port); // IP @ always returns IPv4Only or IPv6Only
}
/* Creates local rtp and rtcp sockets */
while(retry_count--) {
@ -949,8 +955,8 @@ int trtp_manager_prepare(trtp_manager_t* self)
tnet_port_t local_port = 6060;
#else
// first check => try to use port from latest active session if exist
tnet_port_t local_port = (retry_count == __retry_count_max_minus1 && (self->port_range.start <= self->rtp.public_port && self->rtp.public_port <= self->port_range.stop))
? self->rtp.public_port
tnet_port_t local_port = (retry_count == __retry_count_max_minus1 && (self->port_range.start <= self->rtp.public_addr.port && self->rtp.public_addr.port <= self->port_range.stop))
? self->rtp.public_addr.port
: (((rand() ^ ++counter) % (self->port_range.stop - self->port_range.start)) + self->port_range.start);
#endif
local_port = (local_port & 0xFFFE); /* turn to even number */
@ -987,11 +993,13 @@ int trtp_manager_prepare(trtp_manager_t* self)
}
}// end-of-else(!ice)
tsk_strupdate(&self->rtp.public_ip, rtp_local_ip);
self->rtp.public_port = rtp_local_port;
tsk_strupdate(&self->rtp.public_addr.ip, rtp_local_ip);
self->rtp.public_addr.port = rtp_local_port;
self->rtp.public_addr.type = socket_type;
tsk_strupdate(&self->rtcp.public_ip, rtcp_local_ip);
self->rtcp.public_port = rtcp_local_port;
tsk_strupdate(&self->rtcp.public_addr.ip, rtcp_local_ip);
self->rtcp.public_addr.port = rtcp_local_port;
self->rtcp.public_addr.type = socket_type;
if(self->transport) {
/* set callback function */
@ -1225,15 +1233,15 @@ int trtp_manager_set_natt_ctx(trtp_manager_t* self, struct tnet_nat_ctx_s* natt_
tnet_port_t public_port = 0;
// get RTP public IP and Port
if(!tnet_transport_get_public_ip_n_port(self->transport, self->transport->master->fd, &public_ip, &public_port)) {
tsk_strupdate(&self->rtp.public_ip, public_ip);
self->rtp.public_port = public_port;
tsk_strupdate(&self->rtp.public_addr.ip, public_ip);
self->rtp.public_addr.port = public_port;
}
// get RTCP public IP and Port
memset(public_ip, 0, sizeof(public_ip));
public_port = 0;
if(self->rtcp.local_socket && !tnet_transport_get_public_ip_n_port(self->transport, self->rtcp.local_socket->fd, &public_ip, &public_port)) {
tsk_strupdate(&self->rtcp.public_ip, public_ip);
self->rtcp.public_port = public_port;
tsk_strupdate(&self->rtcp.public_addr.ip, public_ip);
self->rtcp.public_addr.port = public_port;
}
// re-enable sockets to be able to receive STUN packets
#if 0
@ -1826,8 +1834,8 @@ int trtp_manager_stop(trtp_manager_t* self)
// Free RTCP info to make sure these values will be updated in next start()
TSK_OBJECT_SAFE_FREE(self->rtcp.local_socket);
TSK_OBJECT_SAFE_FREE(self->rtcp.session);
self->rtcp.public_port = self->rtcp.remote_port = 0;
TSK_FREE(self->rtcp.public_ip);
self->rtcp.public_addr.port = self->rtcp.remote_port = 0;
TSK_FREE(self->rtcp.public_addr.ip);
TSK_FREE(self->rtcp.remote_ip);
// reset default values
@ -1914,13 +1922,13 @@ static tsk_object_t* trtp_manager_dtor(tsk_object_t * self)
/* rtp */
TSK_FREE(manager->rtp.remote_ip);
TSK_FREE(manager->rtp.public_ip);
TSK_FREE(manager->rtp.public_addr.ip);
TSK_FREE(manager->rtp.serial_buffer.ptr);
/* rtcp */
TSK_OBJECT_SAFE_FREE(manager->rtcp.session);
TSK_FREE(manager->rtcp.remote_ip);
TSK_FREE(manager->rtcp.public_ip);
TSK_FREE(manager->rtcp.public_addr.ip);
TSK_FREE(manager->rtcp.cname);
TSK_OBJECT_SAFE_FREE(manager->rtcp.local_socket);

View File

@ -921,8 +921,8 @@ int tsip_transport_init(tsip_transport_t* self, tnet_socket_type_t type, const s
}
self->stack = stack;
self->type = type;
self->net_transport = tnet_transport_create(host, port, type, description);
self->type = tnet_transport_get_type(self->net_transport); // Type could be "ipv46" or any fancy protocol. Update it using the transport master
self->scheme = "sip";

View File

@ -865,7 +865,7 @@ clean_routes:
transport = curr;
break;
}
if((curr->type & destNetType) == destNetType) {
if((curr->type & destNetType) == destNetType || (curr->type & destNetType) == curr->type) {
transport_closest1 = curr;
}
if(self->stack->network.transport_idx_default>= 0 && curr->type == self->stack->network.transport_types[self->stack->network.transport_idx_default]) {