Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

am ecd0e95: Adding a timeout to tcp dns lookup connects.

* commit 'ecd0e95a0276c1ba72c7331f5e4617815f015f22':
  Adding a timeout to tcp dns lookup connects.
  • Loading branch information...
commit 82c4be54da0825ebe74b524932c9db733419057a 2 parents e30e909 + ecd0e95
authored January 12, 2012 Android Git Automerger committed January 12, 2012

Showing 1 changed file with 168 additions and 26 deletions. Show diff stats Hide diff stats

  1. 194  libc/netbsd/resolv/res_send.c
194  libc/netbsd/resolv/res_send.c
@@ -99,6 +99,7 @@ __RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $");
99 99
 #include <arpa/inet.h>
100 100
 
101 101
 #include <errno.h>
  102
+#include <fcntl.h>
102 103
 #include <netdb.h>
103 104
 #ifdef ANDROID_CHANGES
104 105
 #include "resolv_private.h"
@@ -109,6 +110,7 @@ __RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $");
109 110
 #include <stdio.h>
110 111
 #include <stdlib.h>
111 112
 #include <string.h>
  113
+#include <time.h>
112 114
 #include <unistd.h>
113 115
 
114 116
 #include <isc/eventlib.h>
@@ -117,6 +119,8 @@ __RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $");
117 119
 #  include <resolv_cache.h>
118 120
 #endif
119 121
 
  122
+#include "logd.h"
  123
+
120 124
 #ifndef DE_CONST
121 125
 #define DE_CONST(c,v)   v = ((c) ? \
122 126
     strchr((const void *)(c), *(const char *)(const void *)(c)) : NULL)
@@ -130,6 +134,7 @@ __RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $");
130 134
 #include "res_private.h"
131 135
 
132 136
 #define EXT(res) ((res)->_u._ext)
  137
+#define DBG 0
133 138
 
134 139
 static const int highestFD = FD_SETSIZE - 1;
135 140
 
@@ -152,7 +157,10 @@ static int		pselect(int, void *, void *, void *,
152 157
 				const sigset_t *);
153 158
 #endif
154 159
 void res_pquery(const res_state, const u_char *, int, FILE *);
155  
-
  160
+static int connect_with_timeout(int sock, const struct sockaddr *nsap,
  161
+			socklen_t salen, int sec);
  162
+static int retrying_select(const int sock, fd_set *readset, fd_set *writeset,
  163
+			const struct timespec *finish);
156 164
 
157 165
 /* BIONIC-BEGIN: implement source port randomization */
158 166
 typedef union {
@@ -521,16 +529,23 @@ res_nsend(res_state statp,
521 529
 
522 530
 		Dprint(((statp->options & RES_DEBUG) &&
523 531
 			getnameinfo(nsap, (socklen_t)nsaplen, abuf, sizeof(abuf),
524  
-				    NULL, 0, niflags) == 0),
525  
-		       (stdout, ";; Querying server (# %d) address = %s\n",
526  
-			ns + 1, abuf));
  532
+				NULL, 0, niflags) == 0),
  533
+				(stdout, ";; Querying server (# %d) address = %s\n",
  534
+				ns + 1, abuf));
527 535
 
528 536
 
529 537
 		if (v_circuit) {
530 538
 			/* Use VC; at most one attempt per server. */
531 539
 			try = statp->retry;
  540
+
532 541
 			n = send_vc(statp, buf, buflen, ans, anssiz, &terrno,
533 542
 				    ns);
  543
+
  544
+			if (DBG) {
  545
+				__libc_android_log_print(ANDROID_LOG_DEBUG, "libc",
  546
+					"used send_vc %d\n", n);
  547
+			}
  548
+
534 549
 			if (n < 0)
535 550
 				goto fail;
536 551
 			if (n == 0)
@@ -538,12 +553,26 @@ res_nsend(res_state statp,
538 553
 			resplen = n;
539 554
 		} else {
540 555
 			/* Use datagrams. */
  556
+			if (DBG) {
  557
+				__libc_android_log_print(ANDROID_LOG_DEBUG, "libc",
  558
+					"using send_dg\n");
  559
+			}
  560
+
541 561
 			n = send_dg(statp, buf, buflen, ans, anssiz, &terrno,
542 562
 				    ns, &v_circuit, &gotsomewhere);
  563
+			if (DBG) {
  564
+				__libc_android_log_print(ANDROID_LOG_DEBUG, "libc",
  565
+					"used send_dg %d\n",n);
  566
+			}
  567
+
543 568
 			if (n < 0)
544 569
 				goto fail;
545 570
 			if (n == 0)
546 571
 				goto next_ns;
  572
+			if (DBG) {
  573
+				__libc_android_log_print(ANDROID_LOG_DEBUG, "libc",
  574
+					"time=%d, %d\n",time(NULL), time(NULL)%2);
  575
+			}
547 576
 			if (v_circuit)
548 577
 				goto same_ns;
549 578
 			resplen = n;
@@ -668,6 +697,23 @@ get_nsaddr(statp, n)
668 697
 	}
669 698
 }
670 699
 
  700
+static int get_timeout(const res_state statp, const int ns)
  701
+{
  702
+	int timeout = (statp->retrans << ns);
  703
+	if (ns > 0) {
  704
+		timeout /= statp->nscount;
  705
+	}
  706
+	if (timeout <= 0) {
  707
+		timeout = 1;
  708
+	}
  709
+	if (DBG) {
  710
+		__libc_android_log_print(ANDROID_LOG_DEBUG, "libc",
  711
+			"using timeout of %d sec\n", timeout);
  712
+	}
  713
+
  714
+	return timeout;
  715
+}
  716
+
671 717
 static int
672 718
 send_vc(res_state statp,
673 719
 	const u_char *buf, int buflen, u_char *ans, int anssiz,
@@ -683,6 +729,10 @@ send_vc(res_state statp,
683 729
 	u_char *cp;
684 730
 	void *tmp;
685 731
 
  732
+	if (DBG) {
  733
+		__libc_android_log_print(ANDROID_LOG_DEBUG, "libc", "using send_vc\n");
  734
+	}
  735
+
686 736
 	nsap = get_nsaddr(statp, (size_t)ns);
687 737
 	nsaplen = get_salen(nsap);
688 738
 
@@ -735,7 +785,8 @@ send_vc(res_state statp,
735 785
 			res_nclose(statp);
736 786
 			return (0);
737 787
 		}
738  
-		if (connect(statp->_vcsock, nsap, (socklen_t)nsaplen) < 0) {
  788
+		if (connect_with_timeout(statp->_vcsock, nsap, (socklen_t)nsaplen,
  789
+				get_timeout(statp, ns)) < 0) {
739 790
 			*terrno = errno;
740 791
 			Aerror(statp, stderr, "connect/vc", errno, nsap,
741 792
 			    nsaplen);
@@ -859,6 +910,111 @@ send_vc(res_state statp,
859 910
 	return (resplen);
860 911
 }
861 912
 
  913
+/* return -1 on error (errno set), 0 on success */
  914
+static int
  915
+connect_with_timeout(int sock, const struct sockaddr *nsap, socklen_t salen, int sec)
  916
+{
  917
+	int res, origflags;
  918
+	fd_set rset, wset;
  919
+	struct timespec now, timeout, finish;
  920
+
  921
+	origflags = fcntl(sock, F_GETFL, 0);
  922
+	fcntl(sock, F_SETFL, origflags | O_NONBLOCK);
  923
+
  924
+	res = connect(sock, nsap, salen);
  925
+	if (res < 0 && errno != EINPROGRESS) {
  926
+                res = -1;
  927
+                goto done;
  928
+	}
  929
+	if (res != 0) {
  930
+		now = evNowTime();
  931
+		timeout = evConsTime((long)sec, 0L);
  932
+		finish = evAddTime(now, timeout);
  933
+		if (DBG) {
  934
+			__libc_android_log_print(ANDROID_LOG_DEBUG, "libc",
  935
+				"  %d send_vc\n", sock);
  936
+		}
  937
+
  938
+		res = retrying_select(sock, &rset, &wset, &finish);
  939
+		if (res <= 0) {
  940
+                        res = -1;
  941
+		}
  942
+	}
  943
+done:
  944
+	fcntl(sock, F_SETFL, origflags);
  945
+	if (DBG) {
  946
+		__libc_android_log_print(ANDROID_LOG_DEBUG, "libc",
  947
+			"  %d connect_with_timeout returning %s\n", sock, res);
  948
+	}
  949
+	return res;
  950
+}
  951
+
  952
+static int
  953
+retrying_select(const int sock, fd_set *readset, fd_set *writeset, const struct timespec *finish)
  954
+{
  955
+	struct timespec now, timeout;
  956
+	int n, error;
  957
+	socklen_t len;
  958
+
  959
+
  960
+retry:
  961
+	if (DBG) {
  962
+		__libc_android_log_print(ANDROID_LOG_DEBUG, "libc", "  %d retying_select\n", sock);
  963
+	}
  964
+
  965
+	now = evNowTime();
  966
+	if (readset) {
  967
+		FD_ZERO(readset);
  968
+		FD_SET(sock, readset);
  969
+	}
  970
+	if (writeset) {
  971
+		FD_ZERO(writeset);
  972
+		FD_SET(sock, writeset);
  973
+	}
  974
+	if (evCmpTime(*finish, now) > 0)
  975
+		timeout = evSubTime(*finish, now);
  976
+	else
  977
+		timeout = evConsTime(0L, 0L);
  978
+
  979
+	n = pselect(sock + 1, readset, writeset, NULL, &timeout, NULL);
  980
+	if (n == 0) {
  981
+		if (DBG) {
  982
+			__libc_android_log_print(ANDROID_LOG_DEBUG, " libc",
  983
+				"  %d retrying_select timeout\n", sock);
  984
+		}
  985
+		errno = ETIMEDOUT;
  986
+		return 0;
  987
+	}
  988
+	if (n < 0) {
  989
+		if (errno == EINTR)
  990
+			goto retry;
  991
+		if (DBG) {
  992
+			__libc_android_log_print(ANDROID_LOG_DEBUG, "libc",
  993
+				"  %d retrying_select got error %d\n",sock, n);
  994
+		}
  995
+		return n;
  996
+	}
  997
+	if ((readset && FD_ISSET(sock, readset)) || (writeset && FD_ISSET(sock, writeset))) {
  998
+		len = sizeof(error);
  999
+		if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) {
  1000
+			errno = error;
  1001
+			if (DBG) {
  1002
+				__libc_android_log_print(ANDROID_LOG_DEBUG, "libc",
  1003
+					"  %d retrying_select dot error2 %d\n", sock, errno);
  1004
+			}
  1005
+
  1006
+			return -1;
  1007
+		}
  1008
+	}
  1009
+	if (DBG) {
  1010
+		__libc_android_log_print(ANDROID_LOG_DEBUG, "libc",
  1011
+			"  %d retrying_select returning %d for %d\n",sock, n);
  1012
+	}
  1013
+
  1014
+	return n;
  1015
+}
  1016
+
  1017
+
862 1018
 static int
863 1019
 send_dg(res_state statp,
864 1020
 	const u_char *buf, int buflen, u_char *ans, int anssiz,
@@ -944,33 +1100,19 @@ send_dg(res_state statp,
944 1100
 	/*
945 1101
 	 * Wait for reply.
946 1102
 	 */
947  
-	seconds = (statp->retrans << ns);
948  
-	if (ns > 0)
949  
-		seconds /= statp->nscount;
950  
-	if (seconds <= 0)
951  
-		seconds = 1;
  1103
+	seconds = get_timeout(statp, ns);
952 1104
 	now = evNowTime();
953 1105
 	timeout = evConsTime((long)seconds, 0L);
954 1106
 	finish = evAddTime(now, timeout);
955  
-	goto nonow;
956  
- wait:
957  
-	now = evNowTime();
958  
- nonow:
959  
-	FD_ZERO(&dsmask);
960  
-	FD_SET(s, &dsmask);
961  
-	if (evCmpTime(finish, now) > 0)
962  
-		timeout = evSubTime(finish, now);
963  
-	else
964  
-		timeout = evConsTime(0L, 0L);
965  
-	n = pselect(s + 1, &dsmask, NULL, NULL, &timeout, NULL);
  1107
+retry:
  1108
+	n = retrying_select(s, &dsmask, NULL, &finish);
  1109
+
966 1110
 	if (n == 0) {
967 1111
 		Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
968 1112
 		*gotsomewhere = 1;
969 1113
 		return (0);
970 1114
 	}
971 1115
 	if (n < 0) {
972  
-		if (errno == EINTR)
973  
-			goto wait;
974 1116
 		Perror(statp, stderr, "select", errno);
975 1117
 		res_nclose(statp);
976 1118
 		return (0);
@@ -1006,7 +1148,7 @@ send_dg(res_state statp,
1006 1148
 			(statp->pfcode & RES_PRF_REPLY),
1007 1149
 			(stdout, ";; old answer:\n"),
1008 1150
 			ans, (resplen > anssiz) ? anssiz : resplen);
1009  
-		goto wait;
  1151
+		goto retry;
1010 1152
 	}
1011 1153
 	if (!(statp->options & RES_INSECURE1) &&
1012 1154
 	    !res_ourserver_p(statp, (struct sockaddr *)(void *)&from)) {
@@ -1019,7 +1161,7 @@ send_dg(res_state statp,
1019 1161
 			(statp->pfcode & RES_PRF_REPLY),
1020 1162
 			(stdout, ";; not our server:\n"),
1021 1163
 			ans, (resplen > anssiz) ? anssiz : resplen);
1022  
-		goto wait;
  1164
+		goto retry;
1023 1165
 	}
1024 1166
 #ifdef RES_USE_EDNS0
1025 1167
 	if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0U) {
@@ -1049,7 +1191,7 @@ send_dg(res_state statp,
1049 1191
 			(statp->pfcode & RES_PRF_REPLY),
1050 1192
 			(stdout, ";; wrong query name:\n"),
1051 1193
 			ans, (resplen > anssiz) ? anssiz : resplen);
1052  
-		goto wait;
  1194
+		goto retry;;
1053 1195
 	}
1054 1196
 	if (anhp->rcode == SERVFAIL ||
1055 1197
 	    anhp->rcode == NOTIMP ||

0 notes on commit 82c4be5

Please sign in to comment.
Something went wrong with that request. Please try again.