Commit d6b09079 authored by Mickaël Turnel's avatar Mickaël Turnel

Merge branch 'dev_multicast_dns'

parents c499446e aa36b275
......@@ -40,6 +40,7 @@ option(ENABLE_RTP_MAP_ALWAYS_IN_SDP "Always include rtpmap in SDP." OFF)
option(ENABLE_STRICT "Build with strict compile options." YES)
option(ENABLE_TUNNEL "Enable tunnel support" OFF)
option(ENABLE_TESTS "Enable compilation of tests" ON)
option(ENABLE_MDNS "Enable multicast DNS" OFF)
include(CheckLibraryExists)
......@@ -114,6 +115,13 @@ if(ZLIB_FOUND)
set(HAVE_ZLIB 1)
endif()
if(ENABLE_MDNS)
find_package(DNSSD REQUIRED)
if(DNSSD_FOUND)
set(HAVE_MDNS 1)
endif()
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
......@@ -152,6 +160,9 @@ endif()
if(ZLIB_FOUND)
include_directories(${ZLIB_INCLUDE_DIRS})
endif()
if(DNSSD_FOUND)
include_directories(${DNSSD_INCLUDE_DIRS})
endif()
if(MSVC)
include_directories(${MSVC_INCLUDE_DIR})
endif()
......
#
# Copyright 2011 Stefan Eilemann <eile@eyescale.ch>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# - Neither the name of Eyescale Software GmbH nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
#==================================
#
# - Find ZeroConf headers
#
#==================================
#
# The following environment variables are respected for finding Dnssd.
# CMAKE_PREFIX_PATH can also be used for this (see find_library() CMake
# documentation).
#
# DNSSD_ROOT
#
# This module defines the following output variables:
#
# DNSSD_FOUND - Was Dnssd and all of the specified components found?
#
# DNSSD_INCLUDE_DIRS - Where to find the headers
#
# DNSSD_LIBRARIES - The Dnssd libraries
#
#==================================
# Example Usage:
#
# find_package(DNSSD REQUIRED)
# include_directories(${DNSSD_INCLUDE_DIRS})
#
# add_executable(foo foo.cc)
# target_link_libraries(foo ${DNSSD_LIBRARIES})
#
#==================================
# Naming convention:
# Local variables of the form _dnssd_foo
# Output variables of the form DNSSD_FOO
#
if(WIN32)
if("$ENV{ProgramW6432}" STREQUAL "")
set(_dnssd_lib_paths "$ENV{ProgramFiles}/Bonjour SDK")
else()
set(_dnssd_lib_paths "$ENV{ProgramW6432}/Bonjour SDK")
endif()
else()
list(APPEND _dnssd_lib_paths /usr /usr/local /opt/local /opt)
endif()
find_path(_dnssd_INCLUDE_DIR dns_sd.h
HINTS $ENV{DNSSD_ROOT} ${DNSSD_ROOT}
PATH_SUFFIXES include
PATHS ${_dnssd_lib_paths}
)
if(DNSSD_FIND_REQUIRED)
set(_dnssd_output_type FATAL_ERROR)
set(_dnssd_output 1)
else()
set(_dnssd_output_type STATUS)
if(NOT DNSSD_FIND_QUIETLY)
set(_dnssd_output 1)
endif()
endif()
if(NOT _dnssd_INCLUDE_DIR)
set(_dnssd_EPIC_FAIL TRUE)
if(_dnssd_output)
message(${_dnssd_output_type} "Can't find dns_sd.h header file.")
endif()
endif()
if(APPLE)
find_library(_dnssd_LIBRARY System
HINTS $ENV{DNSSD_ROOT} ${DNSSD_ROOT}
PATH_SUFFIXES lib PATHS ${_dnssd_lib_paths}
)
elseif(WIN32)
if("${CMAKE_SHARED_LINKER_FLAGS}" MATCHES "x64")
set(_dnssd_lib_postfix "x64")
else()
set(_dnssd_lib_postfix "Win32")
endif()
find_library(_dnssd_LIBRARY dnssd.lib
HINTS $ENV{DNSSD_ROOT} ${DNSSD_ROOT}
PATH_SUFFIXES lib
PATHS ${_dnssd_lib_paths}/Lib/${_dnssd_lib_postfix})
else()
find_library(_dnssd_LIBRARY dns_sd
HINTS $ENV{DNSSD_ROOT} ${DNSSD_ROOT}
PATH_SUFFIXES lib PATHS ${_dnssd_lib_paths}
)
endif()
if(DNSSD_FIND_REQUIRED)
if(_dnssd_LIBRARY MATCHES "_dnssd_LIBRARY-NOTFOUND")
set(_dnssd_EPIC_FAIL TRUE)
message(FATAL_ERROR "Missing the ZeroConf library.\n"
"Consider using CMAKE_PREFIX_PATH or the DNSSD_ROOT environment variable. "
"See the ${CMAKE_CURRENT_LIST_FILE} for more details.")
endif()
endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(DNSSD DEFAULT_MSG
_dnssd_LIBRARY _dnssd_INCLUDE_DIR)
if(_dnssd_EPIC_FAIL)
# Zero out everything, we didn't meet version requirements
set(DNSSD_FOUND FALSE)
set(_dnssd_LIBRARY)
set(_dnssd_INCLUDE_DIR)
endif()
set(DNSSD_INCLUDE_DIRS ${_dnssd_INCLUDE_DIR})
set(DNSSD_LIBRARIES ${_dnssd_LIBRARY})
if(DNSSD_FOUND AND _dnssd_output)
message(STATUS "Found ZeroConf in ${DNSSD_INCLUDE_DIRS};${DNSSD_LIBRARIES}")
endif()
......@@ -42,3 +42,5 @@
#cmakedefine BELLE_SDP_FORCE_RTP_MAP
#cmakedefine ENABLE_SERVER_SOCKETS
#cmakedefine HAVE_MDNS
......@@ -37,6 +37,7 @@ set(HEADER_FILES
listener.h
listeningpoint.h
mainloop.h
mdns_register.h
message.h
object.h
parameters.h
......
......@@ -42,6 +42,7 @@
#include "belle-sip/http-message.h"
#include "belle-sip/belle-sdp.h"
#include "belle-sip/bodyhandler.h"
#include "belle-sip/mdns_register.h"
#ifdef __ANDROID__
#include "belle-sip/wakelock.h"
......
/*
belle-sip - SIP (RFC3261) library.
Copyright (C) 2010 Belledonne Communications SARL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BELLE_SIP_MDNS_REGISTER_H
#define BELLE_SIP_MDNS_REGISTER_H
typedef struct belle_sip_mdns_register belle_sip_mdns_register_t;
#define BELLE_SIP_MDNS_REGISTER(obj) BELLE_SIP_CAST(obj,belle_sip_mdns_register_t)
/**
* Callback prototype for asynchronous multicast DNS registration (advertisement).
*/
typedef void (*belle_sip_mdns_register_callback_t)(void *data, int error);
BELLE_SIP_BEGIN_DECLS
/**
* Asynchronously performs the mdns registration (advertisement).
* @param service the queried service ("sip", "stun", "turn"...).
* @param transport the queried transport ("udp", "tcp", "tls").
* @param domain the local domain name in which the service will be registered.
* @param name the name of the mdns service, if NULL it is the computer's name. Only useful for multiple registrations to avoid conflicts.
* @param port the port of the service.
* @param priority the priority of the service, lower value means more preferred.
* @param weight a relative weight for services within the same local domain that have the same priority, higher value means more preferred.
* @param cb a callback function that will be called to notify the results.
* @param data a user pointer passed through the callback as first argument.
* @return a #belle_sip_register_t that can be used to cancel the registration if needed. The context must have been ref'd with belle_sip_object_ref().
**/
BELLESIP_EXPORT belle_sip_mdns_register_t *belle_sip_mdns_register(const char *service, const char *transport, const char *domain, const char* name, int port, int prio, int weight, belle_sip_mdns_register_callback_t cb, void *data);
/**
* Cancels the mdns registration.
* @param context the belle_sip_mdns_register_t used to register the service.
**/
BELLESIP_EXPORT void belle_sip_mdns_unregister(belle_sip_mdns_register_t *context);
BELLE_SIP_END_DECLS
#endif /* BELLE_SIP_MDNS_REGISTER_H */
\ No newline at end of file
......@@ -51,6 +51,7 @@ BELLE_SIP_DECLARE_TYPES_BEGIN(belle_sip,1)
BELLE_SIP_TYPE_ID(belle_sip_provider_t),
BELLE_SIP_TYPE_ID(belle_sip_main_loop_t),
BELLE_SIP_TYPE_ID(belle_sip_source_t),
BELLE_SIP_TYPE_ID(belle_sip_mdns_source_t),
BELLE_SIP_TYPE_ID(belle_sip_resolver_context_t),
BELLE_SIP_TYPE_ID(belle_sip_transaction_t),
BELLE_SIP_TYPE_ID(belle_sip_server_transaction_t),
......@@ -145,7 +146,8 @@ BELLE_SIP_DECLARE_TYPES_BEGIN(belle_sip,1)
BELLE_SIP_TYPE_ID(belle_sip_header_content_disposition_t),
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_header_authentication_info_t),
BELLE_SIP_TYPE_ID(belle_sip_mdns_register_t)
BELLE_SIP_DECLARE_TYPES_END
......
......@@ -58,6 +58,12 @@ endif()
if(ZLIB_FOUND)
list(APPEND LIBS ${ZLIB_LIBRARIES})
endif()
if(DNSSD_FOUND)
set(MDNS_SOURCE_FILES_C
belle_sip_mdns_register.c
)
list(APPEND LIBS ${DNSSD_LIBRARIES})
endif()
if(WIN32)
list(APPEND LIBS ws2_32)
endif()
......@@ -151,6 +157,7 @@ set(BELLE_SIP_SOURCE_FILES_C
${SDP_GENERATED_SOURCE_FILES_C}
${SIP_MESSAGE_GENERATED_SOURCE_FILES_C}
${TUNNEL_SOURCE_FILES_C}
${MDNS_SOURCE_FILES_C}
)
add_definitions(
......
......@@ -228,6 +228,10 @@ BELLE_SIP_DECLARE_VPTR(belle_sip_header_content_disposition_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_accept_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_reason_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_authentication_info_t);
#ifdef HAVE_MDNS
BELLE_SIP_DECLARE_VPTR(belle_sip_mdns_source_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_mdns_register_t);
#endif
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_resolver_context_t,belle_sip_source_t)
......
......@@ -260,11 +260,10 @@ struct belle_sip_main_loop{
};
void belle_sip_main_loop_remove_source(belle_sip_main_loop_t *ml, belle_sip_source_t *source){
bool_t elem_removed = FALSE;
int unrefs = 0;
if (source->node.next || source->node.prev || &source->node==ml->fd_sources) {
ml->fd_sources=belle_sip_list_remove_link(ml->fd_sources,&source->node);
belle_sip_object_unref(source);
elem_removed = TRUE;
unrefs++;
}
if (source->it) {
bctbx_mutex_lock(&ml->timer_sources_mutex);
......@@ -273,15 +272,18 @@ void belle_sip_main_loop_remove_source(belle_sip_main_loop_t *ml, belle_sip_sour
bctbx_mutex_unlock(&ml->timer_sources_mutex);
source->it=NULL;
belle_sip_object_unref(source);
elem_removed = TRUE;
unrefs++;
}
if (elem_removed) {
if (unrefs) {
source->cancelled=TRUE;
ml->nsources--;
if (source->on_remove)
source->on_remove(source);
while(unrefs) {
belle_sip_object_unref(source);
unrefs--;
}
}
}
......
/*
belle-sip - SIP (RFC3261) library.
Copyright (C) 2010 Belledonne Communications SARL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "belle_sip_internal.h"
#include <bctoolbox/defs.h>
#include <dns_sd.h>
#ifndef _WIN32
#include <unistd.h>
#include <poll.h>
typedef struct pollfd belle_sip_pollfd_t;
static int belle_sip_poll(belle_sip_pollfd_t *pfd, int count, int duration) {
int err = poll(pfd, count, duration);
if (err == -1 && errno != EINTR)
belle_sip_error("poll() error: %s",strerror(errno));
return err;
}
#else
#include <winsock2.h>
typedef WSAPOLLFD belle_sip_pollfd_t;
static int belle_sip_poll(belle_sip_pollfd_t *pfd, int count, int duration) {
int err = WSAPoll(pfd, count, duration);
if (err == SOCKET_ERROR)
belle_sip_error("WSAPoll() error: %d", WSAGetLastError());
return err;
}
#endif
struct belle_sip_mdns_register {
belle_sip_object_t base;
DNSServiceRef service_ref;
belle_sip_mdns_register_callback_t cb;
void *data;
bctbx_thread_t thread;
volatile bool_t running;
};
belle_sip_mdns_register_t *belle_sip_mdns_register_create(belle_sip_mdns_register_callback_t cb, void *data) {
belle_sip_mdns_register_t *obj = belle_sip_object_new(belle_sip_mdns_register_t);
obj->cb = cb;
obj->data = data;
obj->running = FALSE;
return obj;
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_mdns_register_t);
BELLE_SIP_INSTANCIATE_VPTR(belle_sip_mdns_register_t, belle_sip_object_t, NULL, NULL, NULL, FALSE);
static char * srv_prefix_from_service_and_transport(const char *service, const char *transport) {
if (service == NULL) service = "sip";
if (strcasecmp(transport, "udp") == 0) {
return belle_sip_strdup_printf("_%s._udp.", service);
} else if (strcasecmp(transport, "tcp") == 0) {
return belle_sip_strdup_printf("_%s._tcp.", service);
} else if (strcasecmp(transport, "tls") == 0) {
return belle_sip_strdup_printf("_%ss._tcp.", service);
}
return belle_sip_strdup_printf("_%s._udp.", service);
}
static void belle_sip_mdns_register_reply(DNSServiceRef service_ref
, DNSServiceFlags flags
, DNSServiceErrorType error_code
, const char *name
, const char *type
, const char *domain
, void *data) {
belle_sip_mdns_register_t *reg = (belle_sip_mdns_register_t *)data;
int error = 0;
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;
}
if (reg->cb) reg->cb(reg->data, error);
}
void *mdns_register_poll(void *data) {
belle_sip_mdns_register_t *reg = (belle_sip_mdns_register_t *)data;
belle_sip_pollfd_t pollfd = {0};
pollfd.fd = DNSServiceRefSockFD(reg->service_ref);
pollfd.events = POLLIN;
reg->running = TRUE;
while(reg->running) {
int err = belle_sip_poll(&pollfd, 1, 1000);
if (err > 0) {
DNSServiceProcessResult(reg->service_ref);
}
}
return NULL;
}
belle_sip_mdns_register_t *belle_sip_mdns_register(const char *service, const char *transport, const char *domain, const char *name, int port, int prio, int weight, belle_sip_mdns_register_callback_t cb, void *data) {
belle_sip_mdns_register_t *reg = belle_sip_mdns_register_create(cb, data);
DNSServiceErrorType error;
TXTRecordRef txt_ref;
char number[10];
char *prefix;
int n;
TXTRecordCreate(&txt_ref, 0, NULL);
n = snprintf(number, sizeof(number), "%d", prio);
TXTRecordSetValue(&txt_ref, "prio\0", n, number);
n = snprintf(number, sizeof(number), "%d", weight);
TXTRecordSetValue(&txt_ref, "weight\0", n, number);
prefix = srv_prefix_from_service_and_transport(service, transport);
error = DNSServiceRegister(&reg->service_ref
, 0
, 0
, name
, prefix
, domain
, NULL
, port
, TXTRecordGetLength(&txt_ref)
, TXTRecordGetBytesPtr(&txt_ref)
, belle_sip_mdns_register_reply
, reg);
belle_sip_free(prefix);
TXTRecordDeallocate(&txt_ref);
if (error != kDNSServiceErr_NoError) {
belle_sip_error("%s Register error [_%s._%s.%s]: code %d", __FUNCTION__, service, transport, domain, error);
belle_sip_object_unref(reg);
return NULL;
} else {
int errnum = bctbx_thread_create(&reg->thread, NULL, mdns_register_poll, reg);
if (errnum != 0) {
belle_sip_error("%s Error creating register thread: code %d", __FUNCTION__, errnum);
belle_sip_object_unref(reg);
return NULL;
}
}
return reg;
}
void belle_sip_mdns_unregister(belle_sip_mdns_register_t *reg) {
if (!reg) return;
if (reg->running) {
reg->running = FALSE;
bctbx_thread_join(reg->thread, NULL);
}
DNSServiceRefDeallocate(reg->service_ref);
belle_sip_object_unref(reg);
}
\ No newline at end of file
This diff is collapsed.
......@@ -565,6 +565,95 @@ static void ipv4_and_ipv6_dns_server(void) {
destroy_endpoint(client);
}
#ifdef HAVE_MDNS
static void mdns_register_callback(void *data, int error) {
int *register_error = (int *)data;
*register_error = error;
}
static void mdns_query_ipv4_or_ipv6(int family) {
belle_sip_mdns_register_t *reg;
endpoint_t *client;
int register_error = -1;
client = create_endpoint();
reg = belle_sip_mdns_register("sip", "tcp", "test.linphone.local", NULL, 5060, 10, 100, mdns_register_callback, &register_error);
BC_ASSERT_PTR_NOT_NULL(reg);
BC_ASSERT_TRUE(wait_for(client->stack, &register_error, 0, 5000));
client->resolver_ctx = belle_sip_stack_resolve(client->stack, "sip", "tcp", "test.linphone.local", 5060, family, a_resolve_done, client);
BC_ASSERT_PTR_NOT_NULL(client->resolver_ctx);
BC_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, 6000));
BC_ASSERT_PTR_NOT_NULL(client->ai_list);
belle_sip_mdns_unregister(reg);
destroy_endpoint(client);
}
static void mdns_query(void) {
mdns_query_ipv4_or_ipv6(AF_INET);
}
static void mdns_query_ipv6(void) {
if (!belle_sip_tester_ipv6_available()){
belle_sip_warning("Test skipped, IPv6 connectivity not available.");
return;
}
mdns_query_ipv4_or_ipv6(AF_INET6);
}
static void mdns_query_no_result(void) {
endpoint_t *client;
client = create_endpoint();
client->resolver_ctx = belle_sip_stack_resolve(client->stack, "sip", "tcp", "test.linphone.local", 5060, AF_INET, a_resolve_done, client);
BC_ASSERT_PTR_NOT_NULL(client->resolver_ctx);
BC_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, 6000));
BC_ASSERT_PTR_NULL(client->ai_list);
destroy_endpoint(client);
}
static void mdns_query_multiple_result(void) {
belle_sip_mdns_register_t *reg1, *reg2;
endpoint_t *client;
int register_error = -1;
client = create_endpoint();
reg1 = belle_sip_mdns_register("sip", "tcp", "test.linphone.local", "Register1", 5060, 20, 100, mdns_register_callback, &register_error);
BC_ASSERT_PTR_NOT_NULL(reg1);
BC_ASSERT_TRUE(wait_for(client->stack, &register_error, 0, 5000));
reg2 = belle_sip_mdns_register("sip", "tcp", "test.linphone.local", "Register2", 5070, 10, 100, mdns_register_callback, &register_error);
BC_ASSERT_PTR_NOT_NULL(reg2);
BC_ASSERT_TRUE(wait_for(client->stack, &register_error, 0, 5000));
client->resolver_ctx = belle_sip_stack_resolve(client->stack, "sip", "tcp", "test.linphone.local", 5060, AF_INET, a_resolve_done, client);
BC_ASSERT_PTR_NOT_NULL(client->resolver_ctx);
BC_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, 6000));
BC_ASSERT_PTR_NOT_NULL(client->ai_list);
if (client->ai_list) {
/* The first adress should be the one registered on port 5070 since it has higher priority */
if (client->ai_list->ai_addr->sa_family == AF_INET) {
struct sockaddr_in *sock_in = (struct sockaddr_in *)client->ai_list->ai_addr;
BC_ASSERT_EQUAL((int)ntohs(sock_in->sin_port), 5070, int, "%d");
} else {
struct sockaddr_in6 *sock_in = (struct sockaddr_in6 *)client->ai_list->ai_addr;
BC_ASSERT_EQUAL((int)ntohs(sock_in->sin6_port), 5070, int, "%d");
}
}
belle_sip_mdns_unregister(reg1);
belle_sip_mdns_unregister(reg2);
destroy_endpoint(client);
}
#endif
test_t resolver_tests[] = {
TEST_NO_TAG("A query (IPv4)", ipv4_a_query),
TEST_NO_TAG("A query (IPv4) with CNAME", ipv4_cname_a_query),
......@@ -584,7 +673,13 @@ test_t resolver_tests[] = {
TEST_NO_TAG("DNS fallback because of scope link IPv6", dns_fallback_because_of_scope_link_ipv6),
TEST_NO_TAG("DNS fallback because of invalid IPv6", dns_fallback_because_of_invalid_ipv6),
TEST_NO_TAG("IPv6 DNS server", ipv6_dns_server),
TEST_NO_TAG("IPv4 and v6 DNS servers", ipv4_and_ipv6_dns_server)
TEST_NO_TAG("IPv4 and v6 DNS servers", ipv4_and_ipv6_dns_server),
#ifdef HAVE_MDNS
TEST_NO_TAG("MDNS query", mdns_query),
TEST_NO_TAG("MDNS query with ipv6", mdns_query_ipv6),
TEST_NO_TAG("MDNS query with no result", mdns_query_no_result),
TEST_NO_TAG("MDNS query with multiple result", mdns_query_multiple_result)
#endif
};
test_suite_t resolver_test_suite = {"Resolver", NULL, NULL, belle_sip_tester_before_each, belle_sip_tester_after_each,
......
......@@ -42,6 +42,9 @@ static void resolver_callback(void *data, const char *queried_name, struct addri
printf("\t%s %s (ttl:%u)\n",name,port,ttl);
}
}
if (ai_list){
bctbx_freeaddrinfo(ai_list);
}
belle_sip_main_loop_quit(belle_sip_stack_get_main_loop(stack));
}
......
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