1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
extern crate bytes;
extern crate byteorder;
extern crate rand;
extern crate openssl;
extern crate slab;
#[macro_use]
extern crate failure;
extern crate digest;
extern crate blake2;
extern crate constant_time_eq;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate slog;
#[cfg(test)]
#[macro_use]
extern crate assert_matches;
#[cfg(test)]
#[macro_use]
extern crate hex_literal;
extern crate arrayvec;
extern crate fnv;
use std::fmt;
mod varint;
mod memory_stream;
mod transport_parameters;
mod coding;
mod hkdf;
mod range_set;
mod stream;
mod frame;
use frame::Frame;
pub use frame::{ApplicationClose, ConnectionClose};
mod endpoint;
pub use endpoint::{Endpoint, Config, CertConfig, ListenKeys, ConnectionHandle, Event, Io, Timer, ConnectionError, ReadError, WriteError, ConnectError,
ConnectionId, EndpointError, ClientConfig};
mod transport_error;
pub use transport_error::Error as TransportError;
pub const VERSION: u32 = 0xff00000B;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Side {
Client = 0,
Server = 1,
}
impl ::std::ops::Not for Side {
type Output = Side;
fn not(self) -> Side { match self { Side::Client => Side::Server, Side::Server => Side::Client } }
}
impl slog::Value for Side {
fn serialize(&self, _: &slog::Record, key: slog::Key, serializer: &mut slog::Serializer) -> slog::Result {
serializer.emit_arguments(key, &format_args!("{:?}", self))
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Directionality {
Bi = 0,
Uni = 1,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct StreamId(pub(crate) u64);
impl fmt::Display for StreamId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let initiator = match self.initiator() { Side::Client => "client", Side::Server => "server" };
let directionality = match self.directionality() { Directionality::Uni => "uni", Directionality::Bi => "bi" };
write!(f, "{} {}directional stream {}", initiator, directionality, self.index())
}
}
impl slog::Value for StreamId {
fn serialize(&self, _: &slog::Record, key: slog::Key, serializer: &mut slog::Serializer) -> slog::Result {
serializer.emit_arguments(key, &format_args!("{:?}", self))
}
}
impl StreamId {
pub(crate) fn new(initiator: Side, directionality: Directionality, index: u64) -> Self {
StreamId(index << 2 | (directionality as u64) << 1 | initiator as u64)
}
pub fn initiator(&self) -> Side { if self.0 & 0x1 == 0 { Side::Client } else { Side::Server } }
pub fn directionality(&self) -> Directionality { if self.0 & 0x2 == 0 { Directionality::Bi } else { Directionality::Uni } }
pub fn index(&self) -> u64 { self.0 >> 2 }
}
impl coding::Value for StreamId {
fn decode<B: bytes::Buf>(buf: &mut B) -> coding::Result<StreamId> {
varint::read(buf).map(StreamId).ok_or(coding::UnexpectedEnd)
}
fn encode<B: bytes::BufMut>(&self, buf: &mut B) {
varint::write(self.0, buf).unwrap()
}
}
const RESET_TOKEN_SIZE: usize = 16;
const MAX_CID_SIZE: usize = 18;
const MIN_CID_SIZE: usize = 4;