use a netip.Addr instead of a net.IP in the packetInfo struct

This commit is contained in:
Marten Seemann 2023-05-13 15:19:58 +03:00
parent b27d114f07
commit 3b5950a1ce
5 changed files with 36 additions and 33 deletions

View file

@ -60,7 +60,7 @@ func (c *sconn) LocalAddr() net.Addr {
if c.info != nil { if c.info != nil {
if udpAddr, ok := addr.(*net.UDPAddr); ok { if udpAddr, ok := addr.(*net.UDPAddr); ok {
addrCopy := *udpAddr addrCopy := *udpAddr
addrCopy.IP = c.info.addr addrCopy.IP = c.info.addr.AsSlice()
addr = &addrCopy addr = &addrCopy
} }
} }

View file

@ -2,7 +2,10 @@
package quic package quic
import "net" import (
"net"
"net/netip"
)
func newConn(c net.PacketConn, supportsDF bool) (*basicConn, error) { func newConn(c net.PacketConn, supportsDF bool) (*basicConn, error) {
return &basicConn{PacketConn: c, supportsDF: supportsDF}, nil return &basicConn{PacketConn: c, supportsDF: supportsDF}, nil
@ -12,7 +15,7 @@ func inspectReadBuffer(any) (int, error) { return 0, nil }
func inspectWriteBuffer(any) (int, error) { return 0, nil } func inspectWriteBuffer(any) (int, error) { return 0, nil }
type packetInfo struct { type packetInfo struct {
addr net.IP addr netip.Addr
} }
func (i *packetInfo) OOB() []byte { return nil } func (i *packetInfo) OOB() []byte { return nil }

View file

@ -7,6 +7,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"net" "net"
"net/netip"
"syscall" "syscall"
"time" "time"
@ -173,8 +174,7 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) {
data := msg.OOB[:msg.NN] data := msg.OOB[:msg.NN]
var ecn protocol.ECN var ecn protocol.ECN
var destIP net.IP var info *packetInfo
var ifIndex uint32
for len(data) > 0 { for len(data) > 0 {
hdr, body, remainder, err := unix.ParseOneSocketControlMessage(data) hdr, body, remainder, err := unix.ParseOneSocketControlMessage(data)
if err != nil { if err != nil {
@ -191,15 +191,16 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) {
// struct in_addr ipi_addr; /* Header Destination // struct in_addr ipi_addr; /* Header Destination
// address */ // address */
// }; // };
ip := make([]byte, 4) info = &packetInfo{}
var ip [4]byte
if len(body) == 12 { if len(body) == 12 {
ifIndex = binary.LittleEndian.Uint32(body) copy(ip[:], body[8:12])
copy(ip, body[8:12]) info.ifIndex = binary.LittleEndian.Uint32(body)
} else if len(body) == 4 { } else if len(body) == 4 {
// FreeBSD // FreeBSD
copy(ip, body) copy(ip[:], body)
} }
destIP = net.IP(ip) info.addr = netip.AddrFrom4(ip)
} }
} }
if hdr.Level == unix.IPPROTO_IPV6 { if hdr.Level == unix.IPPROTO_IPV6 {
@ -212,22 +213,17 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) {
// unsigned int ipi6_ifindex; /* send/recv interface index */ // unsigned int ipi6_ifindex; /* send/recv interface index */
// }; // };
if len(body) == 20 { if len(body) == 20 {
ip := make([]byte, 16) var ip [16]byte
copy(ip, body[:16]) copy(ip[:], body[:16])
destIP = net.IP(ip) info = &packetInfo{
ifIndex = binary.LittleEndian.Uint32(body[16:]) addr: netip.AddrFrom16(ip),
ifIndex: binary.LittleEndian.Uint32(body[16:]),
}
} }
} }
} }
data = remainder data = remainder
} }
var info *packetInfo
if destIP != nil {
info = &packetInfo{
addr: destIP,
ifIndex: ifIndex,
}
}
return receivedPacket{ return receivedPacket{
remoteAddr: msg.Addr, remoteAddr: msg.Addr,
rcvTime: time.Now(), rcvTime: time.Now(),
@ -265,7 +261,7 @@ func (c *oobConn) capabilities() connCapabilities {
} }
type packetInfo struct { type packetInfo struct {
addr net.IP addr netip.Addr
ifIndex uint32 ifIndex uint32
} }
@ -273,24 +269,26 @@ func (info *packetInfo) OOB() []byte {
if info == nil { if info == nil {
return nil return nil
} }
if ip4 := info.addr.To4(); ip4 != nil { if info.addr.Is4() {
ip := info.addr.As4()
// struct in_pktinfo { // struct in_pktinfo {
// unsigned int ipi_ifindex; /* Interface index */ // unsigned int ipi_ifindex; /* Interface index */
// struct in_addr ipi_spec_dst; /* Local address */ // struct in_addr ipi_spec_dst; /* Local address */
// struct in_addr ipi_addr; /* Header Destination address */ // struct in_addr ipi_addr; /* Header Destination address */
// }; // };
cm := ipv4.ControlMessage{ cm := ipv4.ControlMessage{
Src: ip4, Src: ip[:],
IfIndex: int(info.ifIndex), IfIndex: int(info.ifIndex),
} }
return cm.Marshal() return cm.Marshal()
} else if len(info.addr) == 16 { } else if info.addr.Is6() {
ip := info.addr.As16()
// struct in6_pktinfo { // struct in6_pktinfo {
// struct in6_addr ipi6_addr; /* src/dst IPv6 address */ // struct in6_addr ipi6_addr; /* src/dst IPv6 address */
// unsigned int ipi6_ifindex; /* send/recv interface index */ // unsigned int ipi6_ifindex; /* send/recv interface index */
// }; // };
cm := ipv6.ControlMessage{ cm := ipv6.ControlMessage{
Src: info.addr, Src: ip[:],
IfIndex: int(info.ifIndex), IfIndex: int(info.ifIndex),
} }
return cm.Marshal() return cm.Marshal()

View file

@ -155,7 +155,7 @@ var _ = Describe("OOB Conn Test", func() {
Expect(p.data).To(Equal([]byte("foobar"))) Expect(p.data).To(Equal([]byte("foobar")))
Expect(p.remoteAddr).To(Equal(sentFrom)) Expect(p.remoteAddr).To(Equal(sentFrom))
Expect(p.info).To(Not(BeNil())) Expect(p.info).To(Not(BeNil()))
Expect(p.info.addr.To4()).To(Equal(ip)) Expect(net.IP(p.info.addr.AsSlice())).To(Equal(ip))
}) })
It("reads packet info on IPv6", func() { It("reads packet info on IPv6", func() {
@ -173,7 +173,7 @@ var _ = Describe("OOB Conn Test", func() {
Expect(p.data).To(Equal([]byte("foobar"))) Expect(p.data).To(Equal([]byte("foobar")))
Expect(p.remoteAddr).To(Equal(sentFrom)) Expect(p.remoteAddr).To(Equal(sentFrom))
Expect(p.info).To(Not(BeNil())) Expect(p.info).To(Not(BeNil()))
Expect(p.info.addr).To(Equal(ip)) Expect(net.IP(p.info.addr.AsSlice())).To(Equal(ip))
}) })
It("reads packet info on a connection that supports both IPv4 and IPv6", func() { It("reads packet info on a connection that supports both IPv4 and IPv6", func() {
@ -182,14 +182,16 @@ var _ = Describe("OOB Conn Test", func() {
port := conn.LocalAddr().(*net.UDPAddr).Port port := conn.LocalAddr().(*net.UDPAddr).Port
// IPv4 // IPv4
ip4 := net.ParseIP("127.0.0.1").To4() ip4 := net.ParseIP("127.0.0.1")
sendPacket("udp4", &net.UDPAddr{IP: ip4, Port: port}) sendPacket("udp4", &net.UDPAddr{IP: ip4, Port: port})
var p receivedPacket var p receivedPacket
Eventually(packetChan).Should(Receive(&p)) Eventually(packetChan).Should(Receive(&p))
Expect(utils.IsIPv4(p.remoteAddr.(*net.UDPAddr).IP)).To(BeTrue()) Expect(utils.IsIPv4(p.remoteAddr.(*net.UDPAddr).IP)).To(BeTrue())
Expect(p.info).To(Not(BeNil())) Expect(p.info).To(Not(BeNil()))
Expect(p.info.addr.To4()).To(Equal(ip4)) Expect(p.info.addr.Is4In6() || p.info.addr.Is4()).To(BeTrue())
ip := p.info.addr.As4()
Expect(net.IP(ip[:])).To(Equal(ip4.To4()))
// IPv6 // IPv6
ip6 := net.ParseIP("::1") ip6 := net.ParseIP("::1")
@ -198,7 +200,7 @@ var _ = Describe("OOB Conn Test", func() {
Eventually(packetChan).Should(Receive(&p)) Eventually(packetChan).Should(Receive(&p))
Expect(utils.IsIPv4(p.remoteAddr.(*net.UDPAddr).IP)).To(BeFalse()) Expect(utils.IsIPv4(p.remoteAddr.(*net.UDPAddr).IP)).To(BeFalse())
Expect(p.info).To(Not(BeNil())) Expect(p.info).To(Not(BeNil()))
Expect(p.info.addr).To(Equal(ip6)) Expect(net.IP(p.info.addr.AsSlice())).To(Equal(ip6))
}) })
}) })

View file

@ -3,7 +3,7 @@
package quic package quic
import ( import (
"net" "net/netip"
"syscall" "syscall"
"golang.org/x/sys/windows" "golang.org/x/sys/windows"
@ -36,7 +36,7 @@ func inspectWriteBuffer(c syscall.RawConn) (int, error) {
} }
type packetInfo struct { type packetInfo struct {
addr net.IP addr netip.Addr
} }
func (i *packetInfo) OOB() []byte { return nil } func (i *packetInfo) OOB() []byte { return nil }