Tue Jun 23 08:18:24 CDT 2009 Mikhail Zabaluev <mikhail.zabaluev@nokia.com>
* sresolv/sres.c: implemented automatic CNAME resolution Ignore-this: 1483f6b65deb976e372921ef7ff1b0a0 Fixes sf.net bug #2531152 Behavioral change: intermediate CNAME results are not retrieved to the client. The only cases where CNAME results are retrieved are queries for sres_type_cname and sres_qtype_any, meaning no CNAME resolution is performed. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@13919 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
9f80035304
commit
848e8f726c
|
@ -1 +1 @@
|
||||||
Tue Jun 23 14:45:32 CDT 2009
|
Tue Jun 23 14:46:33 CDT 2009
|
||||||
|
|
|
@ -311,6 +311,7 @@ struct sres_query_s {
|
||||||
uint16_t q_retry_count;
|
uint16_t q_retry_count;
|
||||||
uint8_t q_n_servers;
|
uint8_t q_n_servers;
|
||||||
uint8_t q_i_server;
|
uint8_t q_i_server;
|
||||||
|
int8_t q_aliased;
|
||||||
int8_t q_edns;
|
int8_t q_edns;
|
||||||
uint8_t q_n_subs;
|
uint8_t q_n_subs;
|
||||||
sres_query_t *q_subqueries[1 + SRES_MAX_SEARCH];
|
sres_query_t *q_subqueries[1 + SRES_MAX_SEARCH];
|
||||||
|
@ -3069,6 +3070,18 @@ sres_resend_dns_query(sres_resolver_t *res, sres_query_t *q, int timeout)
|
||||||
sres_query_report_error(q, NULL);
|
sres_query_report_error(q, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sres_resolve_cname(sres_resolver_t *res,
|
||||||
|
const sres_query_t *orig_query,
|
||||||
|
const char *alias)
|
||||||
|
{
|
||||||
|
sres_query_t *query;
|
||||||
|
query = sres_query_alloc(res,
|
||||||
|
orig_query->q_callback, orig_query->q_context, orig_query->q_type,
|
||||||
|
alias);
|
||||||
|
query->q_aliased = 1;
|
||||||
|
sres_send_dns_query(res, query);
|
||||||
|
}
|
||||||
|
|
||||||
/** Get a server by socket */
|
/** Get a server by socket */
|
||||||
static
|
static
|
||||||
|
@ -3456,10 +3469,30 @@ sres_resolver_receive(sres_resolver_t *res, int socket)
|
||||||
query->q_retry_count++;
|
query->q_retry_count++;
|
||||||
}
|
}
|
||||||
else if (!error && reply) {
|
else if (!error && reply) {
|
||||||
/* Remove the query from the pending list and notify the listener */
|
/* Remove the query from the pending list */
|
||||||
sres_remove_query(res, query, 1);
|
sres_remove_query(res, query, 1);
|
||||||
|
|
||||||
|
/* Resolve the CNAME alias, if necessary */
|
||||||
|
if (query->q_type != sres_type_cname && query->q_type != sres_qtype_any &&
|
||||||
|
reply[0] && reply[0]->sr_type == sres_type_cname) {
|
||||||
|
const char *alias = reply[0]->sr_cname[0].cn_cname;
|
||||||
|
sres_record_t **cached = NULL;
|
||||||
|
|
||||||
|
/* Check for the aliased results in the cache */
|
||||||
|
if (sres_cache_get(res->res_cache, query->q_type, alias, &cached)
|
||||||
|
> 0) {
|
||||||
|
reply = cached;
|
||||||
|
} else {
|
||||||
|
/* Resubmit the query with the aliased name, dropping this result */
|
||||||
|
sres_resolve_cname(res, query, alias);
|
||||||
|
reply = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reply) {
|
||||||
|
/* Notify the listener */
|
||||||
if (query->q_callback != NULL)
|
if (query->q_callback != NULL)
|
||||||
(query->q_callback)(query->q_context, query, reply);
|
(query->q_callback)(query->q_context, query, reply);
|
||||||
|
}
|
||||||
sres_free_query(res, query);
|
sres_free_query(res, query);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -3630,15 +3663,17 @@ sres_decode_msg(sres_resolver_t *res,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m->m_ancount > 0 && errorcount == 0 && query->q_type < sres_qtype_tsig) {
|
if (m->m_ancount > 0 && errorcount == 0 && query->q_type < sres_qtype_tsig
|
||||||
char b0[8], b1[8];
|
&& (query->q_aliased || answers[0]->sr_type != sres_type_cname)) {
|
||||||
|
|
||||||
for (i = 0; i < m->m_ancount; i++) {
|
for (i = 0; i < m->m_ancount; i++) {
|
||||||
if (query->q_type == answers[i]->sr_type)
|
if (query->q_type == answers[i]->sr_type)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == m->m_ancount) {
|
if (i == m->m_ancount) {
|
||||||
/* The queried request was not found. CNAME? */
|
char b0[8], b1[8];
|
||||||
|
/* The queried request was not found */
|
||||||
SU_DEBUG_5(("sres_decode_msg: sent query %s, got %s\n",
|
SU_DEBUG_5(("sres_decode_msg: sent query %s, got %s\n",
|
||||||
sres_record_type(query->q_type, b0),
|
sres_record_type(query->q_type, b0),
|
||||||
sres_record_type(answers[0]->sr_type, b1)));
|
sres_record_type(answers[0]->sr_type, b1)));
|
||||||
|
|
|
@ -226,14 +226,6 @@ sres_cache_get0(sres_htable_t *htable,
|
||||||
struct frame *f, frame = { previous, domain };
|
struct frame *f, frame = { previous, domain };
|
||||||
unsigned hash = sres_hash_key(domain = cname->cn_cname);
|
unsigned hash = sres_hash_key(domain = cname->cn_cname);
|
||||||
|
|
||||||
if (cached) {
|
|
||||||
if (dcount >= len)
|
|
||||||
return -1;
|
|
||||||
cached[dcount] = (sres_record_t *)cname;
|
|
||||||
cname->cn_record->r_refcount++;
|
|
||||||
}
|
|
||||||
dcount++;
|
|
||||||
|
|
||||||
/* Check for cname loops */
|
/* Check for cname loops */
|
||||||
for (f = previous; f; f = f->previous) {
|
for (f = previous; f; f = f->previous) {
|
||||||
if (su_casematch(domain, f->domain))
|
if (su_casematch(domain, f->domain))
|
||||||
|
|
|
@ -998,22 +998,12 @@ int test_cname(sres_context_t *ctx)
|
||||||
TEST_1(result = ctx->result);
|
TEST_1(result = ctx->result);
|
||||||
TEST_1(sr = result[0]);
|
TEST_1(sr = result[0]);
|
||||||
TEST_1(sr->sr_record->r_status == SRES_RECORD_ERR);
|
TEST_1(sr->sr_record->r_status == SRES_RECORD_ERR);
|
||||||
TEST_1(cn = result[1]->sr_cname);
|
|
||||||
TEST(cn->cn_record->r_class, sres_class_in);
|
|
||||||
TEST(cn->cn_record->r_type, sres_type_cname);
|
|
||||||
TEST(cn->cn_record->r_ttl, 60);
|
|
||||||
TEST_S(cn->cn_cname, "sip00.example.com.");
|
|
||||||
|
|
||||||
sres_free_answers(res, ctx->result), ctx->result = NULL;
|
sres_free_answers(res, ctx->result), ctx->result = NULL;
|
||||||
|
|
||||||
TEST_1(result = sres_cached_answers(res, sres_type_naptr, domain));
|
TEST_1(result = sres_cached_answers(res, sres_type_naptr, domain));
|
||||||
TEST_1(sr = result[0]);
|
TEST_1(sr = result[0]);
|
||||||
TEST_1(sr->sr_record->r_status == SRES_RECORD_ERR);
|
TEST_1(sr->sr_record->r_status == SRES_RECORD_ERR);
|
||||||
TEST_1(cn = result[1]->sr_cname);
|
|
||||||
TEST(cn->cn_record->r_class, sres_class_in);
|
|
||||||
TEST(cn->cn_record->r_type, sres_type_cname);
|
|
||||||
TEST(cn->cn_record->r_ttl, 60);
|
|
||||||
TEST_S(cn->cn_cname, "sip00.example.com.");
|
|
||||||
|
|
||||||
sres_free_answers(res, result), ctx->result = NULL;
|
sres_free_answers(res, result), ctx->result = NULL;
|
||||||
|
|
||||||
|
@ -1031,24 +1021,14 @@ int test_cname(sres_context_t *ctx)
|
||||||
TEST_RUN(ctx);
|
TEST_RUN(ctx);
|
||||||
|
|
||||||
TEST_1(result = ctx->result);
|
TEST_1(result = ctx->result);
|
||||||
TEST_1(cn = result[0]->sr_cname);
|
TEST_1(sr = result[0]);
|
||||||
TEST(cn->cn_record->r_class, sres_class_in);
|
|
||||||
TEST(cn->cn_record->r_type, sres_type_cname);
|
|
||||||
TEST(cn->cn_record->r_ttl, 60);
|
|
||||||
TEST_S(cn->cn_cname, "sip00.example.com.");
|
|
||||||
TEST_1(sr = result[1]);
|
|
||||||
TEST(sr->sr_record->r_class, sres_class_in);
|
TEST(sr->sr_record->r_class, sres_class_in);
|
||||||
TEST(sr->sr_record->r_type, sres_type_a);
|
TEST(sr->sr_record->r_type, sres_type_a);
|
||||||
|
|
||||||
sres_free_answers(res, ctx->result), ctx->result = NULL;
|
sres_free_answers(res, ctx->result), ctx->result = NULL;
|
||||||
|
|
||||||
TEST_1(result = sres_cached_answers(res, sres_type_a, domain));
|
TEST_1(result = sres_cached_answers(res, sres_type_a, domain));
|
||||||
TEST_1(cn = result[0]->sr_cname);
|
TEST_1(sr = result[0]);
|
||||||
TEST(cn->cn_record->r_class, sres_class_in);
|
|
||||||
TEST(cn->cn_record->r_type, sres_type_cname);
|
|
||||||
TEST(cn->cn_record->r_ttl, 60);
|
|
||||||
TEST_S(cn->cn_cname, "sip00.example.com.");
|
|
||||||
TEST_1(sr = result[1]);
|
|
||||||
TEST(sr->sr_record->r_class, sres_class_in);
|
TEST(sr->sr_record->r_class, sres_class_in);
|
||||||
TEST(sr->sr_record->r_type, sres_type_a);
|
TEST(sr->sr_record->r_type, sres_type_a);
|
||||||
|
|
||||||
|
@ -1062,54 +1042,12 @@ int test_cname(sres_context_t *ctx)
|
||||||
TEST_1(result = ctx->result);
|
TEST_1(result = ctx->result);
|
||||||
TEST_1(sr = result[0]);
|
TEST_1(sr = result[0]);
|
||||||
TEST_1(sr->sr_record->r_status == SRES_RECORD_ERR);
|
TEST_1(sr->sr_record->r_status == SRES_RECORD_ERR);
|
||||||
TEST_1(cn = result[1]->sr_cname);
|
|
||||||
TEST(cn->cn_record->r_class, sres_class_in);
|
|
||||||
TEST(cn->cn_record->r_type, sres_type_cname);
|
|
||||||
TEST(cn->cn_record->r_ttl, 60);
|
|
||||||
TEST_S(cn->cn_cname, "cloop0.example.com.");
|
|
||||||
TEST_1(cn = result[2]->sr_cname);
|
|
||||||
TEST(cn->cn_record->r_class, sres_class_in);
|
|
||||||
TEST(cn->cn_record->r_type, sres_type_cname);
|
|
||||||
TEST(cn->cn_record->r_ttl, 60);
|
|
||||||
TEST_S(cn->cn_cname, "cloop1.example.com.");
|
|
||||||
TEST_1(cn = result[3]->sr_cname);
|
|
||||||
TEST(cn->cn_record->r_class, sres_class_in);
|
|
||||||
TEST(cn->cn_record->r_type, sres_type_cname);
|
|
||||||
TEST(cn->cn_record->r_ttl, 60);
|
|
||||||
TEST_S(cn->cn_cname, "cloop2.example.com.");
|
|
||||||
TEST_1(cn = result[4]->sr_cname);
|
|
||||||
TEST(cn->cn_record->r_class, sres_class_in);
|
|
||||||
TEST(cn->cn_record->r_type, sres_type_cname);
|
|
||||||
TEST(cn->cn_record->r_ttl, 60);
|
|
||||||
TEST_S(cn->cn_cname, "cloop0.example.com.");
|
|
||||||
TEST_1(result[5] == NULL);
|
|
||||||
|
|
||||||
sres_free_answers(res, ctx->result), ctx->result = NULL;
|
sres_free_answers(res, ctx->result), ctx->result = NULL;
|
||||||
|
|
||||||
TEST_1(result = sres_cached_answers(res, sres_type_a, domain));
|
TEST_1(result = sres_cached_answers(res, sres_type_a, domain));
|
||||||
TEST_1(sr = result[0]);
|
TEST_1(sr = result[0]);
|
||||||
TEST_1(sr->sr_record->r_status == SRES_RECORD_ERR);
|
TEST_1(sr->sr_record->r_status == SRES_RECORD_ERR);
|
||||||
TEST_1(cn = result[1]->sr_cname);
|
|
||||||
TEST(cn->cn_record->r_class, sres_class_in);
|
|
||||||
TEST(cn->cn_record->r_type, sres_type_cname);
|
|
||||||
TEST(cn->cn_record->r_ttl, 60);
|
|
||||||
TEST_S(cn->cn_cname, "cloop0.example.com.");
|
|
||||||
TEST_1(cn = result[2]->sr_cname);
|
|
||||||
TEST(cn->cn_record->r_class, sres_class_in);
|
|
||||||
TEST(cn->cn_record->r_type, sres_type_cname);
|
|
||||||
TEST(cn->cn_record->r_ttl, 60);
|
|
||||||
TEST_S(cn->cn_cname, "cloop1.example.com.");
|
|
||||||
TEST_1(cn = result[3]->sr_cname);
|
|
||||||
TEST(cn->cn_record->r_class, sres_class_in);
|
|
||||||
TEST(cn->cn_record->r_type, sres_type_cname);
|
|
||||||
TEST(cn->cn_record->r_ttl, 60);
|
|
||||||
TEST_S(cn->cn_cname, "cloop2.example.com.");
|
|
||||||
TEST_1(cn = result[4]->sr_cname);
|
|
||||||
TEST(cn->cn_record->r_class, sres_class_in);
|
|
||||||
TEST(cn->cn_record->r_type, sres_type_cname);
|
|
||||||
TEST(cn->cn_record->r_ttl, 60);
|
|
||||||
TEST_S(cn->cn_cname, "cloop0.example.com.");
|
|
||||||
TEST_1(result[5] == NULL);
|
|
||||||
|
|
||||||
sres_free_answers(res, result);
|
sres_free_answers(res, result);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue