85 lines
2.0 KiB
Go
85 lines
2.0 KiB
Go
package peer
|
|
|
|
import (
|
|
"net/netip"
|
|
"time"
|
|
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
|
|
"vppn/peer/control"
|
|
"vppn/peer/wginterface"
|
|
)
|
|
|
|
type PeerState string
|
|
|
|
const (
|
|
StateRelayed = PeerState("RELAY")
|
|
StateProbing = PeerState("PROBE")
|
|
StateDirect = PeerState("DIRECT")
|
|
)
|
|
|
|
type Peer struct {
|
|
wgPeer wgtypes.Peer
|
|
VPNIP netip.Addr // VPN IP address.
|
|
Name string // Human-readable DNS label.
|
|
IsRelay bool // Peer is a relay.
|
|
IsPublic bool // Peer has a public IP.
|
|
EndpointV4 netip.AddrPort // Reported IPv4 endpoint.
|
|
EndpointV6 netip.AddrPort // Reported IPv6 endpoint.
|
|
EndpointLAN netip.AddrPort // Discovered via multicast.
|
|
EndpointWG netip.AddrPort // Current wireguard endpoint.
|
|
RTT time.Duration // Round-trip time.
|
|
ProbeStart time.Time // When we started probing.
|
|
State PeerState // Current routing state; updated on each devXxx call.
|
|
Role control.Role // Role in relation to the local application.
|
|
SignPubKey [32]byte // nacl/sign public key for verifying multicast beacons.
|
|
}
|
|
|
|
// PubKey is the wireguard public key.
|
|
func (p *Peer) PubKey() wgtypes.Key {
|
|
return p.wgPeer.PublicKey
|
|
}
|
|
|
|
func (p *Peer) WGEndpoint() netip.AddrPort {
|
|
ep := p.wgPeer.Endpoint
|
|
if ep == nil {
|
|
return netip.AddrPort{}
|
|
}
|
|
addr, ok := netip.AddrFromSlice(ep.IP)
|
|
if !ok {
|
|
return netip.AddrPort{}
|
|
}
|
|
return netip.AddrPortFrom(addr.Unmap(), uint16(ep.Port))
|
|
}
|
|
|
|
func (p *Peer) LastHandshakeTime() time.Time {
|
|
return p.wgPeer.LastHandshakeTime
|
|
}
|
|
|
|
func (p *Peer) Up() bool {
|
|
return time.Since(p.wgPeer.LastHandshakeTime) < wginterface.SessionTimeout
|
|
}
|
|
|
|
func (p *Peer) CanRelay() bool {
|
|
return p.IsRelay && p.Up()
|
|
}
|
|
|
|
func (p *Peer) PreferredEndpoint() netip.AddrPort {
|
|
if p.EndpointLAN.IsValid() {
|
|
return p.EndpointLAN
|
|
} else if p.EndpointV4.IsValid() {
|
|
return p.EndpointV4
|
|
} else {
|
|
return p.EndpointV6
|
|
}
|
|
}
|
|
|
|
func (p *Peer) UpdateEndpoints(v4, v6 netip.AddrPort) {
|
|
if v4.IsValid() {
|
|
p.EndpointV4 = v4
|
|
}
|
|
if v6.IsValid() {
|
|
p.EndpointV6 = v6
|
|
}
|
|
}
|