peerdiscovery

package module
v1.7.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 9, 2023 License: MIT Imports: 7 Imported by: 37

README

peerdiscovery

Code coverage Go Report Go Doc

Pure-go library for cross-platform thread-safe local peer discovery using UDP multicast. I needed to use peer discovery for croc and everything I tried had problems, so I made another one.

Install

Make sure you have Go 1.5+.

go get -u github.com/schollz/peerdiscovery

Usage

The following is a code to find the first peer on the local network and print it out.

discoveries, _ := peerdiscovery.Discover(peerdiscovery.Settings{Limit: 1})
for _, d := range discoveries {
    fmt.Printf("discovered '%s'\n", d.Address)
}

Here's the output when running on two computers. (Run these gifs in sync by hitting Ctl + F5).

Computer 1:

computer 1

Computer 2:

computer 1

For more examples, see the scanning examples (ipv4 and ipv6) or the docs.

Testing

To test the peer discovery with just one host, one can launch multiple containers. The provided Dockerfile will run the example code. Please make sure to enable Docker's IPv6 support if you are using IPv6 for peer discovery.

# Build the container, named peertest
$ docker build -t peertest .

# Execute the following command in multiple terminals
$ docker run -t --rm peertest
Scanning for 10 seconds to find LAN peers
 100% |████████████████████████████████████████|  [9s:0s]Found 1 other computers
0) '172.17.0.2' with payload 'zqrecHipCO'

Contributing

Pull requests are welcome. Feel free to...

  • Revise documentation
  • Add new features
  • Fix bugs
  • Suggest improvements

Thanks

Thanks @geistesk for adding IPv6 support and a Notify func, and helping maintain! Thanks @Kunde21 for providing a bug fix and massively refactoring the code in a much better way. Thanks @robpre for finding and fixing bugs. Thanks @shvydky for adding dynamic payloads.

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Discovered

type Discovered struct {
	// Address is the local address of a discovered peer.
	Address string
	// Payload is the associated payload from discovered peer.
	Payload []byte

	Metadata *Metadata
}

Discovered is the structure of the discovered peers, which holds their local address (port removed) and a payload if there is one.

func Discover added in v1.0.0

func Discover(settings ...Settings) (discoveries []Discovered, err error)

Discover will use the created settings to scan for LAN peers. It will return an array of the discovered peers and their associate payloads. It will not return broadcasts sent to itself.

func (Discovered) String added in v1.4.0

func (d Discovered) String() string

type IPVersion added in v1.3.0

type IPVersion uint

IPVersion specifies the version of the Internet Protocol to be used.

const (
	IPv4 IPVersion = 4
	IPv6 IPVersion = 6
)

type LostPeer added in v1.7.0

type LostPeer struct {
	Address     string
	LastSeen    time.Time
	LastPayload []byte
	Metadata    *Metadata
}

type Metadata added in v1.7.0

type Metadata struct {
	Data interface{}
}

Metadata is the metadata associated with a discovered peer. To update the metadata, assign your own metadata to the Metadata.Data field. The metadata is not protected by a mutex, so you must do this yourself. The metadata update happens by pointer, to keep the library backwards compatible.

type NetPacketConn added in v1.5.0

type NetPacketConn interface {
	JoinGroup(ifi *net.Interface, group net.Addr) error
	SetMulticastInterface(ini *net.Interface) error
	SetMulticastTTL(int) error
	ReadFrom(buf []byte) (int, net.Addr, error)
	WriteTo(buf []byte, dst net.Addr) (int, error)
}

type PacketConn4 added in v1.5.0

type PacketConn4 struct {
	*ipv4.PacketConn
}

func (PacketConn4) ReadFrom added in v1.5.0

func (pc4 PacketConn4) ReadFrom(buf []byte) (int, net.Addr, error)

ReadFrom wraps the ipv4 ReadFrom without a control message

func (PacketConn4) WriteTo added in v1.5.0

func (pc4 PacketConn4) WriteTo(buf []byte, dst net.Addr) (int, error)

WriteTo wraps the ipv4 WriteTo without a control message

type PacketConn6 added in v1.5.0

type PacketConn6 struct {
	*ipv6.PacketConn
}

func (PacketConn6) ReadFrom added in v1.5.0

func (pc6 PacketConn6) ReadFrom(buf []byte) (int, net.Addr, error)

ReadFrom wraps the ipv6 ReadFrom without a control message

func (PacketConn6) SetMulticastTTL added in v1.5.0

func (pc6 PacketConn6) SetMulticastTTL(i int) error

SetMulticastTTL wraps the hop limit of ipv6

func (PacketConn6) WriteTo added in v1.5.0

func (pc6 PacketConn6) WriteTo(buf []byte, dst net.Addr) (int, error)

WriteTo wraps the ipv6 WriteTo without a control message

type PeerDiscovery

type PeerDiscovery struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

PeerDiscovery is the object that can do the discovery for finding LAN peers.

func NewPeerDiscovery added in v1.7.0

func NewPeerDiscovery(settings ...Settings) (pd *PeerDiscovery, err error)

func (*PeerDiscovery) ActivePeers added in v1.7.0

func (p *PeerDiscovery) ActivePeers() (peers []*PeerState)

func (*PeerDiscovery) Shutdown added in v1.7.0

func (p *PeerDiscovery) Shutdown()

type PeerState added in v1.7.0

type PeerState struct {
	Address string
	// contains filtered or unexported fields
}

PeerState is the state of a peer that has been discovered. It contains the address of the peer, the last time it was seen, the last payload it sent, and the metadata associated with it. To update the metadata, assign your own metadata to the Metadata.Data field. The metadata is not protected by a mutex, so you must do this yourself.

type Settings

type Settings struct {
	// Limit is the number of peers to discover, use < 1 for unlimited.
	Limit int
	// Port is the port to broadcast on (the peers must also broadcast using the same port).
	// The default port is 9999.
	Port string
	// MulticastAddress specifies the multicast address.
	// You should be able to use any of 224.0.0.0/4 or ff00::/8.
	// By default it uses the Simple Service Discovery Protocol
	// address (239.255.255.250 for IPv4 or ff02::c for IPv6).
	MulticastAddress string
	// Payload is the bytes that are sent out with each broadcast. Must be short.
	Payload []byte
	// PayloadFunc is the function that will be called to dynamically generate payload
	// before every broadcast. If this pointer is nil `Payload` field will be broadcasted instead.
	PayloadFunc func() []byte
	// Delay is the amount of time between broadcasts. The default delay is 1 second.
	Delay time.Duration
	// TimeLimit is the amount of time to spend discovering, if the limit is not reached.
	// A negative limit indiciates scanning until the limit was reached or, if an
	// unlimited scanning was requested, no timeout.
	// The default time limit is 10 seconds.
	TimeLimit time.Duration
	// StopChan is a channel to stop the peer discvoery immediatley after reception.
	StopChan chan struct{}
	// AllowSelf will allow discovery the local machine (default false)
	AllowSelf bool
	// DisableBroadcast will not allow sending out a broadcast
	DisableBroadcast bool
	// IPVersion specifies the version of the Internet Protocol (default IPv4)
	IPVersion IPVersion
	// Notify will be called each time a new peer was discovered.
	// The default is nil, which means no notification whatsoever.
	Notify func(Discovered)

	// NotifyLost will be called each time a peer was lost.
	// The default is nil, which means no notification whatsoever.
	// This function should not take too long to execute, as it is called
	// from the peer garbage collector.
	NotifyLost func(LostPeer)
	// contains filtered or unexported fields
}

Settings are the settings that can be specified for doing peer discovery.

Directories

Path Synopsis
examples
ipv6 Module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL