From 716eadcd8f8277ec85fe3b5c4314d3288ffc0924 Mon Sep 17 00:00:00 2001 From: Anton Skorokhod Date: Mon, 17 Aug 2015 19:56:48 +0200 Subject: [PATCH] Fix setting IPv6 source address --- fastping.go | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/fastping.go b/fastping.go index b2bb348..96950ca 100644 --- a/fastping.go +++ b/fastping.go @@ -131,6 +131,7 @@ type Pinger struct { addrs map[string]*net.IPAddr network string source string + source6 string hasIPv4 bool hasIPv6 bool ctx *context @@ -160,6 +161,7 @@ func NewPinger() *Pinger { addrs: make(map[string]*net.IPAddr), network: "ip", source: "", + source6: "", hasIPv4: false, hasIPv6: false, Size: TimeSliceLength, @@ -187,25 +189,36 @@ func (p *Pinger) Network(network string) (string, error) { return origNet, nil } -// Source sets source IP for sending ICMP packets and returns the previous -// setting. Empty value indicates to use system default one. +// Source sets ipv4/ipv6 source IP for sending ICMP packets and returns the previous +// setting. Empty value indicates to use system default one (for both ipv4 and ipv6). func (p *Pinger) Source(source string) (string, error) { + // using ipv4 previous value for new empty one origSource := p.source if "" == source { p.mu.Lock() - p.source = source + p.source = "" + p.source6 = "" p.mu.Unlock() return origSource, nil } addr := net.ParseIP(source) if addr == nil { - return origSource, errors.New(source + " is not a valid textual representation of an IP address") + return origSource, errors.New(source + " is not a valid textual representation of an IPv4/IPv6 address") } - p.mu.Lock() - p.source = source - p.mu.Unlock() + if isIPv4(addr) { + p.mu.Lock() + p.source = source + p.mu.Unlock() + } else if isIPv6(addr) { + origSource = p.source6 + p.mu.Lock() + p.source6 = source + p.mu.Unlock() + } else { + return origSource, errors.New(source + " is not a valid textual representation of an IPv4/IPv6 address") + } return origSource, nil } @@ -396,7 +409,7 @@ func (p *Pinger) run(once bool) { } if p.hasIPv6 { - if conn6 = p.listen(ipv6Proto[p.network], p.source); conn6 == nil { + if conn6 = p.listen(ipv6Proto[p.network], p.source6); conn6 == nil { return } defer conn6.Close()