📄 dns_test.c
字号:
while (result.status == 0x12345678) {
int i = 0;
pj_time_val timeout = { 1, 0 };
pjsip_endpt_handle_events(endpt, &timeout);
if (i == 1)
pj_dns_resolver_dump(pjsip_endpt_get_resolver(endpt), PJ_TRUE);
}
if (result.status != PJ_SUCCESS) {
app_perror(" pjsip_endpt_resolve() error", result.status);
return result.status;
}
if (ref) {
unsigned i;
if (ref->count != result.servers.count) {
PJ_LOG(3,(THIS_FILE, " test_resolve() error 10: result count mismatch"));
return 10;
}
for (i=0; i<ref->count; ++i) {
pj_sockaddr_in *ra = (pj_sockaddr_in *)&ref->entry[i].addr;
pj_sockaddr_in *rb = (pj_sockaddr_in *)&result.servers.entry[i].addr;
if (ra->sin_addr.s_addr != rb->sin_addr.s_addr) {
PJ_LOG(3,(THIS_FILE, " test_resolve() error 20: IP address mismatch"));
return 20;
}
if (ra->sin_port != rb->sin_port) {
PJ_LOG(3,(THIS_FILE, " test_resolve() error 30: port mismatch"));
return 30;
}
if (ref->entry[i].addr_len != result.servers.entry[i].addr_len) {
PJ_LOG(3,(THIS_FILE, " test_resolve() error 40: addr_len mismatch"));
return 40;
}
if (ref->entry[i].type != result.servers.entry[i].type) {
PJ_LOG(3,(THIS_FILE, " test_resolve() error 50: transport type mismatch"));
return 50;
}
}
}
return PJ_SUCCESS;
}
/*
* Perform round-robin/load balance test.
*/
static int round_robin_test(pj_pool_t *pool)
{
enum { COUNT = 400, PCT_ALLOWANCE = 5 };
unsigned i;
struct server_hit
{
char *ip_addr;
unsigned percent;
unsigned hits;
} server_hit[] =
{
{ "1.1.1.1", 3, 0 },
{ "2.2.2.2", 65, 0 },
{ "3.3.3.3", 32, 0 },
{ "4.4.4.4", 0, 0 }
};
PJ_LOG(3,(THIS_FILE, " Performing round-robin/load-balance test.."));
/* Do multiple resolve request to "example.com".
* The resolver should select the server based on the weight proportion
* the the servers in the SRV entry.
*/
for (i=0; i<COUNT; ++i) {
pjsip_host_info dest;
struct result result;
unsigned j;
dest.type = PJSIP_TRANSPORT_UDP;
dest.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_UDP);
dest.addr.host = pj_str("example.com");
dest.addr.port = 0;
result.status = 0x12345678;
pjsip_endpt_resolve(endpt, pool, &dest, &result, &cb);
while (result.status == 0x12345678) {
int i = 0;
pj_time_val timeout = { 1, 0 };
pjsip_endpt_handle_events(endpt, &timeout);
if (i == 1)
pj_dns_resolver_dump(pjsip_endpt_get_resolver(endpt), PJ_TRUE);
}
/* Find which server was "hit" */
for (j=0; j<PJ_ARRAY_SIZE(server_hit); ++j) {
pj_str_t tmp;
pj_in_addr a1;
pj_sockaddr_in *a2;
tmp = pj_str(server_hit[j].ip_addr);
a1 = pj_inet_addr(&tmp);
a2 = (pj_sockaddr_in*) &result.servers.entry[0].addr;
if (a1.s_addr == a2->sin_addr.s_addr) {
server_hit[j].hits++;
break;
}
}
if (j == PJ_ARRAY_SIZE(server_hit)) {
PJ_LOG(1,(THIS_FILE, "..round_robin_test() error 10: returned address mismatch"));
return 10;
}
}
/* Print the actual hit rate */
for (i=0; i<PJ_ARRAY_SIZE(server_hit); ++i) {
PJ_LOG(3,(THIS_FILE, " ..Server %s: weight=%d%%, hit %d%% times",
server_hit[i].ip_addr, server_hit[i].percent,
(server_hit[i].hits * 100) / COUNT));
}
/* Compare the actual hit with the weight proportion */
for (i=0; i<PJ_ARRAY_SIZE(server_hit); ++i) {
int actual_pct = (server_hit[i].hits * 100) / COUNT;
if (actual_pct + PCT_ALLOWANCE < (int)server_hit[i].percent ||
actual_pct - PCT_ALLOWANCE > (int)server_hit[i].percent)
{
PJ_LOG(1,(THIS_FILE,
"..round_robin_test() error 20: "
"hit rate difference for server %s (%d%%) is more than "
"tolerable allowance (%d%%)",
server_hit[i].ip_addr,
actual_pct - server_hit[i].percent,
PCT_ALLOWANCE));
return 20;
}
}
PJ_LOG(3,(THIS_FILE,
" Load balance test success, hit-rate is "
"within %d%% allowance", PCT_ALLOWANCE));
return PJ_SUCCESS;
}
#define C(expr) status = expr; \
if (status != PJ_SUCCESS) app_perror(THIS_FILE, "Error", status);
static void add_ref(pjsip_server_addresses *r,
pjsip_transport_type_e type,
char *addr,
int port)
{
pj_sockaddr_in *a;
pj_str_t tmp;
r->entry[r->count].type = type;
r->entry[r->count].priority = 0;
r->entry[r->count].weight = 0;
r->entry[r->count].addr_len = sizeof(pj_sockaddr_in);
a = (pj_sockaddr_in *)&r->entry[r->count].addr;
a->sin_family = PJ_AF_INET;
tmp = pj_str(addr);
a->sin_addr = pj_inet_addr(&tmp);
a->sin_port = pj_htons((pj_uint16_t)port);
r->count++;
}
static void create_ref(pjsip_server_addresses *r,
pjsip_transport_type_e type,
char *addr,
int port)
{
r->count = 0;
add_ref(r, type, addr, port);
}
/*
* Main test entry.
*/
int resolve_test(void)
{
pj_pool_t *pool;
pj_dns_resolver *resv;
pj_str_t nameserver;
pj_uint16_t port = 5353;
pj_status_t status;
pool = pjsip_endpt_create_pool(endpt, NULL, 4000, 4000);
status = pjsip_endpt_create_resolver(endpt, &resv);
nameserver = pj_str("192.168.0.106");
pj_dns_resolver_set_ns(resv, 1, &nameserver, &port);
pjsip_endpt_set_resolver(endpt, resv);
add_dns_entries(resv);
/* These all should be resolved as IP addresses (DNS A query) */
{
pjsip_server_addresses ref;
create_ref(&ref, PJSIP_TRANSPORT_UDP, "1.1.1.1", 5060);
status = test_resolve("IP address without transport and port", pool, PJSIP_TRANSPORT_UNSPECIFIED, "1.1.1.1", 0, &ref);
if (status != PJ_SUCCESS)
return -100;
}
{
pjsip_server_addresses ref;
create_ref(&ref, PJSIP_TRANSPORT_UDP, "1.1.1.1", 5060);
status = test_resolve("IP address with explicit port", pool, PJSIP_TRANSPORT_UNSPECIFIED, "1.1.1.1", 5060, &ref);
if (status != PJ_SUCCESS)
return -110;
}
{
pjsip_server_addresses ref;
create_ref(&ref, PJSIP_TRANSPORT_TCP, "1.1.1.1", 5060);
status = test_resolve("IP address without port (TCP)", pool, PJSIP_TRANSPORT_TCP,"1.1.1.1", 0, &ref);
if (status != PJ_SUCCESS)
return -120;
}
{
pjsip_server_addresses ref;
create_ref(&ref, PJSIP_TRANSPORT_TLS, "1.1.1.1", 5061);
status = test_resolve("IP address without port (TLS)", pool, PJSIP_TRANSPORT_TLS, "1.1.1.1", 0, &ref);
if (status != PJ_SUCCESS)
return -130;
}
/* This should be resolved as DNS A record (because port is present) */
{
pjsip_server_addresses ref;
create_ref(&ref, PJSIP_TRANSPORT_UDP, "5.5.5.5", 5060);
status = test_resolve("domain name with port should resolve to A record", pool, PJSIP_TRANSPORT_UNSPECIFIED, "example.com", 5060, &ref);
if (status != PJ_SUCCESS)
return -140;
}
/* This will fail to be resolved as SRV, resolver should fallback to
* resolving to A record.
*/
{
pjsip_server_addresses ref;
create_ref(&ref, PJSIP_TRANSPORT_UDP, "2.2.2.2", 5060);
status = test_resolve("failure with SRV fallback to A record", pool, PJSIP_TRANSPORT_UNSPECIFIED, "sip02.example.com", 0, &ref);
if (status != PJ_SUCCESS)
return -150;
}
/* Same as above, but explicitly for TLS. */
{
pjsip_server_addresses ref;
create_ref(&ref, PJSIP_TRANSPORT_TLS, "2.2.2.2", 5061);
status = test_resolve("failure with SRV fallback to A record (for TLS)", pool, PJSIP_TRANSPORT_TLS, "sip02.example.com", 0, &ref);
if (status != PJ_SUCCESS)
return -150;
}
/* Standard DNS SRV followed by A recolution */
{
pjsip_server_addresses ref;
create_ref(&ref, PJSIP_TRANSPORT_UDP, "6.6.6.6", 50060);
status = test_resolve("standard SRV resolution", pool, PJSIP_TRANSPORT_UNSPECIFIED, "domain.com", 0, &ref);
if (status != PJ_SUCCESS)
return -155;
}
/* Standard DNS SRV followed by A recolution (explicit transport) */
{
pjsip_server_addresses ref;
create_ref(&ref, PJSIP_TRANSPORT_TCP, "6.6.6.6", 50060);
add_ref(&ref, PJSIP_TRANSPORT_TCP, "7.7.7.7", 50060);
status = test_resolve("standard SRV resolution with explicit transport (TCP)", pool, PJSIP_TRANSPORT_TCP, "domain.com", 0, &ref);
if (status != PJ_SUCCESS)
return -160;
}
/* Round robin/load balance test */
if (round_robin_test(pool) != 0)
return -170;
/* Timeout test */
{
status = test_resolve("timeout test", pool, PJSIP_TRANSPORT_UNSPECIFIED, "an.invalid.address", 0, NULL);
if (status == PJ_SUCCESS)
return -150;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -