mirror of https://github.com/ctz/rustls
Update mio dependency to 0.6
This commit is contained in:
parent
dac2274e80
commit
14e9529e40
|
@ -24,7 +24,7 @@ logging = ["log"]
|
|||
[dev-dependencies]
|
||||
log = "0.3.7"
|
||||
env_logger = "0.4.2"
|
||||
mio = "0.5"
|
||||
mio = "0.6"
|
||||
docopt = "0.7"
|
||||
rustc-serialize = "0.3"
|
||||
webpki-roots = "0.9"
|
||||
|
|
|
@ -33,22 +33,17 @@ struct TlsClient {
|
|||
tls_session: rustls::ClientSession,
|
||||
}
|
||||
|
||||
impl mio::Handler for TlsClient {
|
||||
type Timeout = ();
|
||||
type Message = ();
|
||||
|
||||
/// Called by mio each time events we register() for happen.
|
||||
impl TlsClient {
|
||||
fn ready(&mut self,
|
||||
event_loop: &mut mio::EventLoop<TlsClient>,
|
||||
token: mio::Token,
|
||||
events: mio::EventSet) {
|
||||
assert_eq!(token, CLIENT);
|
||||
poll: &mut mio::Poll,
|
||||
ev: &mio::Event) {
|
||||
assert_eq!(ev.token(), CLIENT);
|
||||
|
||||
if events.is_readable() {
|
||||
if ev.readiness().is_readable() {
|
||||
self.do_read();
|
||||
}
|
||||
|
||||
if events.is_writable() {
|
||||
if ev.readiness().is_writable() {
|
||||
self.do_write();
|
||||
}
|
||||
|
||||
|
@ -57,16 +52,7 @@ impl mio::Handler for TlsClient {
|
|||
process::exit(if self.clean_closure { 0 } else { 1 });
|
||||
}
|
||||
|
||||
self.reregister(event_loop);
|
||||
}
|
||||
|
||||
// XXX: this won't be called currently, but could be used in the future
|
||||
// to have timeout behaviour.
|
||||
fn timeout(&mut self,
|
||||
_event_loop: &mut mio::EventLoop<TlsClient>,
|
||||
_timeout: <TlsClient as mio::Handler>::Timeout) {
|
||||
println!("connection timed out");
|
||||
process::exit(1);
|
||||
self.reregister(poll);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,34 +144,34 @@ impl TlsClient {
|
|||
self.tls_session.write_tls(&mut self.socket).unwrap();
|
||||
}
|
||||
|
||||
fn register(&self, event_loop: &mut mio::EventLoop<TlsClient>) {
|
||||
event_loop.register(&self.socket,
|
||||
fn register(&self, poll: &mut mio::Poll) {
|
||||
poll.register(&self.socket,
|
||||
CLIENT,
|
||||
self.event_set(),
|
||||
self.ready_interest(),
|
||||
mio::PollOpt::level() | mio::PollOpt::oneshot())
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn reregister(&self, event_loop: &mut mio::EventLoop<TlsClient>) {
|
||||
event_loop.reregister(&self.socket,
|
||||
fn reregister(&self, poll: &mut mio::Poll) {
|
||||
poll.reregister(&self.socket,
|
||||
CLIENT,
|
||||
self.event_set(),
|
||||
self.ready_interest(),
|
||||
mio::PollOpt::level() | mio::PollOpt::oneshot())
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// Use wants_read/wants_write to register for different mio-level
|
||||
// IO readiness events.
|
||||
fn event_set(&self) -> mio::EventSet {
|
||||
fn ready_interest(&self) -> mio::Ready {
|
||||
let rd = self.tls_session.wants_read();
|
||||
let wr = self.tls_session.wants_write();
|
||||
|
||||
if rd && wr {
|
||||
mio::EventSet::readable() | mio::EventSet::writable()
|
||||
mio::Ready::readable() | mio::Ready::writable()
|
||||
} else if wr {
|
||||
mio::EventSet::writable()
|
||||
mio::Ready::writable()
|
||||
} else {
|
||||
mio::EventSet::readable()
|
||||
mio::Ready::readable()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -469,7 +455,17 @@ fn main() {
|
|||
tlsclient.read_source_to_end(&mut stdin).unwrap();
|
||||
}
|
||||
|
||||
let mut event_loop = mio::EventLoop::new().unwrap();
|
||||
tlsclient.register(&mut event_loop);
|
||||
event_loop.run(&mut tlsclient).unwrap();
|
||||
let mut poll = mio::Poll::new()
|
||||
.unwrap();
|
||||
let mut events = mio::Events::with_capacity(32);
|
||||
tlsclient.register(&mut poll);
|
||||
|
||||
loop {
|
||||
poll.poll(&mut events, None)
|
||||
.unwrap();
|
||||
|
||||
for ev in events.iter() {
|
||||
tlsclient.ready(&mut poll, &ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
extern crate mio;
|
||||
use mio::util::Slab;
|
||||
use mio::TryRead;
|
||||
use mio::tcp::{TcpListener, TcpStream, Shutdown};
|
||||
|
||||
#[macro_use]
|
||||
|
@ -12,6 +10,7 @@ use std::fs;
|
|||
use std::io;
|
||||
use std::net;
|
||||
use std::io::{Write, Read, BufReader};
|
||||
use std::collections::HashMap;
|
||||
|
||||
extern crate rustc_serialize;
|
||||
extern crate docopt;
|
||||
|
@ -44,69 +43,56 @@ enum ServerMode {
|
|||
/// connections, and a TLS server configuration.
|
||||
struct TlsServer {
|
||||
server: TcpListener,
|
||||
connections: Slab<Connection>,
|
||||
connections: HashMap<mio::Token, Connection>,
|
||||
next_id: usize,
|
||||
tls_config: Arc<rustls::ServerConfig>,
|
||||
mode: ServerMode,
|
||||
}
|
||||
|
||||
impl TlsServer {
|
||||
fn new(server: TcpListener, mode: ServerMode, cfg: Arc<rustls::ServerConfig>) -> TlsServer {
|
||||
let slab = Slab::new_starting_at(mio::Token(1), 256);
|
||||
|
||||
TlsServer {
|
||||
server: server,
|
||||
connections: slab,
|
||||
connections: HashMap::new(),
|
||||
next_id: 2,
|
||||
tls_config: cfg,
|
||||
mode: mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl mio::Handler for TlsServer {
|
||||
type Timeout = ();
|
||||
type Message = ();
|
||||
fn accept(&mut self, poll: &mut mio::Poll) -> bool {
|
||||
match self.server.accept() {
|
||||
Ok((socket, addr)) => {
|
||||
info!("Accepting new connection from {:?}", addr);
|
||||
|
||||
fn ready(&mut self,
|
||||
event_loop: &mut mio::EventLoop<TlsServer>,
|
||||
token: mio::Token,
|
||||
events: mio::EventSet) {
|
||||
match token {
|
||||
// Our listening socket: we have a new connection.
|
||||
LISTENER => {
|
||||
match self.server.accept() {
|
||||
Ok(Some((socket, addr))) => {
|
||||
info!("Accepting new connection from {:?}", addr);
|
||||
let tls_session = rustls::ServerSession::new(&self.tls_config);
|
||||
let mode = self.mode.clone();
|
||||
|
||||
let tls_session = rustls::ServerSession::new(&self.tls_config);
|
||||
let mode = self.mode.clone();
|
||||
let token = mio::Token(self.next_id);
|
||||
self.next_id += 1;
|
||||
|
||||
match self.connections
|
||||
.insert_with(|token| Connection::new(socket, token, mode, tls_session)) {
|
||||
Some(token) => {
|
||||
self.connections[token].register(event_loop);
|
||||
}
|
||||
None => {
|
||||
error!("Too many connections: rejecting new connection");
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(None) => {}
|
||||
Err(e) => {
|
||||
println!("encountered error while accepting connection; err={:?}", e);
|
||||
event_loop.shutdown();
|
||||
}
|
||||
}
|
||||
self.connections.insert(token, Connection::new(socket, token, mode, tls_session));
|
||||
self.connections[&token].register(poll);
|
||||
true
|
||||
}
|
||||
Err(e) => {
|
||||
println!("encountered error while accepting connection; err={:?}", e);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A connection socket.
|
||||
_ => {
|
||||
if self.connections.contains(token) {
|
||||
self.connections[token].ready(event_loop, events);
|
||||
fn conn_event(&mut self, poll: &mut mio::Poll, event: &mio::Event) {
|
||||
let token = event.token();
|
||||
|
||||
if self.connections[token].is_closed() {
|
||||
self.connections.remove(token);
|
||||
}
|
||||
}
|
||||
if self.connections.contains_key(&token) {
|
||||
self.connections
|
||||
.get_mut(&token)
|
||||
.unwrap()
|
||||
.ready(poll, event);
|
||||
|
||||
if self.connections[&token].is_closed() {
|
||||
self.connections.remove(&token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +125,21 @@ fn open_back(mode: &ServerMode) -> Option<TcpStream> {
|
|||
}
|
||||
}
|
||||
|
||||
/// This used to be conveniently exposed by mio: map EWOULDBLOCK
|
||||
/// errors to something less-errory.
|
||||
fn try_read(r: io::Result<usize>) -> io::Result<Option<usize>> {
|
||||
match r {
|
||||
Ok(len) => Ok(Some(len)),
|
||||
Err(e) => {
|
||||
if e.kind() == io::ErrorKind::WouldBlock {
|
||||
Ok(None)
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Connection {
|
||||
fn new(socket: TcpStream,
|
||||
token: mio::Token,
|
||||
|
@ -158,17 +159,17 @@ impl Connection {
|
|||
}
|
||||
|
||||
/// We're a connection, and we have something to do.
|
||||
fn ready(&mut self, event_loop: &mut mio::EventLoop<TlsServer>, events: mio::EventSet) {
|
||||
fn ready(&mut self, poll: &mut mio::Poll, ev: &mio::Event) {
|
||||
// If we're readable: read some TLS. Then
|
||||
// see if that yielded new plaintext. Then
|
||||
// see if the backend is readable too.
|
||||
if events.is_readable() {
|
||||
if ev.readiness().is_readable() {
|
||||
self.do_tls_read();
|
||||
self.try_plain_read();
|
||||
self.try_back_read();
|
||||
}
|
||||
|
||||
if events.is_writable() {
|
||||
if ev.readiness().is_writable() {
|
||||
self.do_tls_write();
|
||||
}
|
||||
|
||||
|
@ -176,7 +177,7 @@ impl Connection {
|
|||
let _ = self.socket.shutdown(Shutdown::Both);
|
||||
self.close_back();
|
||||
} else {
|
||||
self.reregister(event_loop);
|
||||
self.reregister(poll);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,7 +245,7 @@ impl Connection {
|
|||
// Try a non-blocking read.
|
||||
let mut buf = [0u8; 1024];
|
||||
let back = self.back.as_mut().unwrap();
|
||||
let rc = back.try_read(&mut buf);
|
||||
let rc = try_read(back.read(&mut buf));
|
||||
|
||||
if rc.is_err() {
|
||||
error!("backend read failed: {:?}", rc);
|
||||
|
@ -303,33 +304,33 @@ impl Connection {
|
|||
}
|
||||
}
|
||||
|
||||
fn register(&self, event_loop: &mut mio::EventLoop<TlsServer>) {
|
||||
event_loop.register(&self.socket,
|
||||
fn register(&self, poll: &mut mio::Poll) {
|
||||
poll.register(&self.socket,
|
||||
self.token,
|
||||
self.event_set(),
|
||||
mio::PollOpt::level() | mio::PollOpt::oneshot())
|
||||
.unwrap();
|
||||
|
||||
if self.back.is_some() {
|
||||
event_loop.register(self.back.as_ref().unwrap(),
|
||||
poll.register(self.back.as_ref().unwrap(),
|
||||
self.token,
|
||||
mio::EventSet::readable(),
|
||||
mio::Ready::readable(),
|
||||
mio::PollOpt::level() | mio::PollOpt::oneshot())
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn reregister(&self, event_loop: &mut mio::EventLoop<TlsServer>) {
|
||||
event_loop.reregister(&self.socket,
|
||||
fn reregister(&self, poll: &mut mio::Poll) {
|
||||
poll.reregister(&self.socket,
|
||||
self.token,
|
||||
self.event_set(),
|
||||
mio::PollOpt::level() | mio::PollOpt::oneshot())
|
||||
.unwrap();
|
||||
|
||||
if self.back.is_some() {
|
||||
event_loop.reregister(self.back.as_ref().unwrap(),
|
||||
poll.reregister(self.back.as_ref().unwrap(),
|
||||
self.token,
|
||||
mio::EventSet::readable(),
|
||||
mio::Ready::readable(),
|
||||
mio::PollOpt::level() | mio::PollOpt::oneshot())
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -337,16 +338,16 @@ impl Connection {
|
|||
|
||||
/// What IO events we're currently waiting for,
|
||||
/// based on wants_read/wants_write.
|
||||
fn event_set(&self) -> mio::EventSet {
|
||||
fn event_set(&self) -> mio::Ready {
|
||||
let rd = self.tls_session.wants_read();
|
||||
let wr = self.tls_session.wants_write();
|
||||
|
||||
if rd && wr {
|
||||
mio::EventSet::readable() | mio::EventSet::writable()
|
||||
mio::Ready::readable() | mio::Ready::writable()
|
||||
} else if wr {
|
||||
mio::EventSet::writable()
|
||||
mio::Ready::writable()
|
||||
} else {
|
||||
mio::EventSet::readable()
|
||||
mio::Ready::readable()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,10 +546,11 @@ fn main() {
|
|||
let config = make_config(&args);
|
||||
|
||||
let listener = TcpListener::bind(&addr).expect("cannot listen on port");
|
||||
let mut event_loop = mio::EventLoop::new().unwrap();
|
||||
event_loop.register(&listener,
|
||||
let mut poll = mio::Poll::new()
|
||||
.unwrap();
|
||||
poll.register(&listener,
|
||||
LISTENER,
|
||||
mio::EventSet::readable(),
|
||||
mio::Ready::readable(),
|
||||
mio::PollOpt::level())
|
||||
.unwrap();
|
||||
|
||||
|
@ -561,5 +563,21 @@ fn main() {
|
|||
};
|
||||
|
||||
let mut tlsserv = TlsServer::new(listener, mode, config);
|
||||
event_loop.run(&mut tlsserv).unwrap();
|
||||
|
||||
let mut events = mio::Events::with_capacity(256);
|
||||
loop {
|
||||
poll.poll(&mut events, None)
|
||||
.unwrap();
|
||||
|
||||
for event in events.iter() {
|
||||
match event.token() {
|
||||
LISTENER => {
|
||||
if !tlsserv.accept(&mut poll) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ => tlsserv.conn_event(&mut poll, &event)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue