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 */
|
/* Knuth shuffle */
|
||||||
n = avail;
|
n = avail;
|
||||||
while(--n > 0) {
|
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];
|
temp = shufport[k];
|
||||||
shufport[k] = shufport[n];
|
shufport[k] = shufport[n];
|
||||||
shufport[n] = temp;
|
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
|
16 March 2010: Wouter
|
||||||
- Fix interface-automatic for OpenBSD: msg.controllen was too small,
|
- Fix interface-automatic for OpenBSD: msg.controllen was too small,
|
||||||
also assertions on ancillary data buffer.
|
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 */
|
/* randomly select a target from the list */
|
||||||
log_assert(num > 1);
|
log_assert(num > 1);
|
||||||
/* we do not need secure random numbers here, but
|
/* grab secure random number, to pick unexpected server.
|
||||||
* we do need it to be threadsafe, so we use this */
|
* also we need it to be threadsafe. */
|
||||||
sel = ub_random(env->rnd) % num;
|
sel = ub_random_max(env->rnd, num);
|
||||||
a = dp->result_list;
|
a = dp->result_list;
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
while(sel > 0 && a) {
|
while(sel > 0 && a) {
|
||||||
|
|
@ -418,7 +418,7 @@ iter_ns_probability(struct ub_randstate* rnd, int n, int m)
|
||||||
return 1;
|
return 1;
|
||||||
/* we do not need secure random numbers here, but
|
/* we do not need secure random numbers here, but
|
||||||
* we do need it to be threadsafe, so we use this */
|
* 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);
|
return (sel < n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,8 @@
|
||||||
|
|
||||||
#ifdef S_SPLINT_S
|
#ifdef S_SPLINT_S
|
||||||
typedef struct PyObject PyObject;
|
typedef struct PyObject PyObject;
|
||||||
|
typedef struct PyThreadState PyThreadState;
|
||||||
|
typedef void* PyGILState_STATE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -809,9 +809,9 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
|
||||||
log_assert(outnet->unused_fds);
|
log_assert(outnet->unused_fds);
|
||||||
tries = 0;
|
tries = 0;
|
||||||
while(1) {
|
while(1) {
|
||||||
my_if = ub_random(outnet->rnd) % num_if;
|
my_if = ub_random_max(outnet->rnd, num_if);
|
||||||
pif = &ifs[my_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) {
|
if(my_port < pif->inuse) {
|
||||||
/* port already open */
|
/* port already open */
|
||||||
pend->pc = pif->out[my_port];
|
pend->pc = pif->out[my_port];
|
||||||
|
|
|
||||||
|
|
@ -447,10 +447,12 @@ static void
|
||||||
rnd_test()
|
rnd_test()
|
||||||
{
|
{
|
||||||
struct ub_randstate* r;
|
struct ub_randstate* r;
|
||||||
int num = 100, i;
|
int num = 1000, i;
|
||||||
long int a[100];
|
long int a[1000];
|
||||||
|
unsigned int seed = (unsigned)time(NULL);
|
||||||
unit_show_feature("ub_random");
|
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++) {
|
for(i=0; i<num; i++) {
|
||||||
a[i] = ub_random(r);
|
a[i] = ub_random(r);
|
||||||
unit_assert(a[i] >= 0);
|
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-3] || a[i] != a[i-4] ||
|
||||||
a[i] != a[i-5] || a[i] != a[i-6]);
|
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);
|
ub_randfree(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,18 @@ ub_random(struct ub_randstate* s)
|
||||||
return (long int)((r) % (((unsigned)MAX_VALUE + 1)));
|
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
|
void
|
||||||
ub_randfree(struct ub_randstate* s)
|
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);
|
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.
|
* Delete the random state.
|
||||||
* @param state: to delete.
|
* @param state: to delete.
|
||||||
|
|
|
||||||
|
|
@ -1685,7 +1685,7 @@ calc_next_probe(struct module_env* env, uint32_t wait)
|
||||||
wait = 3600;
|
wait = 3600;
|
||||||
rnd = wait/10;
|
rnd = wait/10;
|
||||||
rest = wait-rnd;
|
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);
|
return (time_t)(*env->now + rest + rnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue