quinn-rs / quinn

Async-friendly QUIC implementation in Rust
Apache License 2.0
3.76k stars 380 forks source link

How to send big datagram? #1261

Closed go-jar closed 2 years ago

go-jar commented 2 years ago

When I use connection.send_datagram() to send data, the error occured: TooLarge . And I find that the maximum size of datagrams is computed as follows.

    /// Compute the maximum size of datagrams that may passed to `send_datagram`
    ///
    /// Returns `None` if datagrams are unsupported by the peer or disabled locally.
    ///
    /// This may change over the lifetime of a connection according to variation in the path MTU
    /// estimate. The peer can also enforce an arbitrarily small fixed limit, but if the peer's
    /// limit is large this is guaranteed to be a little over a kilobyte at minimum.
    ///
    /// Not necessarily the maximum size of received datagrams.
    pub fn max_size(&self) -> Option<usize> {
        // This is usually 1162 bytes, but we shouldn't document that without a doctest.
        let max_size = self.conn.path.max_udp_payload_size as usize
            - 1                 // flags byte
            - self.conn.rem_cids.active().len()
            - 4                 // worst-case packet number size
            - self.conn.spaces[SpaceId::Data].crypto.as_ref().map_or_else(|| &self.conn.zero_rtt_crypto.as_ref().unwrap().packet, |x| &x.packet.local).tag_len()
            - Datagram::SIZE_BOUND;
        let limit = self
            .conn
            .peer_params
            .max_datagram_frame_size?
            .into_inner()
            .saturating_sub(Datagram::SIZE_BOUND as u64);
        Some(limit.min(max_size as u64) as usize)
    }

But I don't know how to resize max_size and limit to 256000 in the above.

Ralith commented 2 years ago

Unless you are on a very unusual network, you cannot. This is the tradeoff you make with datagrams: your payload must fit within a single packet. If you don't want to deal with that, use a stream.

go-jar commented 2 years ago

Thanks!