Commit 28ec2db8 authored by Ghislain MARY's avatar Ghislain MARY
Browse files

Fix channel retry mechanism by using linked list of addrinfo structures...

Fix channel retry mechanism by using linked list of addrinfo structures instead of a belle_sip_list_t for DNS A and AAAA results.
parent d61c6772
......@@ -93,6 +93,17 @@ struct dns_cache *cache(belle_sip_resolver_context_t *ctx) {
return NULL;
}
static struct addrinfo * ai_list_append(struct addrinfo *ai_list, struct addrinfo *ai_to_append) {
struct addrinfo *ai_current = ai_list;
if (ai_to_append == NULL) return ai_list;
if (ai_list == NULL) return ai_to_append;
while (ai_current->ai_next != NULL) {
ai_current = ai_current->ai_next;
}
ai_current->ai_next = ai_to_append;
return ai_list;
}
static int resolver_process_data(belle_sip_resolver_context_t *ctx, unsigned int revents) {
char host[NI_MAXHOST + 1];
char service[NI_MAXSERV + 1];
......@@ -103,7 +114,11 @@ static int resolver_process_data(belle_sip_resolver_context_t *ctx, unsigned int
if (revents & BELLE_SIP_EVENT_TIMEOUT) {
belle_sip_error("%s timed-out", __FUNCTION__);
ctx->cb(ctx->cb_data, ctx->name, NULL);
if ((ctx->type == DNS_T_A) || (ctx->type == DNS_T_AAAA)) {
ctx->cb(ctx->cb_data, ctx->name, NULL);
} else if (ctx->type == DNS_T_SRV) {
ctx->srv_cb(ctx->cb_data, ctx->name, NULL);
}
ctx->done=TRUE;
return BELLE_SIP_STOP;
}
......@@ -137,7 +152,7 @@ static int resolver_process_data(belle_sip_resolver_context_t *ctx, unsigned int
sin6.sin6_port = ctx->port;
if (getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), host, sizeof(host), service, sizeof(service), NI_NUMERICHOST) != 0)
continue;
ctx->ai_list = belle_sip_list_append(ctx->ai_list, belle_sip_ip_address_to_addrinfo(ctx->family, host, ctx->port));
ctx->ai_list = ai_list_append(ctx->ai_list, belle_sip_ip_address_to_addrinfo(ctx->family, host, ctx->port));
belle_sip_message("%s resolved to %s", ctx->name, host);
} else if ((ctx->type == DNS_T_A) && (rr.class == DNS_C_IN) && (rr.type == DNS_T_A)) {
struct dns_a *a = &any.a;
......@@ -148,7 +163,7 @@ static int resolver_process_data(belle_sip_resolver_context_t *ctx, unsigned int
sin.sin_port = ctx->port;
if (getnameinfo((struct sockaddr *)&sin, sizeof(sin), host, sizeof(host), service, sizeof(service), NI_NUMERICHOST) != 0)
continue;
ctx->ai_list = belle_sip_list_append(ctx->ai_list, belle_sip_ip_address_to_addrinfo(ctx->family, host, ctx->port));
ctx->ai_list = ai_list_append(ctx->ai_list, belle_sip_ip_address_to_addrinfo(ctx->family, host, ctx->port));
belle_sip_message("%s resolved to %s", ctx->name, host);
} else if ((ctx->type == DNS_T_SRV) && (rr.class == DNS_C_IN) && (rr.type == DNS_T_SRV)) {
struct dns_srv *srv = &any.srv;
......@@ -164,7 +179,7 @@ static int resolver_process_data(belle_sip_resolver_context_t *ctx, unsigned int
if ((ctx->type == DNS_T_A) || (ctx->type == DNS_T_AAAA)) {
ctx->cb(ctx->cb_data, ctx->name, ctx->ai_list);
} else if (ctx->type == DNS_T_SRV) {
ctx->cb(ctx->cb_data, ctx->name, ctx->srv_list);
ctx->srv_cb(ctx->cb_data, ctx->name, ctx->srv_list);
}
ctx->done=TRUE;
return BELLE_SIP_STOP;
......@@ -334,13 +349,12 @@ unsigned long belle_sip_resolve(belle_sip_stack_t *stack, const char *name, int
return 0; /*resolution done synchronously*/
}
} else {
belle_sip_list_t *ai_list = belle_sip_list_append(NULL, res);
cb(data, name, ai_list);
cb(data, name, res);
return 0;
}
}
unsigned long belle_sip_resolve_srv(belle_sip_stack_t *stack, const char *name, const char *transport, belle_sip_resolver_callback_t cb, void *data, belle_sip_main_loop_t *ml) {
unsigned long belle_sip_resolve_srv(belle_sip_stack_t *stack, const char *name, const char *transport, belle_sip_resolver_srv_callback_t cb, void *data, belle_sip_main_loop_t *ml) {
belle_sip_resolver_context_t *ctx = belle_sip_object_new(belle_sip_resolver_context_t);
char *prefix;
if (strcasecmp(transport, "udp") == 0) {
......@@ -354,7 +368,7 @@ unsigned long belle_sip_resolve_srv(belle_sip_stack_t *stack, const char *name,
}
ctx->stack = stack;
ctx->cb_data = data;
ctx->cb = cb;
ctx->srv_cb = cb;
ctx->name = belle_sip_concat(prefix, name, NULL);
ctx->type = DNS_T_SRV;
if (resolver_start_query(ctx,
......
......@@ -29,20 +29,24 @@ 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)
/**
* Callback prototype for asynchronous DNS resolution.
* The results_list contents depends on the type of DNS query.
* If the DNS query is of type A or AAAA, the results_list contains addrinfo elements that must be
* taken and (possibly later) freed by the callee, using freeaddrinfo().
* If the DNS query is of type SRV, the results_list contains struct dns_srv elements that must be
* taken and (possibly later) freed by the callee, using belle_sip_free().
* 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.
**/
typedef void (*belle_sip_resolver_callback_t)(void *data, const char *name, belle_sip_list_t *results_list);
typedef void (*belle_sip_resolver_callback_t)(void *data, const char *name, struct addrinfo *ai_list);
/**
* 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().
*/
typedef void (*belle_sip_resolver_srv_callback_t)(void *data, const char *name, belle_sip_list_t *srv_list);
struct belle_sip_resolver_context{
belle_sip_source_t source;
belle_sip_stack_t *stack;
belle_sip_resolver_callback_t cb;
belle_sip_resolver_srv_callback_t srv_cb;
void *cb_data;
struct dns_resolv_conf *resconf;
struct dns_hosts *hosts;
......@@ -50,7 +54,7 @@ struct belle_sip_resolver_context{
enum dns_type type;
char *name;
int port;
belle_sip_list_t *ai_list;
struct addrinfo *ai_list;
belle_sip_list_t *srv_list;
int family;
uint8_t cancelled;
......@@ -62,7 +66,7 @@ BELLE_SIP_BEGIN_DECLS
int belle_sip_addrinfo_to_ip(const struct addrinfo *ai, char *ip, size_t ip_size, int *port);
BELLESIP_INTERNAL_EXPORT struct addrinfo * belle_sip_ip_address_to_addrinfo(int family, const char *ipaddress, int port);
BELLESIP_INTERNAL_EXPORT unsigned long belle_sip_resolve(belle_sip_stack_t *stack, const char *name, int port, int family, belle_sip_resolver_callback_t cb, void *data, belle_sip_main_loop_t *ml);
BELLESIP_INTERNAL_EXPORT unsigned long belle_sip_resolve_srv(belle_sip_stack_t *stack, const char *name, const char *transport, belle_sip_resolver_callback_t cb, void *data, belle_sip_main_loop_t *ml);
BELLESIP_INTERNAL_EXPORT unsigned long belle_sip_resolve_srv(belle_sip_stack_t *stack, const char *name, const char *transport, belle_sip_resolver_srv_callback_t cb, void *data, belle_sip_main_loop_t *ml);
void belle_sip_resolve_cancel(belle_sip_main_loop_t *ml, unsigned long id);
/**
......
......@@ -54,14 +54,8 @@ static belle_sip_list_t * for_each_weak_unref_free(belle_sip_list_t *l, belle_si
return NULL;
}
static void belle_sip_channel_free_peer(void *ptr) {
struct addrinfo *ai = (struct addrinfo *)ptr;
freeaddrinfo(ai);
}
static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
belle_sip_list_for_each(obj->peer_list,belle_sip_channel_free_peer);
belle_sip_list_free(obj->peer_list);
if (obj->peer_list) freeaddrinfo(obj->peer_list);
belle_sip_free(obj->peer_cname);
belle_sip_free(obj->peer_name);
if (obj->local_ip) belle_sip_free(obj->local_ip);
......@@ -308,8 +302,7 @@ void belle_sip_channel_init_with_addr(belle_sip_channel_t *obj, belle_sip_stack_
ai.ai_addrlen=addrlen;
belle_sip_addrinfo_to_ip(&ai,remoteip,sizeof(remoteip),&peer_port);
belle_sip_channel_init(obj,stack,NULL,0,NULL,remoteip,peer_port);
obj->current_peer=belle_sip_ip_address_to_addrinfo(ai.ai_family, obj->peer_name,obj->peer_port);
obj->peer_list=belle_sip_list_prepend(obj->peer_list,obj->current_peer);
obj->peer_list=obj->current_peer=belle_sip_ip_address_to_addrinfo(ai.ai_family, obj->peer_name,obj->peer_port);
}
void belle_sip_channel_set_socket(belle_sip_channel_t *obj, belle_sip_socket_t sock, belle_sip_source_func_t datafunc){
......@@ -571,12 +564,11 @@ void belle_sip_channel_set_ready(belle_sip_channel_t *obj, const struct sockaddr
channel_process_queue(obj);
}
static void channel_res_done(void *data, const char *name, belle_sip_list_t *results_list){
static void channel_res_done(void *data, const char *name, struct addrinfo *ai_list){
belle_sip_channel_t *obj=(belle_sip_channel_t*)data;
obj->resolver_id=0;
if (results_list && (belle_sip_list_size(results_list)>0)){
obj->peer_list=results_list;
obj->current_peer=(struct addrinfo *)belle_sip_list_nth_data(obj->peer_list,0);
if (ai_list){
obj->peer_list=obj->current_peer=ai_list;
channel_set_state(obj,BELLE_SIP_CHANNEL_RES_DONE);
channel_prepare_continue(obj);
}else{
......
......@@ -85,7 +85,7 @@ struct belle_sip_channel{
char *local_ip;
int local_port;
unsigned long resolver_id;
belle_sip_list_t *peer_list;
struct addrinfo *peer_list;
struct addrinfo *current_peer;
belle_sip_list_t *outgoing_messages;
belle_sip_list_t* incoming_messages;
......
......@@ -117,7 +117,7 @@ belle_sip_channel_t * belle_sip_channel_new_udp_with_addr(belle_sip_stack_t *sta
if (err!=0){
belle_sip_error("getaddrinfo() failed for udp channel [%p] error [%s]",obj,gai_strerror(err));
}
obj->base.peer_list=belle_sip_list_prepend(obj->base.peer_list,obj->base.current_peer);
obj->base.peer_list=obj->base.current_peer;
return (belle_sip_channel_t*)obj;
}
......@@ -37,10 +37,10 @@
typedef struct endpoint {
belle_sip_stack_t* stack;
long unsigned int resolver_id;
enum dns_type query_type;
int resolve_done;
int resolve_ko;
belle_sip_list_t *results_list; /**< List of struct addrinfo pointers */
struct addrinfo *ai_list;
belle_sip_list_t *srv_list; /**< List of struct dns_srv pointers */
} endpoint_t;
static unsigned int wait_for(belle_sip_stack_t *stack, int *current_value, int expected_value, int timeout) {
......@@ -55,20 +55,14 @@ static unsigned int wait_for(belle_sip_stack_t *stack, int *current_value, int
else return TRUE;
}
static endpoint_t* create_endpoint(enum dns_type query_type) {
static endpoint_t* create_endpoint() {
endpoint_t* endpoint;
if (belle_sip_init_sockets() < 0) return NULL;
endpoint = belle_sip_new0(endpoint_t);
endpoint->stack = belle_sip_stack_new(NULL);
endpoint->query_type = query_type;
return endpoint;
}
static void free_ai_result(void *ptr) {
struct addrinfo *ai = (struct addrinfo *)ptr;
freeaddrinfo(ai);
}
static void free_srv_result(void *ptr) {
struct dns_srv *srv = (struct dns_srv *)ptr;
belle_sip_free(srv);
......@@ -78,13 +72,15 @@ static void reset_endpoint(endpoint_t *endpoint) {
endpoint->resolver_id = 0;
endpoint->resolve_done = 0;
endpoint->resolve_ko = 0;
if ((endpoint->query_type == DNS_T_A) || (endpoint->query_type == DNS_T_AAAA)) {
belle_sip_list_for_each(endpoint->results_list, free_ai_result);
} else if (endpoint->query_type == DNS_T_SRV) {
belle_sip_list_for_each(endpoint->results_list, free_srv_result);
if (endpoint->ai_list != NULL) {
freeaddrinfo(endpoint->ai_list);
endpoint->ai_list = NULL;
}
if (endpoint->srv_list != NULL) {
belle_sip_list_for_each(endpoint->srv_list, free_srv_result);
belle_sip_list_free(endpoint->srv_list);
endpoint->srv_list = NULL;
}
belle_sip_list_free(endpoint->results_list);
endpoint->results_list = NULL;
}
static void destroy_endpoint(endpoint_t *endpoint) {
......@@ -94,12 +90,23 @@ static void destroy_endpoint(endpoint_t *endpoint) {
belle_sip_uninit_sockets();
}
static void resolve_done(void *data, const char *name, belle_sip_list_t *results_list) {
static void a_resolve_done(void *data, const char *name, struct addrinfo *ai_list) {
endpoint_t *client = (endpoint_t *)data;
BELLESIP_UNUSED(name);
client->resolve_done = 1;
if (ai_list) {
client->ai_list = ai_list;
client->resolve_done = 1;
} else
client->resolve_ko = 1;
}
static void srv_resolve_done(void *data, const char *name, belle_sip_list_t *srv_list) {
endpoint_t *client = (endpoint_t *)data;
BELLESIP_UNUSED(name);
client->resolve_done = 1;
if (results_list && (belle_sip_list_size(results_list) > 0)) {
client->results_list = results_list;
if (srv_list) {
client->srv_list = srv_list;
client->resolve_done = 1;
} else
client->resolve_ko = 1;
......@@ -109,17 +116,16 @@ static void resolve_done(void *data, const char *name, belle_sip_list_t *results
static void ipv4_a_query(void) {
struct addrinfo *ai;
int timeout;
endpoint_t *client = create_endpoint(DNS_T_A);
endpoint_t *client = create_endpoint();
CU_ASSERT_PTR_NOT_NULL_FATAL(client);
timeout = belle_sip_stack_get_dns_timeout(client->stack);
client->resolver_id = belle_sip_resolve(client->stack, IPV4_SIP_DOMAIN, SIP_PORT, AF_INET, resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
client->resolver_id = belle_sip_resolve(client->stack, IPV4_SIP_DOMAIN, SIP_PORT, AF_INET, a_resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
CU_ASSERT_NOT_EQUAL(client->resolver_id, 0);
CU_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, timeout));
CU_ASSERT_PTR_NOT_EQUAL(client->results_list, NULL);
if (client->results_list && (belle_sip_list_size(client->results_list) > 0)) {
struct addrinfo *result_ai = belle_sip_list_nth_data(client->results_list, 0);
struct sockaddr_in *sock_in = (struct sockaddr_in *)result_ai->ai_addr;
CU_ASSERT_PTR_NOT_EQUAL(client->ai_list, NULL);
if (client->ai_list) {
struct sockaddr_in *sock_in = (struct sockaddr_in *)client->ai_list->ai_addr;
CU_ASSERT_EQUAL(ntohs(sock_in->sin_port), SIP_PORT);
ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_SIP_IP, SIP_PORT);
if (ai) {
......@@ -134,25 +140,25 @@ static void ipv4_a_query(void) {
/* Successful IPv4 A query with no result */
static void ipv4_a_query_no_result(void) {
int timeout;
endpoint_t *client = create_endpoint(DNS_T_A);
endpoint_t *client = create_endpoint();
CU_ASSERT_PTR_NOT_NULL_FATAL(client);
timeout = belle_sip_stack_get_dns_timeout(client->stack);
client->resolver_id = belle_sip_resolve(client->stack, IPV4_SIP_BAD_DOMAIN, SIP_PORT, AF_INET, resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
client->resolver_id = belle_sip_resolve(client->stack, IPV4_SIP_BAD_DOMAIN, SIP_PORT, AF_INET, a_resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
CU_ASSERT_NOT_EQUAL(client->resolver_id, 0);
CU_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, timeout));
CU_ASSERT_PTR_EQUAL(client->results_list, NULL);
CU_ASSERT_PTR_EQUAL(client->ai_list, NULL);
destroy_endpoint(client);
}
/* IPv4 A query send failure */
static void ipv4_a_query_send_failure(void) {
endpoint_t *client = create_endpoint(DNS_T_A);
endpoint_t *client = create_endpoint();
CU_ASSERT_PTR_NOT_NULL_FATAL(client);
belle_sip_stack_set_resolver_send_error(client->stack, -1);
client->resolver_id = belle_sip_resolve(client->stack, IPV4_SIP_DOMAIN, SIP_PORT, AF_INET, resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
client->resolver_id = belle_sip_resolve(client->stack, IPV4_SIP_DOMAIN, SIP_PORT, AF_INET, a_resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
CU_ASSERT_EQUAL(client->resolver_id, 0);
belle_sip_stack_set_resolver_send_error(client->stack, 0);
......@@ -162,14 +168,14 @@ static void ipv4_a_query_send_failure(void) {
/* IPv4 A query timeout */
static void ipv4_a_query_timeout(void) {
endpoint_t *client = create_endpoint(DNS_T_A);
endpoint_t *client = create_endpoint();
CU_ASSERT_PTR_NOT_NULL_FATAL(client);
belle_sip_stack_set_dns_timeout(client->stack, 0);
client->resolver_id = belle_sip_resolve(client->stack, "toto.com", SIP_PORT, AF_INET, resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
client->resolver_id = belle_sip_resolve(client->stack, "toto.com", SIP_PORT, AF_INET, a_resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
CU_ASSERT_NOT_EQUAL(client->resolver_id, 0);
CU_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, 200));
CU_ASSERT_PTR_EQUAL(client->results_list, NULL);
CU_ASSERT_PTR_EQUAL(client->ai_list, NULL);
CU_ASSERT_EQUAL(client->resolve_ko,1);
destroy_endpoint(client);
}
......@@ -177,17 +183,16 @@ static void ipv4_a_query_timeout(void) {
/* Successful IPv4 A query with multiple results */
static void ipv4_a_query_multiple_results(void) {
int timeout;
endpoint_t *client = create_endpoint(DNS_T_A);
endpoint_t *client = create_endpoint();
CU_ASSERT_PTR_NOT_NULL_FATAL(client);
timeout = belle_sip_stack_get_dns_timeout(client->stack);
client->resolver_id = belle_sip_resolve(client->stack, IPV4_MULTIRES_DOMAIN, SIP_PORT, AF_INET, resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
client->resolver_id = belle_sip_resolve(client->stack, IPV4_MULTIRES_DOMAIN, SIP_PORT, AF_INET, a_resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
CU_ASSERT_NOT_EQUAL(client->resolver_id, 0);
CU_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, timeout));
CU_ASSERT_PTR_NOT_EQUAL(client->results_list, NULL);
if (client->results_list) {
CU_ASSERT_NOT_EQUAL(belle_sip_list_size(client->results_list), 0);
CU_ASSERT_NOT_EQUAL(belle_sip_list_size(client->results_list), 1);
CU_ASSERT_PTR_NOT_EQUAL(client->ai_list, NULL);
if (client->ai_list) {
CU_ASSERT_PTR_NOT_NULL(client->ai_list->ai_next);
}
destroy_endpoint(client);
......@@ -197,17 +202,16 @@ static void ipv4_a_query_multiple_results(void) {
static void ipv6_aaaa_query(void) {
struct addrinfo *ai;
int timeout;
endpoint_t *client = create_endpoint(DNS_T_AAAA);
endpoint_t *client = create_endpoint();
CU_ASSERT_PTR_NOT_NULL_FATAL(client);
timeout = belle_sip_stack_get_dns_timeout(client->stack);
client->resolver_id = belle_sip_resolve(client->stack, IPV6_SIP_DOMAIN, SIP_PORT, AF_INET6, resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
client->resolver_id = belle_sip_resolve(client->stack, IPV6_SIP_DOMAIN, SIP_PORT, AF_INET6, a_resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
CU_ASSERT_NOT_EQUAL(client->resolver_id, 0);
CU_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, timeout));
CU_ASSERT_PTR_NOT_EQUAL(client->results_list, NULL);
if (client->results_list && (belle_sip_list_size(client->results_list) > 0)) {
struct addrinfo *result_ai = belle_sip_list_nth_data(client->results_list, 0);
struct sockaddr_in6 *sock_in6 = (struct sockaddr_in6 *)result_ai->ai_addr;
CU_ASSERT_PTR_NOT_EQUAL(client->ai_list, NULL);
if (client->ai_list) {
struct sockaddr_in6 *sock_in6 = (struct sockaddr_in6 *)client->ai_list->ai_addr;
CU_ASSERT_EQUAL(ntohs(sock_in6->sin6_port), SIP_PORT);
ai = belle_sip_ip_address_to_addrinfo(AF_INET6, IPV6_SIP_IP, SIP_PORT);
if (ai) {
......@@ -226,17 +230,17 @@ static void ipv6_aaaa_query(void) {
/* Successful SRV query */
static void srv_query(void) {
int timeout;
endpoint_t *client = create_endpoint(DNS_T_SRV);
endpoint_t *client = create_endpoint();
CU_ASSERT_PTR_NOT_NULL_FATAL(client);
timeout = belle_sip_stack_get_dns_timeout(client->stack);
client->resolver_id = belle_sip_resolve_srv(client->stack, SRV_DOMAIN, "udp", resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
client->resolver_id = belle_sip_resolve_srv(client->stack, SRV_DOMAIN, "udp", srv_resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
CU_ASSERT_NOT_EQUAL(client->resolver_id, 0);
CU_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, timeout));
CU_ASSERT_PTR_NOT_EQUAL(client->results_list, NULL);
CU_ASSERT_NOT_EQUAL(belle_sip_list_size(client->results_list), 0);
if (client->results_list && (belle_sip_list_size(client->results_list) > 0)) {
struct dns_srv *result_srv = belle_sip_list_nth_data(client->results_list, 0);
CU_ASSERT_PTR_NOT_EQUAL(client->srv_list, NULL);
CU_ASSERT_NOT_EQUAL(belle_sip_list_size(client->srv_list), 0);
if (client->srv_list && (belle_sip_list_size(client->srv_list) > 0)) {
struct dns_srv *result_srv = belle_sip_list_nth_data(client->srv_list, 0);
CU_ASSERT_EQUAL(result_srv->port, SIP_PORT);
}
......
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