Skip to content

Commit 3d33f55

Browse files
committed
TUN-8641: Expose methods to simplify V3 Datagram parsing on the edge
1 parent 589c198 commit 3d33f55

File tree

5 files changed

+37
-11
lines changed

5 files changed

+37
-11
lines changed

quic/v3/datagram.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const (
2727
maxDatagramPayloadLen = 1280
2828
)
2929

30-
func parseDatagramType(data []byte) (DatagramType, error) {
30+
func ParseDatagramType(data []byte) (DatagramType, error) {
3131
if len(data) < datagramTypeLen {
3232
return 0, ErrDatagramHeaderTooSmall
3333
}
@@ -140,7 +140,7 @@ func (s *UDPSessionRegistrationDatagram) MarshalBinary() (data []byte, err error
140140
}
141141

142142
func (s *UDPSessionRegistrationDatagram) UnmarshalBinary(data []byte) error {
143-
datagramType, err := parseDatagramType(data)
143+
datagramType, err := ParseDatagramType(data)
144144
if err != nil {
145145
return err
146146
}
@@ -192,10 +192,10 @@ type UDPSessionPayloadDatagram struct {
192192
}
193193

194194
const (
195-
datagramPayloadHeaderLen = datagramTypeLen + datagramRequestIdLen
195+
DatagramPayloadHeaderLen = datagramTypeLen + datagramRequestIdLen
196196

197197
// The maximum size that a proxied UDP payload can be in a [UDPSessionPayloadDatagram]
198-
maxPayloadPlusHeaderLen = maxDatagramPayloadLen + datagramPayloadHeaderLen
198+
maxPayloadPlusHeaderLen = maxDatagramPayloadLen + DatagramPayloadHeaderLen
199199
)
200200

201201
// The datagram structure for UDPSessionPayloadDatagram is:
@@ -230,7 +230,7 @@ func MarshalPayloadHeaderTo(requestID RequestID, payload []byte) error {
230230
}
231231

232232
func (s *UDPSessionPayloadDatagram) UnmarshalBinary(data []byte) error {
233-
datagramType, err := parseDatagramType(data)
233+
datagramType, err := ParseDatagramType(data)
234234
if err != nil {
235235
return err
236236
}
@@ -332,7 +332,7 @@ func (s *UDPSessionRegistrationResponseDatagram) MarshalBinary() (data []byte, e
332332
}
333333

334334
func (s *UDPSessionRegistrationResponseDatagram) UnmarshalBinary(data []byte) error {
335-
datagramType, err := parseDatagramType(data)
335+
datagramType, err := ParseDatagramType(data)
336336
if err != nil {
337337
return wrapUnmarshalErr(err)
338338
}

quic/v3/muxer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func (c *datagramConn) Serve(ctx context.Context) error {
122122

123123
// Each incoming datagram will be processed in a new go routine to handle the demuxing and action associated.
124124
go func() {
125-
typ, err := parseDatagramType(datagram)
125+
typ, err := ParseDatagramType(datagram)
126126
if err != nil {
127127
c.logger.Err(err).Msgf("unable to parse datagram type: %d", typ)
128128
return

quic/v3/request.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,15 @@ func (id RequestID) MarshalBinaryTo(data []byte) error {
7575
binary.BigEndian.PutUint64(data[8:], id.lo)
7676
return nil
7777
}
78+
79+
func (id *RequestID) UnmarshalBinary(data []byte) error {
80+
if len(data) != 16 {
81+
return fmt.Errorf("invalid length slice provided to unmarshal: %d (expected 16)", len(data))
82+
}
83+
84+
*id = RequestID{
85+
binary.BigEndian.Uint64(data[:8]),
86+
binary.BigEndian.Uint64(data[8:]),
87+
}
88+
return nil
89+
}

quic/v3/request_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"slices"
66
"testing"
77

8+
"github.com/stretchr/testify/require"
9+
810
v3 "github.com/cloudflare/cloudflared/quic/v3"
911
)
1012

@@ -48,3 +50,15 @@ func TestRequestIDParsing(t *testing.T) {
4850
t.Fatalf("buf1 != buf2: %+v %+v", buf1, buf2)
4951
}
5052
}
53+
54+
func TestRequestID_MarshalBinary(t *testing.T) {
55+
buf := make([]byte, 16)
56+
err := testRequestID.MarshalBinaryTo(buf)
57+
require.NoError(t, err)
58+
require.Len(t, buf, 16)
59+
60+
parsed := v3.RequestID{}
61+
err = parsed.UnmarshalBinary(buf)
62+
require.NoError(t, err)
63+
require.Equal(t, testRequestID, parsed)
64+
}

quic/v3/session.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,14 @@ func (s *session) Serve(ctx context.Context) error {
8484
go func() {
8585
// QUIC implementation copies data to another buffer before returning https://github.com/quic-go/quic-go/blob/v0.24.0/session.go#L1967-L1975
8686
// This makes it safe to share readBuffer between iterations
87-
readBuffer := [maxOriginUDPPacketSize + datagramPayloadHeaderLen]byte{}
87+
readBuffer := [maxOriginUDPPacketSize + DatagramPayloadHeaderLen]byte{}
8888
// To perform a zero copy write when passing the datagram to the connection, we prepare the buffer with
8989
// the required datagram header information. We can reuse this buffer for this session since the header is the
9090
// same for the each read.
91-
MarshalPayloadHeaderTo(s.id, readBuffer[:datagramPayloadHeaderLen])
91+
MarshalPayloadHeaderTo(s.id, readBuffer[:DatagramPayloadHeaderLen])
9292
for {
9393
// Read from the origin UDP socket
94-
n, err := s.origin.Read(readBuffer[datagramPayloadHeaderLen:])
94+
n, err := s.origin.Read(readBuffer[DatagramPayloadHeaderLen:])
9595
if errors.Is(err, net.ErrClosed) || errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
9696
s.log.Debug().Msg("Session (origin) connection closed")
9797
}
@@ -109,7 +109,7 @@ func (s *session) Serve(ctx context.Context) error {
109109
}
110110
// Sending a packet to the session does block on the [quic.Connection], however, this is okay because it
111111
// will cause back-pressure to the kernel buffer if the writes are not fast enough to the edge.
112-
err = s.eyeball.SendUDPSessionDatagram(readBuffer[:datagramPayloadHeaderLen+n])
112+
err = s.eyeball.SendUDPSessionDatagram(readBuffer[:DatagramPayloadHeaderLen+n])
113113
if err != nil {
114114
s.closeChan <- err
115115
return

0 commit comments

Comments
 (0)