diff options
Diffstat (limited to 'libc/inet/resolv.c')
-rw-r--r-- | libc/inet/resolv.c | 30 |
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); } |