Commit 55d92ef6 authored by Mickaël Turnel's avatar Mickaël Turnel

Check in reception the type of request (dns, mdns) and treat accordingly

parent 9658442c
...@@ -283,6 +283,8 @@ struct sres_resolver_s { ...@@ -283,6 +283,8 @@ struct sres_resolver_s {
sres_server_t **res_servers; sres_server_t **res_servers;
#if HAVE_MDNS #if HAVE_MDNS
sres_query_t *res_mdns_query;
sres_socket_t res_mdns_socket;
uint8_t res_mdns; uint8_t res_mdns;
sres_record_t **res_mdns_answers; sres_record_t **res_mdns_answers;
#endif #endif
...@@ -1135,13 +1137,13 @@ sres_mdns_process_srv(void *obj) ...@@ -1135,13 +1137,13 @@ sres_mdns_process_srv(void *obj)
if (error == kDNSServiceErr_NoError) { if (error == kDNSServiceErr_NoError) {
handle_poll(browse_ref); handle_poll(browse_ref);
sres_notify_resolver(query);
} else { } else {
SU_DEBUG_9(("sres_mdns_process_srv(\"%s\", %i) browse error\n", SU_DEBUG_9(("sres_mdns_process_srv(\"%s\", %i) browse error\n",
query->q_name, error)); query->q_name, error));
} }
sres_notify_resolver(query);
return NULL; return NULL;
} }
...@@ -1212,13 +1214,13 @@ sres_mdns_process_a_aaaa(void *obj) ...@@ -1212,13 +1214,13 @@ sres_mdns_process_a_aaaa(void *obj)
res_it = res_it->ai_next; res_it = res_it->ai_next;
} while (res_it != NULL); } while (res_it != NULL);
sres_notify_resolver(query);
} }
if (res) if (res)
freeaddrinfo(res); freeaddrinfo(res);
sres_notify_resolver(query);
return NULL; return NULL;
} }
#endif #endif
...@@ -1332,6 +1334,7 @@ sres_query(sres_resolver_t *res, ...@@ -1332,6 +1334,7 @@ sres_query(sres_resolver_t *res,
#if HAVE_MDNS #if HAVE_MDNS
if (query && (res->res_mdns || strstr(domain, ".local"))) { if (query && (res->res_mdns || strstr(domain, ".local"))) {
res->res_mdns = 1; res->res_mdns = 1;
res->res_mdns_query = query;
sres_mdns_query(query); sres_mdns_query(query);
} else } else
#endif #endif
...@@ -3561,6 +3564,9 @@ int sres_resolver_sockets(sres_resolver_t *res, ...@@ -3561,6 +3564,9 @@ int sres_resolver_sockets(sres_resolver_t *res,
} }
return_sockets[i++] = s; return_sockets[i++] = s;
#ifdef HAVE_MDNS
res->res_mdns_socket = s;
#endif
} }
return retval; return retval;
...@@ -3798,99 +3804,119 @@ sres_resolver_report_error(sres_resolver_t *res, ...@@ -3798,99 +3804,119 @@ sres_resolver_report_error(sres_resolver_t *res,
int int
sres_resolver_receive(sres_resolver_t *res, int socket) sres_resolver_receive(sres_resolver_t *res, int socket)
{ {
ssize_t num_bytes; #ifdef HAVE_MDNS
int error; if (res->res_mdns) {
sres_message_t m[1]; sres_query_t *query = NULL;
sres_query_t *query = NULL; if (query) {
sres_record_t **reply; if (res->res_mdns_answers) {
sres_server_t *dns; /* Notify the listener */
if (query->q_callback != NULL)
(query->q_callback)(query->q_context, query, res->res_mdns_answers);
struct sockaddr_storage from[1]; sres_free_query(res, query);
socklen_t fromlen = sizeof from; } else {
sres_query_report_error(query, res->res_mdns_answers);
}
}
} else {
#endif
ssize_t num_bytes;
int error;
sres_message_t m[1];
SU_DEBUG_9(("%s(%p, %u) called\n", "sres_resolver_receive", sres_query_t *query = NULL;
(void *)res, socket)); sres_record_t **reply;
sres_server_t *dns;
memset(m, 0, offsetof(sres_message_t, m_data)); struct sockaddr_storage from[1];
socklen_t fromlen = sizeof from;
num_bytes = sres_recvfrom(socket, m->m_data, sizeof (m->m_data), 0, SU_DEBUG_9(("%s(%p, %u) called\n", "sres_resolver_receive",
(void *)from, &fromlen); (void *)res, socket));
if (num_bytes <= 0) { memset(m, 0, offsetof(sres_message_t, m_data));
SU_DEBUG_5(("%s: %s\n", "sres_resolver_receive", su_strerror(su_errno())));
return 0;
}
if (num_bytes > 65535) num_bytes = sres_recvfrom(socket, m->m_data, sizeof (m->m_data), 0,
num_bytes = 65535; (void *)from, &fromlen);
dns = sres_server_by_socket(res, socket); if (num_bytes <= 0) {
if (!dns) SU_DEBUG_5(("%s: %s\n", "sres_resolver_receive", su_strerror(su_errno())));
return 0; return 0;
}
m->m_size = (uint16_t)num_bytes; if (num_bytes > 65535)
num_bytes = 65535;
/* Decode the received message and get the matching query object */ dns = sres_server_by_socket(res, socket);
error = sres_decode_msg(res, m, &query, &reply); if (!dns)
return 0;
sres_log_response(res, m, from, query, reply); m->m_size = (uint16_t)num_bytes;
if (query == NULL) /* Decode the received message and get the matching query object */
; error = sres_decode_msg(res, m, &query, &reply);
else if (error == SRES_EDNS0_ERR) {
dns->dns_edns = edns_not_supported; sres_log_response(res, m, from, query, reply);
assert(query->q_id);
sres_remove_query(res, query, 0); if (query == NULL)
sres_gen_id(res, query); ;
sres_qtable_append(res->res_queries, query); else if (error == SRES_EDNS0_ERR) {
sres_send_dns_query(res, query); dns->dns_edns = edns_not_supported;
query->q_retry_count++; assert(query->q_id);
} sres_remove_query(res, query, 0);
else if (error == SRES_AUTH_ERR || sres_gen_id(res, query);
error == SRES_UNIMPL_ERR || sres_qtable_append(res->res_queries, query);
error == SRES_SERVER_ERR) { sres_send_dns_query(res, query);
/* query->q_retry_count++;
* Mark server as unresponsive and }
* try to resend query to another server else if (error == SRES_AUTH_ERR ||
*/ error == SRES_UNIMPL_ERR ||
dns->dns_icmp = res->res_now; error == SRES_SERVER_ERR) {
if (sres_resend_dns_query(res, query, 0) < 0) /*
sres_query_report_error(query, reply); * Mark server as unresponsive and
else * try to resend query to another server
sres_cache_free_answers(res->res_cache, reply); */
} dns->dns_icmp = res->res_now;
else if (!error && reply) { if (sres_resend_dns_query(res, query, 0) < 0)
/* Remove the query from the pending list */ sres_query_report_error(query, reply);
sres_remove_query(res, query, 1); else
sres_cache_free_answers(res->res_cache, 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 {
/* Submit a query with the aliased name, dropping this result */
sres_resolve_cname(res, query, alias);
return 1;
}
} }
else if (!error && reply) {
/* Remove the query from the pending list */
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 {
/* Submit a query with the aliased name, dropping this result */
sres_resolve_cname(res, query, alias);
return 1;
}
}
/* Notify the listener */ /* 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 {
sres_query_report_error(query, reply); sres_query_report_error(query, reply);
}
#ifdef HAVE_MDNS
} }
#endif
return 1; return 1;
} }
......
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