]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Use random (thread safe version).
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 26 Feb 2007 09:42:05 +0000 (09:42 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 26 Feb 2007 09:42:05 +0000 (09:42 +0000)
git-svn-id: file:///svn/unbound/trunk@145 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/worker.c
daemon/worker.h
doc/Changelog
services/outside_network.c
services/outside_network.h
testcode/fake_event.c

index 620c39118ca18f441f686a3e4e3f6027342506df..210af5dad6994e83d3930fed98345e9dc0f5840f 100644 (file)
@@ -42,6 +42,7 @@
 #include "config.h"
 #include "util/log.h"
 #include "util/net_help.h"
+#include "util/random.h"
 #include "daemon/worker.h"
 #include "util/netevent.h"
 #include "util/config_file.h"
@@ -103,7 +104,7 @@ worker_process_query(struct worker* worker)
                worker->query_reply.c->buffer));
        pending_udp_query(worker->back, worker->query_reply.c->buffer, 
                &worker->fwd_addr, worker->fwd_addrlen, UDP_QUERY_TIMEOUT,
-               worker_handle_reply, worker);
+               worker_handle_reply, worker, worker->rndstate);
 }
 
 /** check request sanity. Returns error code, 0 OK, or -1 discard. 
@@ -214,6 +215,7 @@ worker_init(struct config_file *cfg, struct listen_port* ports,
 {
        struct worker* worker = (struct worker*)calloc(1, 
                sizeof(struct worker));
+       unsigned int seed;
        if(!worker) 
                return NULL;
        worker->need_to_restart = 0;
@@ -249,12 +251,14 @@ worker_init(struct config_file *cfg, struct listen_port* ports,
                return NULL;
        }
        /* init random(), large table size. */
-       if(!(worker->rndstate = (char*)malloc(RND_STATE_SIZE))) {
+       if(!(worker->rndstate = (struct ub_randstate*)calloc(1,
+               sizeof(struct ub_randstate)))) {
                log_err("malloc rndtable failed.");
                worker_delete(worker);
                return NULL;
        }
-       if(!initstate(time(NULL)^getpid(), worker->rndstate, RND_STATE_SIZE)) {
+       seed = (unsigned int)time(NULL) ^ (unsigned int)getpid();
+       if(!ub_initstate(seed, worker->rndstate, RND_STATE_SIZE)) {
                log_err("could not init random numbers.");
                worker_delete(worker);
                return NULL;
index 7458e0a2a606a054d50ba75310a337a257c319a0..666cd3e08aff9ee01e3e5c7432fa5b07deb3bbec 100644 (file)
@@ -51,6 +51,7 @@ struct outside_network;
 struct config_file;
 struct daemon;
 struct listen_port;
+struct ub_randstate;
 
 /** size of table used for random numbers. large to be more secure. */
 #define RND_STATE_SIZE 256
@@ -86,7 +87,7 @@ struct worker {
        socklen_t fwd_addrlen;
 
        /** random() table for this worker. */
-       char* rndstate;
+       struct ub_randstate* rndstate;
        /** do we need to restart (instead of exit) ? */
        int need_to_restart;
 };
index d566e502672b638e66ad3ec76781e2d8ad146802..3456b983dba49627537d1c1a1a5e882522afe307 100644 (file)
@@ -1,3 +1,6 @@
+26 February 2007: Wouter
+       - ub_random code used to select ID and port.
+
 23 February 2007: Wouter
        - Can do reloads on sigHUP. Everything is stopped, and freed,
          except the listening ports. Then the config file is reread.
index 57063212a7f7a7195df92cd45bfe1c5fa373cb7c..132b7c88b4aeef97a9d8839bb0ebd9f4022d8b2e 100644 (file)
@@ -45,6 +45,7 @@
 #include "util/netevent.h"
 #include "util/log.h"
 #include "util/net_help.h"
+#include "util/random.h"
 
 #ifdef HAVE_SYS_TYPES_H
 #  include <sys/types.h>
@@ -391,7 +392,8 @@ pending_delete(struct outside_network* outnet, struct pending* p)
 static struct pending*
 new_pending(struct outside_network* outnet, ldns_buffer* packet, 
        struct sockaddr_storage* addr, socklen_t addrlen,
-       comm_point_callback_t* callback, void* callback_arg)
+       comm_point_callback_t* callback, void* callback_arg, 
+       struct ub_randstate* rnd)
 {
        /* alloc */
        int id_tries = 0;
@@ -409,7 +411,7 @@ new_pending(struct outside_network* outnet, ldns_buffer* packet,
        }
        /* set */
        /* id uses lousy random() TODO use better and entropy */
-       pend->id = (random()>>8) & 0xffff;
+       pend->id = ((unsigned)ub_random(rnd)>>8) & 0xffff;
        LDNS_ID_SET(ldns_buffer_begin(packet), pend->id);
        memcpy(&pend->addr, addr, addrlen);
        pend->addrlen = addrlen;
@@ -421,7 +423,7 @@ new_pending(struct outside_network* outnet, ldns_buffer* packet,
        pend->node.key = pend;
        while(!rbtree_insert(outnet->pending, &pend->node)) {
                /* change ID to avoid collision */
-               pend->id = (random()>>8) & 0xffff;
+               pend->id = ((unsigned)ub_random(rnd)>>8) & 0xffff;
                LDNS_ID_SET(ldns_buffer_begin(packet), pend->id);
                id_tries++;
                if(id_tries == MAX_ID_RETRY) {
@@ -453,9 +455,11 @@ addr_is_ip6(struct sockaddr_storage* addr)
  * Select outgoing comm point for a query. Fills in c. 
  * @param outnet: network structure that has arrays of ports to choose from.
  * @param pend: the message to send. c is filled in, randomly chosen.
+ * @param rnd: random state for generating ID and port.
  */
 static void 
-select_port(struct outside_network* outnet, struct pending* pend)
+select_port(struct outside_network* outnet, struct pending* pend,
+       struct ub_randstate* rnd)
 {
        double precho;
        int chosen, nummax;
@@ -473,8 +477,8 @@ select_port(struct outside_network* outnet, struct pending* pend)
        }
 
        /* choose a random outgoing port and interface */
-       /* uses lousy random() function. TODO: entropy source. */
-       precho = (double)random() * (double)nummax / 
+       /* TODO: entropy source. */
+       precho = (double)ub_random(rnd) * (double)nummax / 
                ((double)RAND_MAX + 1.0);
        chosen = (int)precho;
 
@@ -494,18 +498,19 @@ select_port(struct outside_network* outnet, struct pending* pend)
 void 
 pending_udp_query(struct outside_network* outnet, ldns_buffer* packet, 
        struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
-       comm_point_callback_t* cb, void* cb_arg)
+       comm_point_callback_t* cb, void* cb_arg, struct ub_randstate* rnd)
 {
        struct pending* pend;
        struct timeval tv;
 
        /* create pending struct and change ID to be unique */
-       if(!(pend=new_pending(outnet, packet, addr, addrlen, cb, cb_arg))) {
+       if(!(pend=new_pending(outnet, packet, addr, addrlen, cb, cb_arg, 
+               rnd))) {
                /* callback user for the error */
                (void)(*cb)(NULL, cb_arg, NETEVENT_CLOSED, NULL);
                return;
        }
-       select_port(outnet, pend);
+       select_port(outnet, pend, rnd);
 
        /* send it over the commlink */
        if(!comm_point_send_udp_msg(pend->c, packet, (struct sockaddr*)addr, 
index d1fe8da5d9f12a6a5e9e889abc6fa8de315b35e7..5aaecec581c1643d88340e9396f20b086b447fb9 100644 (file)
@@ -48,6 +48,7 @@
 #include "util/netevent.h"
 struct pending;
 struct pending_timeout;
+struct ub_randstate;
 
 /**
  * Send queries to outside servers and wait for answers from servers.
@@ -140,10 +141,12 @@ void outside_network_delete(struct outside_network* outnet);
  *    The routine does not return an error, instead it calls the callback,
  *    with an error code if an error happens.
  * @param callback_arg: user argument for callback function.
+ * @param rnd: random state for generating ID and port.
  */
 void pending_udp_query(struct outside_network* outnet, ldns_buffer* packet, 
        struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
-       comm_point_callback_t* callback, void* callback_arg);
+       comm_point_callback_t* callback, void* callback_arg,
+       struct ub_randstate* rnd);
 
 /**
  * Delete pending answer.
index cec9c7c46b5a9391149e022b14317087258cfd1a..c62d33430d17fe4532f315c7cb4e413e055c885f 100644 (file)
@@ -644,7 +644,8 @@ outside_network_delete(struct outside_network* outnet)
 void 
 pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
        struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
-       comm_point_callback_t* callback, void* callback_arg)
+       comm_point_callback_t* callback, void* callback_arg,
+       struct ub_randstate* ATTR_UNUSED(rnd))
 {
        struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
        struct fake_pending* pend = (struct fake_pending*)calloc(1,