diff --git a/connection.go b/connection.go index 9c8821d91..b1e9aaee3 100644 --- a/connection.go +++ b/connection.go @@ -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) diff --git a/connection_test.go b/connection_test.go index c6d9d24ef..7f9468d95 100644 --- a/connection_test.go +++ b/connection_test.go @@ -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)) }) diff --git a/errors.go b/errors.go index fda3c9247..3fe1e0a90 100644 --- a/errors.go +++ b/errors.go @@ -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 { diff --git a/integrationtests/self/datagram_test.go b/integrationtests/self/datagram_test.go index f9608272b..1b4f0efde 100644 --- a/integrationtests/self/datagram_test.go +++ b/integrationtests/self/datagram_test.go @@ -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() }