apply rustffmt on proxy, remove rustfmt.toml for now

This commit is contained in:
Oliver Gould 2017-12-05 00:44:16 +00:00
parent d2c54b65de
commit 3f87213602
39 changed files with 784 additions and 851 deletions

View File

@ -1,84 +0,0 @@
# https://github.com/rust-lang-nursery/rustfmt/blob/master/Configurations.md
verbose = false
disable_all_formatting = false
skip_children = false
max_width = 100
error_on_line_overflow = false
error_on_line_overflow_comments = false
tab_spaces = 4
fn_call_width = 60
struct_lit_width = 18
struct_variant_width = 35
force_explicit_abi = true
newline_style = "Unix"
fn_brace_style = "SameLineWhere"
item_brace_style = "SameLineWhere"
control_style = "Rfc"
control_brace_style = "AlwaysSameLine"
impl_empty_single_line = true
trailing_comma = "Vertical"
trailing_semicolon = true
fn_empty_single_line = true
fn_single_line = false
fn_return_indent = "WithArgs"
fn_args_paren_newline = false
fn_args_density = "Tall"
fn_args_layout = "Block"
array_layout = "Block"
array_width = 60
array_horizontal_layout_threshold = 0
type_punctuation_density = "Wide"
where_style = "Rfc"
where_density = "CompressedIfEmpty"
where_layout = "Vertical"
where_pred_indent = "Visual"
generics_indent = "Block"
struct_lit_style = "Block"
struct_lit_multiline_style = "ForceMulti"
fn_call_style = "Block"
report_todo = "Never"
report_fixme = "Never"
chain_indent = "Block"
chain_one_line_max = 60
chain_split_single_child = false
imports_indent = "Block"
imports_layout = "HorizontalVertical"
reorder_extern_crates = true
reorder_extern_crates_in_group = true
reorder_imports = true
reorder_imports_in_group = true
reorder_imported_names = true
single_line_if_else_max_width = 50
format_strings = true
force_format_strings = false
take_source_hints = false
hard_tabs = false
wrap_comments = false
comment_width = 80
normalize_comments = false
wrap_match_arms = true
match_block_trailing_comma = true
indent_match_arms = true
match_pattern_separator_break_point = "Back"
closure_block_indent_threshold = 0
space_before_type_annotation = false
space_after_type_annotation_colon = true
space_before_struct_lit_field_colon = false
space_after_struct_lit_field_colon = true
space_before_bound = false
space_after_bound_colon = true
spaces_around_ranges = false
spaces_within_angle_brackets = false
spaces_within_square_brackets = false
spaces_within_parens = false
use_try_shorthand = true
write_mode = "Overwrite"
condense_wildcard_suffixes = false
combine_control_expr = true
struct_field_align_threshold = 0
remove_blank_lines_at_start_or_end_of_block = true
attributes_on_same_line_as_field = true
attributes_on_same_line_as_variant = true
multiline_closure_forces_block = false
multiline_match_arm_forces_block = false
merge_derives = true

View File

@ -92,7 +92,8 @@ impl<T> Sender<T> {
} }
} }
self.tx.unbounded_send(v) self.tx
.unbounded_send(v)
.map_err(|se| SendError::NoReceiver(se.into_inner())) .map_err(|se| SendError::NoReceiver(se.into_inner()))
} }
} }
@ -103,8 +104,7 @@ impl<T> Sink for Sender<T> {
type SinkError = SendError<T>; type SinkError = SendError<T>;
fn start_send(&mut self, item: T) -> StartSend<Self::SinkItem, Self::SinkError> { fn start_send(&mut self, item: T) -> StartSend<Self::SinkItem, Self::SinkError> {
self.lossy_send(item) self.lossy_send(item).map(|_| AsyncSink::Ready)
.map(|_| AsyncSink::Ready)
} }
fn poll_complete(&mut self) -> Poll<(), Self::SinkError> { fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
@ -136,8 +136,7 @@ impl<T> fmt::Debug for Sender<T> {
impl<T> SendError<T> { impl<T> SendError<T> {
pub fn into_inner(self) -> T { pub fn into_inner(self) -> T {
match self { match self {
SendError::NoReceiver(v) | SendError::NoReceiver(v) | SendError::Rejected(v) => v,
SendError::Rejected(v) => v
} }
} }
} }

View File

@ -10,12 +10,8 @@ fn build_control() {
"../proto/proxy/destination/destination.proto", "../proto/proxy/destination/destination.proto",
"../proto/proxy/telemetry/telemetry.proto", "../proto/proxy/telemetry/telemetry.proto",
]; ];
let server_files = &[ let server_files = &["../proto/proxy/tap/tap.proto"];
"../proto/proxy/tap/tap.proto", let dirs = &["../proto"];
];
let dirs = &[
"../proto",
];
tower_grpc_build::Config::new() tower_grpc_build::Config::new()
.enable_client(true) .enable_client(true)

View File

@ -5,4 +5,3 @@ pub fn init() -> Result<Config, config::Error> {
logging::init(); logging::init();
Config::load_from_env() Config::load_from_env()
} }

View File

@ -1,7 +1,7 @@
use std::io; use std::io;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::Arc;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::Arc;
use std::sync::atomic::AtomicUsize; use std::sync::atomic::AtomicUsize;
use std::time::Duration; use std::time::Duration;
@ -87,7 +87,6 @@ impl<B> Bind<(), B> {
_p: PhantomData, _p: PhantomData,
} }
} }
} }
impl<C: Clone, B> Clone for Bind<C, B> { impl<C: Clone, B> Clone for Bind<C, B> {
@ -146,7 +145,7 @@ where
let client = tower_h2::client::Client::new( let client = tower_h2::client::Client::new(
connect, connect,
self.h2_builder.clone(), self.h2_builder.clone(),
::logging::context_executor(("client", *addr), self.executor.clone()) ::logging::context_executor(("client", *addr), self.executor.clone()),
); );
let h2_proxy = self.sensors.http(self.req_ids.clone(), client, &client_ctx); let h2_proxy = self.sensors.http(self.req_ids.clone(), client, &client_ctx);

View File

@ -1,7 +1,7 @@
use std::env; use std::env;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::str::FromStr;
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr;
use std::time::Duration; use std::time::Duration;
use url::{Host, HostAndPort, Url}; use url::{Host, HostAndPort, Url};
@ -123,16 +123,16 @@ impl Config {
None => DEFAULT_EVENT_BUFFER_CAPACITY, None => DEFAULT_EVENT_BUFFER_CAPACITY,
Some(c) => match c.parse() { Some(c) => match c.parse() {
Ok(c) => c, Ok(c) => c,
Err(_) => return Err(Error::NotANumber(c)) Err(_) => return Err(Error::NotANumber(c)),
} },
}; };
let metrics_flush_interval = match env::var(ENV_METRICS_FLUSH_INTERVAL_SECS).ok() { let metrics_flush_interval = match env::var(ENV_METRICS_FLUSH_INTERVAL_SECS).ok() {
None => Duration::from_secs(DEFAULT_METRICS_FLUSH_INTERVAL_SECS), None => Duration::from_secs(DEFAULT_METRICS_FLUSH_INTERVAL_SECS),
Some(c) => match c.parse() { Some(c) => match c.parse() {
Ok(c) => Duration::from_secs(c), Ok(c) => Duration::from_secs(c),
Err(_) => return Err(Error::NotANumber(c)) Err(_) => return Err(Error::NotANumber(c)),
} },
}; };
Ok(Config { Ok(Config {
@ -147,11 +147,13 @@ impl Config {
}, },
private_forward: Addr::from_env_opt(ENV_PRIVATE_FORWARD)?, private_forward: Addr::from_env_opt(ENV_PRIVATE_FORWARD)?,
public_connect_timeout: env::var(ENV_PUBLIC_CONNECT_TIMEOUT).ok() public_connect_timeout: env::var(ENV_PUBLIC_CONNECT_TIMEOUT)
.ok()
.and_then(|c| c.parse().ok()) .and_then(|c| c.parse().ok())
.map(Duration::from_millis), .map(Duration::from_millis),
private_connect_timeout: env::var(ENV_PRIVATE_CONNECT_TIMEOUT).ok() private_connect_timeout: env::var(ENV_PRIVATE_CONNECT_TIMEOUT)
.ok()
.and_then(|c| c.parse().ok()) .and_then(|c| c.parse().ok())
.map(Duration::from_millis), .map(Duration::from_millis),
@ -159,7 +161,10 @@ impl Config {
.unwrap_or_else(|_| DEFAULT_RESOLV_CONF.into()) .unwrap_or_else(|_| DEFAULT_RESOLV_CONF.into())
.into(), .into(),
control_host_and_port: control_host_and_port_from_env(ENV_CONTROL_URL, DEFAULT_CONTROL_URL)?, control_host_and_port: control_host_and_port_from_env(
ENV_CONTROL_URL,
DEFAULT_CONTROL_URL,
)?,
event_buffer_capacity, event_buffer_capacity,
metrics_flush_interval, metrics_flush_interval,
}) })
@ -177,8 +182,7 @@ impl Addr {
} }
fn from_env_or(key: &str, default: &str) -> Result<Addr, Error> { fn from_env_or(key: &str, default: &str) -> Result<Addr, Error> {
let s = env::var(key) let s = env::var(key).unwrap_or_else(|_| default.into());
.unwrap_or_else(|_| default.into());
s.parse() s.parse()
} }
@ -190,16 +194,20 @@ impl FromStr for Addr {
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
match Url::parse(s) { match Url::parse(s) {
Err(_) => Err(Error::InvalidAddr), Err(_) => Err(Error::InvalidAddr),
Ok(u) => { Ok(u) => match u.scheme() {
match u.scheme() {
"tcp" => match u.with_default_port(|_| Err(())) { "tcp" => match u.with_default_port(|_| Err(())) {
Ok(HostAndPort { host: Host::Ipv4(ip), port }) => Ok(Addr(SocketAddr::new(ip.into(), port))), Ok(HostAndPort {
Ok(HostAndPort { host: Host::Ipv6(ip), port }) => Ok(Addr(SocketAddr::new(ip.into(), port))), host: Host::Ipv4(ip),
port,
}) => Ok(Addr(SocketAddr::new(ip.into(), port))),
Ok(HostAndPort {
host: Host::Ipv6(ip),
port,
}) => Ok(Addr(SocketAddr::new(ip.into(), port))),
_ => Err(Error::InvalidAddr), _ => Err(Error::InvalidAddr),
}, },
_ => Err(Error::InvalidAddr), _ => Err(Error::InvalidAddr),
} },
}
} }
} }
} }
@ -212,21 +220,37 @@ impl From<Addr> for SocketAddr {
fn control_host_and_port_from_env(key: &str, default: &str) -> Result<HostAndPort, Error> { fn control_host_and_port_from_env(key: &str, default: &str) -> Result<HostAndPort, Error> {
let s = env::var(key).unwrap_or_else(|_| default.into()); let s = env::var(key).unwrap_or_else(|_| default.into());
let url = Url::parse(&s).map_err(|_| Error::ControlPlaneConfigError(s.clone(), UrlError::SyntaxError))?; let url = Url::parse(&s).map_err(|_| {
let host = url.host().ok_or_else(|| Error::ControlPlaneConfigError(s.clone(), UrlError::MissingHost))? Error::ControlPlaneConfigError(s.clone(), UrlError::SyntaxError)
})?;
let host = url.host()
.ok_or_else(|| {
Error::ControlPlaneConfigError(s.clone(), UrlError::MissingHost)
})?
.to_owned(); .to_owned();
if url.scheme() != "tcp" { if url.scheme() != "tcp" {
return Err(Error::ControlPlaneConfigError(s.clone(), UrlError::UnsupportedScheme)); return Err(Error::ControlPlaneConfigError(
s.clone(),
UrlError::UnsupportedScheme,
));
} }
let port = url.port().ok_or_else(|| Error::ControlPlaneConfigError(s.clone(), UrlError::MissingPort))?; let port = url.port().ok_or_else(|| {
Error::ControlPlaneConfigError(s.clone(), UrlError::MissingPort)
})?;
if url.path() != "/" { if url.path() != "/" {
return Err(Error::ControlPlaneConfigError(s.clone(), UrlError::PathNotAllowed)); return Err(Error::ControlPlaneConfigError(
s.clone(),
UrlError::PathNotAllowed,
));
} }
if url.fragment().is_some() { if url.fragment().is_some() {
return Err(Error::ControlPlaneConfigError(s.clone(), UrlError::FragmentNotAllowed)); return Err(Error::ControlPlaneConfigError(
s.clone(),
UrlError::FragmentNotAllowed,
));
} }
Ok(HostAndPort { Ok(HostAndPort {
host, host,
port port,
}) })
} }

View File

@ -23,7 +23,9 @@ pub struct Handshake {
impl Connection { impl Connection {
/// Establish a connection backed by the provided `io`. /// Establish a connection backed by the provided `io`.
pub fn handshake(io: PlaintextSocket) -> Handshake { pub fn handshake(io: PlaintextSocket) -> Handshake {
Handshake { plaintext_socket: Some(io) } Handshake {
plaintext_socket: Some(io),
}
} }
} }

View File

@ -50,13 +50,11 @@ impl<T: Message, U: Message + Default> Codec for Protobuf<T, U> {
trace!("decode; bytes={}", buf.remaining()); trace!("decode; bytes={}", buf.remaining());
match Message::decode(buf) { match Message::decode(buf) {
Ok(msg) => { Ok(msg) => Ok(msg),
Ok(msg)
},
Err(err) => { Err(err) => {
debug!("decode error: {:?}", err); debug!("decode error: {:?}", err);
Err(err) Err(err)
}, }
} }
} }
} }

View File

@ -1,24 +1,20 @@
use std::collections::hash_map::{Entry, HashMap};
use std::collections::{HashSet, VecDeque}; use std::collections::{HashSet, VecDeque};
use std::collections::hash_map::{Entry, HashMap};
use std::net::SocketAddr; use std::net::SocketAddr;
use futures::{Async, Future, Poll, Stream}; use futures::{Async, Future, Poll, Stream};
use futures::sync::mpsc; use futures::sync::mpsc;
use http::uri::Authority; use http::uri::Authority;
use tower::Service; use tower::Service;
use tower_discover::{Discover, Change}; use tower_discover::{Change, Discover};
use tower_grpc; use tower_grpc;
use super::codec::Protobuf; use super::codec::Protobuf;
use super::pb::common::{Destination, TcpAddress}; use super::pb::common::{Destination, TcpAddress};
use super::pb::proxy::destination::Update as PbUpdate; use super::pb::proxy::destination::Update as PbUpdate;
use super::pb::proxy::destination::client::Destination as DestinationSvc;
use super::pb::proxy::destination::client::destination_methods::Get as GetRpc;
use super::pb::proxy::destination::update::Update as PbUpdate2; use super::pb::proxy::destination::update::Update as PbUpdate2;
use super::pb::proxy::destination::client::{
Destination as DestinationSvc
};
use super::pb::proxy::destination::client::destination_methods::{
Get as GetRpc
};
pub type ClientBody = ::tower_grpc::client::codec::EncodingBody< pub type ClientBody = ::tower_grpc::client::codec::EncodingBody<
Protobuf<Destination, PbUpdate>, Protobuf<Destination, PbUpdate>,
@ -44,15 +40,11 @@ pub struct Background {
rx: mpsc::UnboundedReceiver<(Authority, mpsc::UnboundedSender<Update>)>, rx: mpsc::UnboundedReceiver<(Authority, mpsc::UnboundedSender<Update>)>,
} }
type DiscoveryWatch<F> = type DiscoveryWatch<F> = DestinationSet<
DestinationSet<
tower_grpc::client::Streaming< tower_grpc::client::Streaming<
tower_grpc::client::ResponseFuture< tower_grpc::client::ResponseFuture<Protobuf<Destination, PbUpdate>, F>,
Protobuf<Destination, PbUpdate>,
F,
>,
tower_grpc::client::codec::DecodingBody<Protobuf<Destination, PbUpdate>>, tower_grpc::client::codec::DecodingBody<Protobuf<Destination, PbUpdate>>,
> >,
>; >;
/// A future returned from `Background::work()`, doing the work of talking to /// A future returned from `Background::work()`, doing the work of talking to
@ -97,9 +89,7 @@ pub trait Bind {
type BindError; type BindError;
/// The discovered `Service` instance. /// The discovered `Service` instance.
type Service: Service<Request = Self::Request, type Service: Service<Request = Self::Request, Response = Self::Response, Error = Self::Error>;
Response = Self::Response,
Error = Self::Error>;
/// Bind a socket address with a service. /// Bind a socket address with a service.
fn bind(&self, addr: &SocketAddr) -> Result<Self::Service, Self::BindError>; fn bind(&self, addr: &SocketAddr) -> Result<Self::Service, Self::BindError>;
@ -111,11 +101,14 @@ pub trait Bind {
/// on the controller thread. /// on the controller thread.
pub fn new() -> (Discovery, Background) { pub fn new() -> (Discovery, Background) {
let (tx, rx) = mpsc::unbounded(); let (tx, rx) = mpsc::unbounded();
(Discovery { (
Discovery {
tx, tx,
}, Background { },
Background {
rx, rx,
}) },
)
} }
// ==== impl Discovery ===== // ==== impl Discovery =====
@ -125,7 +118,9 @@ impl Discovery {
pub fn resolve<B>(&self, authority: &Authority, bind: B) -> Watch<B> { pub fn resolve<B>(&self, authority: &Authority, bind: B) -> Watch<B> {
trace!("resolve; authority={:?}", authority); trace!("resolve; authority={:?}", authority);
let (tx, rx) = mpsc::unbounded(); let (tx, rx) = mpsc::unbounded();
self.tx.unbounded_send((authority.clone(), tx)).expect("unbounded can't fail"); self.tx
.unbounded_send((authority.clone(), tx))
.expect("unbounded can't fail");
Watch { Watch {
rx, rx,
@ -137,7 +132,8 @@ impl Discovery {
// ==== impl Watch ===== // ==== impl Watch =====
impl<B> Discover for Watch<B> impl<B> Discover for Watch<B>
where B: Bind, where
B: Bind,
{ {
type Key = SocketAddr; type Key = SocketAddr;
type Request = B::Request; type Request = B::Request;
@ -158,8 +154,7 @@ where B: Bind,
match update { match update {
Update::Insert(addr) => { Update::Insert(addr) => {
let service = self.bind.bind(&addr) let service = self.bind.bind(&addr).map_err(|_| ())?;
.map_err(|_| ())?;
Ok(Async::Ready(Change::Insert(addr, service))) Ok(Async::Ready(Change::Insert(addr, service)))
} }
@ -226,11 +221,11 @@ where
match client.poll_ready() { match client.poll_ready() {
Ok(Async::Ready(())) => { Ok(Async::Ready(())) => {
self.rpc_ready = true; self.rpc_ready = true;
}, }
Ok(Async::NotReady) => { Ok(Async::NotReady) => {
self.rpc_ready = false; self.rpc_ready = false;
break; break;
}, }
Err(err) => { Err(err) => {
warn!("Destination.Get poll_ready error: {:?}", err); warn!("Destination.Get poll_ready error: {:?}", err);
self.rpc_ready = false; self.rpc_ready = false;
@ -252,7 +247,7 @@ where
match self.destinations.entry(auth) { match self.destinations.entry(auth) {
Entry::Occupied(mut occ) => { Entry::Occupied(mut occ) => {
occ.get_mut().tx = tx; occ.get_mut().tx = tx;
}, }
Entry::Vacant(vac) => { Entry::Vacant(vac) => {
let req = Destination { let req = Destination {
scheme: "k8s".into(), scheme: "k8s".into(),
@ -267,11 +262,11 @@ where
}); });
} }
} }
}, }
Ok(Async::Ready(None)) => { Ok(Async::Ready(None)) => {
trace!("Discover tx is dropped, shutdown?"); trace!("Discover tx is dropped, shutdown?");
return; return;
}, }
Ok(Async::NotReady) => break, Ok(Async::NotReady) => break,
Err(_) => unreachable!("unbounded receiver doesn't error"), Err(_) => unreachable!("unbounded receiver doesn't error"),
} }
@ -316,40 +311,37 @@ where
} }
let needs_reconnect = 'set: loop { let needs_reconnect = 'set: loop {
match set.rx.poll() { match set.rx.poll() {
Ok(Async::Ready(Some(update))) => { Ok(Async::Ready(Some(update))) => match update.update {
match update.update { Some(PbUpdate2::Add(a_set)) => for addr in a_set.addrs {
Some(PbUpdate2::Add(a_set)) => {
for addr in a_set.addrs {
if let Some(addr) = addr.addr.and_then(pb_to_sock_addr) { if let Some(addr) = addr.addr.and_then(pb_to_sock_addr) {
if set.addrs.insert(addr) { if set.addrs.insert(addr) {
trace!("update {:?} for {:?}", addr, auth); trace!("update {:?} for {:?}", addr, auth);
let _ = set.tx.unbounded_send(Update::Insert(addr)); let _ = set.tx.unbounded_send(Update::Insert(addr));
} }
} }
}
}, },
Some(PbUpdate2::Remove(r_set)) => { Some(PbUpdate2::Remove(r_set)) => for addr in r_set.addrs {
for addr in r_set.addrs {
if let Some(addr) = pb_to_sock_addr(addr) { if let Some(addr) = pb_to_sock_addr(addr) {
if set.addrs.remove(&addr) { if set.addrs.remove(&addr) {
trace!("remove {:?} for {:?}", addr, auth); trace!("remove {:?} for {:?}", addr, auth);
let _ = set.tx.unbounded_send(Update::Remove(addr)); let _ = set.tx.unbounded_send(Update::Remove(addr));
} }
} }
}
}, },
None => (), None => (),
}
}, },
Ok(Async::Ready(None)) => { Ok(Async::Ready(None)) => {
trace!("Destination.Get stream ended for {:?}, must reconnect", auth); trace!(
"Destination.Get stream ended for {:?}, must reconnect",
auth
);
break 'set true; break 'set true;
}, }
Ok(Async::NotReady) => break 'set false, Ok(Async::NotReady) => break 'set false,
Err(err) => { Err(err) => {
warn!("Destination.Get stream errored for {:?}: {:?}", auth, err); warn!("Destination.Get stream errored for {:?}: {:?}", auth, err);
break 'set true; break 'set true;
}, }
} }
}; };
if needs_reconnect { if needs_reconnect {
@ -363,7 +355,8 @@ where
// ===== impl Bind ===== // ===== impl Bind =====
impl<F, S, E> Bind for F impl<F, S, E> Bind for F
where F: Fn(&SocketAddr) -> Result<S, E>, where
F: Fn(&SocketAddr) -> Result<S, E>,
S: Service, S: Service,
{ {
type Request = S::Request; type Request = S::Request;
@ -378,8 +371,8 @@ where F: Fn(&SocketAddr) -> Result<S, E>,
} }
fn pb_to_sock_addr(pb: TcpAddress) -> Option<SocketAddr> { fn pb_to_sock_addr(pb: TcpAddress) -> Option<SocketAddr> {
use std::net::{Ipv4Addr, Ipv6Addr};
use super::pb::common::ip_address::Ip; use super::pb::common::ip_address::Ip;
use std::net::{Ipv4Addr, Ipv6Addr};
/* /*
current structure is: current structure is:
TcpAddress { TcpAddress {
@ -401,7 +394,7 @@ fn pb_to_sock_addr(pb: TcpAddress) -> Option<SocketAddr> {
Some(Ip::Ipv4(octets)) => { Some(Ip::Ipv4(octets)) => {
let ipv4 = Ipv4Addr::from(octets); let ipv4 = Ipv4Addr::from(octets);
Some(SocketAddr::from((ipv4, pb.port as u16))) Some(SocketAddr::from((ipv4, pb.port as u16)))
}, }
Some(Ip::Ipv6(v6)) => { Some(Ip::Ipv6(v6)) => {
let octets = [ let octets = [
(v6.first >> 56) as u8, (v6.first >> 56) as u8,
@ -423,7 +416,7 @@ fn pb_to_sock_addr(pb: TcpAddress) -> Option<SocketAddr> {
]; ];
let ipv6 = Ipv6Addr::from(octets); let ipv6 = Ipv6Addr::from(octets);
Some(SocketAddr::from((ipv6, pb.port as u16))) Some(SocketAddr::from((ipv6, pb.port as u16)))
}, }
None => None, None => None,
}, },
None => None, None => None,

View File

@ -2,7 +2,7 @@ use std::marker::PhantomData;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use bytes::Bytes; use bytes::Bytes;
use futures::{Async, Future, future, Poll, Stream}; use futures::{future, Async, Future, Poll, Stream};
use h2; use h2;
use http; use http;
use tokio_core::reactor::{Handle, Timeout}; use tokio_core::reactor::{Handle, Timeout};
@ -59,7 +59,13 @@ impl Control {
// ===== impl Background ===== // ===== impl Background =====
impl Background { impl Background {
pub fn bind<S>(self, events: S, host_and_port: HostAndPort, dns_config: dns::Config, executor: &Handle) -> Box<Future<Item=(), Error=()>> pub fn bind<S>(
self,
events: S,
host_and_port: HostAndPort,
dns_config: dns::Config,
executor: &Handle,
) -> Box<Future<Item = (), Error = ()>>
where where
S: Stream<Item = ReportRequest, Error = ()> + 'static, S: Stream<Item = ReportRequest, Error = ()> + 'static,
{ {
@ -67,7 +73,8 @@ impl Background {
let mut client = { let mut client = {
let ctx = ("controller-client", format!("{}", host_and_port)); let ctx = ("controller-client", format!("{}", host_and_port));
let scheme = http::uri::Scheme::from_shared(Bytes::from_static(b"http")).unwrap(); let scheme = http::uri::Scheme::from_shared(Bytes::from_static(b"http")).unwrap();
let authority = http::uri::Authority::from_shared(format!("{}", host_and_port).into()).unwrap(); let authority =
http::uri::Authority::from_shared(format!("{}", host_and_port).into()).unwrap();
let dns_resolver = dns::Resolver::new(dns_config, executor); let dns_resolver = dns::Resolver::new(dns_config, executor);
let connect = TimeoutConnect::new( let connect = TimeoutConnect::new(
@ -78,7 +85,7 @@ impl Background {
let h2_client = tower_h2::client::Client::new( let h2_client = tower_h2::client::Client::new(
connect, connect,
h2::client::Builder::default(), h2::client::Builder::default(),
::logging::context_executor(ctx, executor.clone()) ::logging::context_executor(ctx, executor.clone()),
); );
@ -148,7 +155,7 @@ where
self.waiting = true; self.waiting = true;
self.timer.reset(Instant::now() + self.wait_dur); self.timer.reset(Instant::now() + self.wait_dur);
Ok(Async::NotReady) Ok(Async::NotReady)
}, }
ok => ok, ok => ok,
} }
} }
@ -256,7 +263,6 @@ impl tower_h2::Body for GrpcEncodingBody {
GrpcEncodingBody::DestinationGet(ref mut b) => b.poll_trailers(), GrpcEncodingBody::DestinationGet(ref mut b) => b.poll_trailers(),
} }
} }
} }
impl From<self::telemetry::ClientBody> for GrpcEncodingBody { impl From<self::telemetry::ClientBody> for GrpcEncodingBody {

View File

@ -1,17 +1,17 @@
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use futures::{future, Stream, Poll}; use futures::{future, Poll, Stream};
use futures_mpsc_lossy; use futures_mpsc_lossy;
use ordermap::OrderMap; use ordermap::OrderMap;
use tower_grpc::{self, Request, Response}; use tower_grpc::{self, Request, Response};
use tower_grpc::codegen::server::grpc::ServerStreamingService; use tower_grpc::codegen::server::grpc::ServerStreamingService;
use control::pb::common::TapEvent; use control::pb::common::TapEvent;
use control::pb::proxy::tap::{ObserveRequest}; use control::pb::proxy::tap::ObserveRequest;
use convert::*;
use ctx; use ctx;
use telemetry::Event; use telemetry::Event;
use telemetry::tap::{Tap, Taps}; use telemetry::tap::{Tap, Taps};
use convert::*;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Observe { pub struct Observe {
@ -58,10 +58,14 @@ impl ServerStreamingService for Observe {
} }
let (_, req) = req.into_http().into_parts(); let (_, req) = req.into_http().into_parts();
let (tap, rx) = match req.match_.and_then(|m| Tap::new(&m, self.tap_capacity).ok()) { let (tap, rx) = match req.match_
.and_then(|m| Tap::new(&m, self.tap_capacity).ok())
{
Some(m) => m, Some(m) => m,
None => { None => {
return future::err(tower_grpc::Error::Grpc(tower_grpc::Status::INVALID_ARGUMENT)); return future::err(tower_grpc::Error::Grpc(
tower_grpc::Status::INVALID_ARGUMENT,
));
} }
}; };

View File

@ -7,9 +7,9 @@ use std::sync::Arc;
use http; use http;
use convert::*;
use ctx; use ctx;
use telemetry::Event; use telemetry::Event;
use convert::*;
// re-export proxy here since we dont care about the other dirs // re-export proxy here since we dont care about the other dirs
pub use self::proxy::*; pub use self::proxy::*;
@ -57,7 +57,7 @@ fn pb_response_end(
source: Some((&ctx.server.remote).into()), source: Some((&ctx.server.remote).into()),
target: Some((&ctx.client.remote).into()), target: Some((&ctx.client.remote).into()),
event: Some(tap_event::Event::Http(tap_event::Http { event: Some(tap_event::Event::Http(tap_event::Http {
event: Some(tap_event::http::Event::ResponseEnd(end)) event: Some(tap_event::http::Event::ResponseEnd(end)),
})), })),
} }
} }
@ -73,7 +73,8 @@ impl fmt::Display for InvalidMethod {
} }
impl Error for InvalidMethod { impl Error for InvalidMethod {
#[inline] fn description(&self) -> &str { #[inline]
fn description(&self) -> &str {
"invalid http method" "invalid http method"
} }
} }
@ -88,7 +89,8 @@ impl fmt::Display for InvalidScheme {
} }
impl Error for InvalidScheme { impl Error for InvalidScheme {
#[inline] fn description(&self) -> &str { #[inline]
fn description(&self) -> &str {
"invalid http scheme" "invalid http scheme"
} }
} }
@ -103,7 +105,8 @@ impl fmt::Display for UnknownEvent {
} }
impl Error for UnknownEvent { impl Error for UnknownEvent {
#[inline] fn description(&self) -> &str { #[inline]
fn description(&self) -> &str {
"unknown tap event" "unknown tap event"
} }
} }
@ -124,7 +127,8 @@ impl<'a> TryFrom<&'a Event> for common::TapEvent {
}), }),
method: Some((&ctx.method).into()), method: Some((&ctx.method).into()),
scheme: ctx.uri.scheme().map(|s| s.into()), scheme: ctx.uri.scheme().map(|s| s.into()),
authority: ctx.uri.authority_part() authority: ctx.uri
.authority_part()
.map(|a| a.as_str()) .map(|a| a.as_str())
.unwrap_or_default() .unwrap_or_default()
.into(), .into(),
@ -135,10 +139,10 @@ impl<'a> TryFrom<&'a Event> for common::TapEvent {
source: Some((&ctx.server.remote).into()), source: Some((&ctx.server.remote).into()),
target: Some((&ctx.client.remote).into()), target: Some((&ctx.client.remote).into()),
event: Some(tap_event::Event::Http(tap_event::Http { event: Some(tap_event::Event::Http(tap_event::Http {
event: Some(tap_event::http::Event::RequestInit(init)) event: Some(tap_event::http::Event::RequestInit(init)),
})), })),
} }
}, }
Event::StreamResponseOpen(ref ctx, ref rsp) => { Event::StreamResponseOpen(ref ctx, ref rsp) => {
let init = tap_event::http::ResponseInit { let init = tap_event::http::ResponseInit {
@ -155,40 +159,30 @@ impl<'a> TryFrom<&'a Event> for common::TapEvent {
source: Some((&ctx.request.server.remote).into()), source: Some((&ctx.request.server.remote).into()),
target: Some((&ctx.request.client.remote).into()), target: Some((&ctx.request.client.remote).into()),
event: Some(tap_event::Event::Http(tap_event::Http { event: Some(tap_event::Event::Http(tap_event::Http {
event: Some(tap_event::http::Event::ResponseInit(init)) event: Some(tap_event::http::Event::ResponseInit(init)),
})), })),
} }
} }
Event::StreamRequestFail(ref ctx, ref fail) => { Event::StreamRequestFail(ref ctx, ref fail) => {
pb_response_end( pb_response_end(ctx, fail.since_request_open, None, 0, 0)
ctx,
fail.since_request_open,
None,
0,
0,
)
} }
Event::StreamResponseEnd(ref ctx, ref end) => { Event::StreamResponseEnd(ref ctx, ref end) => pb_response_end(
pb_response_end(
&ctx.request, &ctx.request,
end.since_request_open, end.since_request_open,
Some(end.since_response_open), Some(end.since_response_open),
end.bytes_sent, end.bytes_sent,
end.grpc_status.unwrap_or(0), end.grpc_status.unwrap_or(0),
) ),
}
Event::StreamResponseFail(ref ctx, ref fail) => { Event::StreamResponseFail(ref ctx, ref fail) => pb_response_end(
pb_response_end(
&ctx.request, &ctx.request,
fail.since_request_open, fail.since_request_open,
Some(fail.since_response_open), Some(fail.since_response_open),
fail.bytes_sent, fail.bytes_sent,
0, 0,
) ),
}
_ => return Err(UnknownEvent), _ => return Err(UnknownEvent),
}; };
@ -200,12 +194,11 @@ impl<'a> TryFrom<&'a Event> for common::TapEvent {
impl<'a> TryFrom<&'a common::http_method::Type> for http::Method { impl<'a> TryFrom<&'a common::http_method::Type> for http::Method {
type Err = InvalidMethod; type Err = InvalidMethod;
fn try_from(m: &'a common::http_method::Type) -> Result<Self, Self::Err> { fn try_from(m: &'a common::http_method::Type) -> Result<Self, Self::Err> {
use http::HttpTryFrom;
use self::common::http_method::*; use self::common::http_method::*;
use http::HttpTryFrom;
match *m { match *m {
Type::Registered(reg) => { Type::Registered(reg) => if reg == Registered::Get.into() {
if reg == Registered::Get.into() {
Ok(http::Method::GET) Ok(http::Method::GET)
} else if reg == Registered::Post.into() { } else if reg == Registered::Post.into() {
Ok(http::Method::POST) Ok(http::Method::POST)
@ -225,12 +218,11 @@ impl<'a> TryFrom<&'a common::http_method::Type> for http::Method {
Ok(http::Method::TRACE) Ok(http::Method::TRACE)
} else { } else {
Err(InvalidMethod) Err(InvalidMethod)
},
Type::Unregistered(ref m) => {
HttpTryFrom::try_from(m.as_str()).map_err(|_| InvalidMethod)
} }
} }
Type::Unregistered(ref m) =>
HttpTryFrom::try_from(m.as_str())
.map_err(|_| InvalidMethod),
}
} }
} }
@ -240,15 +232,13 @@ impl<'a> TryInto<String> for &'a common::scheme::Type {
use self::common::scheme::*; use self::common::scheme::*;
match *self { match *self {
Type::Registered(reg) => { Type::Registered(reg) => if reg == Registered::Http.into() {
if reg == Registered::Http.into() {
Ok("http".into()) Ok("http".into())
} else if reg == Registered::Https.into() { } else if reg == Registered::Https.into() {
Ok("https".into()) Ok("https".into())
} else { } else {
Err(InvalidScheme) Err(InvalidScheme)
} },
}
Type::Unregistered(ref s) => Ok(s.clone()), Type::Unregistered(ref s) => Ok(s.clone()),
} }
} }
@ -275,7 +265,7 @@ impl<'a> From<&'a http::Method> for common::http_method::Type {
impl<'a> From<&'a http::Method> for common::HttpMethod { impl<'a> From<&'a http::Method> for common::HttpMethod {
fn from(m: &'a http::Method) -> Self { fn from(m: &'a http::Method) -> Self {
common::HttpMethod { common::HttpMethod {
type_: Some(m.into()) type_: Some(m.into()),
} }
} }
} }
@ -295,7 +285,7 @@ impl<'a> From<&'a str> for common::scheme::Type {
impl<'a> From<&'a str> for common::Scheme { impl<'a> From<&'a str> for common::Scheme {
fn from(s: &'a str) -> Self { fn from(s: &'a str) -> Self {
common::Scheme { common::Scheme {
type_: Some(s.into()) type_: Some(s.into()),
} }
} }
} }
@ -304,7 +294,7 @@ impl<'a> From<&'a str> for common::Scheme {
impl<T> From<T> for common::IpAddress impl<T> From<T> for common::IpAddress
where where
common::ip_address::Ip: From<T> common::ip_address::Ip: From<T>,
{ {
#[inline] #[inline]
fn from(ip: T) -> Self { fn from(ip: T) -> Self {
@ -317,12 +307,10 @@ where
impl From<::std::net::IpAddr> for common::IpAddress { impl From<::std::net::IpAddr> for common::IpAddress {
fn from(ip: ::std::net::IpAddr) -> Self { fn from(ip: ::std::net::IpAddr) -> Self {
match ip { match ip {
::std::net::IpAddr::V4(v4) => ::std::net::IpAddr::V4(v4) => Self {
Self {
ip: Some(v4.into()), ip: Some(v4.into()),
}, },
::std::net::IpAddr::V6(v6) => ::std::net::IpAddr::V6(v6) => Self {
Self {
ip: Some(v6.into()), ip: Some(v6.into()),
}, },
} }
@ -333,22 +321,14 @@ impl From<::std::net::IpAddr> for common::IpAddress {
impl From<[u8; 16]> for common::IPv6 { impl From<[u8; 16]> for common::IPv6 {
fn from(octets: [u8; 16]) -> Self { fn from(octets: [u8; 16]) -> Self {
let first = (u64::from(octets[0]) << 56) let first = (u64::from(octets[0]) << 56) + (u64::from(octets[1]) << 48)
+ (u64::from(octets[1]) << 48) + (u64::from(octets[2]) << 40) + (u64::from(octets[3]) << 32)
+ (u64::from(octets[2]) << 40) + (u64::from(octets[4]) << 24) + (u64::from(octets[5]) << 16)
+ (u64::from(octets[3]) << 32) + (u64::from(octets[6]) << 8) + u64::from(octets[7]);
+ (u64::from(octets[4]) << 24) let last = (u64::from(octets[8]) << 56) + (u64::from(octets[9]) << 48)
+ (u64::from(octets[5]) << 16) + (u64::from(octets[10]) << 40) + (u64::from(octets[11]) << 32)
+ (u64::from(octets[6]) << 8) + (u64::from(octets[12]) << 24) + (u64::from(octets[13]) << 16)
+ u64::from(octets[7]); + (u64::from(octets[14]) << 8) + u64::from(octets[15]);
let last = (u64::from(octets[8]) << 56)
+ (u64::from(octets[9]) << 48)
+ (u64::from(octets[10]) << 40)
+ (u64::from(octets[11]) << 32)
+ (u64::from(octets[12]) << 24)
+ (u64::from(octets[13]) << 16)
+ (u64::from(octets[14]) << 8)
+ u64::from(octets[15]);
Self { Self {
first, first,
last, last,
@ -357,7 +337,8 @@ impl From<[u8; 16]> for common::IPv6 {
} }
impl From<::std::net::Ipv6Addr> for common::IPv6 { impl From<::std::net::Ipv6Addr> for common::IPv6 {
#[inline] fn from(v6: ::std::net::Ipv6Addr) -> Self { #[inline]
fn from(v6: ::std::net::Ipv6Addr) -> Self {
Self::from(v6.octets()) Self::from(v6.octets())
} }
} }
@ -382,25 +363,25 @@ impl<'a> From<&'a common::IPv6> for ::std::net::Ipv6Addr {
impl From<[u8; 4]> for common::ip_address::Ip { impl From<[u8; 4]> for common::ip_address::Ip {
fn from(octets: [u8; 4]) -> Self { fn from(octets: [u8; 4]) -> Self {
common::ip_address::Ip::Ipv4( common::ip_address::Ip::Ipv4(
u32::from(octets[0]) << 24 | u32::from(octets[0]) << 24 | u32::from(octets[1]) << 16 | u32::from(octets[2]) << 8
u32::from(octets[1]) << 16 | | u32::from(octets[3]),
u32::from(octets[2]) << 8 |
u32::from(octets[3])
) )
} }
} }
impl From<::std::net::Ipv4Addr> for common::ip_address::Ip { impl From<::std::net::Ipv4Addr> for common::ip_address::Ip {
#[inline] fn from(v4: ::std::net::Ipv4Addr) -> Self { #[inline]
fn from(v4: ::std::net::Ipv4Addr) -> Self {
Self::from(v4.octets()) Self::from(v4.octets())
} }
} }
impl<T> From<T> for common::ip_address::Ip impl<T> From<T> for common::ip_address::Ip
where where
common::IPv6: From<T> common::IPv6: From<T>,
{ {
#[inline] fn from(t: T) -> Self { #[inline]
fn from(t: T) -> Self {
common::ip_address::Ip::Ipv6(common::IPv6::from(t)) common::ip_address::Ip::Ipv6(common::IPv6::from(t))
} }
} }
@ -429,5 +410,8 @@ fn pb_duration(d: &::std::time::Duration) -> ::prost_types::Duration {
d.subsec_nanos() as i32 d.subsec_nanos() as i32
}; };
::prost_types::Duration { seconds, nanos } ::prost_types::Duration {
seconds,
nanos,
}
} }

View File

@ -6,12 +6,8 @@ use tower_grpc;
use super::codec::Protobuf; use super::codec::Protobuf;
use super::pb::proxy::telemetry::{ReportRequest, ReportResponse}; use super::pb::proxy::telemetry::{ReportRequest, ReportResponse};
use super::pb::proxy::telemetry::client::{ use super::pb::proxy::telemetry::client::Telemetry as TelemetrySvc;
Telemetry as TelemetrySvc, use super::pb::proxy::telemetry::client::telemetry_methods::Report as ReportRpc;
};
use super::pb::proxy::telemetry::client::telemetry_methods::{
Report as ReportRpc,
};
pub type ClientBody = tower_grpc::client::codec::EncodingBody< pub type ClientBody = tower_grpc::client::codec::EncodingBody<
Protobuf<ReportRequest, ReportResponse>, Protobuf<ReportRequest, ReportResponse>,
@ -20,12 +16,9 @@ pub type ClientBody = tower_grpc::client::codec::EncodingBody<
type TelemetryStream<F> = tower_grpc::client::BodyFuture< type TelemetryStream<F> = tower_grpc::client::BodyFuture<
tower_grpc::client::Unary< tower_grpc::client::Unary<
tower_grpc::client::ResponseFuture< tower_grpc::client::ResponseFuture<Protobuf<ReportRequest, ReportResponse>, F>,
Protobuf<ReportRequest, ReportResponse>, Protobuf<ReportRequest, ReportResponse>,
F
>, >,
Protobuf<ReportRequest, ReportResponse>,
>
>; >;
#[derive(Debug)] #[derive(Debug)]
@ -70,14 +63,15 @@ where
trace!("report in flight to controller for {:?}", t0.elapsed()); trace!("report in flight to controller for {:?}", t0.elapsed());
self.in_flight = Some((t0, fut)); self.in_flight = Some((t0, fut));
} }
Ok(Async::Ready(_)) => trace!("report sent to controller in {:?}", t0.elapsed()), Ok(Async::Ready(_)) => {
trace!("report sent to controller in {:?}", t0.elapsed())
}
Err(err) => warn!("controller error: {:?}", err), Err(err) => warn!("controller error: {:?}", err),
} }
} }
let controller_ready = self.in_flight.is_none() && let controller_ready = self.in_flight.is_none() && match rpc.poll_ready() {
match rpc.poll_ready() {
Ok(Async::Ready(_)) => true, Ok(Async::Ready(_)) => true,
Ok(Async::NotReady) => { Ok(Async::NotReady) => {
trace!("controller unavailable"); trace!("controller unavailable");
@ -92,14 +86,14 @@ where
match self.reports.poll() { match self.reports.poll() {
Ok(Async::NotReady) => { Ok(Async::NotReady) => {
return; return;
}, }
Ok(Async::Ready(None)) => { Ok(Async::Ready(None)) => {
error!("report stream complete"); error!("report stream complete");
return; return;
}, }
Err(err) => { Err(err) => {
warn!("report stream error: {:?}", err); warn!("report stream error: {:?}", err);
}, }
Ok(Async::Ready(Some(report))) => { Ok(Async::Ready(Some(report))) => {
// Attempt to send the report. Continue looping so that `reports` is // Attempt to send the report. Continue looping so that `reports` is
// polled until it's not ready. // polled until it's not ready.
@ -120,7 +114,7 @@ where
let rep = TelemetrySvc::new(&mut rpc).report(report); let rep = TelemetrySvc::new(&mut rpc).report(report);
self.in_flight = Some((Instant::now(), rep)); self.in_flight = Some((Instant::now(), rep));
} }
}, }
} }
} }
} }

View File

@ -7,9 +7,9 @@
//! As a rule, context types should implement `Clone + Send + Sync`. This allows them to //! As a rule, context types should implement `Clone + Send + Sync`. This allows them to
//! be stored in `http::Extensions`, for instance. Furthermore, because these contexts //! be stored in `http::Extensions`, for instance. Furthermore, because these contexts
//! will be sent to a telemetry processing thread, we want to avoid excessive cloning. //! will be sent to a telemetry processing thread, we want to avoid excessive cloning.
use control::pb::proxy::telemetry as proto;
use std::env; use std::env;
use std::sync::Arc; use std::sync::Arc;
use control::pb::proxy::telemetry as proto;
pub mod http; pub mod http;
pub mod transport; pub mod transport;
@ -51,15 +51,14 @@ impl Process {
Arc::new(Self { Arc::new(Self {
node: node.into(), node: node.into(),
scheduled_instance: instance.into(), scheduled_instance: instance.into(),
scheduled_namespace: ns.into() scheduled_namespace: ns.into(),
}) })
} }
/// Construct a new `Process` from environment variables. /// Construct a new `Process` from environment variables.
pub fn from_env() -> Arc<Self> { pub fn from_env() -> Arc<Self> {
fn get_var(key: &str) -> String { fn get_var(key: &str) -> String {
env::var(key) env::var(key).unwrap_or_else(|why| {
.unwrap_or_else(|why| {
warn!( warn!(
"Process::from_env(): Failed to get value of {} environment variable: {:?}", "Process::from_env(): Failed to get value of {} environment variable: {:?}",
key, key,
@ -103,7 +102,7 @@ impl Proxy {
pub fn is_inbound(&self) -> bool { pub fn is_inbound(&self) -> bool {
match *self { match *self {
Proxy::Inbound(_) => true, Proxy::Inbound(_) => true,
Proxy::Outbound(_) => false Proxy::Outbound(_) => false,
} }
} }

View File

@ -1,9 +1,9 @@
use futures::prelude::*;
use std::net::IpAddr;
use domain;
use ns_dns_tokio;
use abstract_ns; use abstract_ns;
use abstract_ns::HostResolve; use abstract_ns::HostResolve;
use domain;
use futures::prelude::*;
use ns_dns_tokio;
use std::net::IpAddr;
use std::path::Path; use std::path::Path;
use std::str::FromStr; use std::str::FromStr;
use tokio_core::reactor::Handle; use tokio_core::reactor::Handle;
@ -40,7 +40,9 @@ impl Config {
impl Resolver { impl Resolver {
pub fn new(config: Config, executor: &Handle) -> Self { pub fn new(config: Config, executor: &Handle) -> Self {
Resolver(ns_dns_tokio::DnsResolver::new_from_resolver(domain::resolv::Resolver::from_conf(executor, config.0))) Resolver(ns_dns_tokio::DnsResolver::new_from_resolver(
domain::resolv::Resolver::from_conf(executor, config.0),
))
} }
pub fn resolve_host(&self, host: &url::Host) -> IpAddrFuture { pub fn resolve_host(&self, host: &url::Host) -> IpAddrFuture {
@ -65,15 +67,12 @@ impl Future for IpAddrFuture {
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match *self { match *self {
IpAddrFuture::DNS(ref mut inner) => { IpAddrFuture::DNS(ref mut inner) => match inner.poll() {
match inner.poll() {
Ok(Async::NotReady) => Ok(Async::NotReady), Ok(Async::NotReady) => Ok(Async::NotReady),
Ok(Async::Ready(ips)) => Ok(Async::Ready(ips)) => ips.pick_one()
ips.pick_one()
.map(Async::Ready) .map(Async::Ready)
.ok_or(Error::NoAddressesFound), .ok_or(Error::NoAddressesFound),
Err(e) => Err(Error::ResolutionFailed(e)), Err(e) => Err(Error::ResolutionFailed(e)),
}
}, },
IpAddrFuture::Fixed(addr) => Ok(Async::Ready(addr)), IpAddrFuture::Fixed(addr) => Ok(Async::Ready(addr)),
IpAddrFuture::InvalidDNSName(ref name) => Err(Error::InvalidDNSName(name.clone())), IpAddrFuture::InvalidDNSName(ref name) => Err(Error::InvalidDNSName(name.clone())),

View File

@ -32,29 +32,25 @@ type CtxtExec = ::logging::ContextualExecutor<(&'static str, SocketAddr), Handle
// ===== impl Inbound ===== // ===== impl Inbound =====
impl<B> Inbound<B> { impl<B> Inbound<B> {
pub fn new( pub fn new(default_addr: Option<SocketAddr>, bind: Bind<B>) -> Self {
default_addr: Option<SocketAddr>,
bind: Bind<B>
) -> Self {
Self { Self {
default_addr, default_addr,
bind bind,
} }
} }
fn same_addr(a0: &SocketAddr, a1: &SocketAddr) -> bool { fn same_addr(a0: &SocketAddr, a1: &SocketAddr) -> bool {
(a0.port() == a1.port()) && (a0.port() == a1.port()) && match (a0.ip(), a1.ip()) {
match (a0.ip(), a1.ip()) {
(IpAddr::V6(a0), IpAddr::V4(a1)) => a0.to_ipv4() == Some(a1), (IpAddr::V6(a0), IpAddr::V4(a1)) => a0.to_ipv4() == Some(a1),
(IpAddr::V4(a0), IpAddr::V6(a1)) => Some(a0) == a1.to_ipv4(), (IpAddr::V4(a0), IpAddr::V6(a1)) => Some(a0) == a1.to_ipv4(),
(a0, a1) => (a0 == a1) (a0, a1) => (a0 == a1),
} }
} }
} }
impl<B> Recognize for Inbound<B> impl<B> Recognize for Inbound<B>
where where
B: tower_h2::Body + 'static B: tower_h2::Body + 'static,
{ {
type Request = http::Request<B>; type Request = http::Request<B>;
type Response = http::Response<telemetry::sensor::http::ResponseBody<tower_h2::RecvBody>>; type Response = http::Response<telemetry::sensor::http::ResponseBody<tower_h2::RecvBody>>;
@ -66,11 +62,7 @@ where
>; >;
type Key = SocketAddr; type Key = SocketAddr;
type RouteError = (); type RouteError = ();
type Service = Buffer<Reconnect<telemetry::sensor::NewHttp< type Service = Buffer<Reconnect<telemetry::sensor::NewHttp<Client<B>, B, tower_h2::RecvBody>>>;
Client<B>,
B,
tower_h2::RecvBody
>>>;
fn recognize(&self, req: &Self::Request) -> Option<Self::Key> { fn recognize(&self, req: &Self::Request) -> Option<Self::Key> {
let key = req.extensions() let key = req.extensions()
@ -82,8 +74,11 @@ where
Some(orig_dst) => { Some(orig_dst) => {
// If the original destination is actually the listening socket, // If the original destination is actually the listening socket,
// we don't want to create a loop. // we don't want to create a loop.
if Self::same_addr(&orig_dst, &ctx.local) { None } if Self::same_addr(&orig_dst, &ctx.local) {
else { Some(orig_dst) } None
} else {
Some(orig_dst)
}
} }
} }
}) })
@ -107,8 +102,7 @@ where
// is not ideal. // is not ideal.
// //
// TODO: Don't use unbounded buffering. // TODO: Don't use unbounded buffering.
Buffer::new(self.bind.bind_service(addr), self.bind.executor()) Buffer::new(self.bind.bind_service(addr), self.bind.executor()).map_err(|_| {})
.map_err(|_| {})
} }
} }
@ -122,9 +116,9 @@ mod tests {
use tokio_core::reactor::Core; use tokio_core::reactor::Core;
use tower_router::Recognize; use tower_router::Recognize;
use super::Inbound;
use bind::Bind; use bind::Bind;
use ctx; use ctx;
use super::Inbound;
fn new_inbound(default: Option<net::SocketAddr>, ctx: &Arc<ctx::Proxy>) -> Inbound<()> { fn new_inbound(default: Option<net::SocketAddr>, ctx: &Arc<ctx::Proxy>) -> Inbound<()> {
let core = Core::new().unwrap(); let core = Core::new().unwrap();

View File

@ -74,8 +74,8 @@ mod tower_fn; // TODO: move to tower-fn
use bind::Bind; use bind::Bind;
use control::pb::proxy::tap; use control::pb::proxy::tap;
use inbound::Inbound; use inbound::Inbound;
use outbound::Outbound;
use map_err::MapErr; use map_err::MapErr;
use outbound::Outbound;
/// Runs a sidecar proxy. /// Runs a sidecar proxy.
/// ///
@ -99,13 +99,13 @@ pub struct Main {
impl Main { impl Main {
pub fn new(config: config::Config) -> Self { pub fn new(config: config::Config) -> Self {
let control_listener = StdTcpListener::bind(SocketAddr::from(config.control_listener.addr)) let control_listener = StdTcpListener::bind(SocketAddr::from(config.control_listener.addr))
.expect("controller listener bind"); .expect("controller listener bind");
let inbound_listener = StdTcpListener::bind(SocketAddr::from(config.public_listener.addr)) let inbound_listener = StdTcpListener::bind(SocketAddr::from(config.public_listener.addr))
.expect("public listener bind"); .expect("public listener bind");
let outbound_listener = StdTcpListener::bind(SocketAddr::from(config.private_listener.addr)) let outbound_listener = StdTcpListener::bind(
.expect("private listener bind"); SocketAddr::from(config.private_listener.addr),
).expect("private listener bind");
Self { Self {
config, config,
@ -146,10 +146,7 @@ impl Main {
let control_host_and_port = config.control_host_and_port.clone(); let control_host_and_port = config.control_host_and_port.clone();
info!("using controller at {:?}", control_host_and_port); info!("using controller at {:?}", control_host_and_port);
info!( info!("routing on {:?}", outbound_listener.local_addr().unwrap(),);
"routing on {:?}",
outbound_listener.local_addr().unwrap(),
);
info!( info!(
"proxying on {:?} to {:?}", "proxying on {:?} to {:?}",
inbound_listener.local_addr().unwrap(), inbound_listener.local_addr().unwrap(),
@ -170,8 +167,7 @@ impl Main {
let dns_config = dns::Config::from_file(&config.resolv_conf_path); let dns_config = dns::Config::from_file(&config.resolv_conf_path);
let bind = Bind::new(executor.clone()) let bind = Bind::new(executor.clone()).with_sensors(sensors.clone());
.with_sensors(sensors.clone());
// Setup the public listener. This will listen on a publicly accessible // Setup the public listener. This will listen on a publicly accessible
// address and listen for inbound connections that should be forwarded // address and listen for inbound connections that should be forwarded
@ -179,7 +175,9 @@ impl Main {
let inbound = { let inbound = {
let ctx = ctx::Proxy::inbound(&process_ctx); let ctx = ctx::Proxy::inbound(&process_ctx);
let timeout = config.private_connect_timeout.unwrap_or_else(|| Duration::from_millis(20)); let timeout = config
.private_connect_timeout
.unwrap_or_else(|| Duration::from_millis(20));
let bind = bind.clone() let bind = bind.clone()
.with_connect_timeout(timeout) .with_connect_timeout(timeout)
.with_ctx(ctx.clone()); .with_ctx(ctx.clone());
@ -203,11 +201,9 @@ impl Main {
let outbound = { let outbound = {
let ctx = ctx::Proxy::outbound(&process_ctx); let ctx = ctx::Proxy::outbound(&process_ctx);
let bind = config.public_connect_timeout let bind = config
.map_or_else( .public_connect_timeout
|| bind.clone(), .map_or_else(|| bind.clone(), |t| bind.clone().with_connect_timeout(t))
|t| bind.clone().with_connect_timeout(t),
)
.with_ctx(ctx.clone()); .with_ctx(ctx.clone());
let fut = serve( let fut = serve(
@ -233,36 +229,33 @@ impl Main {
let (taps, observe) = control::Observe::new(100); let (taps, observe) = control::Observe::new(100);
let new_service = tap::server::Tap::new_service() let new_service = tap::server::Tap::new_service().observe(observe);
.observe(observe);
let server = serve_control( let server = serve_control(
control_listener, control_listener,
h2::server::Builder::default(), h2::server::Builder::default(),
new_service, new_service,
&executor &executor,
); );
let telemetry = telemetry let telemetry = telemetry
.make_control(&taps, &executor) .make_control(&taps, &executor)
.expect("bad news in telemetry town"); .expect("bad news in telemetry town");
let client = control_bg.bind( let client =
telemetry, control_bg.bind(telemetry, control_host_and_port, dns_config, &executor);
control_host_and_port,
dns_config,
&executor
);
let fut = client.join(server.map_err(|_| {})).map(|_| {}); let fut = client.join(server.map_err(|_| {})).map(|_| {});
executor.spawn(::logging::context_future("controller-client", fut)); executor.spawn(::logging::context_future("controller-client", fut));
let shutdown = controller_shutdown_signal.then(|_| Ok::<(), ()>(())); let shutdown = controller_shutdown_signal.then(|_| Ok::<(), ()>(()));
core.run(shutdown).expect("controller api"); core.run(shutdown).expect("controller api");
}).expect("initialize controller api thread"); })
.expect("initialize controller api thread");
} }
let fut = inbound.join(outbound) let fut = inbound
.join(outbound)
.map(|_| ()) .map(|_| ())
.map_err(|err| error!("main error: {:?}", err)); .map_err(|err| error!("main error: {:?}", err));
@ -288,12 +281,12 @@ where
Response = http::Response<telemetry::sensor::http::ResponseBody<B>>, Response = http::Response<telemetry::sensor::http::ResponseBody<B>>,
Error = E, Error = E,
RouteError = F, RouteError = F,
> + 'static, >
+ 'static,
{ {
let listen_addr = listen.local_addr().expect("local addr"); let listen_addr = listen.local_addr().expect("local addr");
let bind = TcpListener::from_listener(listen, &listen_addr, &executor) let bind = TcpListener::from_listener(listen, &listen_addr, &executor).expect("bind");
.expect("bind");
let router = Router::new(recognize); let router = Router::new(recognize);
let stack = NewServiceFn::new(move || { let stack = NewServiceFn::new(move || {
@ -304,19 +297,28 @@ where
MapErr::new(router) MapErr::new(router)
}); });
let server = Server::new(stack, h2_builder, ::logging::context_executor(("serve", listen_addr) , executor.clone())); let server = Server::new(
stack,
h2_builder,
::logging::context_executor(("serve", listen_addr), executor.clone()),
);
let f = bind.incoming().fold( let f = bind.incoming().fold(
(server, proxy_ctx, sensors, executor), (server, proxy_ctx, sensors, executor),
move |(server, proxy_ctx, sensors, executor), (socket, remote_addr)| { move |(server, proxy_ctx, sensors, executor), (socket, remote_addr)| {
if let Err(e) = socket.set_nodelay(true) { if let Err(e) = socket.set_nodelay(true) {
warn!("could not set TCP_NODELAY on {:?}/{:?}: {}", warn!(
socket.local_addr(), socket.peer_addr(), e); "could not set TCP_NODELAY on {:?}/{:?}: {}",
socket.local_addr(),
socket.peer_addr(),
e
);
} }
let opened_at = Instant::now(); let opened_at = Instant::now();
let orig_dst = transport::get_original_dst(&socket); let orig_dst = transport::get_original_dst(&socket);
let local_addr = socket.local_addr().unwrap_or(listen_addr); let local_addr = socket.local_addr().unwrap_or(listen_addr);
let srv_ctx = ctx::transport::Server::new(&proxy_ctx, &local_addr, &remote_addr, &orig_dst); let srv_ctx =
ctx::transport::Server::new(&proxy_ctx, &local_addr, &remote_addr, &orig_dst);
connection::Connection::handshake(socket).map(move |session| { connection::Connection::handshake(socket).map(move |session| {
let io = sensors.accept(session, opened_at, &srv_ctx); let io = sensors.accept(session, opened_at, &srv_ctx);
@ -345,22 +347,22 @@ fn serve_control<N, B>(
) -> Box<Future<Item = (), Error = io::Error> + 'static> ) -> Box<Future<Item = (), Error = io::Error> + 'static>
where where
B: Body + 'static, B: Body + 'static,
N: NewService< N: NewService<Request = http::Request<RecvBody>, Response = http::Response<B>> + 'static,
Request = http::Request<RecvBody>,
Response = http::Response<B>,
> + 'static,
{ {
let listen_addr = listen.local_addr().expect("local addr"); let listen_addr = listen.local_addr().expect("local addr");
let bind = TcpListener::from_listener(listen, &listen_addr, executor) let bind = TcpListener::from_listener(listen, &listen_addr, executor).expect("bind");
.expect("bind");
let server = Server::new(new_service, h2_builder, executor.clone()); let server = Server::new(new_service, h2_builder, executor.clone());
let f = bind.incoming().fold( let f = bind.incoming().fold(
(server, executor.clone()), (server, executor.clone()),
move |(server, executor), (socket, _)| { move |(server, executor), (socket, _)| {
if let Err(e) = socket.set_nodelay(true) { if let Err(e) = socket.set_nodelay(true) {
warn!("could not set TCP_NODELAY on {:?}/{:?}: {}", warn!(
socket.local_addr(), socket.peer_addr(), e); "could not set TCP_NODELAY on {:?}/{:?}: {}",
socket.local_addr(),
socket.peer_addr(),
e
);
} }
connection::Connection::handshake(socket).map(move |session| { connection::Connection::handshake(socket).map(move |session| {

View File

@ -4,9 +4,9 @@ use std::fmt;
use std::rc::Rc; use std::rc::Rc;
use chrono::Utc; use chrono::Utc;
use futures::{Future, Poll};
use futures::future::{Executor, ExecuteError};
use env_logger::LogBuilder; use env_logger::LogBuilder;
use futures::{Future, Poll};
use futures::future::{ExecuteError, Executor};
use log::LogLevel; use log::LogLevel;
const ENV_LOG: &str = "CONDUIT_PROXY_LOG"; const ENV_LOG: &str = "CONDUIT_PROXY_LOG";
@ -39,7 +39,6 @@ pub fn init() {
.parse(&env::var(ENV_LOG).unwrap_or_default()) .parse(&env::var(ENV_LOG).unwrap_or_default())
.init() .init()
.expect("logger"); .expect("logger");
} }
/// Execute a closure with a `Debug` item attached to allow log messages. /// Execute a closure with a `Debug` item attached to allow log messages.

View File

@ -11,8 +11,7 @@ fn main() {
Err(e) => { Err(e) => {
eprintln!("configuration error: {:#?}", e); eprintln!("configuration error: {:#?}", e);
process::exit(64) process::exit(64)
}, }
}; };
conduit_proxy::Main::new(config) conduit_proxy::Main::new(config).run();
.run();
} }

View File

@ -21,17 +21,22 @@ pub struct ResponseFuture<T, E> {
// ===== impl MapErr ===== // ===== impl MapErr =====
impl<T, E> MapErr<T, E> impl<T, E> MapErr<T, E>
where T: Service<Error = E>, where
T: Service<Error = E>,
E: Debug, E: Debug,
{ {
/// Crete a new `MapErr` /// Crete a new `MapErr`
pub fn new(inner: T) -> Self { pub fn new(inner: T) -> Self {
MapErr { inner, _p: PhantomData } MapErr {
inner,
_p: PhantomData,
}
} }
} }
impl<T, B, E> Service for MapErr<T, E> impl<T, B, E> Service for MapErr<T, E>
where T: Service<Response = http::Response<B>, Error = E>, where
T: Service<Response = http::Response<B>, Error = E>,
B: Default, B: Default,
E: Debug, E: Debug,
{ {
@ -48,14 +53,18 @@ where T: Service<Response = http::Response<B>, Error = E>,
fn call(&mut self, request: Self::Request) -> Self::Future { fn call(&mut self, request: Self::Request) -> Self::Future {
let inner = self.inner.call(request); let inner = self.inner.call(request);
ResponseFuture { inner, _p: PhantomData } ResponseFuture {
inner,
_p: PhantomData,
}
} }
} }
// ===== impl ResponseFuture ===== // ===== impl ResponseFuture =====
impl<T, B, E> Future for ResponseFuture<T, E> impl<T, B, E> Future for ResponseFuture<T, E>
where T: Future<Item = http::Response<B>, Error = E>, where
T: Future<Item = http::Response<B>, Error = E>,
B: Default, B: Default,
E: Debug, E: Debug,
{ {
@ -63,8 +72,7 @@ where T: Future<Item = http::Response<B>, Error = E>,
type Error = h2::Error; type Error = h2::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
self.inner.poll() self.inner.poll().or_else(|e| {
.or_else(|e| {
error!("turning h2 error into 500: {:?}", e); error!("turning h2 error into 500: {:?}", e);
let response = http::Response::builder() let response = http::Response::builder()
.status(500) .status(500)

View File

@ -20,10 +20,10 @@ type Error = tower_buffer::Error<
tower_balance::Error< tower_balance::Error<
tower_reconnect::Error< tower_reconnect::Error<
tower_h2::client::Error, tower_h2::client::Error,
tower_h2::client::ConnectError<transport::TimeoutError<io::Error>> tower_h2::client::ConnectError<transport::TimeoutError<io::Error>>,
>, >,
(), (),
> >,
>; >;
pub struct Outbound<B> { pub struct Outbound<B> {
@ -44,7 +44,7 @@ impl<B> Outbound<B> {
impl<B> Recognize for Outbound<B> impl<B> Recognize for Outbound<B>
where where
B: tower_h2::Body + 'static B: tower_h2::Body + 'static,
{ {
type Request = http::Request<B>; type Request = http::Request<B>;
type Response = http::Response<telemetry::sensor::http::ResponseBody<tower_h2::RecvBody>>; type Response = http::Response<telemetry::sensor::http::ResponseBody<tower_h2::RecvBody>>;
@ -66,9 +66,10 @@ where
/// ///
/// Buffering is currently unbounded and does not apply timeouts. This must be /// Buffering is currently unbounded and does not apply timeouts. This must be
/// changed. /// changed.
fn bind_service(&mut self, authority: &http::uri::Authority) fn bind_service(
-> Result<Self::Service, Self::RouteError> &mut self,
{ authority: &http::uri::Authority,
) -> Result<Self::Service, Self::RouteError> {
debug!("building outbound client to {:?}", authority); debug!("building outbound client to {:?}", authority);
let resolve = self.discovery.resolve(authority, self.bind.clone()); let resolve = self.discovery.resolve(authority, self.bind.clone());
@ -79,7 +80,6 @@ where
// which is not ideal. // which is not ideal.
// //
// TODO: Don't use unbounded buffering. // TODO: Don't use unbounded buffering.
Buffer::new(balance, self.bind.executor()) Buffer::new(balance, self.bind.executor()).map_err(|_| {})
.map_err(|_| {})
} }
} }

View File

@ -1,16 +1,16 @@
use std::{fmt, io}; use std::{fmt, io};
use std::time::{Duration, Instant};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use futures::{Async, Future, Poll, Stream}; use futures::{Async, Future, Poll, Stream};
use futures_mpsc_lossy::Receiver; use futures_mpsc_lossy::Receiver;
use tokio_core::reactor::{Handle, Timeout}; use tokio_core::reactor::{Handle, Timeout};
use ctx;
use super::event::Event; use super::event::Event;
use super::tap::Taps;
use super::metrics::Metrics; use super::metrics::Metrics;
use super::tap::Taps;
use control::pb::telemetry::ReportRequest; use control::pb::telemetry::ReportRequest;
use ctx;
/// A `Control` which has been configured but not initialized. /// A `Control` which has been configured but not initialized.
#[derive(Debug)] #[derive(Debug)]
@ -138,7 +138,8 @@ impl Control {
/// Reset the flush timeout. /// Reset the flush timeout.
fn reset_timeout(&mut self) { fn reset_timeout(&mut self) {
trace!("flushing in {:?}", self.flush_interval); trace!("flushing in {:?}", self.flush_interval);
self.flush_timeout.reset(Instant::now() + self.flush_interval); self.flush_timeout
.reset(Instant::now() + self.flush_interval);
} }
fn recv(&mut self) -> Async<Option<Event>> { fn recv(&mut self) -> Async<Option<Event>> {
@ -185,7 +186,9 @@ impl Stream for Control {
} }
Async::Ready(None) => { Async::Ready(None) => {
warn!("events finished"); warn!("events finished");
let report = self.metrics.take().map(|mut m| Self::generate_report(&mut m)); let report = self.metrics
.take()
.map(|mut m| Self::generate_report(&mut m));
if report.is_none() { if report.is_none() {
return Ok(Async::Ready(None)); return Ok(Async::Ready(None));
} }
@ -226,7 +229,10 @@ impl fmt::Debug for Control {
.field("rx", &self.rx) .field("rx", &self.rx)
.field("taps", &self.taps) .field("taps", &self.taps)
.field("flush_interval", &self.flush_interval) .field("flush_interval", &self.flush_interval)
.field("flush_timeout", &format!("Timeout({:?})", &self.flush_interval)) .field(
"flush_timeout",
&format!("Timeout({:?})", &self.flush_interval),
)
.finish() .finish()
} }
} }

View File

@ -76,18 +76,17 @@ impl Event {
pub fn is_transport(&self) -> bool { pub fn is_transport(&self) -> bool {
match *self { match *self {
Event::TransportOpen(_) | Event::TransportOpen(_) | Event::TransportClose(_, _) => true,
Event::TransportClose(_, _) => true,
_ => false, _ => false,
} }
} }
pub fn proxy(&self) -> &Arc<ctx::Proxy> { pub fn proxy(&self) -> &Arc<ctx::Proxy> {
match *self { match *self {
Event::TransportOpen(ref ctx) | Event::TransportOpen(ref ctx) | Event::TransportClose(ref ctx, _) => ctx.proxy(),
Event::TransportClose(ref ctx, _) => ctx.proxy(), Event::StreamRequestOpen(ref req) | Event::StreamRequestFail(ref req, _) => {
Event::StreamRequestOpen(ref req) | &req.server.proxy
Event::StreamRequestFail(ref req, _) => &req.server.proxy, }
Event::StreamResponseOpen(ref rsp, _) | Event::StreamResponseOpen(ref rsp, _) |
Event::StreamResponseFail(ref rsp, _) | Event::StreamResponseFail(ref rsp, _) |
Event::StreamResponseEnd(ref rsp, _) => &rsp.request.server.proxy, Event::StreamResponseEnd(ref rsp, _) => &rsp.request.server.proxy,

View File

@ -1,21 +1,18 @@
use std::{u32, u64};
use std::net; use std::net;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use std::{u32, u64};
use http; use http;
use ordermap::OrderMap; use ordermap::OrderMap;
use ctx; use control::pb::common::{HttpMethod, TcpAddress};
use control::pb::common::{
TcpAddress,
HttpMethod,
};
use control::pb::proxy::telemetry::{ use control::pb::proxy::telemetry::{
eos_ctx, eos_ctx,
ClientTransport, ClientTransport,
EosCtx, EosCtx,
EosScope, EosScope,
Latency as PbLatency,
ReportRequest, ReportRequest,
RequestCtx, RequestCtx,
RequestScope, RequestScope,
@ -24,9 +21,9 @@ use control::pb::proxy::telemetry::{
ServerTransport, ServerTransport,
StreamSummary, StreamSummary,
TransportSummary, TransportSummary,
Latency as PbLatency,
}; };
use telemetry::event::{Event}; use ctx;
use telemetry::event::Event;
#[derive(Debug)] #[derive(Debug)]
pub struct Metrics { pub struct Metrics {
@ -113,24 +110,27 @@ impl Metrics {
match *event { match *event {
Event::TransportOpen(ref transport) => { Event::TransportOpen(ref transport) => {
self.transport(transport).connects += 1; self.transport(transport).connects += 1;
}, }
Event::TransportClose(ref transport, ref close) => { Event::TransportClose(ref transport, ref close) => {
self.transport(transport).disconnects.push(TransportSummary { self.transport(transport)
.disconnects
.push(TransportSummary {
duration_ms: dur_to_ms(close.duration), duration_ms: dur_to_ms(close.duration),
bytes_sent: 0, bytes_sent: 0,
}); });
}, }
Event::StreamRequestOpen(ref req) => { Event::StreamRequestOpen(ref req) => {
self.request(req).count += 1; self.request(req).count += 1;
}, }
Event::StreamRequestFail(ref req, ref fail) => { Event::StreamRequestFail(ref req, ref fail) => {
let stats = self.request(req) let stats = self.request(req)
.responses .responses
.entry(None) .entry(None)
.or_insert_with(Default::default); .or_insert_with(Default::default);
let ends = stats.ends let ends = stats
.ends
.entry(End::Reset(fail.error.into())) .entry(End::Reset(fail.error.into()))
.or_insert_with(Default::default); .or_insert_with(Default::default);
@ -145,11 +145,11 @@ impl Metrics {
bytes_sent: 0, bytes_sent: 0,
frames_sent: 0, frames_sent: 0,
}); });
}, }
Event::StreamResponseOpen(ref res, ref open) => { Event::StreamResponseOpen(ref res, ref open) => {
self.response(res).latencies.add(open.since_request_open); self.response(res).latencies.add(open.since_request_open);
}, }
Event::StreamResponseFail(ref res, ref fail) => { Event::StreamResponseFail(ref res, ref fail) => {
self.response_end(res, End::Reset(fail.error.into())) self.response_end(res, End::Reset(fail.error.into()))
.push(EndStats { .push(EndStats {
@ -157,7 +157,7 @@ impl Metrics {
bytes_sent: fail.bytes_sent, bytes_sent: fail.bytes_sent,
frames_sent: fail.frames_sent, frames_sent: fail.frames_sent,
}); });
}, }
Event::StreamResponseEnd(ref res, ref end) => { Event::StreamResponseEnd(ref res, ref end) => {
let e = end.grpc_status.map(End::Grpc).unwrap_or(End::Other); let e = end.grpc_status.map(End::Grpc).unwrap_or(End::Other);
self.response_end(res, e).push(EndStats { self.response_end(res, e).push(EndStats {
@ -165,7 +165,7 @@ impl Metrics {
bytes_sent: end.bytes_sent, bytes_sent: end.bytes_sent,
frames_sent: end.frames_sent, frames_sent: end.frames_sent,
}); });
}, }
} }
} }
@ -177,11 +177,20 @@ impl Metrics {
fn response<'a>(&mut self, res: &'a Arc<ctx::http::Response>) -> &mut ResponseStats { fn response<'a>(&mut self, res: &'a Arc<ctx::http::Response>) -> &mut ResponseStats {
let req = self.request(&res.request); let req = self.request(&res.request);
req.responses.entry(Some(res.status)).or_insert_with(Default::default) req.responses
.entry(Some(res.status))
.or_insert_with(Default::default)
} }
fn response_end<'a>(&mut self, res: &'a Arc<ctx::http::Response>, end: End) -> &mut Vec<EndStats> { fn response_end<'a>(
self.response(res).ends.entry(end).or_insert_with(Default::default) &mut self,
res: &'a Arc<ctx::http::Response>,
end: End,
) -> &mut Vec<EndStats> {
self.response(res)
.ends
.entry(end)
.or_insert_with(Default::default)
} }
fn transport<'a>(&mut self, transport: &'a ctx::transport::Ctx) -> &mut TransportStats { fn transport<'a>(&mut self, transport: &'a ctx::transport::Ctx) -> &mut TransportStats {
@ -192,11 +201,9 @@ impl Metrics {
.entry(source) .entry(source)
.or_insert_with(TransportStats::default) .or_insert_with(TransportStats::default)
} }
ctx::transport::Ctx::Client(ref c) => { ctx::transport::Ctx::Client(ref c) => self.destinations
self.destinations
.entry(c.remote) .entry(c.remote)
.or_insert_with(TransportStats::default) .or_insert_with(TransportStats::default),
}
} }
} }
@ -232,7 +239,6 @@ impl Metrics {
let mut ends = Vec::with_capacity(res_stats.ends.len()); let mut ends = Vec::with_capacity(res_stats.ends.len());
for (end, end_stats) in res_stats.ends { for (end, end_stats) in res_stats.ends {
let mut streams = Vec::with_capacity(end_stats.len()); let mut streams = Vec::with_capacity(end_stats.len());
for stats in end_stats { for stats in end_stats {
@ -257,8 +263,10 @@ impl Metrics {
responses.push(ResponseScope { responses.push(ResponseScope {
ctx: status_code.map(|code| ResponseCtx { ctx: status_code.map(|code| {
ResponseCtx {
http_status_code: u32::from(code.as_u16()), http_status_code: u32::from(code.as_u16()),
}
}), }),
ends: ends, ends: ends,
response_latencies: res_stats.latencies.into(), response_latencies: res_stats.latencies.into(),
@ -269,7 +277,8 @@ impl Metrics {
ctx: Some(RequestCtx { ctx: Some(RequestCtx {
method: Some(HttpMethod::from(&req.method)), method: Some(HttpMethod::from(&req.method)),
path: req.uri.path().to_string(), path: req.uri.path().to_string(),
authority: req.uri.authority_part() authority: req.uri
.authority_part()
.map(|a| a.to_string()) .map(|a| a.to_string())
.unwrap_or_else(String::new), .unwrap_or_else(String::new),
source_ip: Some(req.source.into()), source_ip: Some(req.source.into()),
@ -311,9 +320,7 @@ impl From<Duration> for Latency {
}; };
// divide the duration as ms by ten to get the value in tenths of a ms. // divide the duration as ms by ten to get the value in tenths of a ms.
let as_tenths = as_ms let as_tenths = as_ms.and_then(|ms| ms.checked_div(10)).unwrap_or_else(|| {
.and_then(|ms| ms.checked_div(10))
.unwrap_or_else(|| {
debug!("{:?} too large to convert to tenths of a millisecond!", dur); debug!("{:?} too large to convert to tenths of a millisecond!", dur);
u32::MAX u32::MAX
}); });
@ -337,11 +344,13 @@ impl Into<Vec<PbLatency>> for Latencies {
fn into(mut self) -> Vec<PbLatency> { fn into(mut self) -> Vec<PbLatency> {
// NOTE: `OrderMap.drain` means we can reuse the allocated memory --- can we // NOTE: `OrderMap.drain` means we can reuse the allocated memory --- can we
// ensure we're not allocating a new OrderMap after covnerting to pb? // ensure we're not allocating a new OrderMap after covnerting to pb?
self.0.drain(..) self.0
.map(|(Latency(latency), count)| .drain(..)
.map(|(Latency(latency), count)| {
PbLatency { PbLatency {
latency, latency,
count, count,
}
}) })
.collect() .collect()
} }
@ -372,14 +381,29 @@ mod tests {
assert!(latencies.0.is_empty()); assert!(latencies.0.is_empty());
latencies.add(Duration::from_secs(10)); latencies.add(Duration::from_secs(10));
assert_eq!(latencies.0.get(&Latency::from(Duration::from_secs(10))), Some(&1)); assert_eq!(
latencies.0.get(&Latency::from(Duration::from_secs(10))),
Some(&1)
);
latencies.add(Duration::from_secs(15)); latencies.add(Duration::from_secs(15));
assert_eq!(latencies.0.get(&Latency::from(Duration::from_secs(10))), Some(&1)); assert_eq!(
assert_eq!(latencies.0.get(&Latency::from(Duration::from_secs(15))), Some(&1)); latencies.0.get(&Latency::from(Duration::from_secs(10))),
Some(&1)
);
assert_eq!(
latencies.0.get(&Latency::from(Duration::from_secs(15))),
Some(&1)
);
latencies.add(Duration::from_secs(10)); latencies.add(Duration::from_secs(10));
assert_eq!(latencies.0.get(&Latency::from(Duration::from_secs(10))), Some(&2)); assert_eq!(
assert_eq!(latencies.0.get(&Latency::from(Duration::from_secs(15))), Some(&1)); latencies.0.get(&Latency::from(Duration::from_secs(10))),
Some(&2)
);
assert_eq!(
latencies.0.get(&Latency::from(Duration::from_secs(15))),
Some(&1)
);
} }
} }

View File

@ -13,7 +13,7 @@ mod metrics;
pub mod sensor; pub mod sensor;
pub mod tap; pub mod tap;
pub use self::control::{MakeControl, Control}; pub use self::control::{Control, MakeControl};
pub use self::event::Event; pub use self::event::Event;
pub use self::sensor::Sensors; pub use self::sensor::Sensors;
@ -39,10 +39,6 @@ pub fn new(
) -> (Sensors, MakeControl) { ) -> (Sensors, MakeControl) {
let (tx, rx) = futures_mpsc_lossy::channel(capacity); let (tx, rx) = futures_mpsc_lossy::channel(capacity);
let s = Sensors::new(tx); let s = Sensors::new(tx);
let c = MakeControl::new( let c = MakeControl::new(rx, flush_interval, process);
rx,
flush_interval,
process,
);
(s, c) (s, c)
} }

View File

@ -77,17 +77,14 @@ impl<N, A, B> NewHttp<N, A, B>
where where
A: Body + 'static, A: Body + 'static,
B: Body + 'static, B: Body + 'static,
N: NewService< N: NewService<Request = http::Request<A>, Response = http::Response<B>, Error = client::Error>
Request = http::Request<A>, + 'static,
Response = http::Response<B>,
Error = client::Error>
+ 'static
{ {
pub(super) fn new( pub(super) fn new(
next_id: Arc<AtomicUsize>, next_id: Arc<AtomicUsize>,
new_service: N, new_service: N,
handle: &super::Handle, handle: &super::Handle,
client_ctx: &Arc<ctx::transport::Client> client_ctx: &Arc<ctx::transport::Client>,
) -> Self { ) -> Self {
Self { Self {
next_id, next_id,
@ -103,11 +100,8 @@ impl<N, A, B> NewService for NewHttp<N, A, B>
where where
A: Body + 'static, A: Body + 'static,
B: Body + 'static, B: Body + 'static,
N: NewService< N: NewService<Request = http::Request<A>, Response = http::Response<B>, Error = client::Error>
Request = http::Request<A>, + 'static,
Response = http::Response<B>,
Error = client::Error>
+ 'static
{ {
type Request = N::Request; type Request = N::Request;
type Response = http::Response<ResponseBody<B>>; type Response = http::Response<ResponseBody<B>>;
@ -158,11 +152,8 @@ impl<S, A, B> Service for Http<S, A, B>
where where
A: Body + 'static, A: Body + 'static,
B: Body + 'static, B: Body + 'static,
S: Service< S: Service<Request = http::Request<A>, Response = http::Response<B>, Error = client::Error>
Request = http::Request<A>, + 'static,
Response = http::Response<B>,
Error = client::Error>
+ 'static
{ {
type Request = S::Request; type Request = S::Request;
type Response = http::Response<ResponseBody<B>>; type Response = http::Response<ResponseBody<B>>;
@ -180,7 +171,8 @@ where
let id = self.next_id.fetch_add(1, Ordering::SeqCst); let id = self.next_id.fetch_add(1, Ordering::SeqCst);
let ctx = ctx::http::Request::new(&req, &ctx, &self.client_ctx, id); let ctx = ctx::http::Request::new(&req, &ctx, &self.client_ctx, id);
self.handle.send(|| Event::StreamRequestOpen(Arc::clone(&ctx))); self.handle
.send(|| Event::StreamRequestOpen(Arc::clone(&ctx)));
Some(RespondInner { Some(RespondInner {
ctx, ctx,
@ -196,7 +188,7 @@ where
Respond { Respond {
future, future,
inner, inner,
_p: PhantomData _p: PhantomData,
} }
} }
} }
@ -206,7 +198,7 @@ where
impl<F, B> Future for Respond<F, B> impl<F, B> Future for Respond<F, B>
where where
F: Future<Item = http::Response<B>, Error = client::Error>, F: Future<Item = http::Response<B>, Error = client::Error>,
B: Body + 'static B: Body + 'static,
{ {
type Item = http::Response<ResponseBody<B>>; type Item = http::Response<ResponseBody<B>>;
type Error = F::Error; type Error = F::Error;
@ -230,7 +222,7 @@ where
Arc::clone(&ctx), Arc::clone(&ctx),
event::StreamResponseOpen { event::StreamResponseOpen {
since_request_open: request_open.elapsed(), since_request_open: request_open.elapsed(),
} },
) )
}); });
@ -249,7 +241,7 @@ where
since_response_open: Duration::default(), since_response_open: Duration::default(),
bytes_sent: 0, bytes_sent: 0,
frames_sent: 0, frames_sent: 0,
} },
) )
}); });
@ -294,7 +286,7 @@ where
event::StreamRequestFail { event::StreamRequestFail {
error, error,
since_request_open: request_open.elapsed(), since_request_open: request_open.elapsed(),
} },
) )
}); });
} }
@ -341,21 +333,21 @@ impl<B> ResponseBody<B> {
since_response_open: response_open.elapsed(), since_response_open: response_open.elapsed(),
bytes_sent, bytes_sent,
frames_sent, frames_sent,
} },
) )
}); });
} }
} }
Err(e) Err(e)
}, }
} }
} }
} }
impl<B> Body for ResponseBody<B> impl<B> Body for ResponseBody<B>
where where
B: Body + 'static B: Body + 'static,
{ {
/// The body chunk type /// The body chunk type
type Data = <B::Data as IntoBuf>::Buf; type Data = <B::Data as IntoBuf>::Buf;
@ -406,7 +398,7 @@ where
since_response_open: response_open.elapsed(), since_response_open: response_open.elapsed(),
bytes_sent, bytes_sent,
frames_sent, frames_sent,
} },
) )
}) })
} }

View File

@ -15,7 +15,7 @@ use telemetry::event;
pub mod http; pub mod http;
mod transport; mod transport;
pub use self::http::{NewHttp, Http}; pub use self::http::{Http, NewHttp};
pub use self::transport::{Connect, Transport}; pub use self::transport::{Connect, Transport};
/// Accepts events from sensors. /// Accepts events from sensors.
@ -27,7 +27,10 @@ struct Handle(Option<Sender<event::Event>>);
pub struct Sensors(Handle); pub struct Sensors(Handle);
impl Handle { impl Handle {
fn send<F>(&mut self, mk: F) where F: FnOnce()-> event::Event { fn send<F>(&mut self, mk: F)
where
F: FnOnce() -> event::Event,
{
if let Some(tx) = self.0.as_mut() { if let Some(tx) = self.0.as_mut() {
// We may want to capture timestamps here instead of on the consumer-side... That // We may want to capture timestamps here instead of on the consumer-side... That
// level of precision doesn't necessarily seem worth it yet. // level of precision doesn't necessarily seem worth it yet.
@ -51,8 +54,14 @@ impl Sensors {
Sensors(Handle(None)) Sensors(Handle(None))
} }
pub fn accept<T>(&self, io: T, opened_at: Instant, ctx: &Arc<ctx::transport::Server>) -> Transport<T> pub fn accept<T>(
where T: AsyncRead + AsyncWrite &self,
io: T,
opened_at: Instant,
ctx: &Arc<ctx::transport::Server>,
) -> Transport<T>
where
T: AsyncRead + AsyncWrite,
{ {
debug!("server connection open"); debug!("server connection open");
let ctx = Arc::new(ctx::transport::Ctx::Server(Arc::clone(ctx))); let ctx = Arc::new(ctx::transport::Ctx::Server(Arc::clone(ctx)));
@ -60,7 +69,8 @@ impl Sensors {
} }
pub fn connect<C>(&self, connect: C, ctx: &Arc<ctx::transport::Client>) -> Connect<C> pub fn connect<C>(&self, connect: C, ctx: &Arc<ctx::transport::Client>) -> Connect<C>
where C: tokio_connect::Connect where
C: tokio_connect::Connect,
{ {
Connect::new(connect, &self.0, ctx) Connect::new(connect, &self.0, ctx)
} }
@ -69,15 +79,13 @@ impl Sensors {
&self, &self,
next_id: Arc<AtomicUsize>, next_id: Arc<AtomicUsize>,
new_service: N, new_service: N,
client_ctx: &Arc<ctx::transport::Client> client_ctx: &Arc<ctx::transport::Client>,
) -> NewHttp<N, A, B> ) -> NewHttp<N, A, B>
where where
A: Body + 'static, A: Body + 'static,
B: Body + 'static, B: Body + 'static,
N: NewService< N: NewService<Request = Request<A>, Response = Response<B>, Error = client::Error>
Request = Request<A>, + 'static,
Response = Response<B>,
Error = client::Error> + 'static
{ {
NewHttp::new(next_id, new_service, &self.0, client_ctx) NewHttp::new(next_id, new_service, &self.0, client_ctx)
} }

View File

@ -43,7 +43,12 @@ pub struct Connecting<C: tokio_connect::Connect> {
impl<T: AsyncRead + AsyncWrite> Transport<T> { impl<T: AsyncRead + AsyncWrite> Transport<T> {
/// Wraps a transport with telemetry and emits a transport open event. /// Wraps a transport with telemetry and emits a transport open event.
pub(super) fn open(io: T, opened_at: Instant, handle: &super::Handle, ctx: Arc<ctx::transport::Ctx>) -> Self { pub(super) fn open(
io: T,
opened_at: Instant,
handle: &super::Handle,
ctx: Arc<ctx::transport::Ctx>,
) -> Self {
let mut handle = handle.clone(); let mut handle = handle.clone();
handle.send(|| event::Event::TransportOpen(Arc::clone(&ctx))); handle.send(|| event::Event::TransportOpen(Arc::clone(&ctx)));
@ -70,27 +75,43 @@ impl<T: AsyncRead + AsyncWrite> Transport<T> {
Ok(v) => Ok(v), Ok(v) => Ok(v),
Err(e) => { Err(e) => {
if e.kind() != io::ErrorKind::WouldBlock { if e.kind() != io::ErrorKind::WouldBlock {
if let Some(Inner { mut handle, ctx, opened_at }) = self.1.take() { if let Some(Inner {
mut handle,
ctx,
opened_at,
}) = self.1.take()
{
handle.send(move || { handle.send(move || {
let duration = opened_at.elapsed(); let duration = opened_at.elapsed();
let ev = event::TransportClose { duration, clean: false }; let ev = event::TransportClose {
duration,
clean: false,
};
event::Event::TransportClose(ctx, ev) event::Event::TransportClose(ctx, ev)
}); });
} }
} }
Err(e) Err(e)
}, }
} }
} }
} }
impl<T> Drop for Transport<T> { impl<T> Drop for Transport<T> {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(Inner { mut handle, ctx, opened_at }) = self.1.take() { if let Some(Inner {
mut handle,
ctx,
opened_at,
}) = self.1.take()
{
handle.send(move || { handle.send(move || {
let duration = opened_at.elapsed(); let duration = opened_at.elapsed();
let ev = event::TransportClose { clean: true, duration }; let ev = event::TransportClose {
clean: true,
duration,
};
event::Event::TransportClose(ctx, ev) event::Event::TransportClose(ctx, ev)
}); });
} }

View File

@ -1,5 +1,5 @@
use std::net;
use std::boxed::Box; use std::boxed::Box;
use std::net;
use std::sync::Arc; use std::sync::Arc;
use http; use http;
@ -8,8 +8,8 @@ use ipnet::{Contains, Ipv4Net, Ipv6Net};
use super::Event; use super::Event;
use control::pb::common::ip_address; use control::pb::common::ip_address;
use control::pb::tap::observe_request; use control::pb::tap::observe_request;
use ctx;
use convert::*; use convert::*;
use ctx;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(super) enum Match { pub(super) enum Match {
@ -76,55 +76,44 @@ impl Match {
Match::Not(ref not) => !not.matches(ev), Match::Not(ref not) => !not.matches(ev),
Match::Source(ref src) => { Match::Source(ref src) => match *ev {
match *ev {
Event::StreamRequestOpen(ref req) | Event::StreamRequestFail(ref req, _) => { Event::StreamRequestOpen(ref req) | Event::StreamRequestFail(ref req, _) => {
src.matches(&req.server.remote) src.matches(&req.server.remote)
}, }
Event::StreamResponseOpen(ref rsp, _) | Event::StreamResponseOpen(ref rsp, _) |
Event::StreamResponseFail(ref rsp, _) | Event::StreamResponseFail(ref rsp, _) |
Event::StreamResponseEnd(ref rsp, _) => { Event::StreamResponseEnd(ref rsp, _) => src.matches(&rsp.request.server.remote),
src.matches(&rsp.request.server.remote)
},
_ => false, _ => false,
} },
}
Match::Destination(ref dst) => { Match::Destination(ref dst) => match *ev {
match *ev {
Event::StreamRequestOpen(ref req) | Event::StreamRequestFail(ref req, _) => { Event::StreamRequestOpen(ref req) | Event::StreamRequestFail(ref req, _) => {
dst.matches(&req.client.remote) dst.matches(&req.client.remote)
} }
Event::StreamResponseOpen(ref rsp, _) | Event::StreamResponseOpen(ref rsp, _) |
Event::StreamResponseFail(ref rsp, _) | Event::StreamResponseFail(ref rsp, _) |
Event::StreamResponseEnd(ref rsp, _) => { Event::StreamResponseEnd(ref rsp, _) => dst.matches(&rsp.request.client.remote),
dst.matches(&rsp.request.client.remote)
}
_ => false, _ => false,
} },
}
Match::Http(ref http) => { Match::Http(ref http) => match *ev {
match *ev { Event::StreamRequestOpen(ref req) | Event::StreamRequestFail(ref req, _) => {
Event::StreamRequestOpen(ref req) |
Event::StreamRequestFail(ref req, _) => {
http.matches(req) http.matches(req)
} }
Event::StreamResponseOpen(ref rsp, _) | Event::StreamResponseOpen(ref rsp, _) |
Event::StreamResponseFail(ref rsp, _) | Event::StreamResponseFail(ref rsp, _) |
Event::StreamResponseEnd(ref rsp, _) => { Event::StreamResponseEnd(ref rsp, _) => http.matches(&rsp.request),
http.matches(&rsp.request)
}
_ => false, _ => false,
} },
}
} }
} }
pub(super) fn new(match_: &observe_request::Match) -> Result<Match, InvalidMatch> { pub(super) fn new(match_: &observe_request::Match) -> Result<Match, InvalidMatch> {
match_.match_.as_ref() match_
.match_
.as_ref()
.map(Match::try_from) .map(Match::try_from)
.unwrap_or_else(|| Err(InvalidMatch::Empty)) .unwrap_or_else(|| Err(InvalidMatch::Empty))
} }
@ -154,12 +143,10 @@ impl<'a> TryFrom<&'a observe_request::match_::Match> for Match {
match_::Match::Any(ref seq) => Match::Any(Self::from_seq(seq)?), match_::Match::Any(ref seq) => Match::Any(Self::from_seq(seq)?),
match_::Match::Not(ref m) => { match_::Match::Not(ref m) => match m.match_.as_ref() {
match m.match_.as_ref() {
Some(m) => Match::Not(Box::new(Self::try_from(m)?)), Some(m) => Match::Not(Box::new(Self::try_from(m)?)),
None => return Err(InvalidMatch::Empty), None => return Err(InvalidMatch::Empty),
} },
}
match_::Match::Source(ref src) => Match::Source(TcpMatch::try_from(src)?), match_::Match::Source(ref src) => Match::Source(TcpMatch::try_from(src)?),
@ -179,13 +166,9 @@ impl TcpMatch {
match *self { match *self {
// If either a minimum or maximum is not specified, the range is considered to // If either a minimum or maximum is not specified, the range is considered to
// be over a discrete value. // be over a discrete value.
TcpMatch::PortRange(min, max) => { TcpMatch::PortRange(min, max) => min <= addr.port() && addr.port() <= max,
min <= addr.port() && addr.port() <= max
}
TcpMatch::Net(ref net) => { TcpMatch::Net(ref net) => net.matches(&addr.ip()),
net.matches(&addr.ip())
},
} }
} }
} }
@ -228,22 +211,17 @@ impl<'a> TryFrom<&'a observe_request::match_::Tcp> for TcpMatch {
impl NetMatch { impl NetMatch {
fn matches(&self, addr: &net::IpAddr) -> bool { fn matches(&self, addr: &net::IpAddr) -> bool {
match *self { match *self {
NetMatch::Net4(ref net) => { NetMatch::Net4(ref net) => match *addr {
match *addr {
net::IpAddr::V6(_) => false, net::IpAddr::V6(_) => false,
net::IpAddr::V4(ref addr) => net.contains(addr), net::IpAddr::V4(ref addr) => net.contains(addr),
} },
} NetMatch::Net6(ref net) => match *addr {
NetMatch::Net6(ref net) => {
match *addr {
net::IpAddr::V4(_) => false, net::IpAddr::V4(_) => false,
net::IpAddr::V6(ref addr) => net.contains(addr), net::IpAddr::V6(ref addr) => net.contains(addr),
},
} }
} }
} }
}
}
impl<'a> TryFrom<&'a observe_request::match_::tcp::Netmask> for NetMatch { impl<'a> TryFrom<&'a observe_request::match_::tcp::Netmask> for NetMatch {
type Err = InvalidMatch; type Err = InvalidMatch;
@ -263,7 +241,8 @@ impl<'a> TryFrom<&'a observe_request::match_::tcp::Netmask> for NetMatch {
let net = match *ip { let net = match *ip {
ip_address::Ip::Ipv4(ref n) => { ip_address::Ip::Ipv4(ref n) => {
let net = Ipv4Net::new((*n).into(), mask).map_err(|_| InvalidMatch::InvalidNetwork)?; let net =
Ipv4Net::new((*n).into(), mask).map_err(|_| InvalidMatch::InvalidNetwork)?;
NetMatch::Net4(net) NetMatch::Net4(net)
} }
ip_address::Ip::Ipv6(ref ip6) => { ip_address::Ip::Ipv6(ref ip6) => {
@ -281,21 +260,14 @@ impl<'a> TryFrom<&'a observe_request::match_::tcp::Netmask> for NetMatch {
impl HttpMatch { impl HttpMatch {
fn matches(&self, req: &Arc<ctx::http::Request>) -> bool { fn matches(&self, req: &Arc<ctx::http::Request>) -> bool {
match *self { match *self {
HttpMatch::Scheme(ref m) => { HttpMatch::Scheme(ref m) => req.uri.scheme().map(|s| *m == s).unwrap_or(false),
req.uri.scheme()
.map(|s| *m == s)
.unwrap_or(false)
}
HttpMatch::Method(ref m) => { HttpMatch::Method(ref m) => *m == req.method,
*m == req.method
}
HttpMatch::Authority(ref m) => { HttpMatch::Authority(ref m) => req.uri
req.uri.authority_part() .authority_part()
.map(|a| Self::matches_string(m, a.as_str())) .map(|a| Self::matches_string(m, a.as_str()))
.unwrap_or(false) .unwrap_or(false),
}
HttpMatch::Path(ref m) => Self::matches_string(m, req.uri.path()), HttpMatch::Path(ref m) => Self::matches_string(m, req.uri.path()),
} }
@ -303,7 +275,7 @@ impl HttpMatch {
fn matches_string( fn matches_string(
string_match: &observe_request::match_::http::string_match::Match, string_match: &observe_request::match_::http::string_match::Match,
value: &str value: &str,
) -> bool { ) -> bool {
use control::pb::proxy::tap::observe_request::match_::http::string_match::Match::*; use control::pb::proxy::tap::observe_request::match_::http::string_match::Match::*;
@ -312,7 +284,6 @@ impl HttpMatch {
Prefix(ref prefix) => value.starts_with(prefix), Prefix(ref prefix) => value.starts_with(prefix),
} }
} }
} }
impl<'a> TryFrom<&'a observe_request::match_::Http> for HttpMatch { impl<'a> TryFrom<&'a observe_request::match_::Http> for HttpMatch {
@ -320,51 +291,45 @@ impl<'a> TryFrom<&'a observe_request::match_::Http> for HttpMatch {
fn try_from(m: &'a observe_request::match_::Http) -> Result<Self, InvalidMatch> { fn try_from(m: &'a observe_request::match_::Http) -> Result<Self, InvalidMatch> {
use control::pb::proxy::tap::observe_request::match_::http::Match as Pb; use control::pb::proxy::tap::observe_request::match_::http::Match as Pb;
m.match_.as_ref() m.match_
.as_ref()
.ok_or_else(|| InvalidMatch::Empty) .ok_or_else(|| InvalidMatch::Empty)
.and_then(|m| { .and_then(|m| match *m {
match *m { Pb::Scheme(ref s) => s.type_
Pb::Scheme(ref s) => { .as_ref()
s.type_.as_ref()
.ok_or_else(|| InvalidMatch::Empty) .ok_or_else(|| InvalidMatch::Empty)
.and_then(|s| { .and_then(|s| {
s.try_into() s.try_into()
.map(HttpMatch::Scheme) .map(HttpMatch::Scheme)
.map_err(|_| InvalidMatch::InvalidScheme) .map_err(|_| InvalidMatch::InvalidScheme)
}) }),
}
Pb::Method(ref m) => { Pb::Method(ref m) => m.type_
m.type_.as_ref() .as_ref()
.ok_or_else(|| InvalidMatch::Empty) .ok_or_else(|| InvalidMatch::Empty)
.and_then(|m| { .and_then(|m| {
m.try_into() m.try_into()
.map(HttpMatch::Method) .map(HttpMatch::Method)
.map_err(|_| InvalidMatch::InvalidHttpMethod) .map_err(|_| InvalidMatch::InvalidHttpMethod)
}) }),
} Pb::Authority(ref a) => a.match_
.as_ref()
Pb::Authority(ref a) => {
a.match_.as_ref()
.ok_or_else(|| InvalidMatch::Empty) .ok_or_else(|| InvalidMatch::Empty)
.map(|a|HttpMatch::Authority(a.clone())) .map(|a| HttpMatch::Authority(a.clone())),
}
Pb::Path(ref p) => { Pb::Path(ref p) => p.match_
p.match_.as_ref() .as_ref()
.ok_or_else(|| InvalidMatch::Empty) .ok_or_else(|| InvalidMatch::Empty)
.map(|p| HttpMatch::Path(p.clone())) .map(|p| HttpMatch::Path(p.clone())),
}
}
}) })
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::net;
use std::boxed::Box; use std::boxed::Box;
use std::net;
use ipnet::{Contains, Ipv4Net, Ipv6Net}; use ipnet::{Contains, Ipv4Net, Ipv6Net};
use quickcheck::*; use quickcheck::*;
@ -377,7 +342,7 @@ mod tests {
fn arbitrary<G: Gen>(g: &mut G) -> Self { fn arbitrary<G: Gen>(g: &mut G) -> Self {
ObserveRequest { ObserveRequest {
limit: g.gen(), limit: g.gen(),
match_: Arbitrary::arbitrary(g) match_: Arbitrary::arbitrary(g),
} }
} }
} }
@ -385,7 +350,7 @@ mod tests {
impl Arbitrary for observe_request::Match { impl Arbitrary for observe_request::Match {
fn arbitrary<G: Gen>(g: &mut G) -> Self { fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::Match { observe_request::Match {
match_: Arbitrary::arbitrary(g) match_: Arbitrary::arbitrary(g),
} }
} }
} }
@ -399,7 +364,7 @@ mod tests {
3 => observe_request::match_::Match::Source(Arbitrary::arbitrary(g)), 3 => observe_request::match_::Match::Source(Arbitrary::arbitrary(g)),
4 => observe_request::match_::Match::Destination(Arbitrary::arbitrary(g)), 4 => observe_request::match_::Match::Destination(Arbitrary::arbitrary(g)),
5 => observe_request::match_::Match::Http(Arbitrary::arbitrary(g)), 5 => observe_request::match_::Match::Http(Arbitrary::arbitrary(g)),
_ => unreachable!() _ => unreachable!(),
} }
} }
} }
@ -412,8 +377,11 @@ mod tests {
} }
fn shrink(&self) -> Box<Iterator<Item = Self>> { fn shrink(&self) -> Box<Iterator<Item = Self>> {
Box::new(self.matches.shrink() Box::new(self.matches.shrink().map(|matches| {
.map(|matches| observe_request::match_::Seq { matches })) observe_request::match_::Seq {
matches,
}
}))
} }
} }
@ -454,7 +422,10 @@ mod tests {
Some(&ip_address::Ip::Ipv6(_)) => g.gen::<u32>() % 128 + 1, Some(&ip_address::Ip::Ipv6(_)) => g.gen::<u32>() % 128 + 1,
None => 0u32, None => 0u32,
}; };
observe_request::match_::tcp::Netmask { ip, mask } observe_request::match_::tcp::Netmask {
ip,
mask,
}
} }
} }
@ -475,7 +446,7 @@ mod tests {
1 => http::Match::Method(HttpMethod::arbitrary(g)), 1 => http::Match::Method(HttpMethod::arbitrary(g)),
2 => http::Match::Authority(http::StringMatch::arbitrary(g)), 2 => http::Match::Authority(http::StringMatch::arbitrary(g)),
3 => http::Match::Path(http::StringMatch::arbitrary(g)), 3 => http::Match::Path(http::StringMatch::arbitrary(g)),
_ => unreachable!() _ => unreachable!(),
} }
} }
} }
@ -483,7 +454,7 @@ mod tests {
impl Arbitrary for observe_request::match_::http::StringMatch { impl Arbitrary for observe_request::match_::http::StringMatch {
fn arbitrary<G: Gen>(g: &mut G) -> Self { fn arbitrary<G: Gen>(g: &mut G) -> Self {
observe_request::match_::http::StringMatch { observe_request::match_::http::StringMatch {
match_: Arbitrary::arbitrary(g) match_: Arbitrary::arbitrary(g),
} }
} }
} }
@ -495,7 +466,7 @@ mod tests {
match g.gen::<u32>() % 2 { match g.gen::<u32>() % 2 {
0 => string_match::Match::Exact(String::arbitrary(g)), 0 => string_match::Match::Exact(String::arbitrary(g)),
1 => string_match::Match::Prefix(String::arbitrary(g)), 1 => string_match::Match::Prefix(String::arbitrary(g)),
_ => unreachable!() _ => unreachable!(),
} }
} }
} }
@ -503,7 +474,7 @@ mod tests {
impl Arbitrary for IpAddress { impl Arbitrary for IpAddress {
fn arbitrary<G: Gen>(g: &mut G) -> Self { fn arbitrary<G: Gen>(g: &mut G) -> Self {
IpAddress { IpAddress {
ip: Arbitrary::arbitrary(g) ip: Arbitrary::arbitrary(g),
} }
} }
} }
@ -530,7 +501,7 @@ mod tests {
impl Arbitrary for HttpMethod { impl Arbitrary for HttpMethod {
fn arbitrary<G: Gen>(g: &mut G) -> Self { fn arbitrary<G: Gen>(g: &mut G) -> Self {
HttpMethod { HttpMethod {
type_: Arbitrary::arbitrary(g) type_: Arbitrary::arbitrary(g),
} }
} }
} }
@ -547,7 +518,7 @@ mod tests {
impl Arbitrary for Scheme { impl Arbitrary for Scheme {
fn arbitrary<G: Gen>(g: &mut G) -> Self { fn arbitrary<G: Gen>(g: &mut G) -> Self {
Scheme { Scheme {
type_: Arbitrary::arbitrary(g) type_: Arbitrary::arbitrary(g),
} }
} }
} }

View File

@ -62,12 +62,16 @@ impl Taps {
} }
impl Tap { impl Tap {
pub fn new(match_: &observe_request::Match, capacity: usize) pub fn new(
-> Result<(Tap, futures_mpsc_lossy::Receiver<Event>), InvalidMatch> match_: &observe_request::Match,
{ capacity: usize,
) -> Result<(Tap, futures_mpsc_lossy::Receiver<Event>), InvalidMatch> {
let (tx, rx) = futures_mpsc_lossy::channel(capacity); let (tx, rx) = futures_mpsc_lossy::channel(capacity);
let match_ = Match::new(match_)?; let match_ = Match::new(match_)?;
let tap = Tap { match_, tx }; let tap = Tap {
match_,
tx,
};
Ok((tap, rx)) Ok((tap, rx))
} }

View File

@ -1,21 +1,25 @@
use futures::future::{self, FutureResult}; use futures::future::{self, FutureResult};
use tower::{Service, NewService}; use tower::{NewService, Service};
pub struct NewServiceFn<T> { pub struct NewServiceFn<T> {
f: T, f: T,
} }
impl<T, N> NewServiceFn<T> impl<T, N> NewServiceFn<T>
where T: Fn() -> N, where
T: Fn() -> N,
N: Service, N: Service,
{ {
pub fn new(f: T) -> Self { pub fn new(f: T) -> Self {
NewServiceFn { f } NewServiceFn {
f,
}
} }
} }
impl<T, N> NewService for NewServiceFn<T> impl<T, N> NewService for NewServiceFn<T>
where T: Fn() -> N, where
T: Fn() -> N,
N: Service, N: Service,
{ {
type Request = N::Request; type Request = N::Request;

View File

@ -54,8 +54,12 @@ impl Future for TcpStreamNewNoDelay {
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let tcp = try_ready!(self.0.poll()); let tcp = try_ready!(self.0.poll());
if let Err(e) = tcp.set_nodelay(true) { if let Err(e) = tcp.set_nodelay(true) {
warn!("could not set TCP_NODELAY on {:?}/{:?}: {}", warn!(
tcp.local_addr(), tcp.peer_addr(), e); "could not set TCP_NODELAY on {:?}/{:?}: {}",
tcp.local_addr(),
tcp.peer_addr(),
e
);
} }
Ok(Async::Ready(tcp)) Ok(Async::Ready(tcp))
} }
@ -90,7 +94,7 @@ impl LookupAddressAndConnect {
pub fn new( pub fn new(
host_and_port: url::HostAndPort, host_and_port: url::HostAndPort,
dns_resolver: dns::Resolver, dns_resolver: dns::Resolver,
handle: &Handle handle: &Handle,
) -> Self { ) -> Self {
Self { Self {
host_and_port, host_and_port,
@ -109,8 +113,11 @@ impl tokio_connect::Connect for LookupAddressAndConnect {
let port = self.host_and_port.port; let port = self.host_and_port.port;
let handle = self.handle.clone(); let handle = self.handle.clone();
let host = self.host_and_port.host.clone(); let host = self.host_and_port.host.clone();
let c = self.dns_resolver.resolve_host(&self.host_and_port.host) let c = self.dns_resolver
.map_err(|_| io::Error::new(io::ErrorKind::NotFound, "DNS resolution failed")) .resolve_host(&self.host_and_port.host)
.map_err(|_| {
io::Error::new(io::ErrorKind::NotFound, "DNS resolution failed")
})
.and_then(move |ip_addr: IpAddr| { .and_then(move |ip_addr: IpAddr| {
info!("DNS resolved {} to {}", host, ip_addr); info!("DNS resolved {} to {}", host, ip_addr);
let addr = SocketAddr::from((ip_addr, port)); let addr = SocketAddr::from((ip_addr, port));
@ -143,7 +150,11 @@ impl<C: tokio_connect::Connect> tokio_connect::Connect for TimeoutConnect<C> {
let connect = self.connect.connect(); let connect = self.connect.connect();
let duration = self.timeout; let duration = self.timeout;
let timeout = Timeout::new(duration, &self.handle).unwrap(); let timeout = Timeout::new(duration, &self.handle).unwrap();
TimeoutConnectFuture { connect, duration, timeout } TimeoutConnectFuture {
connect,
duration,
timeout,
}
} }
} }

View File

@ -67,7 +67,7 @@ mod linux {
); );
let port = sa.sin_port; let port = sa.sin_port;
Ok(SocketAddr::V4(SocketAddrV4::new(ip, ntoh16(port)))) Ok(SocketAddr::V4(SocketAddrV4::new(ip, ntoh16(port))))
}, }
libc::AF_INET6 => { libc::AF_INET6 => {
assert!(len as usize >= mem::size_of::<libc::sockaddr_in6>()); assert!(len as usize >= mem::size_of::<libc::sockaddr_in6>());
@ -94,7 +94,7 @@ mod linux {
Ok(SocketAddr::V6( Ok(SocketAddr::V6(
SocketAddrV6::new(ip, ntoh16(port), flowinfo, scope_id), SocketAddrV6::new(ip, ntoh16(port), flowinfo, scope_id),
)) ))
}, }
_ => Err(io::Error::new( _ => Err(io::Error::new(
io::ErrorKind::InvalidInput, io::ErrorKind::InvalidInput,
"invalid argument", "invalid argument",

View File

@ -8,17 +8,11 @@ use self::support::*;
fn outbound_asks_controller_api() { fn outbound_asks_controller_api() {
let _ = env_logger::init(); let _ = env_logger::init();
let srv = server::new() let srv = server::new().route("/", "hello").route("/bye", "bye").run();
.route("/", "hello")
.route("/bye", "bye")
.run();
let ctrl = controller::new() let ctrl = controller::new()
.destination("test.conduit.local", srv.addr) .destination("test.conduit.local", srv.addr)
.run(); .run();
let proxy = proxy::new() let proxy = proxy::new().controller(ctrl).outbound(srv).run();
.controller(ctrl)
.outbound(srv)
.run();
let client = client::new(proxy.outbound, "test.conduit.local"); let client = client::new(proxy.outbound, "test.conduit.local");
assert_eq!(client.get("/"), "hello"); assert_eq!(client.get("/"), "hello");
@ -29,17 +23,12 @@ fn outbound_asks_controller_api() {
fn outbound_reconnects_if_controller_stream_ends() { fn outbound_reconnects_if_controller_stream_ends() {
let _ = env_logger::init(); let _ = env_logger::init();
let srv = server::new() let srv = server::new().route("/recon", "nect").run();
.route("/recon", "nect")
.run();
let ctrl = controller::new() let ctrl = controller::new()
.destination_close("test.conduit.local") .destination_close("test.conduit.local")
.destination("test.conduit.local", srv.addr) .destination("test.conduit.local", srv.addr)
.run(); .run();
let proxy = proxy::new() let proxy = proxy::new().controller(ctrl).outbound(srv).run();
.controller(ctrl)
.outbound(srv)
.run();
let client = client::new(proxy.outbound, "test.conduit.local"); let client = client::new(proxy.outbound, "test.conduit.local");
assert_eq!(client.get("/recon"), "nect"); assert_eq!(client.get("/recon"), "nect");

View File

@ -1,6 +1,6 @@
use support::*; use support::*;
use self::futures::sync::{oneshot, mpsc}; use self::futures::sync::{mpsc, oneshot};
use self::tokio_core::net::TcpStream; use self::tokio_core::net::TcpStream;
use self::tower_h2::client::Error; use self::tower_h2::client::Error;
@ -35,14 +35,14 @@ impl Client {
.body(()) .body(())
.unwrap(); .unwrap();
let _ = self.tx.unbounded_send((req, tx)); let _ = self.tx.unbounded_send((req, tx));
rx rx.map_err(|_| panic!("client request dropped"))
.map_err(|_| panic!("client request dropped"))
.and_then(|res| { .and_then(|res| {
let stream = RecvBodyStream(res.unwrap().into_parts().1); let stream = RecvBodyStream(res.unwrap().into_parts().1);
stream.concat2() stream.concat2()
}).map(|body| { })
::std::str::from_utf8(&body).unwrap().to_string() .map(|body| ::std::str::from_utf8(&body).unwrap().to_string())
}).wait().unwrap() .wait()
.unwrap()
} }
} }
@ -56,14 +56,17 @@ fn run(addr: SocketAddr) -> Sender {
let reactor = core.handle(); let reactor = core.handle();
let conn = Conn(addr, reactor.clone()); let conn = Conn(addr, reactor.clone());
let h2 = tower_h2::Client::<Conn, Handle, ()>::new(conn, Default::default(), reactor.clone()); let h2 = tower_h2::Client::<Conn, Handle, ()>::new(
conn,
Default::default(),
reactor.clone(),
);
let done = h2.new_service() let done = h2.new_service()
.map_err(move |err| println!("connect error ({:?}): {:?}", addr, err)) .map_err(move |err| println!("connect error ({:?}): {:?}", addr, err))
.and_then(move |mut h2| { .and_then(move |mut h2| {
rx.for_each(move |(req, cb)| { rx.for_each(move |(req, cb)| {
let fut = h2.call(req) let fut = h2.call(req).then(|result| {
.then(|result| {
let _ = cb.send(result); let _ = cb.send(result);
Ok(()) Ok(())
}); });

View File

@ -35,7 +35,8 @@ impl Controller {
} }
pub fn destination(mut self, dest: &str, addr: SocketAddr) -> Self { pub fn destination(mut self, dest: &str, addr: SocketAddr) -> Self {
self.destinations.push((dest.into(), Some(destination_update(addr)))); self.destinations
.push((dest.into(), Some(destination_update(addr))));
self self
} }
@ -68,7 +69,11 @@ struct Svc {
} }
impl Svc { impl Svc {
fn route(&self, path: &str, body: RecvBodyStream) -> Box<Future<Item=Response, Error=h2::Error>> { fn route(
&self,
path: &str,
body: RecvBodyStream,
) -> Box<Future<Item = Response, Error = h2::Error>> {
let mut rsp = http::Response::builder(); let mut rsp = http::Response::builder();
rsp.version(http::Version::HTTP_2); rsp.version(http::Version::HTTP_2);
@ -94,7 +99,7 @@ impl Svc {
let rsp = rsp.body(body).unwrap(); let rsp = rsp.body(body).unwrap();
Ok(rsp) Ok(rsp)
})) }))
}, }
TELEMETRY_REPORT => { TELEMETRY_REPORT => {
let mut reports = self.reports.clone(); let mut reports = self.reports.clone();
Box::new(body.concat2().and_then(move |mut bytes| { Box::new(body.concat2().and_then(move |mut bytes| {
@ -160,11 +165,7 @@ impl Body for GrpcBody {
fn poll_data(&mut self) -> Poll<Option<Bytes>, self::h2::Error> { fn poll_data(&mut self) -> Poll<Option<Bytes>, self::h2::Error> {
let data = self.message.split_off(0); let data = self.message.split_off(0);
let data = if data.is_empty() { let data = if data.is_empty() { None } else { Some(data) };
None
} else {
Some(data)
};
Ok(Async::Ready(data)) Ok(Async::Ready(data))
} }
@ -231,11 +232,10 @@ fn run(controller: Controller) -> Listening {
}); });
core.handle() core.handle().spawn(
.spawn(
serve serve
.map(|_| ()) .map(|_| ())
.map_err(|e| println!("controller error: {}", e)) .map_err(|e| println!("controller error: {}", e)),
); );
core.run(rx).unwrap(); core.run(rx).unwrap();
@ -251,32 +251,26 @@ fn run(controller: Controller) -> Listening {
fn destination_update(addr: SocketAddr) -> pb::destination::Update { fn destination_update(addr: SocketAddr) -> pb::destination::Update {
pb::destination::Update { pb::destination::Update {
update: Some( update: Some(pb::destination::update::Update::Add(
pb::destination::update::Update::Add(
pb::destination::WeightedAddrSet { pb::destination::WeightedAddrSet {
addrs: vec![ addrs: vec![
pb::destination::WeightedAddr { pb::destination::WeightedAddr {
addr: Some( addr: Some(pb::common::TcpAddress {
pb::common::TcpAddress {
ip: Some(ip_conv(addr.ip())), ip: Some(ip_conv(addr.ip())),
port: u32::from(addr.port()), port: u32::from(addr.port()),
} }),
),
weight: 0, weight: 0,
} },
], ],
} },
) )),
),
} }
} }
fn ip_conv(ip: IpAddr) -> pb::common::IpAddress { fn ip_conv(ip: IpAddr) -> pb::common::IpAddress {
match ip { match ip {
IpAddr::V4(v4) => { IpAddr::V4(v4) => pb::common::IpAddress {
pb::common::IpAddress {
ip: Some(pb::common::ip_address::Ip::Ipv4(v4.into())), ip: Some(pb::common::ip_address::Ip::Ipv4(v4.into())),
}
}, },
IpAddr::V6(v6) => { IpAddr::V6(v6) => {
let (first, last) = octets_to_u64s(v6.octets()); let (first, last) = octets_to_u64s(v6.octets());
@ -291,21 +285,13 @@ fn ip_conv(ip: IpAddr) -> pb::common::IpAddress {
} }
fn octets_to_u64s(octets: [u8; 16]) -> (u64, u64) { fn octets_to_u64s(octets: [u8; 16]) -> (u64, u64) {
let first = (u64::from(octets[0]) << 56) let first = (u64::from(octets[0]) << 56) + (u64::from(octets[1]) << 48)
+ (u64::from(octets[1]) << 48) + (u64::from(octets[2]) << 40) + (u64::from(octets[3]) << 32)
+ (u64::from(octets[2]) << 40) + (u64::from(octets[4]) << 24) + (u64::from(octets[5]) << 16)
+ (u64::from(octets[3]) << 32) + (u64::from(octets[6]) << 8) + u64::from(octets[7]);
+ (u64::from(octets[4]) << 24) let last = (u64::from(octets[8]) << 56) + (u64::from(octets[9]) << 48)
+ (u64::from(octets[5]) << 16) + (u64::from(octets[10]) << 40) + (u64::from(octets[11]) << 32)
+ (u64::from(octets[6]) << 8) + (u64::from(octets[12]) << 24) + (u64::from(octets[13]) << 16)
+ u64::from(octets[7]); + (u64::from(octets[14]) << 8) + u64::from(octets[15]);
let last = (u64::from(octets[8]) << 56)
+ (u64::from(octets[9]) << 48)
+ (u64::from(octets[10]) << 40)
+ (u64::from(octets[11]) << 32)
+ (u64::from(octets[12]) << 24)
+ (u64::from(octets[13]) << 16)
+ (u64::from(octets[14]) << 8)
+ u64::from(octets[15]);
(first, last) (first, last)
} }

View File

@ -2,29 +2,29 @@
extern crate bytes; extern crate bytes;
extern crate conduit_proxy; extern crate conduit_proxy;
pub extern crate env_logger;
extern crate futures; extern crate futures;
extern crate h2; extern crate h2;
extern crate http; extern crate http;
extern crate prost; extern crate prost;
extern crate tokio_core;
extern crate tokio_connect; extern crate tokio_connect;
extern crate tokio_core;
extern crate tower; extern crate tower;
extern crate tower_h2; extern crate tower_h2;
extern crate url; extern crate url;
pub extern crate env_logger;
use std::net::SocketAddr;
pub use std::time::Duration;
use self::bytes::{BigEndian, Bytes, BytesMut}; use self::bytes::{BigEndian, Bytes, BytesMut};
pub use self::futures::*; pub use self::futures::*;
use self::futures::sync::oneshot; use self::futures::sync::oneshot;
use self::http::{Request, HeaderMap}; use self::http::{HeaderMap, Request};
use self::http::header::HeaderValue; use self::http::header::HeaderValue;
use self::tokio_connect::Connect; use self::tokio_connect::Connect;
use self::tokio_core::net::TcpListener; use self::tokio_core::net::TcpListener;
use self::tokio_core::reactor::{Core, Handle}; use self::tokio_core::reactor::{Core, Handle};
use self::tower::{NewService, Service}; use self::tower::{NewService, Service};
use self::tower_h2::{Body, RecvBody}; use self::tower_h2::{Body, RecvBody};
use std::net::SocketAddr;
pub use std::time::Duration;
pub mod client; pub mod client;
pub mod controller; pub mod controller;
@ -32,7 +32,11 @@ pub mod proxy;
pub mod server; pub mod server;
pub type Shutdown = oneshot::Sender<()>; pub type Shutdown = oneshot::Sender<()>;
pub type ShutdownRx = future::Then<oneshot::Receiver<()>, Result<(), ()>, fn(Result<(), oneshot::Canceled>) -> Result<(), ()>>; pub type ShutdownRx = future::Then<
oneshot::Receiver<()>,
Result<(), ()>,
fn(Result<(), oneshot::Canceled>) -> Result<(), ()>,
>;
pub fn shutdown_signal() -> (oneshot::Sender<()>, ShutdownRx) { pub fn shutdown_signal() -> (oneshot::Sender<()>, ShutdownRx) {
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();

View File

@ -39,7 +39,11 @@ impl Server {
let mut core = Core::new().unwrap(); let mut core = Core::new().unwrap();
let reactor = core.handle(); let reactor = core.handle();
let h2 = tower_h2::Server::new(NewSvc(Arc::new(self.routes)), Default::default(), reactor.clone()); let h2 = tower_h2::Server::new(
NewSvc(Arc::new(self.routes)),
Default::default(),
reactor.clone(),
);
let addr = ([127, 0, 0, 1], 0).into(); let addr = ([127, 0, 0, 1], 0).into();
let bind = TcpListener::bind(&addr, &reactor).expect("bind"); let bind = TcpListener::bind(&addr, &reactor).expect("bind");
@ -60,11 +64,10 @@ impl Server {
Ok((h2, reactor)) Ok((h2, reactor))
}); });
core.handle() core.handle().spawn(
.spawn(
serve serve
.map(|_| ()) .map(|_| ())
.map_err(|e| println!("server error: {}", e)) .map_err(|e| println!("server error: {}", e)),
); );
info!("running"); info!("running");

View File

@ -9,9 +9,7 @@ fn inbound_sends_telemetry() {
let _ = env_logger::init(); let _ = env_logger::init();
info!("running test server"); info!("running test server");
let srv = server::new() let srv = server::new().route("/hey", "hello").run();
.route("/hey", "hello")
.run();
let mut ctrl = controller::new(); let mut ctrl = controller::new();
let reports = ctrl.reports(); let reports = ctrl.reports();