hotfix(pmtud/tcp): fix code for IPv6 destinations

This commit is contained in:
Quentin McGaw
2026-02-20 16:23:40 +00:00
parent 73b3e2c88a
commit c66d8bed00
8 changed files with 21 additions and 39 deletions
-5
View File
@@ -1,5 +0,0 @@
package ip
func SetIPv6HeaderIncluded(fd int) error {
panic("darwin does not allow an application to build IPv6 headers")
}
-7
View File
@@ -1,7 +0,0 @@
package ip
import "golang.org/x/sys/unix"
func SetIPv6HeaderIncluded(fd int) error {
return unix.SetsockoptInt(fd, unix.IPPROTO_IPV6, unix.IPV6_HDRINCL, 1)
}
-7
View File
@@ -1,7 +0,0 @@
//go:build !linux && !windows && !darwin
package ip
func SetIPv6HeaderIncluded(fd int) error {
panic("not implemented")
}
-7
View File
@@ -1,7 +0,0 @@
package ip
import "golang.org/x/sys/windows"
func SetIPv6HeaderIncluded(fd windows.Handle) error {
panic("windows does not allow an application to build IPv6 headers")
}
+1 -1
View File
@@ -29,7 +29,7 @@ func makeSockAddr(ip netip.Addr, port uint16) unix.Sockaddr {
} }
} }
return &unix.SockaddrInet6{ return &unix.SockaddrInet6{
Port: int(port), Port: 0,
Addr: ip.As16(), Addr: ip.As16(),
} }
} }
+14 -4
View File
@@ -65,13 +65,15 @@ func createPacket(src, dst netip.AddrPort,
if dst.Addr().Is4() { if dst.Addr().Is4() {
ipHeader = ip.HeaderV4(src.Addr(), dst.Addr(), payloadLength) ipHeader = ip.HeaderV4(src.Addr(), dst.Addr(), payloadLength)
} else { } else {
// Pseudo-header, this is actually not part of the packet since
// the kernel will calculate and add it itself to the packet;
// it is only used for calculating the TCP checksum.
ipHeader = ip.HeaderV6(src.Addr(), dst.Addr(), ipHeader = ip.HeaderV6(src.Addr(), dst.Addr(),
uint16(payloadLength), byte(constants.IPPROTO_TCP)) //nolint:gosec uint16(payloadLength), byte(constants.IPPROTO_TCP)) //nolint:gosec
} }
tcpHeader := makeTCPHeader(src.Port(), dst.Port(), seq, ack, flags) tcpHeader := makeTCPHeader(src.Port(), dst.Port(), seq, ack, flags)
// data is just zeroes
dataLength := int(payloadLength - constants.BaseTCPHeaderLength) dataLength := int(payloadLength - constants.BaseTCPHeaderLength)
var data []byte var data []byte
if dataLength > 0 { if dataLength > 0 {
@@ -81,10 +83,18 @@ func createPacket(src, dst netip.AddrPort,
tcpHeader[16] = byte(checksum >> 8) //nolint:mnd tcpHeader[16] = byte(checksum >> 8) //nolint:mnd
tcpHeader[17] = byte(checksum & 0xff) //nolint:mnd tcpHeader[17] = byte(checksum & 0xff) //nolint:mnd
packet := make([]byte, len(ipHeader)+int(constants.BaseTCPHeaderLength)+dataLength) var packet []byte
i := 0
if dst.Addr().Is4() {
packet = make([]byte, len(ipHeader)+int(constants.BaseTCPHeaderLength)+dataLength)
copy(packet, ipHeader) copy(packet, ipHeader)
copy(packet[len(ipHeader):], tcpHeader) i += len(ipHeader)
copy(packet[len(ipHeader)+int(constants.BaseTCPHeaderLength):], data) } else {
packet = make([]byte, int(constants.BaseTCPHeaderLength)+dataLength)
}
copy(packet[i:], tcpHeader)
i += int(constants.BaseTCPHeaderLength)
copy(packet[i:], data)
return packet return packet
} }
+1 -3
View File
@@ -47,13 +47,11 @@ func startRawSocket(family, excludeMark int) (fd fileDescriptor, stop func(), er
if family == constants.AF_INET { if family == constants.AF_INET {
err = ip.SetIPv4HeaderIncluded(fdPlatform) err = ip.SetIPv4HeaderIncluded(fdPlatform)
} else {
err = ip.SetIPv6HeaderIncluded(fdPlatform)
}
if err != nil { if err != nil {
_ = closeSocket(fdPlatform) _ = closeSocket(fdPlatform)
return 0, nil, fmt.Errorf("setting header option on raw socket: %w", err) return 0, nil, fmt.Errorf("setting header option on raw socket: %w", err)
} }
}
// Allow sending packets larger than cached PMTU (for PMTUD probing) // Allow sending packets larger than cached PMTU (for PMTUD probing)
err = setMTUDiscovery(fdPlatform, family == constants.AF_INET) err = setMTUDiscovery(fdPlatform, family == constants.AF_INET)
+1 -1
View File
@@ -45,7 +45,7 @@ func makeSockAddr(addr netip.AddrPort) unix.Sockaddr {
} }
} }
return &unix.SockaddrInet6{ return &unix.SockaddrInet6{
Port: int(addr.Port()), Port: 0,
Addr: addr.Addr().As16(), Addr: addr.Addr().As16(),
} }
} }