From: Benoît Knecht Date: Wed, 30 Jan 2019 10:57:57 +0000 (+0100) Subject: prober: icmp: Initialize ID and sequence to random values (#412) X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=6958e6f3245455cdd9618bef80185fd50c989ec1;p=blackbox_exporter.git prober: icmp: Initialize ID and sequence to random values (#412) This should help preventing issues with some network devices that have trouble NATing ICMP packets with the same ID and sequence nubmer but a different source IP address. Currently, this can happen if the blackbox_exporter runs in a container (the ID is set to the PID, which is typically 1 in a container), and serveral blackbox_exporters are restarted at the same time (the sequence numbers are reset to zero and stay in sync). This commit sets the ICMP echo ID to a random value if the PID is 1, and initializes the sequence number at a random offset. See #411 for details. Signed-off-by: Benoît Knecht --- diff --git a/prober/icmp.go b/prober/icmp.go index 330ae9d..0f1c819 100644 --- a/prober/icmp.go +++ b/prober/icmp.go @@ -16,6 +16,7 @@ package prober import ( "bytes" "context" + "math/rand" "net" "os" "sync" @@ -32,10 +33,27 @@ import ( ) var ( + icmpID int icmpSequence uint16 icmpSequenceMutex sync.Mutex ) +func init() { + // PID is typically 1 when running in a container; in that case, set + // the ICMP echo ID to a random value to avoid potential clashes with + // other blackbox_exporter instances. See #411. + if pid := os.Getpid(); pid == 1 { + icmpID = rand.Intn(1 << 16) + } else { + icmpID = pid & 0xffff + } + + // Start the ICMP echo sequence at a random offset to prevent them from + // being in sync when several blackbox_exporter instances are restarted + // at the same time. See #411. + icmpSequence = uint16(rand.Intn(1 << 16)) +} + func getICMPSequence() uint16 { icmpSequenceMutex.Lock() defer icmpSequenceMutex.Unlock() @@ -129,7 +147,7 @@ func ProbeICMP(ctx context.Context, target string, module config.Module, registr } body := &icmp.Echo{ - ID: os.Getpid() & 0xffff, + ID: icmpID, Seq: int(getICMPSequence()), Data: data, }