Skip to content

Hello, can anyone explain why conn.recv(&mut buf[..len], quiche::RecvInfo { from, to: local }) toke 90% cpu? #2253

@zylthinking

Description

@zylthinking

Hello, I'm writing a QUIC program using quiche and I have two issues that I don't know how to solve:

  1. The line conn.recv(&mut buf[..len], quiche::RecvInfo { from, to: local }) is taking up 90% of the processor time.

  2. If I uncomment these two lines, quiche reports unknownversion; if I comment them out, it runs normally:

        dcid = {
            let mut cid = [8; quiche::MAX_CONN_ID_LEN];
            // let uuid = Uuid::new_v4();
            // cid[..16].copy_from_slice(uuid.into_bytes().as_slice());
            quiche::ConnectionId::from_vec(cid.into())
        };

I understand these issues might not be bugs, but I really have no direction on how to fix them. Can anybody helps
The full code:

async fn quic_poll<'b, 'a: 'b>(
    connections: &'a mut HashMap<ConnectionId<'_>, Connection>,
    config: &mut Config,
    socket: &UdpSocket,
) -> Result<(&'b mut Connection, ConnectionId<'static>, SocketAddr)> {
    let local = socket.local_addr()?;
    let mut buf = [0; 1530];

    let (len, from) = socket.recv_from(&mut buf).await.unwrap();
    let hdr = quiche::Header::from_slice(&mut buf[..len], quiche::MAX_CONN_ID_LEN)?;

    let mut new_conn = None;
    let mut dcid = hdr.dcid.clone();
    if !connections.contains_key(&hdr.dcid) {
        dcid = {
            let mut cid = [8; quiche::MAX_CONN_ID_LEN];
            // let uuid = Uuid::new_v4();
            // cid[..16].copy_from_slice(uuid.into_bytes().as_slice());
            quiche::ConnectionId::from_vec(cid.into())
        };

        match quiche::accept(&dcid, None, local, from, config) {
            Ok(conn) => new_conn = Some(conn),
            Err(e) => {
                socket.send_to(&make_stateless_reset(), from).await?;
                bail!("unexpected {e}");
            }
        }
    }

    let conn = connections
        .entry(dcid.clone())
        .or_insert_with(|| new_conn.unwrap());
    if let Err(e) = conn.recv(&mut buf[..len], quiche::RecvInfo { from, to: local }) {
        connections.remove(&dcid);
        return Err(e.into());
    }

    let conn = connections.get_mut(&dcid).unwrap();
    Ok((conn, dcid, from))
}

The config is

fn config_load() -> Config {
    let mut config = Config::new(quiche::PROTOCOL_VERSION).unwrap();
    config
        .load_cert_chain_from_pem_file("/home/zylthinking/code/test/quic/a.crt")
        .unwrap();
    config
        .load_priv_key_from_pem_file("/home/zylthinking/code/test/quic/a.key")
        .unwrap();
    config.verify_peer(false);
    config.set_application_protos(&[b"any"]).unwrap();
    config.set_max_idle_timeout(5000);
    config.set_initial_max_data(1_000_000);
    config.set_initial_max_stream_data_bidi_local(1_000_000);
    config.set_initial_max_stream_data_bidi_remote(1_000_000);
    config.set_initial_max_streams_bidi(1);
    config.set_initial_max_streams_uni(1);
    config.set_initial_max_stream_data_uni(1_000_000);
    config.set_stateless_reset_token(Some(u128::from_be_bytes(TOKEN.clone())));
    config
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions