The x/net/ipv4 and x/net/ipv6 packages do not implement the necessary
control message functionality on Microsoft Windows. This commit ignores
any control message errors that are returned by the SetControlMessage
function if the Go runtime is compiled for Windows. This fixes#105.
Signed-off-by: Charlie Jonas <charlie@charliejonas.co.uk>
EditorConfig (https://editorconfig.org) is a dotfile which stores
configuration that is supported by a wide variety of text editors and
IDEs both natively and with plugins. This allows us to enforce project
standards such as line endings and indentation style.
Signed-off-by: Charlie Jonas <charlie@charliejonas.co.uk>
Deadlock observed when starting multiple ping routines.
It happens when writting to `recv` channel (which is full) and no active
readers for this channel.
*Example to reproduce the issue* :
var waiter sync.WaitGroup
pingFunc := func() {
defer waiter.Done()
pinger, err := ping.NewPinger("8.8.8.8")
if err != nil {
return
}
pinger.SetPrivileged(true)
pinger.Count = 5
pinger.Interval = time.Second
pinger.Timeout = time.Second * 4
pinger.Run()
}
for i := 0; i < 1000; i++ {
waiter.Add(1)
go pingFunc()
}
waiter.Wait() // deadlock here! (reproducible almost every time)
Move the DNS resolver out of the NewPinger() function in order to allow
adjusting of IPv4 vs IPv6 DNS resolution before running. This also
allows the user to verify resolution.
* Create new `New()` method that returns a bare default struct.
* Create new `Resolve()` method.
* Call `Resolve()` from `SetAddr()`.
* Call `Resolve()` automatically from `Run()`.
* Remove unecessary private `run()` method.
Update ping command for simplifed return values of `NewPinger()`.
Signed-off-by: Ben Kochie <superq@gmail.com>
Commit d046b245 introduces a bug which causes ping to always fail.
The source of this bug is:
```
// Check if reply from same ID
body := m.Body.(*icmp.Echo)
if body.ID != p.id {
return nil
}
```
Which due to the selection of p.id requires that SetPrivileged is
set to true. In the case where Privileged (i.e p.network == udp)
it is left to the kernel to set the ICMP id.
https://lwn.net/Articles/443051/ Discusses the introduction of
non-setuid-less ping. The kernel implementation for this
interface dictates using the local port, which gets mapped into
the ping_table struct. There is no current implementation in the
go icmp library to address this problem directly.
To address this issue, I've added a `Tracker` field for `Pinger`
as well as `IcmpData` datastructure to allow for uniquely tracking
icmp requests. The id (as with the `id` field) is not unique,
but will statistically rare for duplicates.