summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libc/inet/resolv.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index cde772d52..cda3b399a 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -248,6 +248,7 @@ Domain name in a message can be represented as either:
#include <netdb.h>
#include <ctype.h>
#include <stdbool.h>
+#include <stdint.h>
#include <time.h>
#include <arpa/nameser.h>
#include <sys/utsname.h>
@@ -1131,6 +1132,22 @@ int _dnsrand_getrandom_urcl(int *rand_value) {
#define DNSRAND_RESEED_OP1 (DNSRAND_PRNGSTATE_INT32LEN*6)
#define DNSRAND_RESEED_OP2 DNSRAND_PRNGSTATE_INT32LEN
#endif
+
+#define DNSRAND_TIMEFORCED_RESEED_CHECKMOD (DNSRAND_PRNGSTATE_INT32LEN/8)
+#define DNSRAND_TIMEFORCED_RESEED_SECS 120
+
+time_t clock_getcursec(void) {
+ static time_t dummyTime = 0;
+#if defined __USE_POSIX199309 && defined __UCLIBC_HAS_REALTIME__
+ struct timespec ts;
+ if (clock_gettime(CLOCK_REALTIME, &ts) == 0) {
+ return ts.tv_sec;
+ }
+#endif
+ dummyTime += DNSRAND_TIMEFORCED_RESEED_SECS;
+ return dummyTime;
+}
+
/*
* This logic uses uclibc's random PRNG to generate random int. This keeps the
* logic fast by not depending on a more involved CPRNG kind of logic nor on a
@@ -1171,6 +1188,9 @@ int _dnsrand_getrandom_urcl(int *rand_value) {
*
*/
int _dnsrand_getrandom_prng(int *rand_value) {
+ static time_t reSeededSec = 0;
+ time_t curSec = 0;
+ bool bTimeForcedReSeed = 0;
static int cnt = -1;
static int nextReSeedWindow = DNSRAND_RESEED_OP1;
static int32_t prngState[DNSRAND_PRNGSTATE_INT32LEN]; /* prng logic internally assumes int32_t wrt state array, so to help align if required */
@@ -1185,7 +1205,15 @@ int _dnsrand_getrandom_prng(int *rand_value) {
initstate_r(prngSeed, (char*)&prngState, DNSRAND_PRNGSTATE_INT32LEN*4, &prngData);
}
cnt += 1;
- if ((cnt % nextReSeedWindow) == 0) {
+ if ((cnt % DNSRAND_TIMEFORCED_RESEED_CHECKMOD) == 0) {
+ curSec = clock_getcursec();
+ if ((curSec - reSeededSec) >= DNSRAND_TIMEFORCED_RESEED_SECS) {
+ bTimeForcedReSeed = 1;
+ }
+ }
+ if (((cnt % nextReSeedWindow) == 0) || bTimeForcedReSeed) {
+ if (curSec == 0) curSec = clock_getcursec();
+ reSeededSec = curSec;
if (_dnsrand_getrandom_urcl(&prngSeed) != 0) {
random_r(&prngData, &prngSeed);
}