wire: use netip.AddrPort to encode the IPs in the Preferred Address (#4232)

This commit is contained in:
Marten Seemann 2024-01-03 12:56:25 +07:00 committed by GitHub
parent 59ed51704a
commit 8cad3d2ea5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 38 additions and 48 deletions

View file

@ -9,6 +9,7 @@ import (
"fmt"
"io"
"net"
"net/netip"
"runtime/pprof"
"strings"
"time"
@ -2940,8 +2941,8 @@ var _ = Describe("Client Connection", func() {
OriginalDestinationConnectionID: destConnID,
InitialSourceConnectionID: destConnID,
PreferredAddress: &wire.PreferredAddress{
IPv4: net.IPv4(127, 0, 0, 1),
IPv6: net.IP{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
IPv4: netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 1}), 42),
IPv6: netip.AddrPortFrom(netip.AddrFrom16([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), 13),
ConnectionID: protocol.ParseConnectionID([]byte{1, 2, 3, 4}),
StatelessResetToken: protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
},

View file

@ -3,7 +3,7 @@ package main
import (
"log"
"math"
"net"
"net/netip"
"time"
"golang.org/x/exp/rand"
@ -59,11 +59,13 @@ func main() {
if rand.Int()%2 == 0 {
var token protocol.StatelessResetToken
rand.Read(token[:])
var ip4 [4]byte
rand.Read(ip4[:])
var ip6 [16]byte
rand.Read(ip6[:])
tp.PreferredAddress = &wire.PreferredAddress{
IPv4: net.IPv4(uint8(rand.Int()), uint8(rand.Int()), uint8(rand.Int()), uint8(rand.Int())),
IPv4Port: uint16(rand.Int()),
IPv6: net.IP(getRandomData(16)),
IPv6Port: uint16(rand.Int()),
IPv4: netip.AddrPortFrom(netip.AddrFrom4(ip4), uint16(rand.Int())),
IPv6: netip.AddrPortFrom(netip.AddrFrom16(ip6), uint16(rand.Int())),
ConnectionID: protocol.ParseConnectionID(getRandomData(rand.Intn(21))),
StatelessResetToken: token,
}

View file

@ -4,7 +4,7 @@ import (
"bytes"
"fmt"
"math"
"net"
"net/netip"
"time"
"golang.org/x/exp/rand"
@ -425,10 +425,8 @@ var _ = Describe("Transport Parameters", func() {
BeforeEach(func() {
pa = &PreferredAddress{
IPv4: net.IPv4(127, 0, 0, 1),
IPv4Port: 42,
IPv6: net.IP{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
IPv6Port: 13,
IPv4: netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 1}), 42),
IPv6: netip.AddrPortFrom(netip.AddrFrom16([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), 13),
ConnectionID: protocol.ParseConnectionID([]byte{0xde, 0xad, 0xbe, 0xef}),
StatelessResetToken: protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
}
@ -442,10 +440,8 @@ var _ = Describe("Transport Parameters", func() {
}).Marshal(protocol.PerspectiveServer)
p := &TransportParameters{}
Expect(p.Unmarshal(data, protocol.PerspectiveServer)).To(Succeed())
Expect(p.PreferredAddress.IPv4.String()).To(Equal(pa.IPv4.String()))
Expect(p.PreferredAddress.IPv4Port).To(Equal(pa.IPv4Port))
Expect(p.PreferredAddress.IPv6.String()).To(Equal(pa.IPv6.String()))
Expect(p.PreferredAddress.IPv6Port).To(Equal(pa.IPv6Port))
Expect(p.PreferredAddress.IPv4).To(Equal(pa.IPv4))
Expect(p.PreferredAddress.IPv6).To(Equal(pa.IPv6))
Expect(p.PreferredAddress.ConnectionID).To(Equal(pa.ConnectionID))
Expect(p.PreferredAddress.StatelessResetToken).To(Equal(pa.StatelessResetToken))
})

View file

@ -7,7 +7,7 @@ import (
"errors"
"fmt"
"io"
"net"
"net/netip"
"sort"
"time"
@ -51,10 +51,7 @@ const (
// PreferredAddress is the value encoding in the preferred_address transport parameter
type PreferredAddress struct {
IPv4 net.IP
IPv4Port uint16
IPv6 net.IP
IPv6Port uint16
IPv4, IPv6 netip.AddrPort
ConnectionID protocol.ConnectionID
StatelessResetToken protocol.StatelessResetToken
}
@ -218,26 +215,24 @@ func (p *TransportParameters) unmarshal(r *bytes.Reader, sentBy protocol.Perspec
func (p *TransportParameters) readPreferredAddress(r *bytes.Reader, expectedLen int) error {
remainingLen := r.Len()
pa := &PreferredAddress{}
ipv4 := make([]byte, 4)
if _, err := io.ReadFull(r, ipv4); err != nil {
var ipv4 [4]byte
if _, err := io.ReadFull(r, ipv4[:]); err != nil {
return err
}
pa.IPv4 = net.IP(ipv4)
port, err := utils.BigEndian.ReadUint16(r)
if err != nil {
return err
}
pa.IPv4Port = port
ipv6 := make([]byte, 16)
if _, err := io.ReadFull(r, ipv6); err != nil {
pa.IPv4 = netip.AddrPortFrom(netip.AddrFrom4(ipv4), port)
var ipv6 [16]byte
if _, err := io.ReadFull(r, ipv6[:]); err != nil {
return err
}
pa.IPv6 = net.IP(ipv6)
port, err = utils.BigEndian.ReadUint16(r)
if err != nil {
return err
}
pa.IPv6Port = port
pa.IPv6 = netip.AddrPortFrom(netip.AddrFrom16(ipv6), port)
connIDLen, err := r.ReadByte()
if err != nil {
return err
@ -384,13 +379,12 @@ func (p *TransportParameters) Marshal(pers protocol.Perspective) []byte {
if p.PreferredAddress != nil {
b = quicvarint.Append(b, uint64(preferredAddressParameterID))
b = quicvarint.Append(b, 4+2+16+2+1+uint64(p.PreferredAddress.ConnectionID.Len())+16)
ipv4 := p.PreferredAddress.IPv4
b = append(b, ipv4[len(ipv4)-4:]...)
b = append(b, []byte{0, 0}...)
binary.BigEndian.PutUint16(b[len(b)-2:], p.PreferredAddress.IPv4Port)
b = append(b, p.PreferredAddress.IPv6...)
b = append(b, []byte{0, 0}...)
binary.BigEndian.PutUint16(b[len(b)-2:], p.PreferredAddress.IPv6Port)
ip4 := p.PreferredAddress.IPv4.Addr().As4()
b = append(b, ip4[:]...)
b = binary.BigEndian.AppendUint16(b, p.PreferredAddress.IPv4.Port())
ip6 := p.PreferredAddress.IPv6.Addr().As16()
b = append(b, ip6[:]...)
b = binary.BigEndian.AppendUint16(b, p.PreferredAddress.IPv6.Port())
b = append(b, uint8(p.PreferredAddress.ConnectionID.Len()))
b = append(b, p.PreferredAddress.ConnectionID.Bytes()...)
b = append(b, p.PreferredAddress.StatelessResetToken[:]...)

View file

@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"net"
"net/netip"
"time"
"github.com/quic-go/quic-go"
@ -456,8 +457,7 @@ func (e eventTransportParameters) MarshalJSONObject(enc *gojay.Encoder) {
}
type preferredAddress struct {
IPv4, IPv6 net.IP
PortV4, PortV6 uint16
IPv4, IPv6 netip.AddrPort
ConnectionID protocol.ConnectionID
StatelessResetToken protocol.StatelessResetToken
}
@ -466,10 +466,10 @@ var _ gojay.MarshalerJSONObject = &preferredAddress{}
func (a preferredAddress) IsNil() bool { return false }
func (a preferredAddress) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("ip_v4", a.IPv4.String())
enc.Uint16Key("port_v4", a.PortV4)
enc.StringKey("ip_v6", a.IPv6.String())
enc.Uint16Key("port_v6", a.PortV6)
enc.StringKey("ip_v4", a.IPv4.Addr().String())
enc.Uint16Key("port_v4", a.IPv4.Port())
enc.StringKey("ip_v6", a.IPv6.Addr().String())
enc.Uint16Key("port_v6", a.IPv6.Port())
enc.StringKey("connection_id", a.ConnectionID.String())
enc.StringKey("stateless_reset_token", fmt.Sprintf("%x", a.StatelessResetToken))
}

View file

@ -304,9 +304,7 @@ func (t *connectionTracer) toTransportParameters(tp *wire.TransportParameters) *
if tp.PreferredAddress != nil {
pa = &preferredAddress{
IPv4: tp.PreferredAddress.IPv4,
PortV4: tp.PreferredAddress.IPv4Port,
IPv6: tp.PreferredAddress.IPv6,
PortV6: tp.PreferredAddress.IPv6Port,
ConnectionID: tp.PreferredAddress.ConnectionID,
StatelessResetToken: tp.PreferredAddress.StatelessResetToken,
}

View file

@ -7,6 +7,7 @@ import (
"io"
"log"
"net"
"net/netip"
"os"
"time"
@ -338,10 +339,8 @@ var _ = Describe("Tracing", func() {
It("records transport parameters with a preferred address", func() {
tracer.SentTransportParameters(&logging.TransportParameters{
PreferredAddress: &logging.PreferredAddress{
IPv4: net.IPv4(12, 34, 56, 78),
IPv4Port: 123,
IPv6: net.IP{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
IPv6Port: 456,
IPv4: netip.AddrPortFrom(netip.AddrFrom4([4]byte{12, 34, 56, 78}), 123),
IPv6: netip.AddrPortFrom(netip.AddrFrom16([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), 456),
ConnectionID: protocol.ParseConnectionID([]byte{8, 7, 6, 5, 4, 3, 2, 1}),
StatelessResetToken: protocol.StatelessResetToken{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
},