Skip to content

Commit

Permalink
introduce an API that lets the user get the current datagram size
Browse files Browse the repository at this point in the history
Closes #4259
  • Loading branch information
Constantine Shablia committed Feb 1, 2024
1 parent 4407c60 commit 30dfde0
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 0 deletions.
18 changes: 18 additions & 0 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,8 @@ runLoop:
} else {
sendQueueAvailable = nil
}

s.updateMaxDatagramDataSize()
}

s.cryptoStreamHandler.Close()
Expand Down Expand Up @@ -679,6 +681,22 @@ func (s *connection) ConnectionState() ConnectionState {
return s.connState
}

func (s *connection) updateMaxDatagramDataSize() {
if s.peerParams == nil {
return
}
if !s.supportsDatagrams() {
return
}

maxDatagramFrameSize := min(s.peerParams.MaxDatagramFrameSize, s.packer.MaxPayloadSize(s.mtuDiscoverer.CurrentSize()))
maxDatagramDataSize := (&wire.DatagramFrame{DataLenPresent: true}).MaxDataLen(maxDatagramFrameSize, s.version)

s.connStateMutex.Lock()
s.connState.MaxDatagramSize = int(maxDatagramDataSize)
s.connStateMutex.Unlock()
}

// Time when the connection should time out
func (s *connection) nextIdleTimeoutTime() time.Time {
idleTimeout := max(s.idleTimeout, s.rttStats.PTO(true)*3)
Expand Down
9 changes: 9 additions & 0 deletions interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,15 @@ type ConnectionState struct {
// If datagram support was negotiated, datagrams can be sent and received using the
// SendDatagram and ReceiveDatagram methods on the Connection.
SupportsDatagrams bool
// MaxDatagramSize specifies how big a datagram can be sent using
// SendDatagram. Datagrams bigger than MaxDatagramSize are silently dropped.
//
// Note: MaxDatagramSize can grow or shrink at any time. Users should call
// ConnectionState every once in a while to get up to date MaxDatagramSize.
//
// MaxDatagramSize is zero if datagrams are not supported on this
// connection.
MaxDatagramSize int
// Used0RTT says if 0-RTT resumption was used.
Used0RTT bool
// Version is the QUIC version of the QUIC connection.
Expand Down
38 changes: 38 additions & 0 deletions mock_packer_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions packet_packer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type packer interface {
PackConnectionClose(*qerr.TransportError, protocol.ByteCount, protocol.VersionNumber) (*coalescedPacket, error)
PackApplicationClose(*qerr.ApplicationError, protocol.ByteCount, protocol.VersionNumber) (*coalescedPacket, error)
PackMTUProbePacket(ping ackhandler.Frame, size protocol.ByteCount, v protocol.VersionNumber) (shortHeaderPacket, *packetBuffer, error)
MaxPayloadSize(maxPacketSize protocol.ByteCount) protocol.ByteCount

SetToken([]byte)
}
Expand Down Expand Up @@ -325,6 +326,18 @@ func (p *packetPacker) initialPaddingLen(frames []ackhandler.Frame, currentSize,
return maxPacketSize - currentSize
}

func (p *packetPacker) MaxPayloadSize(maxPacketSize protocol.ByteCount) protocol.ByteCount {
oneRTTSealer, err := p.cryptoSetup.Get1RTTSealer()
if err == nil {
connID := p.getDestConnID()
_, pnLen := p.pnManager.PeekPacketNumber(protocol.Encryption1RTT)
hdrLen := wire.ShortHeaderLen(connID, pnLen)
return maxPacketSize - hdrLen - protocol.ByteCount(oneRTTSealer.Overhead())
}

return 0
}

// PackCoalescedPacket packs a new packet.
// It packs an Initial / Handshake if there is data to send in these packet number spaces.
// It should only be called before the handshake is confirmed.
Expand Down

0 comments on commit 30dfde0

Please sign in to comment.