Documentation
¶
Index ¶
- Constants
- Variables
- func GetKnownMinerPorts() []int
- func GetMsgPatternFromHint(hint MinerTypeHint) (*regexp.Regexp, bool)
- func ParseBPFNetwork(network string) string
- func ParseIPAddress(address string) string
- func ParseMACAddress(address string) string
- type AuradineIPReport
- type CaptureWriter
- type CapturedPacket
- type GoldshellIPReport
- type IPRBroadcast
- type IPRBroadcastMessage
- type IPRInterface
- type IPRListener
- type IPRLogger
- type IPReportPacket
- type ListenerManager
- type ListenerState
- type ListenerStatus
- type Logger
- type MDNSAdvertiser
- type ManagerState
- type ManagerStatus
- type MinerTypeHint
- type OfflineHandler
- type OfflinePacketResult
- type OfflineResult
- type PacketCounters
- type PacketProcessor
- type Record
- type RecordEntry
- type SealminerIPReport
- type StatusProvider
- type TCPCommand
- type TCPResponse
Constants ¶
const ( TCPCommandSubscribe = "iprd_subscribe" TCPCommandStatus = "iprd_status" )
const (
// MDNSServiceType is the DNS-SD service type advertised by iprd.
MDNSServiceType = "_iprd._tcp"
)
Variables ¶
var ( // ErrDuplicatePacket indicates that the processor recently handled an IP // report from the same source MAC address. ErrDuplicatePacket = errors.New("duplicate packet") )
var ( // ErrListenerManagerAlreadyStarted is returned when the listener manager is started more than once. ErrListenerManagerAlreadyStarted = errors.New("listener manager may only be run once") )
Functions ¶
func GetKnownMinerPorts ¶ added in v0.5.3
func GetKnownMinerPorts() []int
GetKnownMinerPorts returns a list of known miner UDP destination ports.
func GetMsgPatternFromHint ¶ added in v0.5.0
func GetMsgPatternFromHint(hint MinerTypeHint) (*regexp.Regexp, bool)
GetMsgPatternFromHint returns the UDP payload regex pattern for the given MinerTypeHint, if known.
func ParseBPFNetwork ¶ added in v0.4.4
ParseBPFNetwork returns the parsed BPF network, or an empty string if invalid. network is a BPF IPv4 network number that can be written as a dotted quad (192.168.1.0), dotted triple (192.168.1), dotted pair (192.168) or single number (10).
func ParseIPAddress ¶ added in v0.5.3
ParseIPAddress parses address and returns a normalized IP address.
func ParseMACAddress ¶ added in v0.3.1
ParseMACAddress parses address and returns a normalized MAC address.
Types ¶
type AuradineIPReport ¶ added in v0.5.0
type AuradineIPReport struct {
Command string `json:"command"`
SerialNo string `json:"SerialNo"`
IPAddress string `json:"ip"`
MACAddress string `json:"mac"`
Model string `json:"model"`
Version string `json:"version"`
Hostname string `json:"hostname"`
InternalType string `json:"InternalType"`
}
AuradineIPReport represents the IP report JSON payload from Auradine miners.
type CaptureWriter ¶ added in v0.5.0
type CaptureWriter struct {
// contains filtered or unexported fields
}
CaptureWriter writes interface-tagged packets to a bounded PCAP-NG capture. It is owned by ListenerManager and must be called serially.
func NewCaptureWriter ¶ added in v0.5.0
func NewCaptureWriter(path string, rotate bool, logger Logger) *CaptureWriter
NewCaptureWriter returns a PCAP-NG writer. An empty path disables capture.
func (*CaptureWriter) Close ¶ added in v0.5.0
func (w *CaptureWriter) Close() error
Close flushes and closes the active capture file.
func (*CaptureWriter) Open ¶ added in v0.5.0
func (w *CaptureWriter) Open() error
Open validates and creates the configured capture path. The PCAP-NG section is initialized lazily when the first packet supplies interface metadata.
func (*CaptureWriter) Path ¶ added in v0.5.0
func (w *CaptureWriter) Path() string
Path returns the normalized capture path, or an empty string when disabled.
func (*CaptureWriter) Write ¶ added in v0.5.0
func (w *CaptureWriter) Write(packet CapturedPacket) error
Write writes and flushes a captured packet, then applies the configured size limit. Flushing keeps byte accounting accurate and capture data durable.
type CapturedPacket ¶ added in v0.5.0
type CapturedPacket struct {
Data []byte
CaptureInfo gopacket.CaptureInfo
LinkType layers.LinkType
Interface IPRInterface
}
CapturedPacket is a raw packet and the interface metadata associated with its capture. The listener emits these events without parsing their contents.
type GoldshellIPReport ¶ added in v0.5.0
type GoldshellIPReport struct {
Version string `json:"version"`
IPAddress string `json:"ip"`
DHCP string `json:"dhcp"`
Model string `json:"model"`
CtrlBoardSN string `json:"ctrlsn"`
MACAddress string `json:"mac"`
Netmask string `json:"mask"`
Gateway string `json:"gateway"`
BoardSNs json.RawMessage `json:"cpbsn"`
DNS json.RawMessage `json:"dns"`
Serial string `json:"boxsn"`
Time string `json:"time"`
LEDStatus bool `json:"ledstatus"`
}
GoldshellIPReport represents the IP report JSON payload from Goldshell miners.
type IPRBroadcast ¶
type IPRBroadcast struct {
Msgs chan []byte
Errs chan error
// contains filtered or unexported fields
}
func NewBroadcaster ¶
func NewBroadcaster(logger Logger, bind string, port int) (*IPRBroadcast, error)
NewBroadcaster returns a new IPRBroadcast at specified port. bind is the local IP address to listen on; an empty bind binds all interfaces.
func (*IPRBroadcast) Listen ¶
func (b *IPRBroadcast) Listen()
Listen accepts incoming clients and subscribes them for broadcasted messages.
func (*IPRBroadcast) SetStatusProvider ¶ added in v0.5.2
func (b *IPRBroadcast) SetStatusProvider(provider StatusProvider)
SetStatusProvider configures the provider used by the iprd_status command.
type IPRBroadcastMessage ¶
type IPRBroadcastMessage struct {
Timestamp int64 `json:"timestamp"`
PacketID string `json:"packetID"`
DstPort int `json:"dstPort"`
SrcIP string `json:"srcIP"`
SrcMAC string `json:"srcMAC"`
MinerHint MinerTypeHint `json:"minerHint"`
}
IPRBroadcastMessage describes the JSON message structure of a IPReportPacket.
func NewIPRBroadcastMessage ¶ added in v0.5.0
func NewIPRBroadcastMessage(report *IPReportPacket) (IPRBroadcastMessage, error)
NewIPRBroadcastMessage creates a new IPRBroadcastMessage from an IPReportPacket.
func (IPRBroadcastMessage) Marshal ¶ added in v0.5.0
func (m IPRBroadcastMessage) Marshal() ([]byte, error)
Marshal serializes the broadcast message without changing its packet ID.
type IPRInterface ¶
type IPRInterface struct {
Index int
Name string
FriendlyName string
Description string
IPv4 net.IP
HardwareAddr net.HardwareAddr
Flags net.Flags
}
IPRInterface describes a network interface supported for IP Report listening.
func FindLANInterface ¶
func FindLANInterface() (*IPRInterface, error)
FindLANInterface returns the first IPRInterface marked as LAN, if any.
func GetInterfaceByIndex ¶ added in v0.2.1
func GetInterfaceByIndex(index int) (*IPRInterface, error)
GetInterfaceByIndex returns the IPRInterface matching index.
func GetInterfaceByName ¶
func GetInterfaceByName(name string) (*IPRInterface, error)
GetInterfaceByName returns the IPRInterface matching name.
func GetInterfaces ¶ added in v0.2.1
func GetInterfaces() ([]IPRInterface, error)
GetInterfaces returns all available IPRInterfaces that can be listened on. Returns error if no valid interfaces found.
func (*IPRInterface) IsLAN ¶
func (i *IPRInterface) IsLAN() bool
IsLAN returns bool for if IPRInterface is marked as LAN interface.
func (*IPRInterface) IsUp ¶
func (i *IPRInterface) IsUp() bool
IsUp returns bool for if IPRInterface is marked as UP.
func (*IPRInterface) MACAddr ¶
func (i *IPRInterface) MACAddr() string
MACAddr returns HardwareAddr as string.
func (*IPRInterface) NetworkPrefix ¶
func (i *IPRInterface) NetworkPrefix() string
NetworkPrefix returns the network prefix(leading two octets) of IPv4.
func (IPRInterface) String ¶ added in v0.2.1
func (i IPRInterface) String() string
String returns IPRInterface as string.
type IPRListener ¶
type IPRListener struct {
// contains filtered or unexported fields
}
func NewListener ¶
func NewListener(cfg *iprdconfig.ListenerConfig, logger Logger, iface *IPRInterface) *IPRListener
NewListener returns a new IPRListener configured by ListenerConfig. If logger is nil, a new IPRLogger is created. If iface is supplied it is pinned and reused; otherwise the interface is resolved from cfg (and re-resolved on each reconnect).
func (*IPRListener) Activate ¶
func (l *IPRListener) Activate() error
Activate sets a new active pcap handle on iface. This must be called once before Listen().
func (*IPRListener) Listen ¶
func (l *IPRListener) Listen()
Listen starts reading packets from the active handle and sends raw capture events to Packets(). It blocks until the handle errors. For a resilient, self-reconnecting listener use Run().
func (*IPRListener) Packets ¶ added in v0.5.0
func (l *IPRListener) Packets() <-chan CapturedPacket
Packets returns the listener's stream of raw captured packets.
func (*IPRListener) Run ¶ added in v0.4.6
func (l *IPRListener) Run(ctx context.Context) error
Run supervises capture on the interface: it activates a handle, captures until the handle errors (e.g. the interface goes down/away) or ctx is cancelled, and on error re-resolves the interface and re-activates with exponential backoff. It returns when ctx is cancelled. The packet channel and any downstream consumers stay intact across reconnects. Run is the resilient alternative to Activate()+Listen().
type IPReportPacket ¶
type IPReportPacket struct {
Timestamp time.Time
Length int
CaptureLength int
InterfaceIndex int
InterfaceName string
SrcIP string
DstIP string
SrcMAC string
DstMAC string
SrcPort int
DstPort int
Datagram []byte
Payload string
MinerHint MinerTypeHint
}
IPReportPacket represents a IP Report packet.
func NewIPReportPacket ¶
func NewIPReportPacket(packet gopacket.Packet) (*IPReportPacket, error)
NewIPReportPacket initializes packet into IPReportPacket. Returns an error on failure.
func (*IPReportPacket) Marshal ¶
func (r *IPReportPacket) Marshal() ([]byte, error)
Marshal creates and serializes an IPRBroadcastMessage. Deprecated: call NewIPRBroadcastMessage and marshal the returned message when the generated packet ID must remain stable across multiple serializations.
func (IPReportPacket) String ¶
func (r IPReportPacket) String() string
String returns relevent IPReportPacket info as a string.
type ListenerManager ¶ added in v0.5.0
type ListenerManager struct {
// contains filtered or unexported fields
}
ListenerManager coordinates interface listeners, capture writing, packet processing, and a single combined IP report stream.
func NewListenerManager ¶ added in v0.5.0
func NewListenerManager(cfg *iprdconfig.ListenerConfig, logger Logger) (*ListenerManager, error)
NewListenerManager returns a manager with one listener per configured interface. Auto mode creates one listener and ignores explicit selectors.
func (*ListenerManager) Reports ¶ added in v0.5.0
func (m *ListenerManager) Reports() <-chan *IPReportPacket
Reports returns the manager's combined stream of validated IP reports. The stream is buffered; if the consumer falls behind and the buffer fills, packet processing applies backpressure until reports are consumed.
func (*ListenerManager) Run ¶ added in v0.5.0
func (m *ListenerManager) Run(ctx context.Context) error
Run processes captured packets while supervising every listener. Each listener reconnects independently; an unexpected listener termination stops the manager. Run returns when ctx is cancelled or a fatal error occurs. A manager may only be run once; Reports is closed before the first call returns.
func (*ListenerManager) Status ¶ added in v0.5.2
func (m *ListenerManager) Status() ManagerStatus
Status returns a concurrency-safe snapshot of manager health and cumulative packet and listener diagnostics. Calling Status does not reset any counters.
type ListenerState ¶ added in v0.5.2
type ListenerState string
ListenerState describes the current lifecycle state of an interface listener.
const ( ListenerStateIdle ListenerState = "idle" ListenerStateStarting ListenerState = "starting" ListenerStateActive ListenerState = "active" ListenerStateReconnecting ListenerState = "reconnecting" ListenerStateStopped ListenerState = "stopped" )
type ListenerStatus ¶ added in v0.5.2
type ListenerStatus struct {
Interface string `json:"interface"`
State ListenerState `json:"state"`
ActivationFailures uint64 `json:"activationFailures"`
CaptureErrors uint64 `json:"captureErrors"`
Reconnects uint64 `json:"reconnects"`
LastError string `json:"lastError,omitempty"`
LastErrorAt time.Time `json:"lastErrorAt,omitempty"`
}
ListenerStatus is a concurrency-safe snapshot of one interface listener.
type MDNSAdvertiser ¶ added in v0.4.7
type MDNSAdvertiser struct {
// contains filtered or unexported fields
}
MDNSAdvertiser publishes the iprd TCP endpoint over mDNS/DNS-SD.
func NewMDNSAdvertiser ¶ added in v0.4.7
func NewMDNSAdvertiser(bind string, port int, version string) (*MDNSAdvertiser, error)
NewMDNSAdvertiser advertises the iprd TCP endpoint. A wildcard bind is published on all operational multicast-capable interfaces; an explicit bind is limited to the local interface that owns that address.
func (*MDNSAdvertiser) Close ¶ added in v0.4.7
func (a *MDNSAdvertiser) Close() error
Close gracefully withdraws the DNS-SD record. It is safe to call more than once.
type ManagerState ¶ added in v0.5.2
type ManagerState string
ManagerState describes the current ListenerManager lifecycle state.
const ( ManagerStateIdle ManagerState = "idle" ManagerStateStarting ManagerState = "starting" ManagerStateHealthy ManagerState = "healthy" ManagerStateDegraded ManagerState = "degraded" ManagerStateFailed ManagerState = "failed" ManagerStateStopped ManagerState = "stopped" )
type ManagerStatus ¶ added in v0.5.2
type ManagerStatus struct {
State ManagerState `json:"state"`
ListenersConfigured int `json:"listenersConfigured"`
ListenersActive int `json:"listenersActive"`
ActivationFailures uint64 `json:"activationFailures"`
CaptureErrors uint64 `json:"captureErrors"`
Reconnects uint64 `json:"reconnects"`
CaptureWriteErrors uint64 `json:"captureWriteErrors"`
Packets PacketCounters `json:"packets"`
Listeners []ListenerStatus `json:"listeners"`
LastPacketAt time.Time `json:"lastPacketAt,omitempty"`
LastReportAt time.Time `json:"lastReportAt,omitempty"`
LastError string `json:"lastError,omitempty"`
LastErrorAt time.Time `json:"lastErrorAt,omitempty"`
}
ManagerStatus is a concurrency-safe snapshot of a ListenerManager. Degraded means at least one listener is unavailable while the manager is still retrying; it can therefore have zero active listeners. Failed means Run has terminated with an error.
type MinerTypeHint ¶
type MinerTypeHint string
const ( UnknownType MinerTypeHint = "unknown" Antminer MinerTypeHint = "antminer" Iceriver MinerTypeHint = "iceriver" Whatsminer MinerTypeHint = "whatsminer" Goldshell MinerTypeHint = "goldshell" Sealminer MinerTypeHint = "sealminer" Elphapex MinerTypeHint = "elphapex" Auradine MinerTypeHint = "auradine" IPollo MinerTypeHint = "ipollo" HiveGPU MinerTypeHint = "hivegpu" )
func GetMinerHintFromPort ¶ added in v0.5.0
func GetMinerHintFromPort(port int) (MinerTypeHint, bool)
GetMinerHintFromPort returns the MinerTypeHint for the given port, if known.
type OfflineHandler ¶ added in v0.5.1
type OfflineHandler func(OfflinePacketResult) error
OfflineHandler handles the result of processing one captured frame.
type OfflinePacketResult ¶ added in v0.5.1
type OfflinePacketResult struct {
Timestamp time.Time
Number int64
InterfaceName string
Packet gopacket.Packet
Report *IPReportPacket
Err error
}
OfflinePacketResult describes the outcome of processing one captured frame. Report is nil when the frame could not be decoded as an IP report packet.
type OfflineResult ¶ added in v0.5.1
OfflineResult summarizes the packets processed from an offline capture.
func ProcessCapture ¶ added in v0.5.1
func ProcessCapture(ctx context.Context, reader io.Reader, handler OfflineHandler) (OfflineResult, error)
ProcessCapture reads a classic PCAP or PCAP-NG stream and invokes handler for every captured frame. Packet decoding and duplicate detection use the same PacketProcessor behavior as live capture processing.
func (OfflineResult) String ¶ added in v0.5.1
func (r OfflineResult) String() string
String returns a string representation of an offline capture result.
type PacketCounters ¶ added in v0.5.2
type PacketCounters struct {
Processed uint64 `json:"processed"`
Reports uint64 `json:"reports"`
Invalid uint64 `json:"invalid"`
Duplicates uint64 `json:"duplicates"`
UnknownFiltered uint64 `json:"unknownFiltered"`
}
PacketCounters contains cumulative packet outcomes for the lifetime of a manager. Reports counts validated reports produced by manager packet processing.
type PacketProcessor ¶ added in v0.5.0
type PacketProcessor struct {
// contains filtered or unexported fields
}
PacketProcessor validates IP report packets and owns their duplicate record. A processor should be shared anywhere duplicate detection must be shared. Calls must be serialized because Record is not safe for concurrent use.
func NewPacketProcessor ¶ added in v0.5.0
func NewPacketProcessor(record *Record) *PacketProcessor
NewPacketProcessor returns a processor using record for duplicate detection. A default record is created when record is nil.
func (*PacketProcessor) IsDuplicate ¶ added in v0.5.1
func (p *PacketProcessor) IsDuplicate(packet *IPReportPacket) bool
IsDuplicate returns true if the packet is a duplicate based on the processor's record. A packet is considered a duplicate if it has the same source MAC as an existing record entry and is within the record's minimum age. After the record's minimum age (10 seconds), the packet is no longer considered a duplicate and can be reported again.
func (*PacketProcessor) ParseIPReportPacket ¶ added in v0.5.0
func (p *PacketProcessor) ParseIPReportPacket(packet *IPReportPacket) error
ParseIPReportPacket analyzes packet for a valid IP report packet. Returns an error if the packet is invalid or a duplicate.
func (*PacketProcessor) ToIPRPacket ¶ added in v0.5.1
func (p *PacketProcessor) ToIPRPacket(captured CapturedPacket) (*IPReportPacket, error)
ToIPRPacket decodes a captured packet into an IPReportPacket.
type Record ¶
type Record struct {
// contains filtered or unexported fields
}
Record is a fixed-size LRU cache of RecordEntry items. Serves as a cache for IP report entries to avoid processing duplicates.
func (*Record) Add ¶
func (r *Record) Add(key string, entry RecordEntry)
Add creates or updates an RecordEntry in Record. Once capacity is reached, entries are removed in FIFO order.
func (*Record) Clear ¶ added in v0.1.1
func (r *Record) Clear()
Clear removes all entries in Record and resets order.
func (*Record) Display ¶
func (r *Record) Display()
Display prints the current record entries and length of record to stdout. Useful for logging/debugging.
func (*Record) Get ¶
func (r *Record) Get(key string) (*RecordEntry, bool)
Get returns the RecordEntry for the given key, and a bool indicating if the key was found.
type RecordEntry ¶
type RecordEntry struct {
SrcIP string
SrcMAC string
MinerHint MinerTypeHint
CreatedAt int64
UpdatedAt int64
}
RecordEntry represents an IP report entry in Record
type SealminerIPReport ¶ added in v0.5.0
type SealminerIPReport struct {
Info sealminerInfo
Interfaces []sealminerInterface
}
SealminerIPReport represents the IP report JSON payload from Sealminer miners.
func (*SealminerIPReport) UnmarshalJSON ¶ added in v0.5.0
func (r *SealminerIPReport) UnmarshalJSON(data []byte) error
type StatusProvider ¶ added in v0.5.2
type StatusProvider interface {
Status() ManagerStatus
}
StatusProvider supplies the current listener manager status.
type TCPCommand ¶
type TCPCommand struct {
Command string `json:"command"`
RequestID string `json:"requestID,omitempty"`
}
TCPCommand describes a TCP command.
type TCPResponse ¶ added in v0.5.2
type TCPResponse struct {
Type string `json:"type"`
RequestID string `json:"requestID,omitempty"`
Timestamp int64 `json:"timestamp"`
Status *ManagerStatus `json:"status,omitempty"`
Error string `json:"error,omitempty"`
}
TCPResponse is the response envelope for one-shot TCP commands.