Skip to content

Commit

Permalink
include the maximum payload size in the DatagramTooLargeError (#4470)
Browse files Browse the repository at this point in the history
This is more useful than the maximum frame size. The user of the library
shouldn't have to care about the QUIC framing layer.

---------

Co-authored-by: 世界 <i@sekai.icu>
  • Loading branch information
marten-seemann and nekohasekai committed Apr 27, 2024
1 parent 34f4d14 commit c0250ce
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 6 deletions.
7 changes: 3 additions & 4 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -2358,10 +2358,9 @@ func (s *connection) SendDatagram(p []byte) error {
}

f := &wire.DatagramFrame{DataLenPresent: true}
if protocol.ByteCount(len(p)) > f.MaxDataLen(s.peerParams.MaxDatagramFrameSize, s.version) {
return &DatagramTooLargeError{
PeerMaxDatagramFrameSize: int64(s.peerParams.MaxDatagramFrameSize),
}
maxDataLen := f.MaxDataLen(s.peerParams.MaxDatagramFrameSize, s.version)
if protocol.ByteCount(len(p)) > maxDataLen {
return &DatagramTooLargeError{MaxDatagramPayloadSize: int64(maxDataLen)}
}
f.Data = make([]byte, len(p))
copy(f.Data, p)
Expand Down
34 changes: 34 additions & 0 deletions connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2477,6 +2477,40 @@ var _ = Describe("Connection", func() {
})
})

Context("datagrams", func() {
It("doesn't allow datagrams if the peer didn't enable support", func() {
conn.peerParams = &wire.TransportParameters{MaxDatagramFrameSize: 0}
Expect(conn.SendDatagram(make([]byte, 200))).To(MatchError("datagram support disabled"))
})

It("sends a datagram", func() {
conn.peerParams = &wire.TransportParameters{MaxDatagramFrameSize: 1000}
Expect(conn.SendDatagram([]byte("foobar"))).To(Succeed())
f := conn.datagramQueue.Peek()
Expect(f).ToNot(BeNil())
Expect(f.Data).To(Equal([]byte("foobar")))
})

It("says when a datagram is too big", func() {
conn.peerParams = &wire.TransportParameters{MaxDatagramFrameSize: 1000}
err := conn.SendDatagram(make([]byte, 2000))
Expect(err).To(HaveOccurred())
Expect(err).To(BeAssignableToTypeOf(&DatagramTooLargeError{}))
derr := err.(*DatagramTooLargeError)
Expect(derr.MaxDatagramPayloadSize).To(BeNumerically("<", 1000))
fmt.Println(derr.MaxDatagramPayloadSize)
Expect(conn.SendDatagram(make([]byte, derr.MaxDatagramPayloadSize))).To(Succeed())
})

It("receives datagrams", func() {
conn.config.EnableDatagrams = true
conn.datagramQueue.HandleDatagramFrame(&wire.DatagramFrame{Data: []byte("foobar")})
data, err := conn.ReceiveDatagram(context.Background())
Expect(err).ToNot(HaveOccurred())
Expect(data).To(Equal([]byte("foobar")))
})
})

It("returns the local address", func() {
Expect(conn.LocalAddr()).To(Equal(localAddr))
})
Expand Down
2 changes: 1 addition & 1 deletion errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (e *StreamError) Error() string {

// DatagramTooLargeError is returned from Connection.SendDatagram if the payload is too large to be sent.
type DatagramTooLargeError struct {
PeerMaxDatagramFrameSize int64
MaxDatagramPayloadSize int64
}

func (e *DatagramTooLargeError) Is(target error) bool {
Expand Down
2 changes: 1 addition & 1 deletion integrationtests/self/datagram_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ var _ = Describe("Datagram test", func() {
maxDatagramMessageSize := f.MaxDataLen(maxDatagramSize, conn.ConnectionState().Version)
b := make([]byte, maxDatagramMessageSize+1)
Expect(conn.SendDatagram(b)).To(MatchError(&quic.DatagramTooLargeError{
PeerMaxDatagramFrameSize: int64(maxDatagramMessageSize),
MaxDatagramPayloadSize: int64(maxDatagramMessageSize),
}))
wg.Wait()
}
Expand Down

0 comments on commit c0250ce

Please sign in to comment.