Following the update to 3.2.16 yesterday, here are cherrypicked patches from upstream for time_t and random issues. OK?
Index: lookup3.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/lookup3.c,v retrieving revision 1.3 diff -u -p -r1.3 lookup3.c --- lookup3.c 3 Sep 2013 09:26:51 -0000 1.3 +++ lookup3.c 3 Sep 2013 20:37:13 -0000 @@ -824,7 +824,7 @@ void driver1() h = hashlittle(&buf[0],1,h); } time(&z); - if (z-a > 0) printf("time %d %.8x\n", z-a, h); + if (z-a > 0) printf("time %lld %.8x\n", (long long) z-a, h); } /* check that every input bit changes every output bit half the time */ Index: nsd.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/nsd.c,v retrieving revision 1.15 diff -u -p -r1.15 nsd.c --- nsd.c 3 Sep 2013 09:26:54 -0000 1.15 +++ nsd.c 3 Sep 2013 20:37:13 -0000 @@ -395,8 +395,8 @@ bind8_stats (struct nsd *nsd) time(&now); /* NSTATS */ - t = msg = buf + snprintf(buf, MAXSYSLOGMSGLEN, "NSTATS %lu %lu", - (unsigned long) now, (unsigned long) nsd->st.boot); + t = msg = buf + snprintf(buf, MAXSYSLOGMSGLEN, "NSTATS %lld %lu", + (long long) now, (unsigned long) nsd->st.boot); for (i = 0; i <= 255; i++) { /* How much space left? */ if ((len = buf + MAXSYSLOGMSGLEN - t) < 32) { @@ -421,12 +421,12 @@ bind8_stats (struct nsd *nsd) || nsd->st.rcode[RCODE_FORMAT] || nsd->st.nona || nsd->st.rcode[RCODE_NXDOMAIN] || nsd->st.opcode[OPCODE_UPDATE]) { - log_msg(LOG_INFO, "XSTATS %lu %lu" + log_msg(LOG_INFO, "XSTATS %lld %lu" " RR=%lu RNXD=%lu RFwdR=%lu RDupR=%lu RFail=%lu RFErr=%lu RErr=%lu RAXFR=%lu" " RLame=%lu ROpts=%lu SSysQ=%lu SAns=%lu SFwdQ=%lu SDupQ=%lu SErr=%lu RQ=%lu" " RIQ=%lu RFwdQ=%lu RDupQ=%lu RTCP=%lu SFwdR=%lu SFail=%lu SFErr=%lu SNaAns=%lu" " SNXD=%lu RUQ=%lu RURQ=%lu RUXFR=%lu RUUpd=%lu", - (unsigned long) now, (unsigned long) nsd->st.boot, + (long long) now, (unsigned long) nsd->st.boot, nsd->st.dropped, (unsigned long)0, (unsigned long)0, (unsigned long)0, (unsigned long)0, (unsigned long)0, (unsigned long)0, nsd->st.raxfr, (unsigned long)0, (unsigned long)0, (unsigned long)0, nsd->st.qudp + nsd->st.qudp6 - nsd->st.dropped, (unsigned long)0, Index: nsec3.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/nsec3.c,v retrieving revision 1.7 diff -u -p -r1.7 nsec3.c --- nsec3.c 18 Feb 2013 10:18:39 -0000 1.7 +++ nsec3.c 3 Sep 2013 20:37:13 -0000 @@ -649,8 +649,8 @@ prehash(struct namedb* db, int updated_o } end = time(NULL); if(count > 0) - VERBOSITY(1, (LOG_INFO, "nsec3-prepare took %d " - "seconds for %d zones.", (int)(end-start), count)); + VERBOSITY(1, (LOG_INFO, "nsec3-prepare took %lld " + "seconds for %d zones.", (long long)(end-start), count)); } Index: rrl.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/rrl.c,v retrieving revision 1.1.1.2 diff -u -p -r1.1.1.2 rrl.c --- rrl.c 3 Sep 2013 09:21:33 -0000 1.1.1.2 +++ rrl.c 3 Sep 2013 20:37:13 -0000 @@ -458,6 +458,7 @@ int rrl_process_query(query_type* query) { uint64_t source; uint32_t hash; + /* we can use circular arithmatic here, so int32 works after 2038 */ int32_t now = (int32_t)time(NULL); uint32_t lm = rrl_ratelimit; uint16_t flags; @@ -477,7 +478,11 @@ int rrl_process_query(query_type* query) query_state_type rrl_slip(query_type* query) { /* discard number of packets, randomly */ +#ifdef HAVE_ARC4RANDOM + if((rrl_slip_ratio > 0) && ((rrl_slip_ratio == 1) || ((arc4random() % rrl_slip_ratio) == 0))) { +#else if((rrl_slip_ratio > 0) && ((rrl_slip_ratio == 1) || ((random() % rrl_slip_ratio) == 0))) { +#endif /* set TC on the rest */ TC_SET(query->packet); ANCOUNT_SET(query->packet, 0); Index: server.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/server.c,v retrieving revision 1.9 diff -u -p -r1.9 server.c --- server.c 3 Sep 2013 09:26:56 -0000 1.9 +++ server.c 3 Sep 2013 20:37:13 -0000 @@ -579,7 +579,6 @@ server_prepare(struct nsd *nsd) #ifdef RATELIMIT /* set secret modifier for hashing (udb ptr buckets and rate limits) */ #ifdef HAVE_ARC4RANDOM - srandom(arc4random()); hash_set_raninit(arc4random()); #else uint32_t v = getpid() ^ time(NULL); Index: xfrd-disk.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/xfrd-disk.c,v retrieving revision 1.1.1.5 diff -u -p -r1.1.1.5 xfrd-disk.c --- xfrd-disk.c 3 Sep 2013 09:21:37 -0000 1.1.1.5 +++ xfrd-disk.c 3 Sep 2013 20:37:13 -0000 @@ -168,8 +168,8 @@ xfrd_read_state(struct xfrd_state* xfrd) !xfrd_read_check_str(in, "numzones:") || !xfrd_read_i32(in, &numzones)) { - log_msg(LOG_ERR, "xfrd: corrupt state file %s dated %d (now=%d)", - statefile, (int)filetime, (int)xfrd_time()); + log_msg(LOG_ERR, "xfrd: corrupt state file %s dated %d (now=%lld)", + statefile, (int)filetime, (long long)xfrd_time()); fclose(in); region_destroy(tempregion); return; @@ -211,8 +211,8 @@ xfrd_read_state(struct xfrd_state* xfrd) !xfrd_read_state_soa(in, "soa_notify_acquired:", "soa_notify:", &soa_notified_read, &soa_notified_acquired_read)) { - log_msg(LOG_ERR, "xfrd: corrupt state file %s dated %d (now=%d)", - statefile, (int)filetime, (int)xfrd_time()); + log_msg(LOG_ERR, "xfrd: corrupt state file %s dated %d (now=%lld)", + statefile, (int)filetime, (long long)xfrd_time()); fclose(in); region_destroy(tempregion); return; @@ -290,8 +290,8 @@ xfrd_read_state(struct xfrd_state* xfrd) } if(!xfrd_read_check_str(in, XFRD_FILE_MAGIC)) { - log_msg(LOG_ERR, "xfrd: corrupt state file %s dated %d (now=%d)", - statefile, (int)filetime, (int)xfrd_time()); + log_msg(LOG_ERR, "xfrd: corrupt state file %s dated %d (now=%lld)", + statefile, (int)filetime, (long long)xfrd_time()); region_destroy(tempregion); fclose(in); return; @@ -304,27 +304,27 @@ xfrd_read_state(struct xfrd_state* xfrd) /* prints neato days hours and minutes. */ static void -neato_timeout(FILE* out, const char* str, uint32_t secs) +neato_timeout(FILE* out, const char* str, time_t secs) { fprintf(out, "%s", str); if(secs <= 0) { - fprintf(out, " %ds", (int)secs); + fprintf(out, " %llds", (long long)secs); return; } if(secs >= 3600*24) { - fprintf(out, " %dd", (int)secs/(3600*24)); + fprintf(out, " %lldd", (long long)(secs/(3600*24))); secs = secs % (3600*24); } if(secs >= 3600) { - fprintf(out, " %dh", (int)secs/3600); + fprintf(out, " %lldh", (long long)(secs/3600)); secs = secs%3600; } if(secs >= 60) { - fprintf(out, " %dm", (int)secs/60); + fprintf(out, " %lldm", (long long)(secs/60)); secs = secs%60; } if(secs > 0) { - fprintf(out, " %ds", (int)secs); + fprintf(out, " %llds", (long long)secs); } } @@ -424,7 +424,7 @@ xfrd_write_state(struct xfrd_state* xfrd fprintf(out, "# Note: if you edit this file while nsd is running,\n"); fprintf(out, "# it will be overwritten on exit by nsd.\n"); fprintf(out, "\n"); - fprintf(out, "filetime: %d\t# %s\n", (int)now, ctime(&now)); + fprintf(out, "filetime: %lld\t# %s\n", (long long)now, ctime(&now)); fprintf(out, "# The number of zone entries in this file\n"); fprintf(out, "numzones: %d\n", (int)xfrd->zones->count); fprintf(out, "\n"); Index: xfrd.c =================================================================== RCS file: /cvs/src/usr.sbin/nsd/xfrd.c,v retrieving revision 1.1.1.9 diff -u -p -r1.1.1.9 xfrd.c --- xfrd.c 3 Sep 2013 09:21:33 -0000 1.1.1.9 +++ xfrd.c 3 Sep 2013 20:37:13 -0000 @@ -138,7 +138,9 @@ xfrd_init(int socket, struct nsd* nsd) xfrd->tcp_set = xfrd_tcp_set_create(xfrd->region); xfrd->tcp_set->tcp_timeout = nsd->tcp_timeout; +#ifndef HAVE_ARC4RANDOM srandom((unsigned long) getpid() * (unsigned long) time(NULL)); +#endif DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd pre-startup")); diff_snip_garbage(nsd->db, nsd->options); @@ -353,16 +355,21 @@ xfrd_set_timer_retry(xfrd_zone_t* zone) /* set timer for next retry or expire timeout if earlier. */ if(zone->soa_disk_acquired == 0) { /* if no information, use reasonable timeout */ +#ifdef HAVE_ARC4RANDOM + xfrd_set_timer(zone, xfrd_time() + zone->fresh_xfr_timeout + + arc4random()%zone->fresh_xfr_timeout); +#else xfrd_set_timer(zone, xfrd_time() + zone->fresh_xfr_timeout + random()%zone->fresh_xfr_timeout); +#endif /* exponential backoff - some master data in zones is paid-for but non-working, and will not get fixed. */ zone->fresh_xfr_timeout *= 2; if(zone->fresh_xfr_timeout > XFRD_TRANSFER_TIMEOUT_MAX) zone->fresh_xfr_timeout = XFRD_TRANSFER_TIMEOUT_MAX; } else if(zone->state == xfrd_zone_expired || - xfrd_time() + ntohl(zone->soa_disk.retry) < - zone->soa_disk_acquired + ntohl(zone->soa_disk.expire)) + xfrd_time() + (time_t)ntohl(zone->soa_disk.retry) < + zone->soa_disk_acquired + (time_t)ntohl(zone->soa_disk.expire)) { if(ntohl(zone->soa_disk.retry) < XFRD_LOWERBOUND_RETRY) xfrd_set_timer(zone, xfrd_time() + XFRD_LOWERBOUND_RETRY); @@ -435,13 +442,13 @@ xfrd_handle_zone(netio_type* ATTR_UNUSED if(zone->soa_disk_acquired) { if (zone->state != xfrd_zone_expired && - (uint32_t)xfrd_time() >= zone->soa_disk_acquired + ntohl(zone->soa_disk.expire)) { + xfrd_time() >= zone->soa_disk_acquired + (time_t)ntohl(zone->soa_disk.expire)) { /* zone expired */ log_msg(LOG_ERR, "xfrd: zone %s has expired", zone->apex_str); xfrd_set_zone_state(zone, xfrd_zone_expired); } else if(zone->state == xfrd_zone_ok && - (uint32_t)xfrd_time() >= zone->soa_disk_acquired + ntohl(zone->soa_disk.refresh)) { + xfrd_time() >= zone->soa_disk_acquired + (time_t)ntohl(zone->soa_disk.refresh)) { /* zone goes to refreshing state. */ DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s is refreshing", zone->apex_str)); xfrd_set_zone_state(zone, xfrd_zone_refreshing); @@ -645,7 +652,11 @@ xfrd_set_timer(xfrd_zone_t* zone, time_t if(t > xfrd_time() + 10) { time_t extra = t - xfrd_time(); time_t base = extra*9/10; +#ifdef HAVE_ARC4RANDOM + t = xfrd_time() + base + arc4random()%(extra-base); +#else t = xfrd_time() + base + random()%(extra-base); +#endif } zone->zone_handler.timeout = &zone->timeout; @@ -678,22 +689,22 @@ xfrd_handle_incoming_soa(xfrd_zone_t* zo (unsigned)ntohl(soa->serial)); zone->soa_nsd = zone->soa_disk; zone->soa_nsd_acquired = zone->soa_disk_acquired; - if((uint32_t)xfrd_time() - zone->soa_disk_acquired - < ntohl(zone->soa_disk.refresh)) + if(xfrd_time() - zone->soa_disk_acquired + < (time_t)ntohl(zone->soa_disk.refresh)) { /* zone ok, wait for refresh time */ xfrd_set_zone_state(zone, xfrd_zone_ok); zone->round_num = -1; xfrd_set_timer_refresh(zone); - } else if((uint32_t)xfrd_time() - zone->soa_disk_acquired - < ntohl(zone->soa_disk.expire)) + } else if(xfrd_time() - zone->soa_disk_acquired + < (time_t)ntohl(zone->soa_disk.expire)) { /* zone refreshing */ xfrd_set_zone_state(zone, xfrd_zone_refreshing); xfrd_set_refresh_now(zone); } - if((uint32_t)xfrd_time() - zone->soa_disk_acquired - >= ntohl(zone->soa_disk.expire)) { + if(xfrd_time() - zone->soa_disk_acquired + >= (time_t)ntohl(zone->soa_disk.expire)) { /* zone expired */ xfrd_set_zone_state(zone, xfrd_zone_expired); xfrd_set_refresh_now(zone); @@ -1450,11 +1461,11 @@ xfrd_handle_received_xfr_packet(xfrd_zon buffer_clear(packet); buffer_printf(packet, "xfrd: zone %s xfr " "rollback serial %u at " - "time %u from %s of %u " + "time %lld from %s of %u " "parts", zone->apex_str, (int)zone->msg_new_serial, - (int)xfrd_time(), + (long long)xfrd_time(), zone->master->ip_address_spec, zone->msg_seq_nr); @@ -1495,8 +1506,9 @@ xfrd_handle_received_xfr_packet(xfrd_zon /* done. we are completely sure of this */ buffer_clear(packet); buffer_printf(packet, "xfrd: zone %s received update to serial %u at " - "time %u from %s in %u parts", - zone->apex_str, (int)zone->msg_new_serial, (int)xfrd_time(), + "time %lld from %s in %u parts", + zone->apex_str, (int)zone->msg_new_serial, + (long long)xfrd_time(), zone->master->ip_address_spec, zone->msg_seq_nr); if(zone->master->key_options) { buffer_printf(packet, " TSIG verified with key %s", @@ -1548,7 +1560,7 @@ xfrd_set_reload_timeout() if(xfrd->nsd->options->xfrd_reload_timeout == -1) return; /* automatic reload disabled. */ if(xfrd->reload_timeout.tv_sec == 0 || - xfrd_time() >= xfrd->reload_timeout.tv_sec ) { + xfrd_time() >= (time_t)xfrd->reload_timeout.tv_sec ) { /* no reload wait period (or it passed), do it right away */ xfrd->need_to_send_reload = 1; xfrd->ipc_handler.event_types |= NETIO_EVENT_WRITE;