summaryrefslogtreecommitdiff
path: root/lib/resolv_wrapper
diff options
context:
space:
mode:
authorJakub Hrozek <jakub.hrozek@gmail.com>2014-12-03 15:45:04 +0100
committerAndrew Bartlett <abartlet@samba.org>2014-12-05 23:32:06 +0100
commit917c3f08440c302511bdf06b5ac11b42630bdd28 (patch)
tree07225a00e185d075b27ad7501b84b8a49ceec73f /lib/resolv_wrapper
parent0d128c5443283dee86edce60325083647985fe02 (diff)
downloadsamba-917c3f08440c302511bdf06b5ac11b42630bdd28.tar.gz
rwrap: SRV record can recurse into A or AAAA.
When querying for a SRV record, we'll need to include A or AAAA records in additional section. Therefore, keep querying the host file until we can either recurse the A/AAAA records or reach the recursion limit Signed-off-by: Jakub Hrozek <jakub.hrozek@gmail.com> Reviewed-by: Andreas Schneider <asn@samba.org> Reviewed-by: Guenther Deschner <gd@samba.org> Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'lib/resolv_wrapper')
-rw-r--r--lib/resolv_wrapper/resolv_wrapper.c55
1 files changed, 47 insertions, 8 deletions
diff --git a/lib/resolv_wrapper/resolv_wrapper.c b/lib/resolv_wrapper/resolv_wrapper.c
index 0c079fe1fc4..99c091d0de0 100644
--- a/lib/resolv_wrapper/resolv_wrapper.c
+++ b/lib/resolv_wrapper/resolv_wrapper.c
@@ -141,6 +141,8 @@ static void rwrap_log(enum rwrap_dbglvl_e dbglvl,
} \
} while(0);
+#define RWRAP_MAX_RECURSION 5
+
/* Priority and weight can be omitted from the hosts file, but need to be part
* of the output
*/
@@ -657,7 +659,25 @@ static ssize_t rwrap_fake_empty_query(const char *key,
(strcasecmp(key, query)) == 0)
-static int rwrap_get_record(const char *hostfile,
+static int rwrap_get_record(const char *hostfile, unsigned recursion,
+ const char *query, int type,
+ struct rwrap_fake_rr *rr);
+
+static int rwrap_srv_recurse(const char *hostfile, unsigned recursion,
+ const char *query, struct rwrap_fake_rr *rr)
+{
+ int rc;
+
+ rc = rwrap_get_record(hostfile, recursion, query, ns_t_a, rr);
+ if (rc == 0) return 0;
+
+ rc = rwrap_get_record(hostfile, recursion, query, ns_t_aaaa, rr);
+ if (rc == ENOENT) rc = 0;
+
+ return rc;
+}
+
+static int rwrap_get_record(const char *hostfile, unsigned recursion,
const char *query, int type,
struct rwrap_fake_rr *rr)
{
@@ -665,7 +685,12 @@ static int rwrap_get_record(const char *hostfile,
char buf[BUFSIZ];
char *key = NULL;
char *value = NULL;
- int rc = 0;
+ int rc = ENOENT;
+
+ if (recursion >= RWRAP_MAX_RECURSION) {
+ RWRAP_LOG(RWRAP_LOG_ERROR, "Recursed too deep!\n");
+ return -1;
+ }
RWRAP_LOG(RWRAP_LOG_TRACE,
"Searching in fake hosts file %s\n", hostfile);
@@ -711,6 +736,11 @@ static int rwrap_get_record(const char *hostfile,
} else if (TYPE_MATCH(type, ns_t_srv,
rec_type, "SRV", key, query)) {
rc = rwrap_create_fake_srv_rr(key, value, rr);
+ if (rc == 0) {
+ rc = rwrap_srv_recurse(hostfile, recursion+1,
+ rr->rrdata.srv_rec.hostname,
+ rr + 1);
+ }
break;
} else if (TYPE_MATCH(type, ns_t_soa,
rec_type, "SOA", key, query)) {
@@ -723,7 +753,7 @@ static int rwrap_get_record(const char *hostfile,
}
}
- if (rc == 0 && rr->type == ns_t_invalid) {
+ if (rc == ENOENT && recursion == 0) {
RWRAP_LOG(RWRAP_LOG_TRACE, "Record for [%s] not found\n", query);
memcpy(rr->key, key, strlen(key) + 1);
}
@@ -782,7 +812,7 @@ static int rwrap_res_fake_hosts(const char *hostfile,
int rc = ENOENT;
char *query_name = NULL;
size_t qlen = strlen(query);
- struct rwrap_fake_rr rr;
+ struct rwrap_fake_rr rrs[RWRAP_MAX_RECURSION];
ssize_t resp_size;
RWRAP_LOG(RWRAP_LOG_TRACE,
@@ -797,17 +827,26 @@ static int rwrap_res_fake_hosts(const char *hostfile,
return -1;
}
- rwrap_fake_rr_init(&rr, 1);
+ rwrap_fake_rr_init(rrs, RWRAP_MAX_RECURSION);
- rc = rwrap_get_record(hostfile, query_name, type, &rr);
- if (rc != 0) {
+ rc = rwrap_get_record(hostfile, 0, query_name, type, rrs);
+ switch (rc) {
+ case 0:
+ RWRAP_LOG(RWRAP_LOG_TRACE,
+ "Found record for [%s]\n", query_name);
+ break;
+ case ENOENT:
+ RWRAP_LOG(RWRAP_LOG_TRACE,
+ "No record for [%s]\n", query_name);
+ break;
+ default:
RWRAP_LOG(RWRAP_LOG_ERROR,
"Error searching for [%s]\n", query_name);
free(query_name);
return -1;
}
- resp_size = rwrap_fake_answer(&rr, type, answer, anslen);
+ resp_size = rwrap_fake_answer(rrs, type, answer, anslen);
switch (resp_size) {
case -1:
RWRAP_LOG(RWRAP_LOG_ERROR,