uint16_t q_retry_count;
uint8_t q_n_servers;
uint8_t q_i_server;
+ int8_t q_aliased;
int8_t q_edns;
uint8_t q_n_subs;
sres_query_t *q_subqueries[1 + SRES_MAX_SEARCH];
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 */
static
query->q_retry_count++;
}
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);
- if (query->q_callback != NULL)
- (query->q_callback)(query->q_context, query, reply);
+
+ /* 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)
+ (query->q_callback)(query->q_context, query, reply);
+ }
sres_free_query(res, query);
}
else {
return -1;
}
- if (m->m_ancount > 0 && errorcount == 0 && query->q_type < sres_qtype_tsig) {
- char b0[8], b1[8];
+ if (m->m_ancount > 0 && errorcount == 0 && query->q_type < sres_qtype_tsig
+ && (query->q_aliased || answers[0]->sr_type != sres_type_cname)) {
+
for (i = 0; i < m->m_ancount; i++) {
if (query->q_type == answers[i]->sr_type)
break;
}
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",
sres_record_type(query->q_type, b0),
sres_record_type(answers[0]->sr_type, b1)));
TEST_1(result = ctx->result);
TEST_1(sr = result[0]);
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;
TEST_1(result = sres_cached_answers(res, sres_type_naptr, domain));
TEST_1(sr = result[0]);
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;
TEST_RUN(ctx);
TEST_1(result = ctx->result);
- TEST_1(cn = result[0]->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.");
- TEST_1(sr = result[1]);
+ TEST_1(sr = result[0]);
TEST(sr->sr_record->r_class, sres_class_in);
TEST(sr->sr_record->r_type, sres_type_a);
sres_free_answers(res, ctx->result), ctx->result = NULL;
TEST_1(result = sres_cached_answers(res, sres_type_a, domain));
- TEST_1(cn = result[0]->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.");
- TEST_1(sr = result[1]);
+ TEST_1(sr = result[0]);
TEST(sr->sr_record->r_class, sres_class_in);
TEST(sr->sr_record->r_type, sres_type_a);
TEST_1(result = ctx->result);
TEST_1(sr = result[0]);
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;
TEST_1(result = sres_cached_answers(res, sres_type_a, domain));
TEST_1(sr = result[0]);
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);