mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
Use random (thread safe version).
git-svn-id: file:///svn/unbound/trunk@145 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
7ccdfe8f7c
commit
e679f51ed9
6 changed files with 32 additions and 15 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue