Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b803fce3 authored by Mike Yu's avatar Mike Yu Committed by Automerger Merge Worker
Browse files

Merge "Test: Use 8-bytes of dcid as connection ID" am: 40bff9c6

parents d7963f23 40bff9c6
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ rust_ffi_static {
        "libandroid_logger",
        "libanyhow",
        "libquiche",
        "libring",
        "liblazy_static",
        "libtokio",
        "libbase64_rust",
+32 −33
Original line number Diff line number Diff line
@@ -19,8 +19,6 @@
use anyhow::{anyhow, bail, ensure, Result};
use log::{debug, error, info, warn};
use quiche::h3::NameValue;
use ring::hmac;
use ring::rand::SystemRandom;
use std::collections::{hash_map, HashMap};
use std::net::SocketAddr;
use std::pin::Pin;
@@ -28,6 +26,7 @@ use std::time::Duration;

pub const DNS_HEADER_SIZE: usize = 12;
pub const MAX_UDP_PAYLOAD_SIZE: usize = 1350;
pub const CONN_ID_LEN: usize = 8;

pub type ConnectionID = Vec<u8>;

@@ -247,18 +246,12 @@ impl std::fmt::Debug for Client {

pub struct ClientMap {
    clients: HashMap<ConnectionID, Client>,
    conn_id_seed: hmac::Key,
    config: quiche::Config,
}

impl ClientMap {
    pub fn new(config: quiche::Config) -> Result<ClientMap> {
        let conn_id_seed = match hmac::Key::generate(hmac::HMAC_SHA256, &SystemRandom::new()) {
            Ok(v) => v,
            Err(e) => bail!("Failed to generate a seed: {}", e),
        };

        Ok(ClientMap { clients: HashMap::new(), conn_id_seed, config })
        Ok(ClientMap { clients: HashMap::new(), config })
    }

    pub fn get_or_create(
@@ -266,27 +259,26 @@ impl ClientMap {
        hdr: &quiche::Header,
        addr: &SocketAddr,
    ) -> Result<&mut Client> {
        let dcid = hdr.dcid.as_ref().to_vec();
        let client = if !self.clients.contains_key(&dcid) {
        let conn_id = get_conn_id(hdr)?;
        let client = match self.clients.entry(conn_id.clone()) {
            hash_map::Entry::Occupied(client) => client.into_mut(),
            hash_map::Entry::Vacant(vacant) => {
                ensure!(hdr.ty == quiche::Type::Initial, "Packet is not Initial");
            ensure!(quiche::version_is_supported(hdr.version), "Protocol version not supported");

            let scid = generate_conn_id(&self.conn_id_seed, &dcid);
                ensure!(
                    quiche::version_is_supported(hdr.version),
                    "Protocol version not supported"
                );
                let conn = quiche::accept(
                &quiche::ConnectionId::from_ref(&scid),
                    &quiche::ConnectionId::from_ref(&conn_id),
                    None, /* odcid */
                    *addr,
                    &mut self.config,
                )?;
            let client = Client::new(conn, addr, scid.clone());

                let client = Client::new(conn, addr, conn_id.clone());
                info!("New client: {:?}", client);
            self.clients.insert(scid.clone(), client);
            self.clients.get_mut(&scid).unwrap()
        } else {
            self.clients.get_mut(&dcid).unwrap()
                vacant.insert(client)
            }
        };

        Ok(client)
    }

@@ -307,8 +299,15 @@ impl ClientMap {
    }
}

fn generate_conn_id(conn_id_seed: &hmac::Key, dcid: &[u8]) -> ConnectionID {
    let conn_id = hmac::sign(conn_id_seed, dcid);
    let conn_id = &conn_id.as_ref()[..quiche::MAX_CONN_ID_LEN];
    conn_id.to_vec()
// Per RFC 9000 section 7.2, an Initial packet's dcid from a new client must be
// at least 8 bytes in length. We use the first 8 bytes of dcid as new connection
// ID to identify the client.
// This is helpful to identify 0-RTT packets. In 0-RTT handshake, 0-RTT packets
// are followed after the Initial packet with the same dcid. With this function, we
// know which 0-RTT packets belong to which client.
fn get_conn_id(hdr: &quiche::Header) -> Result<ConnectionID> {
    if let Some(v) = hdr.dcid.as_ref().get(0..CONN_ID_LEN) {
        return Ok(v.to_vec());
    }
    bail!("QUIC packet {:?} dcid too small", hdr.ty)
}
+2 −2
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

//! DoH server frontend.

use crate::client::{ClientMap, ConnectionID, DNS_HEADER_SIZE, MAX_UDP_PAYLOAD_SIZE};
use crate::client::{ClientMap, ConnectionID, CONN_ID_LEN, DNS_HEADER_SIZE, MAX_UDP_PAYLOAD_SIZE};
use crate::config::{Config, QUICHE_IDLE_TIMEOUT_MS};
use crate::stats::Stats;
use anyhow::{bail, ensure, Result};
@@ -309,7 +309,7 @@ async fn worker_thread(params: WorkerParams) -> Result<()> {

                // Parse QUIC packet.
                let pkt_buf = &mut frontend_buf[..len];
                let hdr = match quiche::Header::from_slice(pkt_buf, quiche::MAX_CONN_ID_LEN) {
                let hdr = match quiche::Header::from_slice(pkt_buf, CONN_ID_LEN) {
                    Ok(v) => v,
                    Err(e) => {
                        error!("Failed to parse QUIC header: {:?}", e);