mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-21 12:28:39 +00:00
net/packet: add NAT support for DCCP and GRE
Updates tailscale/corp#8020 Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
parent
ce11c82d51
commit
f58751eb2b
@ -558,19 +558,42 @@ func withPort(ap netip.AddrPort, port uint16) netip.AddrPort {
|
||||
// Currently (2023-03-01) only TCP/UDP/ICMP over IPv4 is supported.
|
||||
// p is modified in place.
|
||||
// If p.IPProto is unknown, only the IP header checksum is updated.
|
||||
// TODO(maisem): more protocols (sctp, gre, dccp)
|
||||
func updateV4PacketChecksums(p *Parsed, old, new netip.Addr) {
|
||||
o4, n4 := old.As4(), new.As4()
|
||||
updateV4Checksum(p.Buffer()[10:12], o4[:], n4[:]) // header
|
||||
switch p.IPProto {
|
||||
case ipproto.UDP:
|
||||
updateV4Checksum(p.Transport()[6:8], o4[:], n4[:])
|
||||
case ipproto.TCP:
|
||||
updateV4Checksum(p.Transport()[16:18], o4[:], n4[:])
|
||||
case ipproto.ICMPv4:
|
||||
// Nothing to do.
|
||||
if len(p.Buffer()) < 12 {
|
||||
// Not enough space for an IPv4 header.
|
||||
return
|
||||
}
|
||||
o4, n4 := old.As4(), new.As4()
|
||||
|
||||
// First update the checksum in the IP header.
|
||||
updateV4Checksum(p.Buffer()[10:12], o4[:], n4[:])
|
||||
|
||||
// Now update the transport layer checksums, where applicable.
|
||||
tr := p.Transport()
|
||||
switch p.IPProto {
|
||||
case ipproto.UDP, ipproto.DCCP:
|
||||
if len(tr) < 8 {
|
||||
// Not enough space for a UDP header.
|
||||
return
|
||||
}
|
||||
updateV4Checksum(tr[6:8], o4[:], n4[:])
|
||||
case ipproto.TCP:
|
||||
if len(tr) < 18 {
|
||||
// Not enough space for a TCP header.
|
||||
return
|
||||
}
|
||||
updateV4Checksum(tr[16:18], o4[:], n4[:])
|
||||
case ipproto.GRE:
|
||||
if len(tr) < 6 {
|
||||
// Not enough space for a GRE header.
|
||||
return
|
||||
}
|
||||
if tr[0] == 1 { // checksum present
|
||||
updateV4Checksum(tr[4:6], o4[:], n4[:])
|
||||
}
|
||||
case ipproto.SCTP, ipproto.ICMPv4:
|
||||
// No transport layer update required.
|
||||
}
|
||||
// TODO(maisem): more protocols (sctp, gre, dccp)
|
||||
}
|
||||
|
||||
// updateV4Checksum calculates and updates the checksum in the packet buffer for
|
||||
|
@ -72,6 +72,19 @@ func TestHeaderChecksums(t *testing.T) {
|
||||
0x45, 0x00, 0x00, 0x74, 0xe2, 0x85, 0x00, 0x00, 0x40, 0x11, 0x96, 0xb5, 0x64, 0x64, 0x64, 0x64, 0x64, 0x42, 0xd4, 0x33, 0x00, 0x35, 0xec, 0x55, 0x00, 0x60, 0xd9, 0x19, 0xed, 0xfd, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x34, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x1e, 0x00, 0x0c, 0x07, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x01, 0x6c, 0xc0, 0x15, 0xc0, 0x31, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x1e, 0x00, 0x04, 0x8e, 0xfa, 0xbd, 0xce, 0x00, 0x00, 0x29, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "DCCP",
|
||||
packet: []byte{
|
||||
0x45, 0x00, 0x00, 0x28, 0x15, 0x06, 0x40, 0x00, 0x40, 0x21, 0x5f, 0x2f, 0xc0, 0xa8, 0x01, 0x1f, 0xc9, 0x0b, 0x3b, 0xad, 0x80, 0x04, 0x13, 0x89, 0x05, 0x00, 0x08, 0xdb, 0x01, 0x00, 0x00, 0x04, 0x29, 0x01, 0x6d, 0xdc, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SCTP",
|
||||
packet: []byte{
|
||||
0x45, 0x00, 0x00, 0x30, 0x09, 0xd9, 0x40, 0x00, 0xff, 0x84, 0x50, 0xe2, 0x0a, 0x1c, 0x06, 0x2c, 0x0a, 0x1c, 0x06, 0x2b, 0x0b, 0x80, 0x40, 0x00, 0x21, 0x44, 0x15, 0x23, 0x2b, 0xf2, 0x02, 0x4e, 0x03, 0x00, 0x00, 0x10, 0x28, 0x02, 0x43, 0x45, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
},
|
||||
// TODO(maisem): add test for GRE.
|
||||
}
|
||||
var p Parsed
|
||||
for _, tt := range tests {
|
||||
|
@ -25,6 +25,8 @@ const (
|
||||
ICMPv6 Proto = 0x3a
|
||||
TCP Proto = 0x06
|
||||
UDP Proto = 0x11
|
||||
DCCP Proto = 0x21
|
||||
GRE Proto = 0x2f
|
||||
SCTP Proto = 0x84
|
||||
|
||||
// TSMP is the Tailscale Message Protocol (our ICMP-ish
|
||||
@ -67,6 +69,10 @@ func (p Proto) String() string {
|
||||
return "SCTP"
|
||||
case TSMP:
|
||||
return "TSMP"
|
||||
case GRE:
|
||||
return "GRE"
|
||||
case DCCP:
|
||||
return "DCCP"
|
||||
default:
|
||||
return fmt.Sprintf("IPProto-%d", int(p))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user