about summary refs log tree commit diff
path: root/resolv/res_send.c
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2017-06-30 21:10:23 +0200
committerFlorian Weimer <fweimer@redhat.com>2017-07-03 20:52:59 +0200
commit352f4ff9a268b81ef5d4b2413f582565806e4790 (patch)
treefb27056dfdeafe43c021f6127c9544c016e78019 /resolv/res_send.c
parent4e45d83c92dbb5b8dc20654f32395108d18cf739 (diff)
downloadglibc-352f4ff9a268b81ef5d4b2413f582565806e4790.tar.gz
glibc-352f4ff9a268b81ef5d4b2413f582565806e4790.tar.xz
glibc-352f4ff9a268b81ef5d4b2413f582565806e4790.zip
resolv: Introduce struct resolv_context [BZ #21668]
struct resolv_context objects provide a temporary resolver context
which does not change during a name lookup operation.  Only when the
outmost context is created, the stub resolver configuration is
verified to be current (at present, only against previous res_init
calls).  Subsequent attempts to obtain the context will reuse the
result of the initial verification operation.

struct resolv_context can also be extended in the future to store
data which needs to be deallocated during thread cancellation.
Diffstat (limited to 'resolv/res_send.c')
-rw-r--r--resolv/res_send.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/resolv/res_send.c b/resolv/res_send.c
index a7daae8a06..b396aae03c 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -102,6 +102,7 @@
 #include <fcntl.h>
 #include <netdb.h>
 #include <resolv/resolv-internal.h>
+#include <resolv/resolv_context.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
@@ -400,11 +401,14 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1,
 libresolv_hidden_def (res_queriesmatch)
 
 int
-__libc_res_nsend(res_state statp, const u_char *buf, int buflen,
-		 const u_char *buf2, int buflen2,
-		 u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
-		 int *nansp2, int *resplen2, int *ansp2_malloced)
+__res_context_send (struct resolv_context *ctx,
+		    const unsigned char *buf, int buflen,
+		    const unsigned char *buf2, int buflen2,
+		    unsigned char *ans, int anssiz,
+		    unsigned char **ansp, unsigned char **ansp2,
+		    int *nansp2, int *resplen2, int *ansp2_malloced)
 {
+	struct __res_state *statp = ctx->resp;
 	int gotsomewhere, terrno, try, v_circuit, resplen, n;
 
 	if (statp->nscount == 0) {
@@ -541,22 +545,36 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
 	return (-1);
 }
 
+/* Common part of res_nsend and res_send.  */
+static int
+context_send_common (struct resolv_context *ctx,
+		     const unsigned char *buf, int buflen,
+		     unsigned char *ans, int anssiz)
+{
+  if (ctx == NULL)
+    {
+      RES_SET_H_ERRNO (&_res, NETDB_INTERNAL);
+      return -1;
+    }
+  int result = __res_context_send (ctx, buf, buflen, NULL, 0, ans, anssiz,
+				   NULL, NULL, NULL, NULL, NULL);
+  __resolv_context_put (ctx);
+  return result;
+}
+
 int
-res_nsend(res_state statp,
-	  const u_char *buf, int buflen, u_char *ans, int anssiz)
+res_nsend (res_state statp, const unsigned char *buf, int buflen,
+	   unsigned char *ans, int anssiz)
 {
-  return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
-			  NULL, NULL, NULL, NULL, NULL);
+  return context_send_common
+    (__resolv_context_get_override (statp), buf, buflen, ans, anssiz);
 }
-libresolv_hidden_def (res_nsend)
 
 int
 res_send (const unsigned char *buf, int buflen, unsigned char *ans, int anssiz)
 {
-  if (__res_maybe_init (&_res, 1) == -1)
-    /* errno should have been set by res_init in this case.  */
-    return -1;
-  return res_nsend (&_res, buf, buflen, ans, anssiz);
+  return context_send_common
+    (__resolv_context_get (), buf, buflen, ans, anssiz);
 }
 
 /* Private */