mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
Fixed random numbers for port, interface and server selection.
Removed very small bias. Also some lint fixes. git-svn-id: file:///svn/unbound/trunk@2049 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
cd57530efd
commit
75565262f7
9 changed files with 48 additions and 11 deletions
|
|
@ -292,7 +292,7 @@ int daemon_get_shufport(struct daemon* daemon, int* shufport)
|
|||
/* Knuth shuffle */
|
||||
n = avail;
|
||||
while(--n > 0) {
|
||||
k = ub_random(daemon->rand) % (n+1); /* 0<= k<= n */
|
||||
k = ub_random_max(daemon->rand, n+1); /* 0<= k<= n */
|
||||
temp = shufport[k];
|
||||
shufport[k] = shufport[n];
|
||||
shufport[n] = temp;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
18 March 2010: Wouter
|
||||
- Fixed random numbers for port, interface and server selection.
|
||||
Removed very small bias.
|
||||
|
||||
16 March 2010: Wouter
|
||||
- Fix interface-automatic for OpenBSD: msg.controllen was too small,
|
||||
also assertions on ancillary data buffer.
|
||||
|
|
|
|||
|
|
@ -350,9 +350,9 @@ iter_server_selection(struct iter_env* iter_env,
|
|||
|
||||
/* randomly select a target from the list */
|
||||
log_assert(num > 1);
|
||||
/* we do not need secure random numbers here, but
|
||||
* we do need it to be threadsafe, so we use this */
|
||||
sel = ub_random(env->rnd) % num;
|
||||
/* grab secure random number, to pick unexpected server.
|
||||
* also we need it to be threadsafe. */
|
||||
sel = ub_random_max(env->rnd, num);
|
||||
a = dp->result_list;
|
||||
prev = NULL;
|
||||
while(sel > 0 && a) {
|
||||
|
|
@ -418,7 +418,7 @@ iter_ns_probability(struct ub_randstate* rnd, int n, int m)
|
|||
return 1;
|
||||
/* we do not need secure random numbers here, but
|
||||
* we do need it to be threadsafe, so we use this */
|
||||
sel = ub_random(rnd) % m;
|
||||
sel = ub_random_max(rnd, m);
|
||||
return (sel < n);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@
|
|||
|
||||
#ifdef S_SPLINT_S
|
||||
typedef struct PyObject PyObject;
|
||||
typedef struct PyThreadState PyThreadState;
|
||||
typedef void* PyGILState_STATE;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -809,9 +809,9 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
|
|||
log_assert(outnet->unused_fds);
|
||||
tries = 0;
|
||||
while(1) {
|
||||
my_if = ub_random(outnet->rnd) % num_if;
|
||||
my_if = ub_random_max(outnet->rnd, num_if);
|
||||
pif = &ifs[my_if];
|
||||
my_port = ub_random(outnet->rnd) % pif->avail_total;
|
||||
my_port = ub_random_max(outnet->rnd, pif->avail_total);
|
||||
if(my_port < pif->inuse) {
|
||||
/* port already open */
|
||||
pend->pc = pif->out[my_port];
|
||||
|
|
|
|||
|
|
@ -447,10 +447,12 @@ static void
|
|||
rnd_test()
|
||||
{
|
||||
struct ub_randstate* r;
|
||||
int num = 100, i;
|
||||
long int a[100];
|
||||
int num = 1000, i;
|
||||
long int a[1000];
|
||||
unsigned int seed = (unsigned)time(NULL);
|
||||
unit_show_feature("ub_random");
|
||||
unit_assert( (r = ub_initstate((unsigned)time(NULL), NULL)) );
|
||||
printf("ub_random seed is %u\n", seed);
|
||||
unit_assert( (r = ub_initstate(seed, NULL)) );
|
||||
for(i=0; i<num; i++) {
|
||||
a[i] = ub_random(r);
|
||||
unit_assert(a[i] >= 0);
|
||||
|
|
@ -460,6 +462,14 @@ rnd_test()
|
|||
a[i] != a[i-3] || a[i] != a[i-4] ||
|
||||
a[i] != a[i-5] || a[i] != a[i-6]);
|
||||
}
|
||||
a[0] = ub_random_max(r, 1);
|
||||
unit_assert(a[0] >= 0 && a[0] < 1);
|
||||
a[0] = ub_random_max(r, 10000);
|
||||
unit_assert(a[0] >= 0 && a[0] < 10000);
|
||||
for(i=0; i<num; i++) {
|
||||
a[i] = ub_random_max(r, 10);
|
||||
unit_assert(a[i] >= 0 && a[i] < 10);
|
||||
}
|
||||
ub_randfree(r);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -177,6 +177,18 @@ ub_random(struct ub_randstate* s)
|
|||
return (long int)((r) % (((unsigned)MAX_VALUE + 1)));
|
||||
}
|
||||
|
||||
long int
|
||||
ub_random_max(struct ub_randstate* state, long int x)
|
||||
{
|
||||
/* make sure we fetch in a range that is divisible by x. ignore
|
||||
* values from d .. MAX_VALUE, instead draw a new number */
|
||||
long int d = MAX_VALUE - (MAX_VALUE % x); /* d is divisible by x */
|
||||
long int v = ub_random(state);
|
||||
while(d <= v)
|
||||
v = ub_random(state);
|
||||
return (v % x);
|
||||
}
|
||||
|
||||
void
|
||||
ub_randfree(struct ub_randstate* s)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -75,6 +75,15 @@ struct ub_randstate* ub_initstate(unsigned int seed,
|
|||
*/
|
||||
long int ub_random(struct ub_randstate* state);
|
||||
|
||||
/**
|
||||
* Generate random number between 0 and x-1. No modulo bias.
|
||||
* @param state: must have been initialised with ub_initstate.
|
||||
* @param x: an upper limit. not negative or zero. must be smaller than 2**31.
|
||||
* @return: random value between 0..x-1. Possibly more than one
|
||||
* random number is picked from the random stream to satisfy this.
|
||||
*/
|
||||
long int ub_random_max(struct ub_randstate* state, long int x);
|
||||
|
||||
/**
|
||||
* Delete the random state.
|
||||
* @param state: to delete.
|
||||
|
|
|
|||
|
|
@ -1685,7 +1685,7 @@ calc_next_probe(struct module_env* env, uint32_t wait)
|
|||
wait = 3600;
|
||||
rnd = wait/10;
|
||||
rest = wait-rnd;
|
||||
rnd = (uint32_t)ub_random(env->rnd) % rnd;
|
||||
rnd = (uint32_t)ub_random_max(env->rnd, (long int)rnd);
|
||||
return (time_t)(*env->now + rest + rnd);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue