mirror of
https://github.com/n0-computer/noq.git
synced 2026-09-22 11:13:44 +00:00
Always pass all datagram contents to Connection in one go
This commit is contained in:
@@ -3,7 +3,7 @@ use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use std::{cmp, io, mem};
|
||||
|
||||
use bytes::{Buf, Bytes};
|
||||
use bytes::{Buf, Bytes, BytesMut};
|
||||
use err_derive::Error;
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use rand::{rngs::OsRng, Rng};
|
||||
@@ -816,9 +816,11 @@ impl Connection {
|
||||
pub fn handle_initial(
|
||||
&mut self,
|
||||
now: u64,
|
||||
remote: SocketAddr,
|
||||
ecn: Option<EcnCodepoint>,
|
||||
packet_number: u64,
|
||||
packet: Packet,
|
||||
remaining: Option<BytesMut>,
|
||||
) -> Result<(), TransportError> {
|
||||
let len = packet.header_data.len() + packet.payload.len();
|
||||
self.on_packet_authenticated(now, SpaceId::Initial, ecn, Some(packet_number), false, len);
|
||||
@@ -833,6 +835,7 @@ impl Connection {
|
||||
self.set_params(params)?;
|
||||
self.write_tls();
|
||||
self.init_0rtt();
|
||||
self.handle_coalesced(now, remote, ecn, remaining);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -963,12 +966,13 @@ impl Connection {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_decode(
|
||||
pub fn handle_dgram(
|
||||
&mut self,
|
||||
now: u64,
|
||||
remote: SocketAddr,
|
||||
ecn: Option<EcnCodepoint>,
|
||||
partial_decode: PartialDecode,
|
||||
first_decode: PartialDecode,
|
||||
remaining: Option<BytesMut>,
|
||||
) {
|
||||
if remote != self.remote && self.side.is_client() {
|
||||
trace!(
|
||||
@@ -978,6 +982,39 @@ impl Connection {
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
self.handle_decode(now, remote, ecn, first_decode);
|
||||
self.handle_coalesced(now, remote, ecn, remaining);
|
||||
}
|
||||
|
||||
fn handle_coalesced(
|
||||
&mut self,
|
||||
now: u64,
|
||||
remote: SocketAddr,
|
||||
ecn: Option<EcnCodepoint>,
|
||||
mut remaining: Option<BytesMut>,
|
||||
) {
|
||||
while let Some(data) = remaining {
|
||||
match PartialDecode::new(data, self.config.local_cid_len) {
|
||||
Ok((partial_decode, rest)) => {
|
||||
remaining = rest;
|
||||
self.handle_decode(now, remote, ecn, partial_decode);
|
||||
}
|
||||
Err(e) => {
|
||||
trace!(self.log, "malformed header"; "reason" => %e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_decode(
|
||||
&mut self,
|
||||
now: u64,
|
||||
remote: SocketAddr,
|
||||
ecn: Option<EcnCodepoint>,
|
||||
partial_decode: PartialDecode,
|
||||
) {
|
||||
let header_crypto = if partial_decode.is_0rtt() {
|
||||
if let Some(ref crypto) = self.zero_rtt_crypto {
|
||||
Some(&crypto.header)
|
||||
|
||||
+40
-47
@@ -145,55 +145,40 @@ impl Endpoint {
|
||||
data: BytesMut,
|
||||
) {
|
||||
let datagram_len = data.len();
|
||||
let mut remaining = Some(data);
|
||||
while let Some(data) = remaining {
|
||||
match PartialDecode::new(data, self.config.local_cid_len) {
|
||||
Ok((partial_decode, rest)) => {
|
||||
remaining = rest;
|
||||
self.handle_decode(now, remote, ecn, partial_decode, datagram_len);
|
||||
}
|
||||
Err(PacketDecodeError::UnsupportedVersion {
|
||||
source,
|
||||
destination,
|
||||
}) => {
|
||||
if !self.is_server() {
|
||||
debug!(self.log, "dropping packet with unsupported version");
|
||||
return;
|
||||
}
|
||||
trace!(self.log, "sending version negotiation");
|
||||
// Negotiate versions
|
||||
let mut buf = Vec::<u8>::new();
|
||||
Header::VersionNegotiate {
|
||||
random: self.rng.gen(),
|
||||
src_cid: destination,
|
||||
dst_cid: source,
|
||||
}
|
||||
.encode(&mut buf);
|
||||
buf.write::<u32>(0x0a1a_2a3a); // reserved version
|
||||
buf.write(VERSION); // supported version
|
||||
self.io.push_back(Io::Transmit {
|
||||
destination: remote,
|
||||
ecn: None,
|
||||
packet: buf.into(),
|
||||
});
|
||||
let (partial_decode, rest) = match PartialDecode::new(data, self.config.local_cid_len) {
|
||||
Ok(x) => x,
|
||||
Err(PacketDecodeError::UnsupportedVersion {
|
||||
source,
|
||||
destination,
|
||||
}) => {
|
||||
if !self.is_server() {
|
||||
debug!(self.log, "dropping packet with unsupported version");
|
||||
return;
|
||||
}
|
||||
Err(e) => {
|
||||
trace!(self.log, "malformed header"; "reason" => %e);
|
||||
return;
|
||||
trace!(self.log, "sending version negotiation");
|
||||
// Negotiate versions
|
||||
let mut buf = Vec::<u8>::new();
|
||||
Header::VersionNegotiate {
|
||||
random: self.rng.gen(),
|
||||
src_cid: destination,
|
||||
dst_cid: source,
|
||||
}
|
||||
.encode(&mut buf);
|
||||
buf.write::<u32>(0x0a1a_2a3a); // reserved version
|
||||
buf.write(VERSION); // supported version
|
||||
self.io.push_back(Io::Transmit {
|
||||
destination: remote,
|
||||
ecn: None,
|
||||
packet: buf.into(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
trace!(self.log, "malformed header"; "reason" => %e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
fn handle_decode(
|
||||
&mut self,
|
||||
now: u64,
|
||||
remote: SocketAddr,
|
||||
ecn: Option<EcnCodepoint>,
|
||||
partial_decode: PartialDecode,
|
||||
datagram_len: usize,
|
||||
) {
|
||||
//
|
||||
// Handle packet on existing connection, if any
|
||||
//
|
||||
@@ -219,7 +204,7 @@ impl Endpoint {
|
||||
};
|
||||
if let Some(ch) = known_ch {
|
||||
let had_1rtt = self.connections[ch].has_1rtt();
|
||||
self.connections[ch].handle_decode(now, remote, ecn, partial_decode);
|
||||
self.connections[ch].handle_dgram(now, remote, ecn, partial_decode, rest);
|
||||
if !had_1rtt
|
||||
&& (self.connections[ch].has_1rtt() || !self.connections[ch].is_handshaking())
|
||||
{
|
||||
@@ -259,7 +244,7 @@ impl Endpoint {
|
||||
let header_crypto = crypto.header_crypto();
|
||||
match partial_decode.finish(Some(&header_crypto)) {
|
||||
Ok(packet) => {
|
||||
self.handle_initial(now, remote, ecn, packet, &crypto, &header_crypto)
|
||||
self.handle_initial(now, remote, ecn, packet, rest, &crypto, &header_crypto)
|
||||
}
|
||||
Err(e) => {
|
||||
trace!(self.log, "unable to decode packet"; "reason" => %e);
|
||||
@@ -423,6 +408,7 @@ impl Endpoint {
|
||||
remote: SocketAddr,
|
||||
ecn: Option<EcnCodepoint>,
|
||||
mut packet: Packet,
|
||||
rest: Option<BytesMut>,
|
||||
crypto: &Crypto,
|
||||
header_crypto: &HeaderCrypto,
|
||||
) {
|
||||
@@ -554,7 +540,14 @@ impl Endpoint {
|
||||
if dst_cid.len() != 0 {
|
||||
self.connection_ids_initial.insert(dst_cid, ch);
|
||||
}
|
||||
match self.connections[ch].handle_initial(now, ecn, packet_number as u64, packet) {
|
||||
match self.connections[ch].handle_initial(
|
||||
now,
|
||||
remote,
|
||||
ecn,
|
||||
packet_number as u64,
|
||||
packet,
|
||||
rest,
|
||||
) {
|
||||
Ok(()) => {
|
||||
self.incoming_handshakes += 1;
|
||||
self.dirty_conns.insert(ch);
|
||||
|
||||
Reference in New Issue
Block a user