Commit 4453910c authored by Ghislain MARY's avatar Ghislain MARY

Add unit tests for resolver failure and resolver timeout.

parent 569239a9
......@@ -156,6 +156,42 @@ static int resolver_process_a_data(belle_sip_resolver_context_t *ctx, unsigned i
return BELLE_SIP_CONTINUE;
}
static int _resolver_start_query(belle_sip_resolver_context_t *ctx, belle_sip_source_func_t datafunc, enum dns_type type, int timeout) {
int error;
if (!ctx->stack->send_error) {
error = dns_res_submit(ctx->R, ctx->name, type, DNS_C_IN);
if (error)
belle_sip_error("%s dns_res_submit error [%s]: %s", __FUNCTION__, ctx->name, dns_strerror(error));
} else {
/* Error simulation */
error = ctx->stack->send_error;
belle_sip_error("%s dns_res_submit error [%s]: simulated error %d", __FUNCTION__, ctx->name, error);
}
if (error < 0) {
return -1;
}
(*datafunc)(ctx, 0);
belle_sip_socket_source_init((belle_sip_source_t*)ctx, datafunc, ctx, dns_res_pollfd(ctx->R), BELLE_SIP_EVENT_READ | BELLE_SIP_EVENT_TIMEOUT, timeout);
return 0;
}
typedef struct delayed_send {
belle_sip_resolver_context_t *ctx;
belle_sip_source_func_t datafunc;
enum dns_type type;
int timeout;
} delayed_send_t;
static int on_delayed_send_do(delayed_send_t *ds) {
belle_sip_message("%s sending now", __FUNCTION__);
_resolver_start_query(ds->ctx, ds->datafunc, ds->type, ds->timeout);
belle_sip_object_unref(ds->ctx);
belle_sip_free(ds);
return FALSE;
}
static int resolver_start_query(belle_sip_resolver_context_t *ctx, belle_sip_source_func_t datafunc, enum dns_type type, int timeout) {
struct dns_hints *(*hints)() = &dns_hints_local;
struct dns_options *opts;
......@@ -184,14 +220,19 @@ static int resolver_start_query(belle_sip_resolver_context_t *ctx, belle_sip_sou
return -1;
}
if ((error = dns_res_submit(ctx->R, ctx->name, type, DNS_C_IN))) {
belle_sip_error("%s dns_res_submit error [%s]: %s", __FUNCTION__, ctx->name, dns_strerror(error));
return -1;
if (ctx->stack->tx_delay > 0) {
delayed_send_t *ds = belle_sip_new(delayed_send_t);
ds->ctx = (belle_sip_resolver_context_t *)belle_sip_object_ref(ctx);
ds->datafunc = datafunc;
ds->type = type;
ds->timeout = timeout;
belle_sip_main_loop_add_timeout(ctx->stack->ml, (belle_sip_source_func_t)on_delayed_send_do, ds, ctx->stack->tx_delay);
belle_sip_socket_source_init((belle_sip_source_t*)ctx, datafunc, ctx, dns_res_pollfd(ctx->R), BELLE_SIP_EVENT_READ | BELLE_SIP_EVENT_TIMEOUT, timeout);
belle_sip_message("%s DNS resolution delayed by %d ms", __FUNCTION__, ctx->stack->tx_delay);
return 0;
} else {
return _resolver_start_query(ctx, datafunc, type, timeout);
}
(*datafunc)(ctx, 0);
belle_sip_socket_source_init((belle_sip_source_t*)ctx, datafunc, ctx, dns_res_pollfd(ctx->R), BELLE_SIP_EVENT_READ | BELLE_SIP_EVENT_TIMEOUT, timeout);
return 0;
}
......@@ -245,6 +286,7 @@ unsigned long belle_sip_resolve(belle_sip_stack_t *stack, const char *name, int
if (res == NULL) {
/* Then perform asynchronous DNS query */
belle_sip_resolver_context_t *ctx = belle_sip_object_new(belle_sip_resolver_context_t);
ctx->stack = stack;
ctx->cb_data = data;
ctx->cb = cb;
ctx->name = belle_sip_strdup(name);
......
......@@ -37,6 +37,7 @@ typedef void (*belle_sip_resolver_callback_t)(void *data, const char *name, stru
struct belle_sip_resolver_context{
belle_sip_source_t source;
belle_sip_stack_t *stack;
belle_sip_resolver_callback_t cb;
void *cb_data;
struct dns_resolv_conf *resconf;
......
......@@ -22,11 +22,12 @@
#include "belle_sip_internal.h"
#define IPV4_SIP_DOMAIN "sip.linphone.org"
#define IPV4_SIP_IP "37.59.129.73"
#define IPV6_SIP_DOMAIN "videolan.org"
#define IPV6_SIP_IP "2a01:e0d:1:3:58bf:fa02:0:1"
#define SIP_PORT 5060
#define IPV4_SIP_DOMAIN "sip.linphone.org"
#define IPV4_SIP_IP "37.59.129.73"
#define IPV4_SIP_BAD_DOMAIN "dummy.linphone.org"
#define IPV6_SIP_DOMAIN "videolan.org"
#define IPV6_SIP_IP "2a01:e0d:1:3:58bf:fa02:0:1"
#define SIP_PORT 5060
typedef struct endpoint {
......@@ -64,6 +65,7 @@ static void reset_endpoint(endpoint_t *endpoint) {
}
static void destroy_endpoint(endpoint_t *endpoint) {
reset_endpoint(endpoint);
belle_sip_object_unref(endpoint->stack);
belle_sip_free(endpoint);
belle_sip_uninit_sockets();
......@@ -82,14 +84,17 @@ static void resolve(void) {
int peer_port = SIP_PORT;
struct addrinfo *ai;
int family;
int timeout;
endpoint_t *client = create_endpoint();
CU_ASSERT_PTR_NOT_NULL_FATAL(client);
timeout = belle_sip_stack_get_dns_timeout(client->stack);
/* IPv4 A query */
/* Successful IPv4 A query */
family = AF_INET;
peer_name = IPV4_SIP_DOMAIN;
client->resolver_id = belle_sip_resolve(client->stack, peer_name, peer_port, family, resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
CU_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, 2000));
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->result, NULL);
if (client->result) {
struct sockaddr_in *sock_in = (struct sockaddr_in *)client->result->ai_addr;
......@@ -100,12 +105,42 @@ static void resolve(void) {
}
}
/* IPv6 AAAA query */
/* Successful IPv4 A query with no result */
reset_endpoint(client);
family = AF_INET;
peer_name = IPV4_SIP_BAD_DOMAIN;
client->resolver_id = belle_sip_resolve(client->stack, peer_name, peer_port, family, 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->result, NULL);
/* IPv4 A query send failure */
reset_endpoint(client);
family = AF_INET;
peer_name = IPV4_SIP_DOMAIN;
belle_sip_stack_set_send_error(client->stack, -1);
client->resolver_id = belle_sip_resolve(client->stack, peer_name, peer_port, family, resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
CU_ASSERT_EQUAL(client->resolver_id, 0);
belle_sip_stack_set_send_error(client->stack, 0);
/* IPv4 A query timeout */
reset_endpoint(client);
family = AF_INET;
peer_name = IPV4_SIP_DOMAIN;
belle_sip_stack_set_tx_delay(client->stack, timeout);
client->resolver_id = belle_sip_resolve(client->stack, peer_name, peer_port, family, resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
CU_ASSERT_NOT_EQUAL(client->resolver_id, 0);
CU_ASSERT_FALSE(wait_for(client->stack, &client->resolve_done, 1, timeout));
CU_ASSERT_PTR_EQUAL(client->result, NULL);
belle_sip_stack_set_tx_delay(client->stack, 0);
/* Successful IPv6 AAAA query */
reset_endpoint(client);
family = AF_INET6;
peer_name = IPV6_SIP_DOMAIN;
client->resolver_id = belle_sip_resolve(client->stack, peer_name, peer_port, family, resolve_done, client, belle_sip_stack_get_main_loop(client->stack));
CU_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, 2000));
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->result, NULL);
if (client->result) {
struct sockaddr_in6 *sock_in6 = (struct sockaddr_in6 *)client->result->ai_addr;
......
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