diff --git a/conn/conn.go b/conn/conn.go index a1f57d2..8df5aaa 100644 --- a/conn/conn.go +++ b/conn/conn.go @@ -84,6 +84,20 @@ type Endpoint interface { SrcIP() netip.Addr } +// PeerAwareEndpoint is an optional Endpoint specialization for +// integrations that want to know about the outcome of cryptorouting +// identification. +// +// If they receive a packet from a source they had not pre-identified, +// to learn the identification WireGuard can derive from the session +// or handshake. +// +// If GetPeerEndpoint returns nil, WireGuard will be unable to respond +// to the peer until a new endpoint is written by a later packet. +type PeerAwareEndpoint interface { + GetPeerEndpoint(peerPublicKey [32]byte) Endpoint +} + var ( ErrBindAlreadyOpen = errors.New("bind is already open") ErrWrongEndpointType = errors.New("endpoint type does not correspond with bind type") diff --git a/device/noise-protocol.go b/device/noise-protocol.go index 9f2ba50..2d8f984 100644 --- a/device/noise-protocol.go +++ b/device/noise-protocol.go @@ -124,7 +124,7 @@ type Handshake struct { localEphemeral NoisePrivateKey // ephemeral secret key localIndex uint32 // used to clear hash-table remoteIndex uint32 // index for sending - remoteStatic NoisePublicKey // long term key + remoteStatic NoisePublicKey // long term key, never changes, can be accessed without mutex remoteEphemeral NoisePublicKey // ephemeral public key precomputedStaticStatic [NoisePublicKeySize]byte // precomputed shared secret lastTimestamp tai64n.Timestamp diff --git a/device/peer.go b/device/peer.go index 89b719b..876e5da 100644 --- a/device/peer.go +++ b/device/peer.go @@ -283,6 +283,9 @@ func (peer *Peer) SetEndpointFromPacket(endpoint conn.Endpoint) { return } peer.endpoint.clearSrcOnTx = false + if ep, ok := endpoint.(conn.PeerAwareEndpoint); ok { + endpoint = ep.GetPeerEndpoint(peer.handshake.remoteStatic) + } peer.endpoint.val = endpoint }