This commit is contained in:
2026-02-19 10:07:43 +00:00
parent 007438e372
commit 6e637ecf77
1763 changed files with 60820 additions and 279516 deletions

View File

@@ -341,7 +341,7 @@ func (e ErrUDPGSODisabled) Unwrap() error {
return e.RetryErr
}
func (s *StdNetBind) Send(bufs [][]byte, endpoint Endpoint) error {
func (s *StdNetBind) Send(bufs [][]byte, endpoint Endpoint, offset int) error {
s.mu.Lock()
blackhole := s.blackhole4
conn := s.ipv4
@@ -384,7 +384,7 @@ func (s *StdNetBind) Send(bufs [][]byte, endpoint Endpoint) error {
)
retry:
if offload {
n := coalesceMessages(ua, endpoint.(*StdNetEndpoint), bufs, *msgs, setGSOSize)
n := coalesceMessages(ua, endpoint.(*StdNetEndpoint), bufs, offset, *msgs, setGSOSize)
err = s.send(conn, br, (*msgs)[:n])
if err != nil && offload && errShouldDisableUDPGSO(err) {
offload = false
@@ -401,7 +401,7 @@ retry:
} else {
for i := range bufs {
(*msgs)[i].Addr = ua
(*msgs)[i].Buffers[0] = bufs[i]
(*msgs)[i].Buffers[0] = bufs[i][offset:]
setSrcControl(&(*msgs)[i].OOB, endpoint.(*StdNetEndpoint))
}
err = s.send(conn, br, (*msgs)[:len(bufs)])
@@ -450,7 +450,7 @@ const (
type setGSOFunc func(control *[]byte, gsoSize uint16)
func coalesceMessages(addr *net.UDPAddr, ep *StdNetEndpoint, bufs [][]byte, msgs []ipv6.Message, setGSO setGSOFunc) int {
func coalesceMessages(addr *net.UDPAddr, ep *StdNetEndpoint, bufs [][]byte, offset int, msgs []ipv6.Message, setGSO setGSOFunc) int {
var (
base = -1 // index of msg we are currently coalescing into
gsoSize int // segmentation size of msgs[base]
@@ -462,6 +462,7 @@ func coalesceMessages(addr *net.UDPAddr, ep *StdNetEndpoint, bufs [][]byte, msgs
maxPayloadLen = maxIPv6PayloadLen
}
for i, buf := range bufs {
buf = buf[offset:]
if i > 0 {
msgLen := len(buf)
baseLenBefore := len(msgs[base].Buffers[0])

View File

@@ -486,7 +486,7 @@ func (bind *afWinRingBind) Send(buf []byte, nend *WinRingEndpoint, isOpen *atomi
return winrio.SendEx(bind.rq, dataBuffer, 1, nil, addressBuffer, nil, nil, 0, 0)
}
func (bind *WinRingBind) Send(bufs [][]byte, endpoint Endpoint) error {
func (bind *WinRingBind) Send(bufs [][]byte, endpoint Endpoint, offset int) error {
nend, ok := endpoint.(*WinRingEndpoint)
if !ok {
return ErrWrongEndpointType
@@ -494,6 +494,7 @@ func (bind *WinRingBind) Send(bufs [][]byte, endpoint Endpoint) error {
bind.mu.RLock()
defer bind.mu.RUnlock()
for _, buf := range bufs {
buf = buf[offset:]
switch nend.family {
case windows.AF_INET:
if bind.v4.blackhole {

View File

@@ -45,9 +45,11 @@ type Bind interface {
// This mark is passed to the kernel as the socket option SO_MARK.
SetMark(mark uint32) error
// Send writes one or more packets in bufs to address ep. The length of
// bufs must not exceed BatchSize().
Send(bufs [][]byte, ep Endpoint) error
// Send writes one or more packets in bufs to address ep. A nonzero offset
// can be used to instruct the Bind on where packet data begins in each
// element of the bufs slice. Space preceding offset is free to use for
// additional encapsulation. The length of bufs must not exceed BatchSize().
Send(bufs [][]byte, ep Endpoint, offset int) error
// ParseEndpoint creates a new endpoint from a string.
ParseEndpoint(s string) (Endpoint, error)
@@ -84,18 +86,38 @@ type Endpoint interface {
SrcIP() netip.Addr
}
// InitiationAwareEndpoint is an optional [Endpoint] specialization for
// integrations that want to know when a WireGuard handshake initiation
// message has been received, enabling just-in-time peer configuration before
// attempted decryption.
//
// It's most useful when used in combination with [PeerAwareEndpoint], enabling
// JIT peer configuration and post-decryption peer verification from a single
// implementer.
type InitiationAwareEndpoint interface {
// InitiationMessagePublicKey is called when a handshake initiation message
// has been received, and the sender's public key has been identified, but
// BEFORE an attempt has been made to verify it.
InitiationMessagePublicKey(peerPublicKey [32]byte)
}
// PeerAwareEndpoint is an optional Endpoint specialization for
// integrations that want to know about the outcome of cryptorouting
// integrations that want to know about the outcome of Cryptokey Routing
// 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.
// A [PeerAwareEndpoint] may be installed as the [conn.Endpoint] following
// successful decryption unless endpoint roaming has been disabled for
// the peer.
type PeerAwareEndpoint interface {
GetPeerEndpoint(peerPublicKey [32]byte) Endpoint
// FromPeer is called at least once per successfully Cryptokey Routing ID'd
// [ReceiveFunc] packets batch for a given node key. wireguard-go will
// always call it for the latest/tail packet in the batch, only ever
// suppressing calls for older packets.
FromPeer(peerPublicKey [32]byte)
}
var (