netstack: make tcpip.Address an opaque type

The important change here is in tcpip/tcpip.go, where tcpip.Address is defined.
The rest is updating uses of tcpip.Address.

This is preparation for netip.Addr or []byte based addresses, which should save
us a bunch of allocations. Currently, we allocate every time we want to, say,
get a tcpip.Address from a header. This is because the header is a byte slice,
but Address is a string. Strings are immutable, so Go allocates and copies.

PiperOrigin-RevId: 532284732
This commit is contained in:
Kevin Krakauer
2023-05-15 18:03:37 -07:00
committed by gVisor bot
parent 83f4f485b4
commit 64268c8483
110 changed files with 1419 additions and 1141 deletions
+5 -5
View File
@@ -284,21 +284,21 @@ func doNetlinkInterfaceRequest(typ, flags uint16, idx uint32, addr inet.Interfac
Flags: addr.Flags,
}
// Local address.
localAddr := tcpip.Address(addr.Addr)
localAddr := tcpip.AddrFromSlice(addr.Addr)
if addr.Family == linux.AF_INET {
localAddr = localAddr.To4()
}
rtLocal := linux.RtAttr{
Len: linux.SizeOfRtAttr + uint16(len(localAddr)),
Len: linux.SizeOfRtAttr + uint16(localAddr.Len()),
Type: linux.IFA_LOCAL,
}
localAddrBs := primitive.ByteSlice(localAddr)
localAddrBs := primitive.ByteSlice(localAddr.AsSlice())
// Peer is always the local address for us.
rtPeer := linux.RtAttr{
Len: linux.SizeOfRtAttr + uint16(len(localAddr)),
Len: linux.SizeOfRtAttr + uint16(localAddr.Len()),
Type: linux.IFA_ADDRESS,
}
peerAddrBs := primitive.ByteSlice(localAddr)
peerAddrBs := primitive.ByteSlice(localAddr.AsSlice())
msgs := []marshal.Marshallable{
&hdr,
+12 -12
View File
@@ -28,10 +28,10 @@ import (
// emptyIPv4Filter is for comparison with a rule's filters to determine whether
// it is also empty. It is immutable.
var emptyIPv4Filter = stack.IPHeaderFilter{
Dst: "\x00\x00\x00\x00",
DstMask: "\x00\x00\x00\x00",
Src: "\x00\x00\x00\x00",
SrcMask: "\x00\x00\x00\x00",
Dst: tcpip.AddrFrom4([4]byte{0x00, 0x00, 0x00, 0x00}),
DstMask: tcpip.AddrFrom4([4]byte{0x00, 0x00, 0x00, 0x00}),
Src: tcpip.AddrFrom4([4]byte{0x00, 0x00, 0x00, 0x00}),
SrcMask: tcpip.AddrFrom4([4]byte{0x00, 0x00, 0x00, 0x00}),
}
// convertNetstackToBinary4 converts the iptables as stored in netstack to the
@@ -75,10 +75,10 @@ func getEntries4(table stack.Table, tablename linux.TableName) (linux.KernelIPTG
TargetOffset: linux.SizeOfIPTEntry,
},
}
copy(entry.Entry.IP.Dst[:], rule.Filter.Dst)
copy(entry.Entry.IP.DstMask[:], rule.Filter.DstMask)
copy(entry.Entry.IP.Src[:], rule.Filter.Src)
copy(entry.Entry.IP.SrcMask[:], rule.Filter.SrcMask)
copy(entry.Entry.IP.Dst[:], rule.Filter.Dst.AsSlice())
copy(entry.Entry.IP.DstMask[:], rule.Filter.DstMask.AsSlice())
copy(entry.Entry.IP.Src[:], rule.Filter.Src.AsSlice())
copy(entry.Entry.IP.SrcMask[:], rule.Filter.SrcMask.AsSlice())
copy(entry.Entry.IP.OutputInterface[:], rule.Filter.OutputInterface)
copy(entry.Entry.IP.OutputInterfaceMask[:], rule.Filter.OutputInterfaceMask)
copy(entry.Entry.IP.InputInterface[:], rule.Filter.InputInterface)
@@ -218,11 +218,11 @@ func filterFromIPTIP(iptip linux.IPTIP) (stack.IPHeaderFilter, error) {
Protocol: tcpip.TransportProtocolNumber(iptip.Protocol),
// A Protocol value of 0 indicates all protocols match.
CheckProtocol: iptip.Protocol != 0,
Dst: tcpip.Address(iptip.Dst[:]),
DstMask: tcpip.Address(iptip.DstMask[:]),
Dst: tcpip.AddrFrom4(iptip.Dst),
DstMask: tcpip.AddrFrom4(iptip.DstMask),
DstInvert: iptip.InverseFlags&linux.IPT_INV_DSTIP != 0,
Src: tcpip.Address(iptip.Src[:]),
SrcMask: tcpip.Address(iptip.SrcMask[:]),
Src: tcpip.AddrFrom4(iptip.Src),
SrcMask: tcpip.AddrFrom4(iptip.SrcMask),
SrcInvert: iptip.InverseFlags&linux.IPT_INV_SRCIP != 0,
InputInterface: string(trimNullBytes(iptip.InputInterface[:])),
InputInterfaceMask: string(trimNullBytes(iptip.InputInterfaceMask[:])),
+12 -12
View File
@@ -28,10 +28,10 @@ import (
// emptyIPv6Filter is for comparison with a rule's filters to determine whether
// it is also empty. It is immutable.
var emptyIPv6Filter = stack.IPHeaderFilter{
Dst: "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
DstMask: "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
Src: "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
SrcMask: "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
Dst: tcpip.AddrFrom16([16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
DstMask: tcpip.AddrFrom16([16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
Src: tcpip.AddrFrom16([16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
SrcMask: tcpip.AddrFrom16([16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
}
// convertNetstackToBinary6 converts the ip6tables as stored in netstack to the
@@ -75,10 +75,10 @@ func getEntries6(table stack.Table, tablename linux.TableName) (linux.KernelIP6T
TargetOffset: linux.SizeOfIP6TEntry,
},
}
copy(entry.Entry.IPv6.Dst[:], rule.Filter.Dst)
copy(entry.Entry.IPv6.DstMask[:], rule.Filter.DstMask)
copy(entry.Entry.IPv6.Src[:], rule.Filter.Src)
copy(entry.Entry.IPv6.SrcMask[:], rule.Filter.SrcMask)
copy(entry.Entry.IPv6.Dst[:], rule.Filter.Dst.AsSlice())
copy(entry.Entry.IPv6.DstMask[:], rule.Filter.DstMask.AsSlice())
copy(entry.Entry.IPv6.Src[:], rule.Filter.Src.AsSlice())
copy(entry.Entry.IPv6.SrcMask[:], rule.Filter.SrcMask.AsSlice())
copy(entry.Entry.IPv6.OutputInterface[:], rule.Filter.OutputInterface)
copy(entry.Entry.IPv6.OutputInterfaceMask[:], rule.Filter.OutputInterfaceMask)
copy(entry.Entry.IPv6.InputInterface[:], rule.Filter.InputInterface)
@@ -221,11 +221,11 @@ func filterFromIP6TIP(iptip linux.IP6TIP) (stack.IPHeaderFilter, error) {
Protocol: tcpip.TransportProtocolNumber(iptip.Protocol),
// In ip6tables a flag controls whether to check the protocol.
CheckProtocol: iptip.Flags&linux.IP6T_F_PROTO != 0,
Dst: tcpip.Address(iptip.Dst[:]),
DstMask: tcpip.Address(iptip.DstMask[:]),
Dst: tcpip.AddrFrom16(iptip.Dst),
DstMask: tcpip.AddrFrom16(iptip.DstMask),
DstInvert: iptip.InverseFlags&linux.IP6T_INV_DSTIP != 0,
Src: tcpip.Address(iptip.Src[:]),
SrcMask: tcpip.Address(iptip.SrcMask[:]),
Src: tcpip.AddrFrom16(iptip.Src),
SrcMask: tcpip.AddrFrom16(iptip.SrcMask),
SrcInvert: iptip.InverseFlags&linux.IP6T_INV_SRCIP != 0,
InputInterface: string(trimNullBytes(iptip.InputInterface[:])),
InputInterfaceMask: string(trimNullBytes(iptip.InputInterfaceMask[:])),
+10 -10
View File
@@ -346,7 +346,7 @@ func (*redirectTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (
return nil, syserr.ErrInvalidArgument
}
target.addr = tcpip.Address(nfRange.RangeIPV4.MinIP[:])
target.addr = tcpip.AddrFrom4(nfRange.RangeIPV4.MinIP)
target.Port = ntohs(nfRange.RangeIPV4.MinPort)
return &target, nil
@@ -382,8 +382,8 @@ func (*nfNATTargetMaker) marshal(target target) []byte {
},
}
copy(nt.Target.Name[:], RedirectTargetName)
copy(nt.Range.MinAddr[:], rt.addr)
copy(nt.Range.MaxAddr[:], rt.addr)
copy(nt.Range.MinAddr[:], rt.addr.AsSlice())
copy(nt.Range.MaxAddr[:], rt.addr.AsSlice())
nt.Range.MinProto = htons(rt.Port)
nt.Range.MaxProto = nt.Range.MinProto
@@ -426,7 +426,7 @@ func (*nfNATTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (tar
NetworkProtocol: filter.NetworkProtocol(),
Port: ntohs(natRange.MinProto),
},
addr: tcpip.Address(natRange.MinAddr[:]),
addr: tcpip.AddrFrom16(natRange.MinAddr),
}
return &target, nil
@@ -457,8 +457,8 @@ func (*snatTargetMakerV4) marshal(target target) []byte {
xt.NfRange.RangeIPV4.Flags |= linux.NF_NAT_RANGE_MAP_IPS | linux.NF_NAT_RANGE_PROTO_SPECIFIED
xt.NfRange.RangeIPV4.MinPort = htons(st.Port)
xt.NfRange.RangeIPV4.MaxPort = xt.NfRange.RangeIPV4.MinPort
copy(xt.NfRange.RangeIPV4.MinIP[:], st.Addr)
copy(xt.NfRange.RangeIPV4.MaxIP[:], st.Addr)
copy(xt.NfRange.RangeIPV4.MinIP[:], st.Addr.AsSlice())
copy(xt.NfRange.RangeIPV4.MaxIP[:], st.Addr.AsSlice())
return marshal.Marshal(&xt)
}
@@ -504,7 +504,7 @@ func (*snatTargetMakerV4) unmarshal(buf []byte, filter stack.IPHeaderFilter) (ta
return nil, syserr.ErrInvalidArgument
}
target.Addr = tcpip.Address(nfRange.RangeIPV4.MinIP[:])
target.Addr = tcpip.AddrFrom4(nfRange.RangeIPV4.MinIP)
target.Port = ntohs(nfRange.RangeIPV4.MinPort)
return &target, nil
@@ -533,8 +533,8 @@ func (*snatTargetMakerV6) marshal(target target) []byte {
},
}
copy(nt.Target.Name[:], SNATTargetName)
copy(nt.Range.MinAddr[:], st.Addr)
copy(nt.Range.MaxAddr[:], st.Addr)
copy(nt.Range.MinAddr[:], st.Addr.AsSlice())
copy(nt.Range.MaxAddr[:], st.Addr.AsSlice())
nt.Range.MinProto = htons(st.Port)
nt.Range.MaxProto = nt.Range.MinProto
@@ -574,7 +574,7 @@ func (*snatTargetMakerV6) unmarshal(buf []byte, filter stack.IPHeaderFilter) (ta
target := snatTarget{
SNATTarget: stack.SNATTarget{
NetworkProtocol: filter.NetworkProtocol(),
Addr: tcpip.Address(natRange.MinAddr[:]),
Addr: tcpip.AddrFrom16(natRange.MinAddr),
Port: ntohs(natRange.MinProto),
},
}
+13 -10
View File
@@ -666,8 +666,8 @@ func (s *sock) checkFamily(family uint16, exact bool) bool {
//
// TODO(gvisor.dev/issue/1556): remove this function.
func (s *sock) mapFamily(addr tcpip.FullAddress, family uint16) tcpip.FullAddress {
if len(addr.Addr) == 0 && s.family == linux.AF_INET6 && family == linux.AF_INET {
addr.Addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00"
if addr.Addr.BitLen() == 0 && s.family == linux.AF_INET6 && family == linux.AF_INET {
addr.Addr = tcpip.AddrFrom16([16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00})
}
return addr
}
@@ -748,8 +748,11 @@ func (s *sock) Bind(_ *kernel.Task, sockaddr []byte) *syserr.Error {
a.UnmarshalBytes(sockaddr)
addr = tcpip.FullAddress{
NIC: tcpip.NICID(a.InterfaceIndex),
Addr: tcpip.Address(a.HardwareAddr[:header.EthernetAddressSize]),
NIC: tcpip.NICID(a.InterfaceIndex),
Addr: tcpip.AddrFrom16Slice(append(
a.HardwareAddr[:header.EthernetAddressSize],
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}...,
)),
Port: socket.Ntohs(a.Protocol),
}
} else {
@@ -2181,7 +2184,7 @@ func setSockOptIPv6(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int
return syserr.TranslateNetstackError(ep.SetSockOpt(&tcpip.AddMembershipOption{
NIC: tcpip.NICID(req.InterfaceIndex),
MulticastAddr: tcpip.Address(req.MulticastAddr[:]),
MulticastAddr: tcpip.AddrFrom16(req.MulticastAddr),
}))
case linux.IPV6_DROP_MEMBERSHIP:
@@ -2192,7 +2195,7 @@ func setSockOptIPv6(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int
return syserr.TranslateNetstackError(ep.SetSockOpt(&tcpip.RemoveMembershipOption{
NIC: tcpip.NICID(req.InterfaceIndex),
MulticastAddr: tcpip.Address(req.MulticastAddr[:]),
MulticastAddr: tcpip.AddrFrom16(req.MulticastAddr),
}))
case linux.IPV6_IPSEC_POLICY,
@@ -2399,8 +2402,8 @@ func setSockOptIP(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int,
NIC: tcpip.NICID(req.InterfaceIndex),
// TODO(igudger): Change AddMembership to use the standard
// any address representation.
InterfaceAddr: tcpip.Address(req.InterfaceAddr[:]),
MulticastAddr: tcpip.Address(req.MulticastAddr[:]),
InterfaceAddr: tcpip.AddrFrom4(req.InterfaceAddr),
MulticastAddr: tcpip.AddrFrom4(req.MulticastAddr),
}))
case linux.IP_DROP_MEMBERSHIP:
@@ -2413,8 +2416,8 @@ func setSockOptIP(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int,
NIC: tcpip.NICID(req.InterfaceIndex),
// TODO(igudger): Change DropMembership to use the standard
// any address representation.
InterfaceAddr: tcpip.Address(req.InterfaceAddr[:]),
MulticastAddr: tcpip.Address(req.MulticastAddr[:]),
InterfaceAddr: tcpip.AddrFrom4(req.InterfaceAddr),
MulticastAddr: tcpip.AddrFrom4(req.MulticastAddr),
}))
case linux.IP_MULTICAST_IF:
+10 -10
View File
@@ -120,7 +120,7 @@ func (s *Stack) InterfaceAddrs() map[int32][]inet.InterfaceAddr {
addrs = append(addrs, inet.InterfaceAddr{
Family: family,
PrefixLen: uint8(a.AddressWithPrefix.PrefixLen),
Addr: []byte(a.AddressWithPrefix.Address),
Addr: a.AddressWithPrefix.Address.AsSlice(),
// TODO(b/68878065): Other fields.
})
}
@@ -145,7 +145,7 @@ func convertAddr(addr inet.InterfaceAddr) (tcpip.ProtocolAddress, error) {
return protocolAddress, linuxerr.EINVAL
}
protocol = ipv4.ProtocolNumber
address = tcpip.Address(addr.Addr)
address = tcpip.AddrFrom4Slice(addr.Addr)
case linux.AF_INET6:
if len(addr.Addr) != header.IPv6AddressSize {
return protocolAddress, linuxerr.EINVAL
@@ -154,7 +154,7 @@ func convertAddr(addr inet.InterfaceAddr) (tcpip.ProtocolAddress, error) {
return protocolAddress, linuxerr.EINVAL
}
protocol = ipv6.ProtocolNumber
address = tcpip.Address(addr.Addr)
address = tcpip.AddrFrom16Slice(addr.Addr)
default:
return protocolAddress, linuxerr.ENOTSUP
}
@@ -185,7 +185,7 @@ func (s *Stack) AddInterfaceAddr(idx int32, addr inet.InterfaceAddr) error {
// Add route for local network if it doesn't exist already.
localRoute := tcpip.Route{
Destination: protocolAddress.AddressWithPrefix.Subnet(),
Gateway: "", // No gateway for local network.
Gateway: tcpip.Address{}, // No gateway for local network.
NIC: nicID,
}
@@ -217,7 +217,7 @@ func (s *Stack) RemoveInterfaceAddr(idx int32, addr inet.InterfaceAddr) error {
// Remove the corresponding local network route if it exists.
localRoute := tcpip.Route{
Destination: protocolAddress.AddressWithPrefix.Subnet(),
Gateway: "", // No gateway for local network.
Gateway: tcpip.Address{}, // No gateway for local network.
NIC: nicID,
}
s.Stack.RemoveRoutes(func(rt tcpip.Route) bool {
@@ -430,10 +430,10 @@ func (s *Stack) RouteTable() []inet.Route {
for _, rt := range s.Stack.GetRouteTable() {
var family uint8
switch len(rt.Destination.ID()) {
case header.IPv4AddressSize:
switch rt.Destination.ID().BitLen() {
case header.IPv4AddressSizeBits:
family = linux.AF_INET
case header.IPv6AddressSize:
case header.IPv6AddressSizeBits:
family = linux.AF_INET6
default:
log.Warningf("Unknown network protocol in route %+v", rt)
@@ -453,9 +453,9 @@ func (s *Stack) RouteTable() []inet.Route {
Scope: linux.RT_SCOPE_LINK,
Type: linux.RTN_UNICAST,
DstAddr: []byte(rt.Destination.ID()),
DstAddr: rt.Destination.ID().AsSlice(),
OutputInterface: int32(rt.NIC),
GatewayAddr: []byte(rt.Gateway),
GatewayAddr: rt.Gateway.AsSlice(),
})
}
+24 -31
View File
@@ -49,8 +49,8 @@ type ControlMessages struct {
func packetInfoToLinux(packetInfo tcpip.IPPacketInfo) linux.ControlMessageIPPacketInfo {
var p linux.ControlMessageIPPacketInfo
p.NIC = int32(packetInfo.NIC)
copy(p.LocalAddr[:], packetInfo.LocalAddr)
copy(p.DestinationAddr[:], packetInfo.DestinationAddr)
copy(p.LocalAddr[:], packetInfo.LocalAddr.AsSlice())
copy(p.DestinationAddr[:], packetInfo.DestinationAddr.AsSlice())
return p
}
@@ -58,7 +58,7 @@ func packetInfoToLinux(packetInfo tcpip.IPPacketInfo) linux.ControlMessageIPPack
// format.
func ipv6PacketInfoToLinux(packetInfo tcpip.IPv6PacketInfo) linux.ControlMessageIPv6PacketInfo {
var p linux.ControlMessageIPv6PacketInfo
if n := copy(p.Addr[:], packetInfo.Addr); n != len(p.Addr) {
if n := copy(p.Addr[:], packetInfo.Addr.AsSlice()); n != len(p.Addr) {
panic(fmt.Sprintf("got copy(%x, %x) = %d, want = %d", p.Addr, packetInfo.Addr, n, len(p.Addr)))
}
p.NIC = uint32(packetInfo.NIC)
@@ -99,14 +99,14 @@ func sockErrCmsgToLinux(sockErr *tcpip.SockError) linux.SockErrCMsg {
switch sockErr.NetProto {
case header.IPv4ProtocolNumber:
errMsg := &linux.SockErrCMsgIPv4{SockExtendedErr: ee}
if len(sockErr.Offender.Addr) > 0 {
if len(sockErr.Offender.Addr.AsSlice()) > 0 {
addr, _ := ConvertAddress(linux.AF_INET, sockErr.Offender)
errMsg.Offender = *addr.(*linux.SockAddrInet)
}
return errMsg
case header.IPv6ProtocolNumber:
errMsg := &linux.SockErrCMsgIPv6{SockExtendedErr: ee}
if len(sockErr.Offender.Addr) > 0 {
if len(sockErr.Offender.Addr.AsSlice()) > 0 {
addr, _ := ConvertAddress(linux.AF_INET6, sockErr.Offender)
errMsg.Offender = *addr.(*linux.SockAddrInet6)
}
@@ -461,7 +461,8 @@ func Htons(v uint16) uint16 {
// case when it has the fe80::/10 prefix. This check is used to determine when
// the NICID is relevant for a given IPv6 address.
func isLinkLocal(addr tcpip.Address) bool {
return len(addr) >= 2 && addr[0] == 0xfe && addr[1]&0xc0 == 0x80
addrBytes := addr.AsSlice()
return len(addrBytes) >= 2 && addrBytes[0] == 0xfe && addrBytes[1]&0xc0 == 0x80
}
// ConvertAddress converts the given address to a native format.
@@ -469,20 +470,21 @@ func ConvertAddress(family int, addr tcpip.FullAddress) (linux.SockAddr, uint32)
switch family {
case linux.AF_INET:
var out linux.SockAddrInet
copy(out.Addr[:], addr.Addr)
copy(out.Addr[:], addr.Addr.AsSlice())
out.Family = linux.AF_INET
out.Port = Htons(addr.Port)
return &out, uint32(sockAddrInetSize)
case linux.AF_INET6:
var out linux.SockAddrInet6
if len(addr.Addr) == header.IPv4AddressSize {
addrBytes := addr.Addr.AsSlice()
if len(addrBytes) == header.IPv4AddressSize {
// Copy address in v4-mapped format.
copy(out.Addr[12:], addr.Addr)
copy(out.Addr[12:], addrBytes)
out.Addr[10] = 0xff
out.Addr[11] = 0xff
} else {
copy(out.Addr[:], addr.Addr)
copy(out.Addr[:], addrBytes)
}
out.Family = linux.AF_INET6
out.Port = Htons(addr.Port)
@@ -496,7 +498,7 @@ func ConvertAddress(family int, addr tcpip.FullAddress) (linux.SockAddr, uint32)
out.Family = linux.AF_PACKET
out.InterfaceIndex = int32(addr.NIC)
out.HardwareAddrLen = header.EthernetAddressSize
copy(out.HardwareAddr[:], addr.Addr)
copy(out.HardwareAddr[:], addr.Addr.AsSlice())
return &out, uint32(sockAddrLinkSize)
default:
@@ -508,9 +510,9 @@ func ConvertAddress(family int, addr tcpip.FullAddress) (linux.SockAddr, uint32)
// netstack representation taking any addresses into account.
func BytesToIPAddress(addr []byte) tcpip.Address {
if bytes.Equal(addr, make([]byte, 4)) || bytes.Equal(addr, make([]byte, 16)) {
return ""
return tcpip.Address{}
}
return tcpip.Address(addr)
return tcpip.AddrFromSlice(addr)
}
// AddressAndFamily reads an sockaddr struct from the given address and
@@ -526,22 +528,6 @@ func AddressAndFamily(addr []byte) (tcpip.FullAddress, uint16, *syserr.Error) {
// Get the rest of the fields based on the address family.
switch family := hostarch.ByteOrder.Uint16(addr); family {
case linux.AF_UNIX:
path := addr[2:]
if len(path) > linux.UnixPathMax {
return tcpip.FullAddress{}, family, syserr.ErrInvalidArgument
}
// Drop the terminating NUL (if one exists) and everything after
// it for filesystem (non-abstract) addresses.
if len(path) > 0 && path[0] != 0 {
if n := bytes.IndexByte(path[1:], 0); n >= 0 {
path = path[:n+1]
}
}
return tcpip.FullAddress{
Addr: tcpip.Address(path),
}, family, nil
case linux.AF_INET:
var a linux.SockAddrInet
if len(addr) < sockAddrInetSize {
@@ -584,8 +570,15 @@ func AddressAndFamily(addr []byte) (tcpip.FullAddress, uint16, *syserr.Error) {
}
return tcpip.FullAddress{
NIC: tcpip.NICID(a.InterfaceIndex),
Addr: tcpip.Address(a.HardwareAddr[:header.EthernetAddressSize]),
NIC: tcpip.NICID(a.InterfaceIndex),
// This is a hack. FullAddress is designed to carry IP
// addresses, but it's overloaded here to carry a link
// address. We stick the 6 byte link address to 10
// zeroed bytes.
Addr: tcpip.AddrFrom16Slice(append(
a.HardwareAddr[:header.EthernetAddressSize],
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}...,
)),
Port: Ntohs(a.Protocol),
}, family, nil
+30 -2
View File
@@ -17,6 +17,7 @@
package unix
import (
"bytes"
"fmt"
"golang.org/x/sys/unix"
@@ -435,7 +436,7 @@ func (s *Socket) Endpoint() transport.Endpoint {
// extractPath extracts and validates the address.
func extractPath(sockaddr []byte) (string, *syserr.Error) {
addr, family, err := socket.AddressAndFamily(sockaddr)
addr, family, err := addressAndFamily(sockaddr)
if err != nil {
if err == syserr.ErrAddressFamilyNotSupported {
err = syserr.ErrInvalidArgument
@@ -447,7 +448,7 @@ func extractPath(sockaddr []byte) (string, *syserr.Error) {
}
// The address is trimmed by GetAddress.
p := string(addr.Addr)
p := addr.Addr
if p == "" {
// Not allowed.
return "", syserr.ErrInvalidArgument
@@ -460,6 +461,33 @@ func extractPath(sockaddr []byte) (string, *syserr.Error) {
return p, nil
}
func addressAndFamily(addr []byte) (transport.Address, uint16, *syserr.Error) {
// Make sure we have at least 2 bytes for the address family.
if len(addr) < 2 {
return transport.Address{}, 0, syserr.ErrInvalidArgument
}
// Get the rest of the fields based on the address family.
switch family := hostarch.ByteOrder.Uint16(addr); family {
case linux.AF_UNIX:
path := addr[2:]
if len(path) > linux.UnixPathMax {
return transport.Address{}, family, syserr.ErrInvalidArgument
}
// Drop the terminating NUL (if one exists) and everything after
// it for filesystem (non-abstract) addresses.
if len(path) > 0 && path[0] != 0 {
if n := bytes.IndexByte(path[1:], 0); n >= 0 {
path = path[:n+1]
}
}
return transport.Address{
Addr: string(path),
}, family, nil
}
return transport.Address{}, 0, syserr.ErrAddressFamilyNotSupported
}
// GetPeerName implements the linux syscall getpeername(2) for sockets backed by
// a transport.Endpoint.
func (s *Socket) GetPeerName(t *kernel.Task) (linux.SockAddr, uint32, *syserr.Error) {
+1 -1
View File
@@ -352,7 +352,7 @@ func sockAddr(t *kernel.Task, addr hostarch.Addr, length uint32) string {
}
if family == linux.AF_UNIX {
return fmt.Sprintf("%#x {Family: %s, Addr: %q}", addr, familyStr, string(fa.Addr))
return fmt.Sprintf("%#x {Family: %s, Addr: %q}", addr, familyStr, string(fa.Addr.AsSlice()))
}
return fmt.Sprintf("%#x {Family: %s, Addr: %v, Port: %d}", addr, familyStr, fa.Addr, fa.Port)
+3 -3
View File
@@ -469,11 +469,11 @@ func (c *TCPConn) newOpError(op string, err error) *net.OpError {
}
func fullToTCPAddr(addr tcpip.FullAddress) *net.TCPAddr {
return &net.TCPAddr{IP: net.IP(addr.Addr), Port: int(addr.Port)}
return &net.TCPAddr{IP: net.IP(addr.Addr.AsSlice()), Port: int(addr.Port)}
}
func fullToUDPAddr(addr tcpip.FullAddress) *net.UDPAddr {
return &net.UDPAddr{IP: net.IP(addr.Addr), Port: int(addr.Port)}
return &net.UDPAddr{IP: net.IP(addr.Addr.AsSlice()), Port: int(addr.Port)}
}
// DialTCP creates a new TCPConn connected to the specified address.
@@ -664,7 +664,7 @@ func (c *UDPConn) WriteTo(b []byte, addr net.Addr) (int, error) {
if addr != nil {
ua := addr.(*net.UDPAddr)
writeOptions.To = &tcpip.FullAddress{
Addr: tcpip.Address(ua.IP),
Addr: tcpip.AddrFromSlice(ua.IP),
Port: uint16(ua.Port),
}
}
+16 -16
View File
@@ -136,7 +136,7 @@ func TestCloseReader(t *testing.T) {
s.Wait()
}()
addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
addr := tcpip.FullAddress{NICID, tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4()), 11211}
protocolAddr := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
@@ -196,7 +196,7 @@ func TestCloseReaderWithForwarder(t *testing.T) {
s.Wait()
}()
addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
addr := tcpip.FullAddress{NICID, tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4()), 11211}
protocolAddr := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
AddressWithPrefix: addr.Addr.WithPrefix(),
@@ -256,7 +256,7 @@ func TestCloseRead(t *testing.T) {
s.Wait()
}()
addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
addr := tcpip.FullAddress{NICID, tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4()), 11211}
protocolAddr := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
AddressWithPrefix: addr.Addr.WithPrefix(),
@@ -314,7 +314,7 @@ func TestCloseWrite(t *testing.T) {
s.Wait()
}()
addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
addr := tcpip.FullAddress{NICID, tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4()), 11211}
protocolAddr := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
AddressWithPrefix: addr.Addr.WithPrefix(),
@@ -378,7 +378,7 @@ func TestCloseStack(t *testing.T) {
t.Fatalf("newLoopbackStack() = %v", err)
}
addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
addr := tcpip.FullAddress{NICID, tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4()), 11211}
protocolAddr := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
AddressWithPrefix: addr.Addr.WithPrefix(),
@@ -440,7 +440,7 @@ func TestUDPForwarder(t *testing.T) {
s.Wait()
}()
ip1 := tcpip.Address(net.IPv4(169, 254, 10, 1).To4())
ip1 := tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4())
addr1 := tcpip.FullAddress{NICID, ip1, 11211}
protocolAddr1 := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
@@ -449,7 +449,7 @@ func TestUDPForwarder(t *testing.T) {
if err := s.AddProtocolAddress(NICID, protocolAddr1, stack.AddressProperties{}); err != nil {
t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", NICID, protocolAddr1, err)
}
ip2 := tcpip.Address(net.IPv4(169, 254, 10, 2).To4())
ip2 := tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 2).To4())
addr2 := tcpip.FullAddress{NICID, ip2, 11311}
protocolAddr2 := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
@@ -513,7 +513,7 @@ func TestDeadlineChange(t *testing.T) {
s.Wait()
}()
addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
addr := tcpip.FullAddress{NICID, tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4()), 11211}
protocolAddr := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
@@ -574,7 +574,7 @@ func TestPacketConnTransfer(t *testing.T) {
s.Wait()
}()
ip1 := tcpip.Address(net.IPv4(169, 254, 10, 1).To4())
ip1 := tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4())
addr1 := tcpip.FullAddress{NICID, ip1, 11211}
protocolAddr1 := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
@@ -583,7 +583,7 @@ func TestPacketConnTransfer(t *testing.T) {
if err := s.AddProtocolAddress(NICID, protocolAddr1, stack.AddressProperties{}); err != nil {
t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", NICID, protocolAddr1, err)
}
ip2 := tcpip.Address(net.IPv4(169, 254, 10, 2).To4())
ip2 := tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 2).To4())
addr2 := tcpip.FullAddress{NICID, ip2, 11311}
protocolAddr2 := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
@@ -642,7 +642,7 @@ func TestConnectedPacketConnTransfer(t *testing.T) {
s.Wait()
}()
ip := tcpip.Address(net.IPv4(169, 254, 10, 1).To4())
ip := tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4())
addr := tcpip.FullAddress{NICID, ip, 11211}
protocolAddr := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
@@ -692,7 +692,7 @@ func makePipe() (c1, c2 net.Conn, stop func(), err error) {
return nil, nil, nil, fmt.Errorf("newLoopbackStack() = %v", e)
}
ip := tcpip.Address(net.IPv4(169, 254, 10, 1).To4())
ip := tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4())
addr := tcpip.FullAddress{NICID, ip, 11211}
protocolAddr := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
@@ -792,7 +792,7 @@ func TestTCPDialError(t *testing.T) {
s.Wait()
}()
ip := tcpip.Address(net.IPv4(169, 254, 10, 1).To4())
ip := tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4())
addr := tcpip.FullAddress{NICID, ip, 11211}
switch _, err := DialTCP(s, addr, ipv4.ProtocolNumber); err := err.(type) {
@@ -815,7 +815,7 @@ func TestDialContextTCPCanceled(t *testing.T) {
s.Wait()
}()
addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
addr := tcpip.FullAddress{NICID, tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4()), 11211}
protocolAddr := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
AddressWithPrefix: addr.Addr.WithPrefix(),
@@ -843,7 +843,7 @@ func TestDialContextTCPTimeout(t *testing.T) {
s.Wait()
}()
addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
addr := tcpip.FullAddress{NICID, tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4()), 11211}
protocolAddr := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
AddressWithPrefix: addr.Addr.WithPrefix(),
@@ -903,7 +903,7 @@ func TestInterruptListender(t *testing.T) {
s.Wait()
}()
addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
addr := tcpip.FullAddress{NICID, tcpip.AddrFromSlice(net.IPv4(169, 254, 10, 1).To4()), 11211}
protocolAddr := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
+30 -10
View File
@@ -28,8 +28,8 @@ import (
// destination protocol and network address. Pseudo-headers are needed by
// transport layers when calculating their own checksum.
func PseudoHeaderChecksum(protocol tcpip.TransportProtocolNumber, srcAddr tcpip.Address, dstAddr tcpip.Address, totalLen uint16) uint16 {
xsum := checksum.Checksum([]byte(srcAddr), 0)
xsum = checksum.Checksum([]byte(dstAddr), xsum)
xsum := checksum.Checksum(srcAddr.AsSlice(), 0)
xsum = checksum.Checksum(dstAddr.AsSlice(), xsum)
// Add the length portion of the checksum to the pseudo-checksum.
tmp := make([]byte, 2)
@@ -68,12 +68,32 @@ func checksumUpdate2ByteAlignedUint16(xsum, old, new uint16) uint16 {
func checksumUpdate2ByteAlignedAddress(xsum uint16, old, new tcpip.Address) uint16 {
const uint16Bytes = 2
if len(old) != len(new) {
panic(fmt.Sprintf("buffer lengths are different; old = %d, new = %d", len(old), len(new)))
if old.BitLen() != new.BitLen() {
panic(fmt.Sprintf("buffer lengths are different; old = %d, new = %d", old.BitLen()/8, new.BitLen()/8))
}
if len(old)%uint16Bytes != 0 {
panic(fmt.Sprintf("buffer has an odd number of bytes; got = %d", len(old)))
if oldBytes := old.BitLen() % 16; oldBytes != 0 {
panic(fmt.Sprintf("buffer has an odd number of bytes; got = %d", oldBytes))
}
// Try to avoid allocating.
var oldAddr []byte
var newAddr []byte
switch old.BitLen() {
case 32:
var oldAddr4 [4]byte
var newAddr4 [4]byte
oldAddr4 = old.As4()
newAddr4 = new.As4()
oldAddr = oldAddr4[:]
newAddr = newAddr4[:]
case 128:
var oldAddr16 [16]byte
var newAddr16 [16]byte
oldAddr16 = old.As16()
newAddr16 = new.As16()
oldAddr = oldAddr16[:]
newAddr = newAddr16[:]
}
// As per RFC 1071 page 4,
@@ -89,12 +109,12 @@ func checksumUpdate2ByteAlignedAddress(xsum uint16, old, new tcpip.Address) uint
// checksum C, the new checksum C' is:
//
// C' = C + (-m) + m' = C + (m' - m)
for len(old) != 0 {
for len(oldAddr) != 0 {
// Convert the 2 byte sequences to uint16 values then apply the increment
// update.
xsum = checksumUpdate2ByteAlignedUint16(xsum, (uint16(old[0])<<8)+uint16(old[1]), (uint16(new[0])<<8)+uint16(new[1]))
old = old[uint16Bytes:]
new = new[uint16Bytes:]
xsum = checksumUpdate2ByteAlignedUint16(xsum, (uint16(oldAddr[0])<<8)+uint16(oldAddr[1]), (uint16(newAddr[0])<<8)+uint16(newAddr[1]))
oldAddr = oldAddr[uint16Bytes:]
newAddr = newAddr[uint16Bytes:]
}
return xsum
+2 -2
View File
@@ -130,7 +130,7 @@ func randomAddress(size int) tcpip.Address {
for i := 0; i < size; i++ {
s[i] = byte(rand.Uint32())
}
return tcpip.Address(s)
return tcpip.AddrFromSlice(s)
}
func TestChecksummableNetworkUpdateAddress(t *testing.T) {
@@ -272,7 +272,7 @@ func TestChecksummableTransportUpdatePort(t *testing.T) {
}
func TestChecksummableTransportUpdatePseudoHeaderAddress(t *testing.T) {
const addressSize = 6
const addressSize = 16
tests := []struct {
name string
+5 -3
View File
@@ -159,10 +159,11 @@ func EthernetAddressFromMulticastIPv4Address(addr tcpip.Address) tcpip.LinkAddre
// address by placing the low-order 23-bits of the IP address
// into the low-order 23 bits of the Ethernet multicast address
// 01-00-5E-00-00-00 (hex).
addrBytes := addr.As4()
linkAddrBytes[0] = 0x1
linkAddrBytes[2] = 0x5e
linkAddrBytes[3] = addr[1] & 0x7F
copy(linkAddrBytes[4:], addr[IPv4AddressSize-2:])
linkAddrBytes[3] = addrBytes[1] & 0x7F
copy(linkAddrBytes[4:], addrBytes[IPv4AddressSize-2:])
return tcpip.LinkAddress(linkAddrBytes[:])
}
@@ -180,7 +181,8 @@ func EthernetAddressFromMulticastIPv6Address(addr tcpip.Address) tcpip.LinkAddre
// transmitted to the Ethernet multicast address whose first
// two octets are the value 3333 hexadecimal and whose last
// four octets are the last four octets of DST.
linkAddrBytes := []byte(addr[IPv6AddressSize-EthernetAddressSize:])
addrBytes := addr.As16()
linkAddrBytes := []byte(addrBytes[IPv6AddressSize-EthernetAddressSize:])
linkAddrBytes[0] = 0x33
linkAddrBytes[1] = 0x33
return tcpip.LinkAddress(linkAddrBytes[:])
+3 -3
View File
@@ -118,7 +118,7 @@ func TestIsMulticastEthernetAddress(t *testing.T) {
func TestEthernetAddressFromMulticastIPv4Address(t *testing.T) {
tests := []struct {
name string
addr tcpip.Address
addr string
expectedLinkAddr tcpip.LinkAddress
}{
{
@@ -135,7 +135,7 @@ func TestEthernetAddressFromMulticastIPv4Address(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if got := EthernetAddressFromMulticastIPv4Address(test.addr); got != test.expectedLinkAddr {
if got := EthernetAddressFromMulticastIPv4Address(tcpip.AddrFrom4Slice([]byte(test.addr))); got != test.expectedLinkAddr {
t.Fatalf("got EthernetAddressFromMulticastIPv4Address(%s) = %s, want = %s", test.addr, got, test.expectedLinkAddr)
}
})
@@ -144,7 +144,7 @@ func TestEthernetAddressFromMulticastIPv4Address(t *testing.T) {
func TestEthernetAddressFromMulticastIPv6Address(t *testing.T) {
addr := testutil.MustParse6("ff02:304:506:708:90a:b0c:d0e:f1a")
if got, want := EthernetAddressFromMulticastIPv6Address(addr), tcpip.LinkAddress("\x33\x33\x0d\x0e\x0f\x1a"); got != want {
if got, want := EthernetAddressFromMulticastIPv6Address(tcpip.AddrFrom16Slice(addr.AsSlice())), tcpip.LinkAddress("\x33\x33\x0d\x0e\x0f\x1a"); got != want {
t.Fatalf("got EthernetAddressFromMulticastIPv6Address(%s) = %s, want = %s", addr, got, want)
}
}
+3 -2
View File
@@ -132,12 +132,13 @@ func (b IGMP) SetChecksum(checksum uint16) {
// GroupAddress gets the Group Address field.
func (b IGMP) GroupAddress() tcpip.Address {
return tcpip.Address(b[igmpGroupAddressOffset:][:IPv4AddressSize])
return tcpip.AddrFrom4([4]byte(b[igmpGroupAddressOffset:][:IPv4AddressSize]))
}
// SetGroupAddress sets the Group Address field.
func (b IGMP) SetGroupAddress(address tcpip.Address) {
if n := copy(b[igmpGroupAddressOffset:], address); n != IPv4AddressSize {
addrBytes := address.As4()
if n := copy(b[igmpGroupAddressOffset:], addrBytes[:]); n != IPv4AddressSize {
panic(fmt.Sprintf("copied %d bytes, expected %d", n, IPv4AddressSize))
}
}
+1 -1
View File
@@ -234,7 +234,7 @@ func TestIGMPv3Query(t *testing.T) {
if got := query.QuerierQueryInterval(); got != qqic.expectedInterval {
t.Errorf("got query.QuerierQueryInterval() = %s, want = %s", got, qqic.expectedInterval)
}
if got, want := query.GroupAddress(), tcpip.Address([]byte{1, 2, 3, 4}); got != want {
if got, want := query.GroupAddress(), tcpip.AddrFrom4([4]byte{1, 2, 3, 4}); got != want {
t.Errorf("got query.GroupAddress() = %s, want = %s", got, want)
}
+8 -5
View File
@@ -23,15 +23,17 @@ import (
"gvisor.dev/gvisor/pkg/tcpip"
)
const (
var (
// IGMPv3RoutersAddress is the address to send IGMPv3 reports to.
//
// As per RFC 3376 section 4.2.14,
//
// Version 3 Reports are sent with an IP destination address of
// 224.0.0.22, to which all IGMPv3-capable multicast routers listen.
IGMPv3RoutersAddress tcpip.Address = "\xe0\x00\x00\x16"
IGMPv3RoutersAddress = tcpip.AddrFrom4([4]byte{0xe0, 0x00, 0x00, 0x16})
)
const (
// IGMPv3QueryMinimumSize is the mimum size of a valid IGMPv3 query,
// as per RFC 3376 section 4.1.
IGMPv3QueryMinimumSize = 12
@@ -116,7 +118,7 @@ func IGMPv3MaximumResponseDelay(codeRaw uint8) time.Duration {
// GroupAddress returns the group address.
func (i IGMPv3Query) GroupAddress() tcpip.Address {
return tcpip.Address(i[igmpv3QueryGroupAddressOffset:][:IPv4AddressSize])
return tcpip.AddrFrom4([4]byte(i[igmpv3QueryGroupAddressOffset:][:IPv4AddressSize]))
}
// QuerierRobustnessVariable returns the querier's robustness variable.
@@ -227,7 +229,8 @@ func (s *IGMPv3ReportGroupAddressRecordSerializer) Length() int {
}
func copyIPv4Address(dst []byte, src tcpip.Address) {
if n := copy(dst, src); n != IPv4AddressSize {
srcBytes := src.As4()
if n := copy(dst, srcBytes[:]); n != IPv4AddressSize {
panic(fmt.Sprintf("got copy(...) = %d, want = %d", n, IPv4AddressSize))
}
}
@@ -387,7 +390,7 @@ func (r IGMPv3ReportGroupAddressRecord) numberOfSources() uint16 {
// GroupAddress returns the multicast address this record targets.
func (r IGMPv3ReportGroupAddressRecord) GroupAddress() tcpip.Address {
return tcpip.Address(r[igmpv3ReportGroupAddressRecordGroupAddressOffset:][:IPv4AddressSize])
return tcpip.AddrFrom4([4]byte(r[igmpv3ReportGroupAddressRecordGroupAddressOffset:][:IPv4AddressSize]))
}
// Sources returns an iterator over source addresses in the query.
+39 -32
View File
@@ -142,26 +142,15 @@ const (
// IPv4AddressSize is the size, in bytes, of an IPv4 address.
IPv4AddressSize = 4
// IPv4AddressSizeBits is the size, in bits, of an IPv4 address.
IPv4AddressSizeBits = 32
// IPv4ProtocolNumber is IPv4's network protocol number.
IPv4ProtocolNumber tcpip.NetworkProtocolNumber = 0x0800
// IPv4Version is the version of the IPv4 protocol.
IPv4Version = 4
// IPv4AllSystems is the all systems IPv4 multicast address as per
// IANA's IPv4 Multicast Address Space Registry. See
// https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml.
IPv4AllSystems tcpip.Address = "\xe0\x00\x00\x01"
// IPv4Broadcast is the broadcast address of the IPv4 procotol.
IPv4Broadcast tcpip.Address = "\xff\xff\xff\xff"
// IPv4Any is the non-routable IPv4 "any" meta address.
IPv4Any tcpip.Address = "\x00\x00\x00\x00"
// IPv4AllRoutersGroup is a multicast address for all routers.
IPv4AllRoutersGroup tcpip.Address = "\xe0\x00\x00\x02"
// IPv4MinimumProcessableDatagramSize is the minimum size of an IP
// packet that every IPv4 capable host must be able to
// process/reassemble.
@@ -175,6 +164,22 @@ const (
IPv4MinimumMTU = 68
)
var (
// IPv4AllSystems is the all systems IPv4 multicast address as per
// IANA's IPv4 Multicast Address Space Registry. See
// https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml.
IPv4AllSystems = tcpip.AddrFrom4([4]byte{0xe0, 0x00, 0x00, 0x01})
// IPv4Broadcast is the broadcast address of the IPv4 procotol.
IPv4Broadcast = tcpip.AddrFrom4([4]byte{0xff, 0xff, 0xff, 0xff})
// IPv4Any is the non-routable IPv4 "any" meta address.
IPv4Any = tcpip.AddrFrom4([4]byte{0x00, 0x00, 0x00, 0x00})
// IPv4AllRoutersGroup is a multicast address for all routers.
IPv4AllRoutersGroup = tcpip.AddrFrom4([4]byte{0xe0, 0x00, 0x00, 0x02})
)
// Flags that may be set in an IPv4 packet.
const (
IPv4FlagMoreFragments = 1 << iota
@@ -184,7 +189,7 @@ const (
// ipv4LinkLocalUnicastSubnet is the IPv4 link local unicast subnet as defined
// by RFC 3927 section 1.
var ipv4LinkLocalUnicastSubnet = func() tcpip.Subnet {
subnet, err := tcpip.NewSubnet("\xa9\xfe\x00\x00", "\xff\xff\x00\x00")
subnet, err := tcpip.NewSubnet(tcpip.AddrFrom4([4]byte{0xa9, 0xfe, 0x00, 0x00}), tcpip.MaskFrom("\xff\xff\x00\x00"))
if err != nil {
panic(err)
}
@@ -194,7 +199,7 @@ var ipv4LinkLocalUnicastSubnet = func() tcpip.Subnet {
// ipv4LinkLocalMulticastSubnet is the IPv4 link local multicast subnet as
// defined by RFC 5771 section 4.
var ipv4LinkLocalMulticastSubnet = func() tcpip.Subnet {
subnet, err := tcpip.NewSubnet("\xe0\x00\x00\x00", "\xff\xff\xff\x00")
subnet, err := tcpip.NewSubnet(tcpip.AddrFrom4([4]byte{0xe0, 0x00, 0x00, 0x00}), tcpip.MaskFrom("\xff\xff\xff\x00"))
if err != nil {
panic(err)
}
@@ -203,7 +208,7 @@ var ipv4LinkLocalMulticastSubnet = func() tcpip.Subnet {
// IPv4EmptySubnet is the empty IPv4 subnet.
var IPv4EmptySubnet = func() tcpip.Subnet {
subnet, err := tcpip.NewSubnet(IPv4Any, tcpip.AddressMask(IPv4Any))
subnet, err := tcpip.NewSubnet(IPv4Any, tcpip.MaskFrom("\x00\x00\x00\x00"))
if err != nil {
panic(err)
}
@@ -228,7 +233,7 @@ var IPv4EmptySubnet = func() tcpip.Subnet {
// | Reserved-by-Protocol | True |
// +----------------------+----------------------------+
var IPv4CurrentNetworkSubnet = func() tcpip.Subnet {
subnet, err := tcpip.NewSubnet(IPv4Any, tcpip.AddressMask("\xff\x00\x00\x00"))
subnet, err := tcpip.NewSubnet(IPv4Any, tcpip.MaskFrom("\xff\x00\x00\x00"))
if err != nil {
panic(err)
}
@@ -237,7 +242,7 @@ var IPv4CurrentNetworkSubnet = func() tcpip.Subnet {
// IPv4LoopbackSubnet is the loopback subnet for IPv4.
var IPv4LoopbackSubnet = func() tcpip.Subnet {
subnet, err := tcpip.NewSubnet(tcpip.Address("\x7f\x00\x00\x00"), tcpip.AddressMask("\xff\x00\x00\x00"))
subnet, err := tcpip.NewSubnet(tcpip.AddrFrom4([4]byte{0x7f, 0x00, 0x00, 0x00}), tcpip.MaskFrom("\xff\x00\x00\x00"))
if err != nil {
panic(err)
}
@@ -332,13 +337,13 @@ func (b IPv4) Checksum() uint16 {
// SourceAddress returns the "source address" field of the IPv4 header.
func (b IPv4) SourceAddress() tcpip.Address {
return tcpip.Address(b[srcAddr : srcAddr+IPv4AddressSize])
return tcpip.AddrFrom4([4]byte(b[srcAddr : srcAddr+IPv4AddressSize]))
}
// DestinationAddress returns the "destination address" field of the IPv4
// header.
func (b IPv4) DestinationAddress() tcpip.Address {
return tcpip.Address(b[dstAddr : dstAddr+IPv4AddressSize])
return tcpip.AddrFrom4([4]byte(b[dstAddr : dstAddr+IPv4AddressSize]))
}
// SetSourceAddressWithChecksumUpdate implements ChecksummableNetwork.
@@ -425,13 +430,13 @@ func (b IPv4) SetID(v uint16) {
// SetSourceAddress sets the "source address" field of the IPv4 header.
func (b IPv4) SetSourceAddress(addr tcpip.Address) {
copy(b[srcAddr:srcAddr+IPv4AddressSize], addr)
copy(b[srcAddr:srcAddr+IPv4AddressSize], addr.AsSlice())
}
// SetDestinationAddress sets the "destination address" field of the IPv4
// header.
func (b IPv4) SetDestinationAddress(addr tcpip.Address) {
copy(b[dstAddr:dstAddr+IPv4AddressSize], addr)
copy(b[dstAddr:dstAddr+IPv4AddressSize], addr.AsSlice())
}
// CalculateChecksum calculates the checksum of the IPv4 header.
@@ -460,8 +465,8 @@ func (b IPv4) Encode(i *IPv4Fields) {
b[ttl] = i.TTL
b[protocol] = i.Protocol
b.SetChecksum(i.Checksum)
copy(b[srcAddr:srcAddr+IPv4AddressSize], i.SrcAddr)
copy(b[dstAddr:dstAddr+IPv4AddressSize], i.DstAddr)
copy(b[srcAddr:srcAddr+IPv4AddressSize], i.SrcAddr.AsSlice())
copy(b[dstAddr:dstAddr+IPv4AddressSize], i.DstAddr.AsSlice())
}
// EncodePartial updates the total length and checksum fields of IPv4 header,
@@ -535,19 +540,21 @@ func (b IPv4) IsChecksumValid() bool {
// address (range 224.0.0.0 to 239.255.255.255). The four most significant bits
// will be 1110 = 0xe0.
func IsV4MulticastAddress(addr tcpip.Address) bool {
if len(addr) != IPv4AddressSize {
if addr.BitLen() != IPv4AddressSizeBits {
return false
}
return (addr[0] & 0xf0) == 0xe0
addrBytes := addr.As4()
return (addrBytes[0] & 0xf0) == 0xe0
}
// IsV4LoopbackAddress determines if the provided address is an IPv4 loopback
// address (belongs to 127.0.0.0/8 subnet). See RFC 1122 section 3.2.1.3.
func IsV4LoopbackAddress(addr tcpip.Address) bool {
if len(addr) != IPv4AddressSize {
if addr.BitLen() != IPv4AddressSizeBits {
return false
}
return addr[0] == 0x7f
addrBytes := addr.As4()
return addrBytes[0] == 0x7f
}
// ========================= Options ==========================
@@ -929,13 +936,13 @@ func (ts *IPv4OptionTimestamp) UpdateTimestamp(addr tcpip.Address, clock tcpip.C
binary.BigEndian.PutUint32(slot, ipv4TimestampTime(clock))
(*ts)[IPv4OptTSPointerOffset] += IPv4OptionTimestampSize
case IPv4OptionTimestampWithIPFlag:
if n := copy(slot, addr); n != IPv4AddressSize {
if n := copy(slot, addr.AsSlice()); n != IPv4AddressSize {
panic(fmt.Sprintf("copied %d bytes, expected %d bytes", n, IPv4AddressSize))
}
binary.BigEndian.PutUint32(slot[IPv4AddressSize:], ipv4TimestampTime(clock))
(*ts)[IPv4OptTSPointerOffset] += IPv4OptionTimestampWithAddrSize
case IPv4OptionTimestampWithPredefinedIPFlag:
if tcpip.Address(slot[:IPv4AddressSize]) == addr {
if tcpip.AddrFrom4([4]byte(slot[:IPv4AddressSize])) == addr {
binary.BigEndian.PutUint32(slot[IPv4AddressSize:], ipv4TimestampTime(clock))
(*ts)[IPv4OptTSPointerOffset] += IPv4OptionTimestampWithAddrSize
}
@@ -987,7 +994,7 @@ func (rr *IPv4OptionRecordRoute) Pointer() uint8 {
func (rr *IPv4OptionRecordRoute) StoreAddress(addr tcpip.Address) {
start := rr.Pointer() - 1 // A one based number.
// start and room checked by caller.
if n := copy((*rr)[start:], addr); n != IPv4AddressSize {
if n := copy((*rr)[start:], addr.AsSlice()); n != IPv4AddressSize {
panic(fmt.Sprintf("copied %d bytes, expected %d bytes", n, IPv4AddressSize))
}
(*rr)[IPv4OptRRPointerOffset] += IPv4AddressSize
+4 -4
View File
@@ -182,7 +182,7 @@ func TestIPv4EncodeOptions(t *testing.T) {
func TestIsV4LinkLocalUnicastAddress(t *testing.T) {
tests := []struct {
name string
addr tcpip.Address
addr string
expected bool
}{
{
@@ -209,7 +209,7 @@ func TestIsV4LinkLocalUnicastAddress(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if got := header.IsV4LinkLocalUnicastAddress(test.addr); got != test.expected {
if got := header.IsV4LinkLocalUnicastAddress(tcpip.AddrFromSlice([]byte(test.addr))); got != test.expected {
t.Errorf("got header.IsV4LinkLocalUnicastAddress(%s) = %t, want = %t", test.addr, got, test.expected)
}
})
@@ -219,7 +219,7 @@ func TestIsV4LinkLocalUnicastAddress(t *testing.T) {
func TestIsV4LinkLocalMulticastAddress(t *testing.T) {
tests := []struct {
name string
addr tcpip.Address
addr string
expected bool
}{
{
@@ -246,7 +246,7 @@ func TestIsV4LinkLocalMulticastAddress(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if got := header.IsV4LinkLocalMulticastAddress(test.addr); got != test.expected {
if got := header.IsV4LinkLocalMulticastAddress(tcpip.AddrFrom4Slice([]byte(test.addr))); got != test.expected {
t.Errorf("got header.IsV4LinkLocalMulticastAddress(%s) = %t, want = %t", test.addr, got, test.expected)
}
})

Some files were not shown because too many files have changed in this diff Show More