Documentation ¶
Overview ¶
This is the local node discovery protocol. In principle we might be better served by something more standardized, such as mDNS / DNS-SD. In practice, this was much easier and quicker to get up and running.
The mode of operation is to periodically (currently once every 30 seconds) broadcast an Announcement packet to UDP port 21025. The packet has the following format:
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Magic Number (0x20121025) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Port Number | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Length of NodeID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / \ NodeID (variable length) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Length of IP | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / \ IP (variable length) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This is the XDR encoding of:
struct Announcement { unsigned int Magic; unsigned short Port; string NodeID<>; }
(Hence NodeID is padded to a multiple of 32 bits)
The sending node's address is not encoded in local announcement -- the Length of IP field is set to zero and the address is taken to be the source address of the announcement. In announcement packets sent by a discovery server in response to a query, the IP is present and the length is either 4 (IPv4) or 16 (IPv6).
Every time such a packet is received, a local table that maps NodeID to Address is updated. When the local node wants to connect to another node with the address specification 'dynamic', this table is consulted.
For external discovery, an identical packet is sent every 30 minutes to the external discovery server. The server keeps information for up to 60 minutes. To query the server, and UDP packet with the format below is sent.
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Magic Number (0x19760309) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Length of NodeID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / \ NodeID (variable length) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This is the XDR encoding of:
struct Announcement { unsigned int Magic; string NodeID<>; }
(Hence NodeID is padded to a multiple of 32 bits)
It is answered with an announcement packet for the queried node ID if the information is available. There is no answer for queries about unknown nodes. A reasonable timeout is recommended instead. (This, combined with server side rate limits for packets per source IP and queries per node ID, prevents the server from being used as an amplifier in a DDoS attack.)
Index ¶
Constants ¶
const ( AnnouncementPort = 21025 AnnouncementMagic = 0x20121025 QueryMagic = 0x19760309 )
Variables ¶
This section is empty.
Functions ¶
func EncodePacket ¶
Types ¶
type Discoverer ¶
type Discoverer struct { MyID string ListenPort int BroadcastIntv time.Duration ExtBroadcastIntv time.Duration // contains filtered or unexported fields }
func NewDiscoverer ¶
func NewDiscoverer(id string, port int, extServer string) (*Discoverer, error)