Commit a3ab888d authored by Simon Morlat's avatar Simon Morlat

Allow the channel to know which hostname it is connected to in case of SRV...

Allow the channel to know which hostname it is connected to in case of SRV resolution. THis will avoid a DNS resolution when resolving record-routes in dialogs.
This change required a refactoring of resolver code. A new object belle_sip_resolver_results_t is introduced to provide addrinfos together with dns srv records.
parent 91455800
......@@ -25,6 +25,9 @@ typedef struct belle_sip_dns_srv belle_sip_dns_srv_t;
typedef struct belle_sip_resolver_context belle_sip_resolver_context_t;
#define BELLE_SIP_RESOLVER_CONTEXT(obj) BELLE_SIP_CAST(obj,belle_sip_resolver_context_t)
typedef struct belle_sip_resolver_results belle_sip_resolver_results_t;
#define BELLE_SIP_RESOLVER_RESULTS(obj) BELLE_SIP_CAST(obj,belle_sip_resolver_results_t)
/**
* Callback prototype for asynchronous DNS SRV resolution.
* The srv_list contains struct dns_srv elements that must be taken and (possibly later) freed by the callee, using belle_sip_free().
......@@ -33,10 +36,10 @@ typedef void (*belle_sip_resolver_srv_callback_t)(void *data, const char *name,
/**
* Callback prototype for asynchronous DNS A and AAAA resolution.
* The ai_list contains addrinfo elements that must be taken and (possibly later) freed by the callee, using freeaddrinfo().
* These elements are linked by their ai_next field.
* The 'results' object must be acquired (ref'd) in order for being accessed outside of the callback.
* The results object provides SRV records list and addrinfo list.
**/
typedef void (*belle_sip_resolver_callback_t)(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl);
typedef void (*belle_sip_resolver_callback_t)(void *data, belle_sip_resolver_results_t *results);
BELLE_SIP_BEGIN_DECLS
......@@ -49,6 +52,20 @@ BELLESIP_EXPORT unsigned short belle_sip_dns_srv_get_weight(const belle_sip_dns_
BELLESIP_EXPORT unsigned short belle_sip_dns_srv_get_port(const belle_sip_dns_srv_t *obj);
/**
* Find the belle_sip_dns_srv_t object associated with a particular addrinfo.
* The srv_list and the addrinfo must be the ones given by the belle_sip_resolver_callback_t callback invoked consecutively to a call
* to belle_sip_stack_resolve().
**/
BELLESIP_EXPORT const belle_sip_dns_srv_t * belle_sip_resolver_results_get_srv_from_addrinfo(const belle_sip_resolver_results_t *obj, const struct addrinfo *ai);
BELLESIP_EXPORT const bctbx_list_t *belle_sip_resolver_results_get_srv_records(const belle_sip_resolver_results_t *obj);
BELLESIP_EXPORT const struct addrinfo *belle_sip_resolver_results_get_addrinfos(const belle_sip_resolver_results_t *obj);
BELLESIP_EXPORT int belle_sip_resolver_results_get_ttl(const belle_sip_resolver_results_t *obj);
BELLESIP_EXPORT const char * belle_sip_resolver_results_get_name(const belle_sip_resolver_results_t *obj);
/**
* Asynchronously performs DNS SRV followed A/AAAA query. Automatically fallbacks to A/AAAA if SRV isn't found.
......
......@@ -149,7 +149,8 @@ BELLE_SIP_DECLARE_TYPES_BEGIN(belle_sip,1)
BELLE_SIP_TYPE_ID(belle_sip_header_accept_t),
BELLE_SIP_TYPE_ID(belle_sip_header_reason_t),
BELLE_SIP_TYPE_ID(belle_sip_header_authentication_info_t),
BELLE_SIP_TYPE_ID(belle_sip_mdns_register_t)
BELLE_SIP_TYPE_ID(belle_sip_mdns_register_t),
BELLE_SIP_TYPE_ID(belle_sip_resolver_results_t)
BELLE_SIP_DECLARE_TYPES_END
......
......@@ -234,6 +234,7 @@ BELLE_SIP_DECLARE_VPTR(belle_sip_header_authentication_info_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_mdns_source_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_mdns_register_t);
#endif
BELLE_SIP_DECLARE_VPTR(belle_sip_resolver_results_t);
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_resolver_context_t,belle_sip_source_t)
......
......@@ -50,7 +50,7 @@ struct belle_sip_dns_srv{
unsigned short weight;
unsigned short port;
unsigned char a_done;
unsigned char pad;
unsigned char dont_free_a_results;
int cumulative_weight; /*used only temporarily*/
char *target;
belle_sip_combined_resolver_context_t *root_resolver;/* used internally to combine SRV and A queries*/
......@@ -71,7 +71,7 @@ static void belle_sip_dns_srv_destroy(belle_sip_dns_srv_t *obj){
belle_sip_object_unref(obj->a_resolver);
obj->a_resolver=NULL;
}
if (obj->a_results){
if (obj->a_results && !obj->dont_free_a_results){
bctbx_freeaddrinfo(obj->a_results);
obj->a_results=NULL;
}
......@@ -124,6 +124,87 @@ BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_dns_srv_t);
BELLE_SIP_INSTANCIATE_VPTR(belle_sip_dns_srv_t, belle_sip_object_t,belle_sip_dns_srv_destroy, NULL, NULL,TRUE);
struct belle_sip_resolver_results{
belle_sip_object_t base;
struct addrinfo *ai_list;
bctbx_list_t *srv_list;
char *name;
uint32_t ttl;
};
static void belle_sip_resolver_results_destroy(belle_sip_resolver_results_t *obj){
if (obj->ai_list) bctbx_freeaddrinfo(obj->ai_list);
bctbx_list_free_with_data(obj->srv_list, belle_sip_object_unref);
if (obj->name) bctbx_free(obj->name);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_resolver_results_t);
BELLE_SIP_INSTANCIATE_VPTR(belle_sip_resolver_results_t, belle_sip_object_t,belle_sip_resolver_results_destroy, NULL, NULL,FALSE);
static int addrinfo_in_range(const struct addrinfo *ai, const struct addrinfo *begin, const struct addrinfo *end){
const struct addrinfo *it;
for (it = begin ; it != end; it = it->ai_next){
if (it == NULL){
belle_sip_error("addrinfo_in_range(): it == NULL, this should not happen, this is a bug !");
break;
}
if (it == ai){
return 1;
}
}
return 0;
}
static const belle_sip_dns_srv_t * _belle_sip_dns_srv_get_from_addrinfo(const belle_sip_list_t *srv_list, const struct addrinfo *ai){
/* We simply iterate on the addrinfo pointed by the srv objects in the srv list until we find "ai".
* This is not very efficient but there is not that much alternatives:
* - there is no user pointer in struct addrinfo
* - there might not be srv record for a domain, in which case the srv_list is empty...
*/
const bctbx_list_t *elem;
for (elem = srv_list; elem != NULL; elem = elem->next){
const belle_sip_dns_srv_t *srv = (const belle_sip_dns_srv_t *) elem->data;
const belle_sip_dns_srv_t *next_srv = elem->next ? (const belle_sip_dns_srv_t *) elem->next->data : NULL;
if (addrinfo_in_range(ai, srv->a_results, next_srv ? next_srv->a_results : NULL)){
return srv;
}
}
return NULL;
}
const belle_sip_dns_srv_t * belle_sip_resolver_results_get_srv_from_addrinfo(const belle_sip_resolver_results_t *obj, const struct addrinfo *ai){
return _belle_sip_dns_srv_get_from_addrinfo(obj->srv_list, ai);
}
const bctbx_list_t *belle_sip_resolver_results_get_srv_records(const belle_sip_resolver_results_t *obj){
return obj->srv_list;
}
const struct addrinfo *belle_sip_resolver_results_get_addrinfos(const belle_sip_resolver_results_t *obj){
return obj->ai_list;
}
int belle_sip_resolver_results_get_ttl(const belle_sip_resolver_results_t *obj){
return obj->ttl;
}
const char *belle_sip_resolver_get_name(const belle_sip_resolver_results_t *obj){
return obj->name;
}
belle_sip_resolver_results_t *belle_sip_resolver_results_create(const char *name, struct addrinfo *ai_list, belle_sip_list_t *srv_list, int ttl){
belle_sip_resolver_results_t *obj = belle_sip_object_new(belle_sip_resolver_results_t);
obj->ai_list = ai_list;
obj->srv_list = srv_list;
obj->ttl = ttl;
obj->name = bctbx_strdup(name);
return obj;
}
struct belle_sip_resolver_context{
belle_sip_source_t source;
belle_sip_stack_t *stack;
......@@ -466,11 +547,14 @@ static void simple_resolver_context_notify(belle_sip_resolver_context_t *obj) {
belle_sip_simple_resolver_context_t *ctx = BELLE_SIP_SIMPLE_RESOLVER_CONTEXT(obj);
if ((ctx->type == DNS_T_A) || (ctx->type == DNS_T_AAAA)) {
struct addrinfo **ai_list = &ctx->ai_list;
belle_sip_resolver_results_t *results;
#if defined(USE_GETADDRINFO_FALLBACK) || defined(HAVE_MDNS)
if (ctx->getaddrinfo_ai_list != NULL) ai_list = &ctx->getaddrinfo_ai_list;
#endif
ctx->cb(ctx->cb_data, ctx->name, *ai_list, BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl);
results = belle_sip_resolver_results_create(ctx->name, *ai_list, NULL, BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl);
ctx->cb(ctx->cb_data, results);
*ai_list = NULL;
belle_sip_object_unref(results);
} else if (ctx->type == DNS_T_SRV) {
ctx->srv_list = srv_select_by_weight(ctx->srv_list);
ctx->srv_cb(ctx->srv_cb_data, ctx->name, ctx->srv_list, BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl);
......@@ -480,10 +564,13 @@ static void simple_resolver_context_notify(belle_sip_resolver_context_t *obj) {
static void dual_resolver_context_notify(belle_sip_resolver_context_t *obj) {
belle_sip_dual_resolver_context_t *ctx = BELLE_SIP_DUAL_RESOLVER_CONTEXT(obj);
struct addrinfo *results = ctx->aaaa_results;
belle_sip_resolver_results_t *result_obj;
results = ai_list_append(results, ctx->a_results);
ctx->a_results = NULL;
ctx->aaaa_results = NULL;
ctx->cb(ctx->cb_data, ctx->name, results, BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl);
result_obj = belle_sip_resolver_results_create(ctx->name, results, NULL, BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl);
ctx->cb(ctx->cb_data, result_obj);
belle_sip_object_unref(result_obj);
}
static void combined_resolver_context_cleanup(belle_sip_combined_resolver_context_t *ctx) {
......@@ -501,8 +588,11 @@ static void combined_resolver_context_cleanup(belle_sip_combined_resolver_contex
static void combined_resolver_context_notify(belle_sip_resolver_context_t *obj) {
belle_sip_combined_resolver_context_t *ctx = BELLE_SIP_COMBINED_RESOLVER_CONTEXT(obj);
ctx->cb(ctx->cb_data, ctx->name, ctx->final_results, BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl);
belle_sip_resolver_results_t *results = belle_sip_resolver_results_create(ctx->name, ctx->final_results, ctx->srv_results, BELLE_SIP_RESOLVER_CONTEXT(obj)->min_ttl);
ctx->cb(ctx->cb_data, results);
belle_sip_object_unref(results);
ctx->final_results = NULL;
ctx->srv_results = NULL;
combined_resolver_context_cleanup(ctx);
}
......@@ -1217,9 +1307,10 @@ static char * srv_prefix_from_service_and_transport(const char *service, const c
return belle_sip_strdup_printf("_%s._udp.", service);
}
static void process_a_fallback_result(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl){
static void process_a_fallback_result(void *data, belle_sip_resolver_results_t *results){
belle_sip_combined_resolver_context_t *ctx=(belle_sip_combined_resolver_context_t *)data;
ctx->final_results=ai_list;
ctx->final_results = results->ai_list;
results->ai_list = NULL;
belle_sip_resolver_context_notify(BELLE_SIP_RESOLVER_CONTEXT(ctx));
}
......@@ -1250,13 +1341,14 @@ static void combined_resolver_context_check_finished(belle_sip_combined_resolver
}
}
static void process_a_from_srv(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl){
static void process_a_from_srv(void *data, belle_sip_resolver_results_t *results){
belle_sip_dns_srv_t *srv=(belle_sip_dns_srv_t*)data;
srv->a_results=ai_list;
srv->a_results = results->ai_list;
results->ai_list = NULL;
srv->a_done=TRUE;
belle_sip_message("A query finished for srv result [%s]",srv->target);
if (ttl < BELLE_SIP_RESOLVER_CONTEXT(srv->root_resolver)->min_ttl) BELLE_SIP_RESOLVER_CONTEXT(srv->root_resolver)->min_ttl = ttl;
combined_resolver_context_check_finished(srv->root_resolver, ttl);
if (results->ttl < BELLE_SIP_RESOLVER_CONTEXT(srv->root_resolver)->min_ttl) BELLE_SIP_RESOLVER_CONTEXT(srv->root_resolver)->min_ttl = results->ttl;
combined_resolver_context_check_finished(srv->root_resolver, results->ttl);
}
static void srv_resolve_a(belle_sip_combined_resolver_context_t *obj, belle_sip_dns_srv_t *srv){
......@@ -1337,8 +1429,10 @@ belle_sip_resolver_context_t * belle_sip_stack_resolve(belle_sip_stack_t *stack,
belle_sip_object_unref(ctx);
return BELLE_SIP_RESOLVER_CONTEXT(ctx);
} else {
/* There is no resolve to be done */
cb(data, name, res, UINT32_MAX);
/* There is no resolution to be done */
belle_sip_resolver_results_t *results = belle_sip_resolver_results_create(name, res, NULL, UINT32_MAX);
cb(data, results);
belle_sip_object_unref(results);
return NULL;
}
}
......@@ -1376,16 +1470,18 @@ static void dual_resolver_context_check_finished(belle_sip_dual_resolver_context
}
}
static void on_ipv4_results(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl) {
static void on_ipv4_results(void *data, belle_sip_resolver_results_t *results) {
belle_sip_dual_resolver_context_t *ctx = BELLE_SIP_DUAL_RESOLVER_CONTEXT(data);
ctx->a_results = ai_list;
ctx->a_results = results->ai_list;
results->ai_list = NULL;
ctx->a_notified = TRUE;
dual_resolver_context_check_finished(ctx);
}
static void on_ipv6_results(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl) {
static void on_ipv6_results(void *data, belle_sip_resolver_results_t *results) {
belle_sip_dual_resolver_context_t *ctx = BELLE_SIP_DUAL_RESOLVER_CONTEXT(data);
ctx->aaaa_results = ai_list;
ctx->aaaa_results = results->ai_list;
results->ai_list = NULL;
ctx->aaaa_notified = TRUE;
dual_resolver_context_check_finished(ctx);
}
......@@ -1430,8 +1526,10 @@ belle_sip_resolver_context_t * belle_sip_stack_resolve_a(belle_sip_stack_t *stac
belle_sip_error("belle_sip_stack_resolve_a(): unsupported address family [%i]",family);
}
} else {
/* There is no resolve to be done */
cb(data, name, res, UINT32_MAX);
/* There is no resolution to be done */
belle_sip_resolver_results_t *results = belle_sip_resolver_results_create(name, res, NULL, UINT32_MAX);
cb(data, results);
belle_sip_object_unref(results);
}
return NULL;
}
......
......@@ -109,7 +109,6 @@ static size_t belle_sip_channel_input_stream_get_buff_length(belle_sip_channel_i
static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
belle_sip_channel_input_stream_reset(&obj->input_stream);
if (obj->peer_list) bctbx_freeaddrinfo(obj->peer_list);
if (obj->peer_cname) belle_sip_free(obj->peer_cname);
belle_sip_free(obj->peer_name);
if (obj->local_ip) belle_sip_free(obj->local_ip);
......@@ -120,6 +119,8 @@ static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
belle_sip_resolver_context_cancel(obj->resolver_ctx);
belle_sip_object_unref(obj->resolver_ctx);
}
SET_OBJECT_PROPERTY(obj, resolver_results, NULL);
if (obj->static_peer_list) bctbx_freeaddrinfo(obj->static_peer_list);
if (obj->inactivity_timer){
belle_sip_main_loop_remove_source(obj->stack->ml,obj->inactivity_timer);
belle_sip_object_unref(obj->inactivity_timer);
......@@ -745,7 +746,7 @@ static void update_inactivity_timer(belle_sip_channel_t *obj, int from_recv){
* locaport locaport to use for binding, can be set to 0 if port doesn't matter
* peer_cname canonical name of remote host, used for TLS verification
* peername peer's hostname, either ip address or DNS name
* pee_port peer's port to connect to.
* peer_port peer's port to connect to.
*/
void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack,const char *bindip,int localport,const char *peer_cname, const char *peername, int peer_port){
/*to initialize our base class:*/
......@@ -787,7 +788,7 @@ void belle_sip_channel_init_with_addr(belle_sip_channel_t *obj, belle_sip_stack_
ai.ai_addrlen=addrlen;
bctbx_addrinfo_to_ip_address(&ai,remoteip,sizeof(remoteip),&peer_port);
belle_sip_channel_init(obj,stack,bindip,localport,NULL,remoteip,peer_port);
obj->peer_list=obj->current_peer=bctbx_ip_address_to_addrinfo(ai.ai_family, ai.ai_socktype, obj->peer_name,obj->peer_port);
obj->peer_list = obj->current_peer = obj->static_peer_list = bctbx_ip_address_to_addrinfo(ai.ai_family, ai.ai_socktype, obj->peer_name,obj->peer_port);
obj->ai_family=ai.ai_family;
}
......@@ -835,7 +836,8 @@ void belle_sip_channel_remove_listener(belle_sip_channel_t *obj, belle_sip_chann
}
int belle_sip_channel_matches(const belle_sip_channel_t *obj, const belle_sip_hop_t *hop, const struct addrinfo *addr){
if (hop && strcmp(hop->host,obj->peer_name)==0 && (hop->port==obj->peer_port || obj->srv_overrides_port)){
if (hop && (strcmp(hop->host,obj->peer_name)==0 || (obj->current_peer_cname && strcmp(hop->host,obj->current_peer_cname)==0))
&& (hop->port==obj->peer_port || obj->srv_overrides_port)){
if (hop->cname && obj->peer_cname && strcmp(hop->cname,obj->peer_cname)!=0)
return 0; /*cname mismatch*/
return 1;
......@@ -1000,13 +1002,26 @@ static void channel_connect_next(belle_sip_channel_t *obj){
belle_sip_object_unref(obj);
}
static void channel_set_current_peer(belle_sip_channel_t *obj, const struct addrinfo *ai){
if (obj->resolver_results){
const belle_sip_dns_srv_t *srv = belle_sip_resolver_results_get_srv_from_addrinfo(obj->resolver_results, ai);
obj->current_peer_cname = srv ? belle_sip_dns_srv_get_target(srv) : NULL;
if (obj->current_peer_cname){
belle_sip_message("channel[%p]: current peer hostname is [%s].", obj, obj->current_peer_cname);
}
}else{
obj->current_peer_cname = NULL;
}
obj->current_peer = ai;
}
static void belle_sip_channel_handle_error(belle_sip_channel_t *obj){
if (obj->state!=BELLE_SIP_CHANNEL_READY || obj->soft_error){
/* Previous connection attempts were failed (channel could not get ready) OR soft error reported*/
obj->soft_error = FALSE;
/* See if you can retry on an alternate ip address.*/
if (obj->current_peer && obj->current_peer->ai_next){ /*obj->current_peer may be null in case of dns error*/
obj->current_peer=obj->current_peer->ai_next;
channel_set_current_peer(obj, obj->current_peer->ai_next);
channel_set_state(obj,BELLE_SIP_CHANNEL_RETRY);
belle_sip_channel_close(obj);
belle_sip_main_loop_do_later(obj->stack->ml,(belle_sip_callback_t)channel_connect_next,belle_sip_object_ref(obj));
......@@ -1440,50 +1455,63 @@ static int channel_dns_ttl_timeout(void *data, unsigned int event) {
return BELLE_SIP_STOP;
}
static bool_t addrinfo_in_list(const struct addrinfo *ai, const struct addrinfo *list) {
/* returns the addrinfo from list that matches 'ai' in terms of content*/
static const struct addrinfo* addrinfo_in_list(const struct addrinfo *ai, const struct addrinfo *list) {
const struct addrinfo *item = list;
bool_t in_list = FALSE;
while (item != NULL) {
if ((ai->ai_family == item->ai_family) && (bctbx_sockaddr_equals(ai->ai_addr, item->ai_addr))) {
in_list = TRUE;
break;
return item;
}
item = item->ai_next;
}
return in_list;
return NULL;
}
static bool_t addrinfo_is_first(const struct addrinfo *ai, const struct addrinfo *list) {
/* returns the first addrinfo from list, if it is matching 'ai' in terms content*/
static const struct addrinfo * addrinfo_is_first(const struct addrinfo *ai, const struct addrinfo *list) {
if (list != NULL && (ai->ai_family == list->ai_family) && (bctbx_sockaddr_equals(ai->ai_addr, list->ai_addr)))
return TRUE;
return FALSE;
return list;
return NULL;
}
static void channel_res_done(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl){
static void channel_res_done(void *data, belle_sip_resolver_results_t *results){
belle_sip_channel_t *obj=(belle_sip_channel_t*)data;
const struct addrinfo *ai_list = NULL;
const char *name = NULL;
if (obj->resolver_ctx){
belle_sip_object_unref(obj->resolver_ctx);
obj->resolver_ctx=NULL;
}
if (results){
ai_list = belle_sip_resolver_results_get_addrinfos(results);
SET_OBJECT_PROPERTY(obj, resolver_results, results);
name = belle_sip_resolver_results_get_name(results);
}
if (ai_list){
int ttl = belle_sip_resolver_results_get_ttl(results);
obj->peer_list = ai_list;
if (!obj->current_peer) {
obj->peer_list=obj->current_peer=ai_list;
channel_set_current_peer(obj, ai_list);
channel_set_state(obj,BELLE_SIP_CHANNEL_RES_DONE);
} else {
bool_t check;
const struct addrinfo *existing_peer;
if (belle_sip_stack_reconnect_to_primary_asap_enabled(obj->stack)) {
check = addrinfo_is_first(obj->current_peer, ai_list);
existing_peer = addrinfo_is_first(obj->current_peer, ai_list);
} else {
check = addrinfo_in_list(obj->current_peer, ai_list);
existing_peer = addrinfo_in_list(obj->current_peer, ai_list);
}
if (check) {
if (existing_peer) {
belle_sip_message("channel[%p]: DNS resolution returned the currently used address, continue using it", obj);
obj->peer_list = ai_list;
channel_set_current_peer(obj, existing_peer);
channel_set_state(obj, BELLE_SIP_CHANNEL_READY);
} else {
belle_sip_message("channel[%p]: DNS resolution returned an address different than the one being used, reconnect to the new address", obj);
obj->peer_list = obj->current_peer = ai_list;
channel_set_current_peer(obj, ai_list);
belle_sip_channel_close(obj);
belle_sip_main_loop_do_later(obj->stack->ml, (belle_sip_callback_t)channel_connect_next, belle_sip_object_ref(obj));
channel_set_state(obj, BELLE_SIP_CHANNEL_RETRY);
......
......@@ -94,16 +94,19 @@ struct belle_sip_channel{
belle_sip_list_t *state_listeners;
belle_sip_list_t *full_listeners;
int ai_family;
char *peer_cname;
char *peer_name;
char *peer_cname; /* A or SRV name */
char *peer_name; /* A or SRV name */
int peer_port;
char *local_ip;
int local_port;
char *public_ip;
int public_port;
belle_sip_resolver_context_t* resolver_ctx;
struct addrinfo *peer_list;
struct addrinfo *current_peer;
belle_sip_resolver_results_t* resolver_results;
struct addrinfo *static_peer_list; /*this is the addrinfo when the channel is instanciated from destination IP address directly (no dns resolution)*/
const struct addrinfo *peer_list; /*points to the addrinfo list in resolver_results, or to the static_peer_list*/
const struct addrinfo *current_peer; /*points in the currently used element in peer_list */
const char *current_peer_cname; /*name of the host we are currently connected to. Set only in SRV case*/
belle_sip_list_t *outgoing_messages;
belle_sip_message_t *cur_out_message;
output_stream_state_t out_state;
......
......@@ -414,17 +414,18 @@ static int tls_channel_connect_to(belle_sip_channel_t *obj, const struct addrinf
return -1;
}
static void http_proxy_res_done(void *data, const char *name, struct addrinfo *ai_list, uint32_t ttl){
static void http_proxy_res_done(void *data, belle_sip_resolver_results_t *results){
belle_sip_tls_channel_t *obj=(belle_sip_tls_channel_t*)data;
const struct addrinfo *ai_list;
if (obj->http_proxy_resolver_ctx){
belle_sip_object_unref(obj->http_proxy_resolver_ctx);
obj->http_proxy_resolver_ctx=NULL;
}
ai_list = belle_sip_resolver_results_get_addrinfos(results);
if (ai_list){
tls_channel_connect_to((belle_sip_channel_t *)obj,ai_list);
bctbx_freeaddrinfo(ai_list);
}else{
belle_sip_error("%s: DNS resolution failed for %s", __FUNCTION__, name);
belle_sip_error("%s: DNS resolution failed for %s", __FUNCTION__, belle_sip_resolver_results_get_name(results));
channel_set_state((belle_sip_channel_t*)obj,BELLE_SIP_CHANNEL_ERROR);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment