179 lines
3.8 KiB
Go
179 lines
3.8 KiB
Go
package peer
|
|
|
|
import (
|
|
"io"
|
|
"net"
|
|
"net/netip"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
version = 1
|
|
|
|
bufferSize = 8192 // Enough for data packets and encryption buffers.
|
|
|
|
if_mtu = 1200
|
|
if_queue_len = 2048
|
|
|
|
controlCipherOverhead = 16
|
|
dataCipherOverhead = 16
|
|
signOverhead = 64
|
|
|
|
pingInterval = 8 * time.Second
|
|
timeoutInterval = 30 * time.Second
|
|
broadcastInterval = 16 * time.Second
|
|
broadcastErrorTimeoutInterval = 8 * time.Second
|
|
)
|
|
|
|
var multicastAddr = net.UDPAddrFromAddrPort(netip.AddrPortFrom(
|
|
netip.AddrFrom4([4]byte{224, 0, 0, 157}),
|
|
4560))
|
|
|
|
<<<<<<< HEAD
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type Globals struct {
|
|
LocalConfig // Embed, immutable.
|
|
|
|
// The number of startups
|
|
StartupCount uint16
|
|
|
|
// Local public address (if available). Immutable.
|
|
LocalAddr netip.AddrPort
|
|
|
|
// True if local public address is valid. Immutable.
|
|
LocalAddrValid bool
|
|
|
|
// All remote peers by VPN IP.
|
|
RemotePeers [256]*atomic.Pointer[Remote]
|
|
|
|
// Discovered public addresses.
|
|
PubAddrs *pubAddrStore
|
|
|
|
// Attempts to ensure that we have a relay available.
|
|
RelayHandler *relayHandler
|
|
|
|
// Send UDP - Global function to write UDP packets.
|
|
SendUDP func(b []byte, addr netip.AddrPort) (n int, err error)
|
|
|
|
// Global TUN interface.
|
|
IFace io.ReadWriteCloser
|
|
|
|
// For trace ID.
|
|
NewTraceID func() uint64
|
|
}
|
|
|
|
func NewGlobals(
|
|
localConfig LocalConfig,
|
|
startupCount startupCount,
|
|
localAddr netip.AddrPort,
|
|
conn *net.UDPConn,
|
|
iface io.ReadWriteCloser,
|
|
) (g Globals) {
|
|
g.LocalConfig = localConfig
|
|
g.StartupCount = startupCount.Count
|
|
|
|
g.LocalAddr = localAddr
|
|
g.LocalAddrValid = localAddr.IsValid()
|
|
|
|
g.PubAddrs = newPubAddrStore(localAddr)
|
|
|
|
g.RelayHandler = newRelayHandler()
|
|
|
|
// Use a lock here avoids starvation, at least on my Linux machine.
|
|
sendLock := sync.Mutex{}
|
|
g.SendUDP = func(b []byte, addr netip.AddrPort) (int, error) {
|
|
sendLock.Lock()
|
|
n, err := conn.WriteToUDPAddrPort(b, addr)
|
|
sendLock.Unlock()
|
|
return n, err
|
|
}
|
|
|
|
g.IFace = iface
|
|
|
|
traceID := (uint64(g.StartupCount) << 48) + 1
|
|
g.NewTraceID = func() uint64 {
|
|
return atomic.AddUint64(&traceID, 1)
|
|
}
|
|
|
|
for i := range g.RemotePeers {
|
|
g.RemotePeers[i] = &atomic.Pointer[Remote]{}
|
|
}
|
|
|
|
for i := range g.RemotePeers {
|
|
g.RemotePeers[i].Store(newRemote(g, byte(i)))
|
|
}
|
|
|
|
return g
|
|
=======
|
|
type marshaller interface {
|
|
Marshal([]byte) []byte
|
|
>>>>>>> 69f2536 (WIP)
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type Globals struct {
|
|
LocalConfig // Embed, immutable.
|
|
|
|
// Local public address (if available). Immutable.
|
|
LocalAddr netip.AddrPort
|
|
|
|
// True if local public address is valid. Immutable.
|
|
LocalAddrValid bool
|
|
|
|
// All remote peers by VPN IP.
|
|
RemotePeers [256]*atomic.Pointer[Remote]
|
|
|
|
// Discovered public addresses.
|
|
PubAddrs *pubAddrStore
|
|
|
|
// Attempts to ensure that we have a relay available.
|
|
RelayHandler *relayHandler
|
|
|
|
// Send UDP - Global function to write UDP packets.
|
|
SendUDP func(b []byte, addr netip.AddrPort) (n int, err error)
|
|
|
|
// Global TUN interface.
|
|
IFace io.ReadWriteCloser
|
|
}
|
|
|
|
func NewGlobals(
|
|
localConfig LocalConfig,
|
|
localAddr netip.AddrPort,
|
|
conn *net.UDPConn,
|
|
iface io.ReadWriteCloser,
|
|
) (g Globals) {
|
|
g.LocalConfig = localConfig
|
|
|
|
g.LocalAddr = localAddr
|
|
g.LocalAddrValid = localAddr.IsValid()
|
|
|
|
g.PubAddrs = newPubAddrStore(localAddr)
|
|
|
|
g.RelayHandler = newRelayHandler()
|
|
|
|
// Use a lock here avoids starvation, at least on my Linux machine.
|
|
sendLock := sync.Mutex{}
|
|
g.SendUDP = func(b []byte, addr netip.AddrPort) (int, error) {
|
|
sendLock.Lock()
|
|
n, err := conn.WriteToUDPAddrPort(b, addr)
|
|
sendLock.Unlock()
|
|
return n, err
|
|
}
|
|
|
|
g.IFace = iface
|
|
|
|
for i := range g.RemotePeers {
|
|
g.RemotePeers[i] = &atomic.Pointer[Remote]{}
|
|
}
|
|
|
|
for i := range g.RemotePeers {
|
|
g.RemotePeers[i].Store(newRemote(g, byte(i)))
|
|
}
|
|
|
|
return g
|
|
}
|