On Wed, Oct 24, 2012 at 07:07:18PM +0200, Gert Doering wrote:
 
> Specifically, every DNS probe SmokePing sends carries the very same
> Query ID - which it shouldn't do from a DNS PoV, but even from staring
> at the code involved, this should not happen (I have traces from various
> versions of SmokePing and perl on FreeBSD and Linux that show this, so 
> I claim it's not my local installation that is borked).

I think I see the problem. The main SmokePing process forks the probe
subprocesses, which first call srand() in Smokeping::make_kid() to
initialize the random number generator.  The AnotherDNS probe then
starts one subprocess for each ping, but all of those inherit the state
of the RNG.

Does the attached (untested) patch fix it for you? 

% perl -le 'srand; fork; print "pid $$ => " . rand()'
pid 5039 => 0.712492274426953
pid 5040 => 0.712492274426953

% perl -le 'fork; srand; print "pid $$ => " . rand()'
pid 5250 => 0.967728406264545
pid 5251 => 0.62419137808411

Cheers,
-- 
Niko Tyni   nt...@debian.org
>From 9571093782e110a56007f91d96f5fcbfa3830ea0 Mon Sep 17 00:00:00 2001
From: Niko Tyni <nt...@debian.org>
Date: Wed, 24 Oct 2012 20:34:07 +0300
Subject: [PATCH] Reseed the random number generator for each pinger process

As spotted by Gert Doering, rand() gives the same results in each
pinger subprocess. This is because they all inherit the same RNG state
from their parent.

Fix this undesired behaviour by reseeding the RNG with the current time
and the process ID.

The argument of srand() shouldn't really matter much on modern Perls,
but we're not very concerned about the quality of the random numbers
either, and time()+$$ should make sure it's different for each process.
---
 lib/Smokeping/probes/basefork.pm |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/Smokeping/probes/basefork.pm b/lib/Smokeping/probes/basefork.pm
index 0de7b6d..147c572 100644
--- a/lib/Smokeping/probes/basefork.pm
+++ b/lib/Smokeping/probes/basefork.pm
@@ -201,6 +201,9 @@ sub ping {
 				# we detach from the parent's process group
 				setpgrp(0, $$);
 
+				# re-initialize the RNG for each subprocess
+				srand(time()+$$);
+
 				my @times = $self->pingone($t);
 				print join(" ", @times), "\n";
 				exit;
-- 
1.7.10.4

_______________________________________________
smokeping-users mailing list
smokeping-users@lists.oetiker.ch
https://lists.oetiker.ch/cgi-bin/listinfo/smokeping-users

Reply via email to