From: Apple Date: Mon, 4 Aug 2008 15:45:09 +0000 (+0000) Subject: libresolv-25.0.2.tar.gz X-Git-Tag: mac-os-x-1055^0 X-Git-Url: https://git.saurik.com/apple/libresolv.git/commitdiff_plain/51a689d1e242c816edddcc4423c02227a6e1c140 libresolv-25.0.2.tar.gz --- diff --git a/dns.c b/dns.c index fa5ddfa..7c5ceb4 100644 --- a/dns.c +++ b/dns.c @@ -882,7 +882,7 @@ _pdns_get_default_handles(sdns_handle_t *sdns, pdns_handle_t ***pdns) } static uint32_t -_pdns_get_handles_for_name(sdns_handle_t *sdns, const char *name, pdns_handle_t ***pdns) +_pdns_get_handles_for_name(sdns_handle_t *sdns, const char *name, uint32_t nlabels, pdns_handle_t ***pdns) { char *p, *vname; int i, j, k, count; @@ -906,6 +906,9 @@ _pdns_get_handles_for_name(sdns_handle_t *sdns, const char *name, pdns_handle_t { if (sdns->client[i]->name == NULL) continue; + /* Special case: Don't send to ".local[.]" queries to mDNSResponder if nlabels > 2 */ + if ((nlabels > 2) && (sdns->client[i]->flags & DNS_FLAG_FORWARD_TO_MDNSRESPONDER) && (!strcasecmp(sdns->client[i]->name, "local"))) continue; + if (!strcasecmp(sdns->client[i]->name, p)) { if (count == 0) @@ -1248,7 +1251,7 @@ _pdns_delay(sdns_handle_t *sdns) tick = time(NULL); /* * Subsequent threads sleep for the remaining duration. - * We add one to round up the interval since our garnularity is coarse. + * We add one to round up the interval since our granularity is coarse. */ snooze = 1 + (sdns->dns_delay - tick); if (snooze < 0) snooze = 0; @@ -1355,7 +1358,7 @@ _pdns_search(sdns_handle_t *sdns, pdns_handle_t *pdns, const char *name, uint32_ } static int -_sdns_send(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t type, uint32_t fqdn, char *buf, uint32_t len, struct sockaddr *from, uint32_t *fromlen, int *min) +_sdns_send(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t type, uint32_t fqdn, char *buf, uint32_t len, struct sockaddr *from, uint32_t *fromlen, uint32_t nlabels, int *min) { char *qname; pdns_handle_t **pdns; @@ -1370,7 +1373,7 @@ _sdns_send(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t type, *min = -1; m = -1; - pdns_count = _pdns_get_handles_for_name(sdns, name, &pdns); + pdns_count = _pdns_get_handles_for_name(sdns, name, nlabels, &pdns); if (pdns_count == 0) return -1; @@ -1409,7 +1412,7 @@ __private_extern__ int _sdns_search(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t type, uint32_t fqdn, uint32_t recurse, char *buf, uint32_t len, struct sockaddr *from, uint32_t *fromlen, int *min) { pdns_handle_t *primary, **pdns; - int i, n, ndots, status; + int i, n, ndots, nlabels, status; int m, tmin, minstate; char *dot, *qname; uint32_t pdns_count; @@ -1452,6 +1455,9 @@ _sdns_search(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t typ /* the last dot is the last character, name is fully qualified */ if ((fqdn == 0) && (dot != NULL) && (*(dot + 1) == '\0')) fqdn = 1; + /* number of labels */ + nlabels = n + 1 - fqdn; + /* * If n >= ndots, or it's a FQDN, or if it's a PTR query, * we try a query with the name "as is". @@ -1459,7 +1465,7 @@ _sdns_search(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t typ if ((n >= ndots) || (fqdn == 1) || (type == ns_t_ptr)) { tmin = -1; - status = _sdns_send(sdns, name, class, type, fqdn, buf, len, from, fromlen, &tmin); + status = _sdns_send(sdns, name, class, type, fqdn, buf, len, from, fromlen, nlabels, &tmin); if (status > 0) return status; if (tmin < 0) minstate = -1; diff --git a/res_init.c b/res_init.c index 0057cbb..bdb3845 100644 --- a/res_init.c +++ b/res_init.c @@ -134,7 +134,6 @@ res_state res_build_start(res_state x) { res_state res; - int rf; res = NULL; @@ -158,10 +157,7 @@ res_build_start(res_state x) res->retry = RES_DFLRETRY; res->options = RES_DEFAULT; - - rf = open("/dev/random", O_RDONLY, 0); - read(rf, &(res->id), 2); - close(rf); + res->id = res_randomid(); res->ndots = 1; res->_vcsock = -1; @@ -1367,33 +1363,15 @@ net_mask(in) /* XXX - should really use system's version of this */ #endif u_int -res_randomid(void) { - struct timeval now; +res_randomid(void) +{ #ifdef __APPLE__ - int rf; - static u_int x = 0; - - if (x == 0) - { - rf = open("/dev/random", O_RDONLY, 0); - if (rf >= 0) - { - read(rf, &x, sizeof(u_int)); - close(rf); - } - else - { - x = (getpid() << 10) + time(NULL); - } - - srandom(x); - } - - return random(); -#endif - + return arc4random(); +#else + struct timeval now; gettimeofday(&now, NULL); return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid())); +#endif } /* diff --git a/res_send.c b/res_send.c index e70c2e4..1018e6c 100644 --- a/res_send.c +++ b/res_send.c @@ -133,6 +133,11 @@ static const int highestFD = FD_SETSIZE - 1; #define MAX_HOOK_RETRIES 42 +/* port randomization */ +#define RANDOM_BIND_MAX_TRIES 16 +#define RANDOM_BIND_FIRST IPPORT_HIFIRSTAUTO +#define RANDOM_BIND_LAST IPPORT_HILASTAUTO + /* Forward. */ static int get_salen __P((const struct sockaddr *)); @@ -149,6 +154,29 @@ static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; static int interrupt_pipe_enabled = 0; static pthread_key_t interrupt_pipe_key; +static int +bind_random(int sock) +{ + int i, status; + uint16_t src_port; + struct sockaddr_in local; + + src_port = 0; + status = -1; + + for (i = 0; (i < RANDOM_BIND_MAX_TRIES) && (status < 0); i++) + { + /* random port in the range RANDOM_BIND_FIRST to RANDOM_BIND_LAST */ + src_port = (res_randomid() % (RANDOM_BIND_LAST - RANDOM_BIND_FIRST)) + RANDOM_BIND_FIRST; + memset(&local, 0, sizeof(struct sockaddr_in)); + local.sin_port = htons(src_port); + + status = bind(sock, (struct sockaddr *)&local, sizeof(struct sockaddr_in)); + } + + return status; +} + void res_delete_interrupt_token(void *token) { @@ -1155,6 +1183,8 @@ send_dg(res_state statp, const u_char *buf, int buflen, u_char *ans, int *anssiz return DNS_RES_STATUS_SYSTEM_ERROR; } + bind_random(EXT(statp).nssocks[ns]); + #ifndef CANNOT_CONNECT_DGRAM /* * On a 4.3BSD+ machine (client and server,