Documentation ¶
Index ¶
- Constants
- func FakeDrop(dropProb float64) (drop bool)
- func WriteTo(wb []byte, addr *net.UDPAddr, socket *icmp.PacketConn, debugLevel int, ...)
- type DebugLevelsT
- type ExpirersT
- type ICMPEchoReply
- type ICMPEngine
- func (ie *ICMPEngine) CheckExpirerIsRunning() (started bool)
- func (ie *ICMPEngine) CloseSockets()
- func (ie *ICMPEngine) ExpirerConfig(FakeSuccess bool)
- func (ie *ICMPEngine) HackSysctl() (success bool)
- func (ie *ICMPEngine) OpenDoneChannels(fakeSuccess bool)
- func (ie *ICMPEngine) OpenSockets()
- func (ie *ICMPEngine) Pinger(IP netaddr.IP, packets Sequence, interval time.Duration, sortRTTs bool, ...) (results PingerResults)
- func (ie *ICMPEngine) PingerConfig(IP netaddr.IP, packets Sequence, interval time.Duration, sortRTTs bool, ...) (results PingerResults)
- func (ie *ICMPEngine) PingerWithStatsChannel(IP netaddr.IP, packets Sequence, interval time.Duration, sortRTTs bool, ...)
- func (ie *ICMPEngine) Receiver(proto Protocol, index int, allDone <-chan struct{}, done <-chan struct{})
- func (ie *ICMPEngine) Run(wg *sync.WaitGroup)
- func (ie *ICMPEngine) Start()
- func (ie *ICMPEngine) StartReceiversSplay()
- func (ie *ICMPEngine) Stop(fakeSuccess bool)
- type PingExpired
- type PingSuccess
- type PingerResults
- type PingersT
- type Pings
- type Protocol
- type ReceiversT
- type Sequence
- type SocketsT
- type WorkerType
Constants ¶
const ( //"golang.org/x/net/internal/iana" ProtocolICMP = 1 // Internet Control Message ProtocolIPv6ICMP = 58 // ICMP for IPv6 Receivers4Cst = 2 Receivers6Cst = 2 OpenSocketsRetriesCst = 2 SplayReceiversCst = true IEdebugLevel = 111 )
const ( PingerFractionModulo = 10 PdebugLevel = 111 )
const ( //ReceiveBufferMax = 1500 // max packet receive size ReceiveBufferMax = 200 // max packet receive size RdebugLevel = 111 )
const (
EdebugLevel = 111
)
const IsRaceEnabled = false
Enabled reports if the race detector is enabled.
const (
SdebugLevel = 111
)
Variables ¶
This section is empty.
Functions ¶
func FakeDrop ¶
FakeDrop is a simple function to return true based on a probability Looking at this issue, I'm not sure if this is perfect, but should be ok https://github.com/golang/go/issues/12290
Types ¶
type DebugLevelsT ¶
func GetDebugLevels ¶
func GetDebugLevels(debuglevel int) (debugLevels DebugLevelsT)
GetDebugLevels is a little helper function to return DebugLevelsT filled in with the same debug level for each component
type ICMPEchoReply ¶
ICMPEchoReply represents Echo Reply messages per the IPv4/rfc792 and IPv6/rfc2463 ( see extended comments below )
func ParseICMPEchoReply ¶
func ParseICMPEchoReply(b []byte) (*ICMPEchoReply, error)
ParseICMPEchoReply parses the ICMP echo reply messages This was originally based on on the the golang standard icmp ParseMessage, which for unknown reasons don't parse ICMP echo https://pkg.go.dev/golang.org/x/net/icmp#ParseMessage https://github.com/golang/net/blob/7fd8e65b6420/icmp/message.go#L139
func ParseICMPEchoReplyBB ¶
func ParseICMPEchoReplyBB(b bytes.Buffer) (*ICMPEchoReply, error)
ParseICMPEchoReplyBB is the same as ParseICMPEchoReply, except uses bytes.Buffer, instead of []byte This is mostly to allow use of sync.Pool, which should be faster (maybe?) https://www.akshaydeo.com/blog/2017/12/23/How-did-I-improve-latency-by-700-percent-using-syncPool/
type ICMPEngine ¶
type ICMPEngine struct { Log hclog.Logger sync.RWMutex Timeout time.Duration ReadDeadline time.Duration Protocols []Protocol PID int EID int DoneCh chan struct{} Sockets SocketsT Receivers ReceiversT Expirers ExpirersT Pingers PingersT DebugLevel int }
ICMPEngine holds the object state Most of this data is for tracking ICMP echo requests sent, and their expiry times The double linked-list (DLL) allows tracking the next Expiry time, while allowing entries to be removed efficently when a ping is recieved. Leveraging https://golang.org/pkg/container/list/ Need to move to https://golang.org/pkg/container/heap/
func New ¶
func New(l hclog.Logger, done chan struct{}, to time.Duration, rd time.Duration, start bool) (icmpEngine *ICMPEngine)
New creates ICMPEngine with default Receivers Per Protocol
func NewFullConfig ¶
func NewFullConfig(logger hclog.Logger, done chan struct{}, timeout time.Duration, deadline time.Duration, start bool, receivers4 int, receivers6 int, SplayReceivers bool, debugLevels DebugLevelsT, fakeSuccess bool) (icmpEngine *ICMPEngine)
NewFullConfig creates ICMPEngine with the full set of configuration options Please note could icmpEngine.Start() It is recommended NOT to actually start until you really need ICMPengine listening for incoming packets e.g. You can defer opening the sockets, and starting the receivers until you actually need them
func (*ICMPEngine) CheckExpirerIsRunning ¶
func (ie *ICMPEngine) CheckExpirerIsRunning() (started bool)
CheckExpirerIsRunning checks Expirers is running, and starts it if required returns if Expirers was started CheckExpirerIsRunning assumes the LOCK is already held by Pinger
func (*ICMPEngine) CloseSockets ¶
func (ie *ICMPEngine) CloseSockets()
CloseSockets() closes the sockets with some assertion checks
func (*ICMPEngine) ExpirerConfig ¶
func (ie *ICMPEngine) ExpirerConfig(FakeSuccess bool)
Expirer tracks the ICMP echo timeouts The idea is to just have the single and nearest timer running at any single moment The "Config" implies that we can configure the FakeSuccess, which is used for testing
func (*ICMPEngine) HackSysctl ¶
func (ie *ICMPEngine) HackSysctl() (success bool)
HackSysctl does sysctl -w net.ipv4.ping_group_range=0 2147483647 This requires root
func (*ICMPEngine) OpenDoneChannels ¶
func (ie *ICMPEngine) OpenDoneChannels(fakeSuccess bool)
OpenDoneChannels opens the main done channel for each worker type
func (*ICMPEngine) OpenSockets ¶
func (ie *ICMPEngine) OpenSockets()
OpenSockets opens non-privleged ICMP sockets for sending echo requests/replies OpenSockets has retry logic, and can use HackSysctl to change the sysctl for the non-privleged ICMP sockets if ICMPEngine is running as root Hopefully ICMPEngine is not running as root, in which case, if it can't open the sockets, it will log fatal
func (*ICMPEngine) Pinger ¶
func (ie *ICMPEngine) Pinger(IP netaddr.IP, packets Sequence, interval time.Duration, sortRTTs bool, DoneCh chan struct{}) (results PingerResults)
Pinger calls PingerConfig with: - zero (0) probability of drop, - no fake success
func (*ICMPEngine) PingerConfig ¶
func (ie *ICMPEngine) PingerConfig(IP netaddr.IP, packets Sequence, interval time.Duration, sortRTTs bool, DoneCh chan struct{}, dropProb float64) (results PingerResults)
Welford's math stolen from https://pkg.go.dev/github.com/eclesh/welford Welford's one-pass algorithm for computing the mean and variance of a set of numbers. For more information see Knuth (TAOCP Vol 2, 3rd ed, pg 232)
func (*ICMPEngine) PingerWithStatsChannel ¶
func (ie *ICMPEngine) PingerWithStatsChannel(IP netaddr.IP, packets Sequence, interval time.Duration, sortRTTs bool, DoneCh chan struct{}, wg *sync.WaitGroup, pingerResultsCh chan<- PingerResults)
PingerWithStatsChannel is the Pinger which sends stats on the output channel, rather than returning the values
func (*ICMPEngine) Receiver ¶
func (ie *ICMPEngine) Receiver(proto Protocol, index int, allDone <-chan struct{}, done <-chan struct{})
Receiver receives ICMP messages, calculates the round-trip-time(RTT) and then send the response to the requesting Pinger Receiver is also responsible for tracking the timeouts, using the double-linked-list and map ie.ReadDeadline is used to not just block forever on the read call, so we can check the Done channel has been called When choosing the ReadDeadline, it's just changing how quickly the Receiver might detect the Done signal
Because ReadFrom syscall is blocking, a SetReadDeadline is used to allow ReadFrom to finish, this is mostly to allow checking for the done signal, and therefore allow closing down the Receivers gracefully. There is [Timeouts In A Row] code that increases these timeouts gradually, to decrease the ReadFrom thrashing
func (*ICMPEngine) Run ¶
func (ie *ICMPEngine) Run(wg *sync.WaitGroup)
func (*ICMPEngine) Start ¶
func (ie *ICMPEngine) Start()
Start OpenSockets and starts the Receivers, with default to splay the receiver start times This isn't done on New or NewRPP, to avoid opening the sockets and having the Receivers busy making recieve syscalls until ICMPEngine really needs to be running. e.g. ICMPEngine "object" can be created once, but not actually running much until Start() is called This is possibly an premature optimization.
func (*ICMPEngine) StartReceiversSplay ¶
func (ie *ICMPEngine) StartReceiversSplay()
StartReceiversSplay starts the receivers, with some sanity checking Splay the receiver start times, means this will essentailly offset the start time of the receivers, but this slows down the startup time
func (*ICMPEngine) Stop ¶
func (ie *ICMPEngine) Stop(fakeSuccess bool)
Stop gracefully stops the workers
type PingExpired ¶
PingExpired is passed from the Expirer to the Pingers This only happens when there is a timeout (obviously)
type PingSuccess ¶
PingSuccess is passed from the Receivers to the Pingers
type PingerResults ¶
type ReceiversT ¶
type WorkerType ¶
type WorkerType rune