Hi All,
As mentioned in my previous message, attached is a patch which uses /dev/urandom to
generate a random id for dns query id field. However if it is not able to access urandom
file, then it falls back to the old logic of simple incrementing counter. Have done some
minimal test on my linux system and it seems to be working fine.
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index 92a65d0dc..c37f6fab7 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -255,6 +255,7 @@ Domain name in a message can be represented as either:
#include <sys/stat.h>
#include <sys/param.h>
#include <bits/uClibc_mutex.h>
+#include <fcntl.h>
#include "internal/parse_config.h"
/* poll() is not supported in kernel <= 2.0, therefore if __NR_poll is
@@ -1045,6 +1046,20 @@ static int __decode_answer(const unsigned char *message, /* packet
*/
return i + RRFIXEDSZ + a->rdlength;
}
+
+uint16_t dnsrand_next(int urand_fd, int def_value) {
+ if (urand_fd == -1) return def_value;
+ uint16_t val;
+ if(read(urand_fd, &val, 2) != 2) return def_value;
+ return val;
+}
+
+int dnsrand_setup(int *urand_fd, int def_value) {
+ *urand_fd = open("/dev/urandom", O_RDONLY);
+ if (*urand_fd == -1) return def_value;
+ return dnsrand_next(*urand_fd, def_value);
+}
+
/* On entry:
* a.buf(len) = auxiliary buffer for IP addresses after first one
* a.add_count = how many additional addresses are there already
@@ -1070,6 +1085,7 @@ int __dns_lookup(const char *name,
/* Protected by __resolv_lock: */
static int last_ns_num = 0;
static uint16_t last_id = 1;
+ static int urand_fd = -1;
int i, j, fd, rc;
int packet_len;
@@ -1149,7 +1165,7 @@ int __dns_lookup(const char *name,
}
/* first time? pick starting server etc */
if (local_ns_num < 0) {
- local_id = last_id;
+ local_id = dnsrand_setup(&urand_fd, last_id);
/*TODO: implement /etc/resolv.conf's "options rotate"
(a.k.a. RES_ROTATE bit in _res.options)
local_ns_num = 0;
@@ -1159,8 +1175,9 @@ int __dns_lookup(const char *name,
}
if (local_ns_num >= __nameservers)
local_ns_num = 0;
- local_id++;
+ local_id = dnsrand_next(urand_fd, local_id++);
local_id &= 0xffff;
+ DPRINTF("uClibc:DBUG:local_id:0x%hx\n", local_id);
/* write new values back while still under lock */
last_id = local_id;
last_ns_num = local_ns_num;