Commit fcc83e64 authored by Simon Morlat's avatar Simon Morlat

Fix crash in mdns resolver due to closing of pipe's file descriptors not initialized.

parent 836b3051
......@@ -96,6 +96,8 @@ static void belle_sip_mdns_register_reply(DNSServiceRef service_ref
if (error_code != kDNSServiceErr_NoError) {
belle_sip_error("%s error while registering %s [%s%s]: code %d", __FUNCTION__, name, type, domain, error_code);
error = -1;
}else{
belle_sip_message("mDNS register of %s/%s/%s completed.", name, type, domain);
}
if (reg->cb) reg->cb(reg->data, error);
......@@ -176,7 +178,7 @@ belle_sip_mdns_register_t *belle_sip_mdns_register(const char *service, const ch
return NULL;
}
}
belle_sip_message("MDNS register of %s/%s/%s/%s starting.", service, transport, domain, name);
return reg;
#else
return NULL;
......@@ -186,6 +188,8 @@ belle_sip_mdns_register_t *belle_sip_mdns_register(const char *service, const ch
void belle_sip_mdns_unregister(belle_sip_mdns_register_t *reg) {
#ifdef HAVE_MDNS
if (!reg) return;
belle_sip_message("MDNS unregistering service.");
if (reg->running) {
reg->running = FALSE;
......
......@@ -139,6 +139,7 @@ struct belle_sip_simple_resolver_context{
char *srv_name;
int resolving;
bool_t result;
bool_t browse_should_continue;
#endif
#if defined(USE_GETADDRINFO_FALLBACK) || defined(HAVE_MDNS)
struct addrinfo *getaddrinfo_ai_list;
......@@ -152,6 +153,7 @@ struct belle_sip_simple_resolver_context{
int ctlpipe[2];
#endif
#endif
bool_t not_using_dns_socket;
};
struct belle_sip_combined_resolver_context{
......@@ -656,15 +658,45 @@ static void _resolver_getaddrinfo_start(belle_sip_simple_resolver_context_t *ctx
}
fd = ctx->ctlpipe[0];
#endif
belle_sip_message("Starting getaddrinfo() thread.");
bctbx_thread_create(&ctx->getaddrinfo_thread, NULL, _resolver_getaddrinfo_thread, ctx);
ctx->getaddrinfo_source = belle_sip_fd_source_new((belle_sip_source_func_t)_resolver_getaddrinfo_callback, ctx, fd, BELLE_SIP_EVENT_READ, -1);
belle_sip_main_loop_add_source(ctx->base.stack->ml, ctx->getaddrinfo_source);
}
#endif
#if defined(HAVE_MDNS)
static int is_mdns_query(const char *name){
const char *suffix;
char *tmp = NULL;
int ret;
int len = strlen(name);
if (len > 0 && name[len-1] == '.'){
tmp = belle_sip_strdup(name);
tmp[len-1] = '\0';
name = tmp;
}
/* Check if name ends with .local to determine if we'll use multicast DNS or not */
suffix = strrchr(name, '.');
ret = suffix && strcmp(suffix, ".local") == 0;
if (tmp) belle_sip_free(tmp);
return ret;
}
#endif
static int _resolver_send_query(belle_sip_simple_resolver_context_t *ctx) {
int error = 0;
#if defined(HAVE_MDNS)
if (is_mdns_query(ctx->name)){
ctx->not_using_dns_socket = TRUE;
_resolver_getaddrinfo_start(ctx);
return 0;
}
#endif
if (!ctx->base.stack->resolver_send_error) {
error = dns_res_submit(ctx->R, ctx->name, ctx->type, DNS_C_IN);
if (error)
......@@ -684,7 +716,7 @@ static int _resolver_send_query(belle_sip_simple_resolver_context_t *ctx) {
/*only init source if res inprogress*/
/*the timeout set to the source is 1 s, this is to allow dns.c to send request retransmissions*/
belle_sip_socket_source_init((belle_sip_source_t*)ctx, (belle_sip_source_func_t)resolver_process_data, ctx, dns_res_pollfd(ctx->R), BELLE_SIP_EVENT_READ | BELLE_SIP_EVENT_TIMEOUT, 1000);
#if defined(USE_GETADDRINFO_FALLBACK) || defined(HAVE_MDNS)
#if defined(USE_GETADDRINFO_FALLBACK)
{
int timeout = belle_sip_stack_get_dns_timeout(ctx->base.stack);
if ((timeout != 0) && ((ctx->type == DNS_T_A) || (ctx->type == DNS_T_AAAA))) {
......@@ -726,8 +758,14 @@ belle_sip_mdns_source_t *belle_sip_mdns_source_new(DNSServiceRef service_ref, be
return obj;
}
static void belle_sip_mdns_source_destroy(belle_sip_mdns_source_t *obj){
if (obj->service_ref){
DNSServiceRefDeallocate(obj->service_ref);
}
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_mdns_source_t);
BELLE_SIP_INSTANCIATE_VPTR(belle_sip_mdns_source_t, belle_sip_source_t, NULL, NULL, NULL, TRUE);
BELLE_SIP_INSTANCIATE_VPTR(belle_sip_mdns_source_t, belle_sip_source_t, belle_sip_mdns_source_destroy, NULL, NULL, TRUE);
static void resolver_process_mdns_resolve(DNSServiceRef service_ref
, DNSServiceFlags flags
......@@ -765,15 +803,21 @@ static void resolver_process_mdns_resolve(DNSServiceRef service_ref
weight = atoi(weight_value);
belle_sip_dns_srv_t *b_srv = belle_sip_dns_srv_create_raw(prio, weight, port, hosttarget);
if (!belle_sip_list_find_custom(ctx->srv_list, srv_compare_host_and_port, b_srv))
if (!belle_sip_list_find_custom(ctx->srv_list, srv_compare_host_and_port, b_srv)){
ctx->srv_list = belle_sip_list_insert_sorted(ctx->srv_list, belle_sip_object_ref(b_srv), srv_compare_prio);
else
belle_sip_dns_srv_destroy(b_srv);
}else{
belle_sip_object_unref(b_srv);
}
belle_sip_free(prio_value);
belle_sip_free(weight_value);
belle_sip_message("mDNS %s resolved to [target:%s port:%d prio:%d weight:%d]", ctx->name, hosttarget, port, prio, weight);
if (flags & kDNSServiceFlagsMoreComing){
belle_sip_message("resolver_process_mdns_resolve(): more coming");
}else{
}
} else {
belle_sip_warning("%s TXT record of %s does not contain a priority or weight key!", __FUNCTION__, hosttarget);
}
......@@ -782,6 +826,7 @@ static void resolver_process_mdns_resolve(DNSServiceRef service_ref
static int resolver_process_mdns_resolve_result(belle_sip_mdns_source_t *source, unsigned int revents) {
if (revents & BELLE_SIP_EVENT_READ) {
belle_sip_message("resolver_process_mdns_resolve_result(): have data");
DNSServiceProcessResult(source->service_ref);
}
......@@ -790,9 +835,8 @@ static int resolver_process_mdns_resolve_result(belle_sip_mdns_source_t *source,
if (source->ctx->resolving == 0) {
/* There is no resolve left, we can notify */
belle_sip_resolver_context_notify(BELLE_SIP_RESOLVER_CONTEXT(source->ctx));
belle_sip_message("resolver_process_mdns_resolve_result(): have notfied, job finished");
}
DNSServiceRefDeallocate(source->service_ref);
return BELLE_SIP_STOP;
}
return BELLE_SIP_CONTINUE;
......@@ -812,6 +856,7 @@ static void resolver_process_mdns_browse(DNSServiceRef service_ref
DNSServiceRef resolve_ref;
DNSServiceErrorType error;
belle_sip_message("resolver_process_mdns_browse(): found %s/%s/%s, starting DNSServiceResolve()", name, type, domain);
error = DNSServiceResolve(&resolve_ref, 0, interface, name, type, domain, (DNSServiceResolveReply)resolver_process_mdns_resolve, ctx);
if (error == kDNSServiceErr_NoError) {
......@@ -820,6 +865,11 @@ static void resolver_process_mdns_browse(DNSServiceRef service_ref
belle_sip_mdns_source_t *source = belle_sip_mdns_source_new(resolve_ref, ctx, (belle_sip_source_func_t)resolver_process_mdns_resolve_result, 1000);
belle_sip_main_loop_add_source(ctx->base.stack->ml, (belle_sip_source_t*)source);
if (flags & kDNSServiceFlagsMoreComing){
belle_sip_message("resolver_process_mdns_browse(): more coming.");
}else{
ctx->browse_should_continue = FALSE;
}
} else {
belle_sip_error("%s DNSServiceResolve error [%s]: code %d", __FUNCTION__, ctx->name, error);
}
......@@ -828,40 +878,36 @@ static void resolver_process_mdns_browse(DNSServiceRef service_ref
static int resolver_process_mdns_browse_result(belle_sip_mdns_source_t *source, unsigned int revents) {
if (revents & BELLE_SIP_EVENT_READ) {
belle_sip_message("resolver_process_mdns_browse_result() we have data.");
DNSServiceProcessResult(source->service_ref);
}
if (revents & BELLE_SIP_EVENT_TIMEOUT) {
belle_sip_message("resolver_process_mdns_browse_result() timeout.");
if (!source->ctx->result) {
belle_sip_resolver_context_notify(BELLE_SIP_RESOLVER_CONTEXT(source->ctx));
}
DNSServiceRefDeallocate(source->service_ref);
return BELLE_SIP_STOP;
}
return BELLE_SIP_CONTINUE;
return source->ctx->browse_should_continue;;
}
#endif
static int _resolver_start_query(belle_sip_simple_resolver_context_t *ctx) {
#ifdef HAVE_MDNS
char *suffix;
if (!ctx->name) return -1;
/* Check if name ends with .local to determine if we'll use multicast DNS or not */
suffix = strrchr(ctx->name, '.');
if (suffix && strcmp(suffix, ".local") == 0 && ctx->type == DNS_T_SRV) {
if (is_mdns_query(ctx->name) && ctx->type == DNS_T_SRV) {
DNSServiceErrorType error;
DNSServiceRef browse_ref;
ctx->browse_should_continue = TRUE;
error = DNSServiceBrowse(&browse_ref, 0, 0, ctx->srv_prefix, ctx->srv_name, (DNSServiceBrowseReply)resolver_process_mdns_browse, ctx);
if (error == kDNSServiceErr_NoError) {
belle_sip_mdns_source_t *source = belle_sip_mdns_source_new(browse_ref, ctx, (belle_sip_source_func_t)resolver_process_mdns_browse_result, 5000);
belle_sip_main_loop_add_source(ctx->base.stack->ml, (belle_sip_source_t*)source);
belle_sip_message("DNSServiceBrowse() started for %s/%s", ctx->srv_prefix, ctx->srv_name);
return 0;
} else {
belle_sip_error("%s DNSServiceBrowse error [%s]: code %d", __FUNCTION__, ctx->name, error);
......@@ -904,7 +950,7 @@ static int _resolver_start_query(belle_sip_simple_resolver_context_t *ctx) {
} else {
error=_resolver_send_query(ctx);
}
if (error==0 && !ctx->base.notified) belle_sip_main_loop_add_source(ctx->base.stack->ml,(belle_sip_source_t*)ctx);
if (error==0 && !ctx->base.notified && !ctx->not_using_dns_socket) belle_sip_main_loop_add_source(ctx->base.stack->ml,(belle_sip_source_t*)ctx);
return error;
#ifdef HAVE_MDNS
}
......@@ -954,15 +1000,16 @@ static void belle_sip_simple_resolver_context_destroy(belle_sip_simple_resolver_
#if defined(USE_GETADDRINFO_FALLBACK) || defined(HAVE_MDNS)
if (ctx->getaddrinfo_thread != 0) {
bctbx_thread_join(ctx->getaddrinfo_thread, NULL);
}
if (ctx->getaddrinfo_source) belle_sip_object_unref(ctx->getaddrinfo_source);
#ifdef _WIN32
if (ctx->ctlevent != (belle_sip_fd_t)-1)
CloseHandle(ctx->ctlevent);
if (ctx->ctlevent != (belle_sip_fd_t)-1)
CloseHandle(ctx->ctlevent);
#else
close(ctx->ctlpipe[0]);
close(ctx->ctlpipe[1]);
close(ctx->ctlpipe[0]);
close(ctx->ctlpipe[1]);
#endif
}
if (ctx->getaddrinfo_source) belle_sip_object_unref(ctx->getaddrinfo_source);
#endif
if (ctx->ai_list != NULL) {
......
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