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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
use std::io;
use std::marker::PhantomData;
use std::sync::Arc;
use std::net::SocketAddr;
use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::time::Duration;
@ -65,14 +65,14 @@ impl<B> Bind<(), B> {
pub fn with_connect_timeout(self, connect_timeout: Duration) -> Self {
Self {
connect_timeout,
.. self
..self
}
}
pub fn with_sensors(self, sensors: telemetry::Sensors) -> Self {
Self {
sensors,
.. self
..self
}
}
@ -87,7 +87,6 @@ impl<B> Bind<(), B> {
_p: PhantomData,
}
}
}
impl<C: Clone, B> Clone for Bind<C, B> {
@ -139,14 +138,14 @@ where
&self.executor,
);
self.sensors.connect(c, &client_ctx )
self.sensors.connect(c, &client_ctx)
};
// Establishes an HTTP/2.0 connection
let client = tower_h2::client::Client::new(
connect,
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);

View File

@ -1,7 +1,7 @@
use std::env;
use std::net::SocketAddr;
use std::str::FromStr;
use std::path::PathBuf;
use std::str::FromStr;
use std::time::Duration;
use url::{Host, HostAndPort, Url};
@ -109,7 +109,7 @@ const ENV_RESOLV_CONF: &str = "CONDUIT_RESOLV_CONF";
const DEFAULT_EVENT_BUFFER_CAPACITY: usize = 10_000; // FIXME
const DEFAULT_METRICS_FLUSH_INTERVAL_SECS: u64 = 10;
const DEFAULT_PRIVATE_LISTENER: &str = "tcp://127.0.0.1:4140";
const DEFAULT_PUBLIC_LISTENER: &str = "tcp://0.0.0.0:4143";
const DEFAULT_PUBLIC_LISTENER: &str = "tcp://0.0.0.0:4143";
const DEFAULT_CONTROL_LISTENER: &str = "tcp://0.0.0.0:4190";
const DEFAULT_CONTROL_URL: &str = "tcp://proxy-api.conduit.svc.cluster.local:8086";
const DEFAULT_RESOLV_CONF: &str = "/etc/resolv.conf";
@ -123,16 +123,16 @@ impl Config {
None => DEFAULT_EVENT_BUFFER_CAPACITY,
Some(c) => match c.parse() {
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() {
None => Duration::from_secs(DEFAULT_METRICS_FLUSH_INTERVAL_SECS),
Some(c) => match c.parse() {
Ok(c) => Duration::from_secs(c),
Err(_) => return Err(Error::NotANumber(c))
}
Err(_) => return Err(Error::NotANumber(c)),
},
};
Ok(Config {
@ -147,11 +147,13 @@ impl Config {
},
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())
.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())
.map(Duration::from_millis),
@ -159,7 +161,10 @@ impl Config {
.unwrap_or_else(|_| DEFAULT_RESOLV_CONF.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,
metrics_flush_interval,
})
@ -177,8 +182,7 @@ impl Addr {
}
fn from_env_or(key: &str, default: &str) -> Result<Addr, Error> {
let s = env::var(key)
.unwrap_or_else(|_| default.into());
let s = env::var(key).unwrap_or_else(|_| default.into());
s.parse()
}
@ -190,16 +194,20 @@ impl FromStr for Addr {
fn from_str(s: &str) -> Result<Self, Self::Err> {
match Url::parse(s) {
Err(_) => Err(Error::InvalidAddr),
Ok(u) => {
match u.scheme() {
"tcp" => match u.with_default_port(|_| Err(())) {
Ok(HostAndPort { 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),
},
Ok(u) => match u.scheme() {
"tcp" => match u.with_default_port(|_| Err(())) {
Ok(HostAndPort {
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),
},
}
}
}
@ -212,21 +220,37 @@ impl From<Addr> for SocketAddr {
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 url = Url::parse(&s).map_err(|_| Error::ControlPlaneConfigError(s.clone(), UrlError::SyntaxError))?;
let host = url.host().ok_or_else(|| Error::ControlPlaneConfigError(s.clone(), UrlError::MissingHost))?
let url = Url::parse(&s).map_err(|_| {
Error::ControlPlaneConfigError(s.clone(), UrlError::SyntaxError)
})?;
let host = url.host()
.ok_or_else(|| {
Error::ControlPlaneConfigError(s.clone(), UrlError::MissingHost)
})?
.to_owned();
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() != "/" {
return Err(Error::ControlPlaneConfigError(s.clone(), UrlError::PathNotAllowed));
return Err(Error::ControlPlaneConfigError(
s.clone(),
UrlError::PathNotAllowed,
));
}
if url.fragment().is_some() {
return Err(Error::ControlPlaneConfigError(s.clone(), UrlError::FragmentNotAllowed));
return Err(Error::ControlPlaneConfigError(
s.clone(),
UrlError::FragmentNotAllowed,
));
}
Ok(HostAndPort {
host,
port
port,
})
}

View File

@ -23,7 +23,9 @@ pub struct Handshake {
impl Connection {
/// Establish a connection backed by the provided `io`.
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());
match Message::decode(buf) {
Ok(msg) => {
Ok(msg)
},
Ok(msg) => Ok(msg),
Err(err) => {
debug!("decode error: {:?}", err);
Err(err)
},
}
}
}
}

View File

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

View File

@ -2,7 +2,7 @@ use std::marker::PhantomData;
use std::time::{Duration, Instant};
use bytes::Bytes;
use futures::{Async, Future, future, Poll, Stream};
use futures::{future, Async, Future, Poll, Stream};
use h2;
use http;
use tokio_core::reactor::{Handle, Timeout};
@ -59,15 +59,22 @@ impl Control {
// ===== 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
S: Stream<Item=ReportRequest, Error=()> + 'static,
S: Stream<Item = ReportRequest, Error = ()> + 'static,
{
// Build up the Controller Client Stack
let mut client = {
let ctx = ("controller-client", format!("{}", host_and_port));
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 connect = TimeoutConnect::new(
@ -78,7 +85,7 @@ impl Background {
let h2_client = tower_h2::client::Client::new(
connect,
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.timer.reset(Instant::now() + self.wait_dur);
Ok(Async::NotReady)
},
}
ok => ok,
}
}
@ -177,7 +184,7 @@ impl<S> AddOrigin<S> {
impl<S, B> Service for AddOrigin<S>
where
S: Service<Request=http::Request<B>>,
S: Service<Request = http::Request<B>>,
{
type Request = http::Request<B>;
type Response = S::Response;
@ -205,7 +212,7 @@ struct EnumService<S, B>(S, PhantomData<B>);
impl<S, B> Service for EnumService<S, B>
where
S: Service<Request=http::Request<GrpcEncodingBody>>,
S: Service<Request = http::Request<GrpcEncodingBody>>,
B: Into<GrpcEncodingBody>,
{
type Request = http::Request<B>;
@ -256,7 +263,6 @@ impl tower_h2::Body for GrpcEncodingBody {
GrpcEncodingBody::DestinationGet(ref mut b) => b.poll_trailers(),
}
}
}
impl From<self::telemetry::ClientBody> for GrpcEncodingBody {

View File

@ -1,17 +1,17 @@
use std::sync::{Arc, Mutex};
use futures::{future, Stream, Poll};
use futures::{future, Poll, Stream};
use futures_mpsc_lossy;
use ordermap::OrderMap;
use tower_grpc::{self, Request, Response};
use tower_grpc::codegen::server::grpc::ServerStreamingService;
use control::pb::common::TapEvent;
use control::pb::proxy::tap::{ObserveRequest};
use control::pb::proxy::tap::ObserveRequest;
use convert::*;
use ctx;
use telemetry::Event;
use telemetry::tap::{Tap, Taps};
use convert::*;
#[derive(Clone, Debug)]
pub struct Observe {
@ -58,10 +58,14 @@ impl ServerStreamingService for Observe {
}
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,
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 convert::*;
use ctx;
use telemetry::Event;
use convert::*;
// re-export proxy here since we dont care about the other dirs
pub use self::proxy::*;
@ -57,7 +57,7 @@ fn pb_response_end(
source: Some((&ctx.server.remote).into()),
target: Some((&ctx.client.remote).into()),
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 {
#[inline] fn description(&self) -> &str {
#[inline]
fn description(&self) -> &str {
"invalid http method"
}
}
@ -88,7 +89,8 @@ impl fmt::Display for InvalidScheme {
}
impl Error for InvalidScheme {
#[inline] fn description(&self) -> &str {
#[inline]
fn description(&self) -> &str {
"invalid http scheme"
}
}
@ -103,7 +105,8 @@ impl fmt::Display for UnknownEvent {
}
impl Error for UnknownEvent {
#[inline] fn description(&self) -> &str {
#[inline]
fn description(&self) -> &str {
"unknown tap event"
}
}
@ -124,7 +127,8 @@ impl<'a> TryFrom<&'a Event> for common::TapEvent {
}),
method: Some((&ctx.method).into()),
scheme: ctx.uri.scheme().map(|s| s.into()),
authority: ctx.uri.authority_part()
authority: ctx.uri
.authority_part()
.map(|a| a.as_str())
.unwrap_or_default()
.into(),
@ -135,10 +139,10 @@ impl<'a> TryFrom<&'a Event> for common::TapEvent {
source: Some((&ctx.server.remote).into()),
target: Some((&ctx.client.remote).into()),
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) => {
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()),
target: Some((&ctx.request.client.remote).into()),
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) => {
pb_response_end(
ctx,
fail.since_request_open,
None,
0,
0,
)
pb_response_end(ctx, fail.since_request_open, None, 0, 0)
}
Event::StreamResponseEnd(ref ctx, ref end) => {
pb_response_end(
&ctx.request,
end.since_request_open,
Some(end.since_response_open),
end.bytes_sent,
end.grpc_status.unwrap_or(0),
)
}
Event::StreamResponseEnd(ref ctx, ref end) => pb_response_end(
&ctx.request,
end.since_request_open,
Some(end.since_response_open),
end.bytes_sent,
end.grpc_status.unwrap_or(0),
),
Event::StreamResponseFail(ref ctx, ref fail) => {
pb_response_end(
&ctx.request,
fail.since_request_open,
Some(fail.since_response_open),
fail.bytes_sent,
0,
)
}
Event::StreamResponseFail(ref ctx, ref fail) => pb_response_end(
&ctx.request,
fail.since_request_open,
Some(fail.since_response_open),
fail.bytes_sent,
0,
),
_ => return Err(UnknownEvent),
};
@ -200,36 +194,34 @@ impl<'a> TryFrom<&'a Event> for common::TapEvent {
impl<'a> TryFrom<&'a common::http_method::Type> for http::Method {
type Err = InvalidMethod;
fn try_from(m: &'a common::http_method::Type) -> Result<Self, Self::Err> {
use http::HttpTryFrom;
use self::common::http_method::*;
use http::HttpTryFrom;
match *m {
Type::Registered(reg) => {
if reg == Registered::Get.into() {
Ok(http::Method::GET)
} else if reg == Registered::Post.into() {
Ok(http::Method::POST)
} else if reg == Registered::Put.into() {
Ok(http::Method::PUT)
} else if reg == Registered::Delete.into() {
Ok(http::Method::DELETE)
} else if reg == Registered::Patch.into() {
Ok(http::Method::PATCH)
} else if reg == Registered::Options.into() {
Ok(http::Method::OPTIONS)
} else if reg == Registered::Connect.into() {
Ok(http::Method::CONNECT)
} else if reg == Registered::Head.into() {
Ok(http::Method::HEAD)
} else if reg == Registered::Trace.into() {
Ok(http::Method::TRACE)
} else {
Err(InvalidMethod)
}
Type::Registered(reg) => if reg == Registered::Get.into() {
Ok(http::Method::GET)
} else if reg == Registered::Post.into() {
Ok(http::Method::POST)
} else if reg == Registered::Put.into() {
Ok(http::Method::PUT)
} else if reg == Registered::Delete.into() {
Ok(http::Method::DELETE)
} else if reg == Registered::Patch.into() {
Ok(http::Method::PATCH)
} else if reg == Registered::Options.into() {
Ok(http::Method::OPTIONS)
} else if reg == Registered::Connect.into() {
Ok(http::Method::CONNECT)
} else if reg == Registered::Head.into() {
Ok(http::Method::HEAD)
} else if reg == Registered::Trace.into() {
Ok(http::Method::TRACE)
} else {
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::*;
match *self {
Type::Registered(reg) => {
if reg == Registered::Http.into() {
Ok("http".into())
} else if reg == Registered::Https.into() {
Ok("https".into())
} else {
Err(InvalidScheme)
}
}
Type::Registered(reg) => if reg == Registered::Http.into() {
Ok("http".into())
} else if reg == Registered::Https.into() {
Ok("https".into())
} else {
Err(InvalidScheme)
},
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 {
fn from(m: &'a http::Method) -> Self {
common::HttpMethod {
type_: Some(m.into())
type_: Some(m.into()),
}
}
}
@ -295,18 +285,18 @@ impl<'a> From<&'a str> for common::scheme::Type {
impl<'a> From<&'a str> for common::Scheme {
fn from(s: &'a str) -> Self {
common::Scheme {
type_: Some(s.into())
type_: Some(s.into()),
}
}
}
// ===== impl common::IpAddress =====
impl<T> From<T> for common::IpAddress
where
common::ip_address::Ip: From<T>
impl<T> From<T> for common::IpAddress
where
common::ip_address::Ip: From<T>,
{
#[inline]
#[inline]
fn from(ip: T) -> Self {
Self {
ip: Some(ip.into()),
@ -317,14 +307,12 @@ where
impl From<::std::net::IpAddr> for common::IpAddress {
fn from(ip: ::std::net::IpAddr) -> Self {
match ip {
::std::net::IpAddr::V4(v4) =>
Self {
ip: Some(v4.into()),
},
::std::net::IpAddr::V6(v6) =>
Self {
ip: Some(v6.into()),
},
::std::net::IpAddr::V4(v4) => Self {
ip: Some(v4.into()),
},
::std::net::IpAddr::V6(v6) => Self {
ip: Some(v6.into()),
},
}
}
}
@ -333,22 +321,14 @@ impl From<::std::net::IpAddr> for common::IpAddress {
impl From<[u8; 16]> for common::IPv6 {
fn from(octets: [u8; 16]) -> Self {
let first = (u64::from(octets[0]) << 56)
+ (u64::from(octets[1]) << 48)
+ (u64::from(octets[2]) << 40)
+ (u64::from(octets[3]) << 32)
+ (u64::from(octets[4]) << 24)
+ (u64::from(octets[5]) << 16)
+ (u64::from(octets[6]) << 8)
+ u64::from(octets[7]);
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]);
let first = (u64::from(octets[0]) << 56) + (u64::from(octets[1]) << 48)
+ (u64::from(octets[2]) << 40) + (u64::from(octets[3]) << 32)
+ (u64::from(octets[4]) << 24) + (u64::from(octets[5]) << 16)
+ (u64::from(octets[6]) << 8) + u64::from(octets[7]);
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 {
first,
last,
@ -357,7 +337,8 @@ impl From<[u8; 16]> 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())
}
}
@ -382,25 +363,25 @@ impl<'a> From<&'a common::IPv6> for ::std::net::Ipv6Addr {
impl From<[u8; 4]> for common::ip_address::Ip {
fn from(octets: [u8; 4]) -> Self {
common::ip_address::Ip::Ipv4(
u32::from(octets[0]) << 24 |
u32::from(octets[1]) << 16 |
u32::from(octets[2]) << 8 |
u32::from(octets[3])
u32::from(octets[0]) << 24 | u32::from(octets[1]) << 16 | u32::from(octets[2]) << 8
| u32::from(octets[3]),
)
}
}
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())
}
}
impl<T> From<T> for common::ip_address::Ip
where
common::IPv6: From<T>
where
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))
}
}
@ -429,5 +410,8 @@ fn pb_duration(d: &::std::time::Duration) -> ::prost_types::Duration {
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::pb::proxy::telemetry::{ReportRequest, ReportResponse};
use super::pb::proxy::telemetry::client::{
Telemetry as TelemetrySvc,
};
use super::pb::proxy::telemetry::client::telemetry_methods::{
Report as ReportRpc,
};
use super::pb::proxy::telemetry::client::Telemetry as TelemetrySvc;
use super::pb::proxy::telemetry::client::telemetry_methods::Report as ReportRpc;
pub type ClientBody = tower_grpc::client::codec::EncodingBody<
Protobuf<ReportRequest, ReportResponse>,
@ -20,12 +16,9 @@ pub type ClientBody = tower_grpc::client::codec::EncodingBody<
type TelemetryStream<F> = tower_grpc::client::BodyFuture<
tower_grpc::client::Unary<
tower_grpc::client::ResponseFuture<
Protobuf<ReportRequest, ReportResponse>,
F
>,
tower_grpc::client::ResponseFuture<Protobuf<ReportRequest, ReportResponse>, F>,
Protobuf<ReportRequest, ReportResponse>,
>
>,
>;
#[derive(Debug)]
@ -36,9 +29,9 @@ pub struct Telemetry<T, F> {
impl<T, F> Telemetry<T, F>
where
T: Stream<Item=ReportRequest>,
T: Stream<Item = ReportRequest>,
T::Error: ::std::fmt::Debug,
F: Future<Item=::http::Response<::tower_h2::RecvBody>>,
F: Future<Item = ::http::Response<::tower_h2::RecvBody>>,
F::Error: ::std::fmt::Debug,
{
pub fn new(reports: T) -> Self {
@ -51,10 +44,10 @@ where
pub fn poll_rpc<S>(&mut self, client: &mut S)
where
S: Service<
Request=::http::Request<ClientBody>,
Response=F::Item,
Error=F::Error,
Future=F,
Request = ::http::Request<ClientBody>,
Response = F::Item,
Error = F::Error,
Future = F,
>,
{
let grpc = tower_grpc::Client::new(Protobuf::new(), client);
@ -70,57 +63,58 @@ where
trace!("report in flight to controller for {:?}", t0.elapsed());
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),
}
}
let controller_ready = self.in_flight.is_none() &&
match rpc.poll_ready() {
Ok(Async::Ready(_)) => true,
Ok(Async::NotReady) => {
trace!("controller unavailable");
false
}
Err(err) => {
warn!("controller error: {:?}", err);
false
}
};
let controller_ready = self.in_flight.is_none() && match rpc.poll_ready() {
Ok(Async::Ready(_)) => true,
Ok(Async::NotReady) => {
trace!("controller unavailable");
false
}
Err(err) => {
warn!("controller error: {:?}", err);
false
}
};
match self.reports.poll() {
Ok(Async::NotReady) => {
return;
},
}
Ok(Async::Ready(None)) => {
error!("report stream complete");
return;
},
}
Err(err) => {
warn!("report stream error: {:?}", err);
},
}
Ok(Async::Ready(Some(report))) => {
// Attempt to send the report. Continue looping so that `reports` is
// polled until it's not ready.
if !controller_ready {
info!(
"report dropped; requests={} accepts={} connects={}",
report.requests.len(),
report.server_transports.len(),
report.client_transports.len(),
report.requests.len(),
report.server_transports.len(),
report.client_transports.len(),
);
} else {
trace!(
"report sent; requests={} accepts={} connects={}",
report.requests.len(),
report.server_transports.len(),
report.client_transports.len(),
report.requests.len(),
report.server_transports.len(),
report.client_transports.len(),
);
let rep = TelemetrySvc::new(&mut rpc).report(report);
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
//! 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.
use control::pb::proxy::telemetry as proto;
use std::env;
use std::sync::Arc;
use control::pb::proxy::telemetry as proto;
pub mod http;
pub mod transport;
@ -51,22 +51,21 @@ impl Process {
Arc::new(Self {
node: node.into(),
scheduled_instance: instance.into(),
scheduled_namespace: ns.into()
scheduled_namespace: ns.into(),
})
}
/// Construct a new `Process` from environment variables.
pub fn from_env() -> Arc<Self> {
fn get_var(key: &str) -> String {
env::var(key)
.unwrap_or_else(|why| {
warn!(
"Process::from_env(): Failed to get value of {} environment variable: {:?}",
key,
why
);
String::from("")
})
env::var(key).unwrap_or_else(|why| {
warn!(
"Process::from_env(): Failed to get value of {} environment variable: {:?}",
key,
why
);
String::from("")
})
}
let node = get_var(::config::ENV_NODE_NAME);
@ -103,7 +102,7 @@ impl Proxy {
pub fn is_inbound(&self) -> bool {
match *self {
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::HostResolve;
use domain;
use futures::prelude::*;
use ns_dns_tokio;
use std::net::IpAddr;
use std::path::Path;
use std::str::FromStr;
use tokio_core::reactor::Handle;
@ -40,7 +40,9 @@ impl Config {
impl Resolver {
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 {
@ -65,15 +67,12 @@ impl Future for IpAddrFuture {
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match *self {
IpAddrFuture::DNS(ref mut inner) => {
match inner.poll() {
Ok(Async::NotReady) => Ok(Async::NotReady),
Ok(Async::Ready(ips)) =>
ips.pick_one()
.map(Async::Ready)
.ok_or(Error::NoAddressesFound),
Err(e) => Err(Error::ResolutionFailed(e)),
}
IpAddrFuture::DNS(ref mut inner) => match inner.poll() {
Ok(Async::NotReady) => Ok(Async::NotReady),
Ok(Async::Ready(ips)) => ips.pick_one()
.map(Async::Ready)
.ok_or(Error::NoAddressesFound),
Err(e) => Err(Error::ResolutionFailed(e)),
},
IpAddrFuture::Fixed(addr) => Ok(Async::Ready(addr)),
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<B> Inbound<B> {
pub fn new(
default_addr: Option<SocketAddr>,
bind: Bind<B>
) -> Self {
pub fn new(default_addr: Option<SocketAddr>, bind: Bind<B>) -> Self {
Self {
default_addr,
bind
bind,
}
}
fn same_addr(a0: &SocketAddr, a1: &SocketAddr) -> bool {
(a0.port() == a1.port()) &&
match (a0.ip(), a1.ip()) {
(a0.port() == a1.port()) && match (a0.ip(), a1.ip()) {
(IpAddr::V6(a0), IpAddr::V4(a1)) => a0.to_ipv4() == Some(a1),
(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>
where
B: tower_h2::Body + 'static
B: tower_h2::Body + 'static,
{
type Request = http::Request<B>;
type Response = http::Response<telemetry::sensor::http::ResponseBody<tower_h2::RecvBody>>;
@ -66,11 +62,7 @@ where
>;
type Key = SocketAddr;
type RouteError = ();
type Service = Buffer<Reconnect<telemetry::sensor::NewHttp<
Client<B>,
B,
tower_h2::RecvBody
>>>;
type Service = Buffer<Reconnect<telemetry::sensor::NewHttp<Client<B>, B, tower_h2::RecvBody>>>;
fn recognize(&self, req: &Self::Request) -> Option<Self::Key> {
let key = req.extensions()
@ -82,8 +74,11 @@ where
Some(orig_dst) => {
// If the original destination is actually the listening socket,
// we don't want to create a loop.
if Self::same_addr(&orig_dst, &ctx.local) { None }
else { Some(orig_dst) }
if Self::same_addr(&orig_dst, &ctx.local) {
None
} else {
Some(orig_dst)
}
}
}
})
@ -107,8 +102,7 @@ where
// is not ideal.
//
// TODO: Don't use unbounded buffering.
Buffer::new(self.bind.bind_service(addr), self.bind.executor())
.map_err(|_| {})
Buffer::new(self.bind.bind_service(addr), self.bind.executor()).map_err(|_| {})
}
}
@ -122,9 +116,9 @@ mod tests {
use tokio_core::reactor::Core;
use tower_router::Recognize;
use super::Inbound;
use bind::Bind;
use ctx;
use super::Inbound;
fn new_inbound(default: Option<net::SocketAddr>, ctx: &Arc<ctx::Proxy>) -> Inbound<()> {
let core = Core::new().unwrap();

View File

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

View File

@ -4,9 +4,9 @@ use std::fmt;
use std::rc::Rc;
use chrono::Utc;
use futures::{Future, Poll};
use futures::future::{Executor, ExecuteError};
use env_logger::LogBuilder;
use futures::{Future, Poll};
use futures::future::{ExecuteError, Executor};
use log::LogLevel;
const ENV_LOG: &str = "CONDUIT_PROXY_LOG";
@ -39,7 +39,6 @@ pub fn init() {
.parse(&env::var(ENV_LOG).unwrap_or_default())
.init()
.expect("logger");
}
/// Execute a closure with a `Debug` item attached to allow log messages.
@ -112,7 +111,7 @@ impl<T, E, F> Executor<F> for ContextualExecutor<T, E>
where
T: ::std::fmt::Debug + 'static,
E: Executor<ContextualFuture<Rc<T>, F>>,
F: Future<Item=(), Error=()>,
F: Future<Item = (), Error = ()>,
{
fn execute(&self, future: F) -> Result<(), ExecuteError<F>> {
let fut = context_future(self.context.clone(), future);

View File

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

View File

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

View File

@ -20,10 +20,10 @@ type Error = tower_buffer::Error<
tower_balance::Error<
tower_reconnect::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> {
@ -44,7 +44,7 @@ impl<B> Outbound<B> {
impl<B> Recognize for Outbound<B>
where
B: tower_h2::Body + 'static
B: tower_h2::Body + 'static,
{
type Request = http::Request<B>;
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
/// changed.
fn bind_service(&mut self, authority: &http::uri::Authority)
-> Result<Self::Service, Self::RouteError>
{
fn bind_service(
&mut self,
authority: &http::uri::Authority,
) -> Result<Self::Service, Self::RouteError> {
debug!("building outbound client to {:?}", authority);
let resolve = self.discovery.resolve(authority, self.bind.clone());
@ -79,7 +80,6 @@ where
// which is not ideal.
//
// TODO: Don't use unbounded buffering.
Buffer::new(balance, self.bind.executor())
.map_err(|_| {})
Buffer::new(balance, self.bind.executor()).map_err(|_| {})
}
}

View File

@ -1,16 +1,16 @@
use std::{fmt, io};
use std::time::{Duration, Instant};
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use futures::{Async, Future, Poll, Stream};
use futures_mpsc_lossy::Receiver;
use tokio_core::reactor::{Handle, Timeout};
use ctx;
use super::event::Event;
use super::tap::Taps;
use super::metrics::Metrics;
use super::tap::Taps;
use control::pb::telemetry::ReportRequest;
use ctx;
/// A `Control` which has been configured but not initialized.
#[derive(Debug)]
@ -64,7 +64,7 @@ impl MakeControl {
/// - `rx`: the `Receiver` side of the channel on which events are sent.
/// - `flush_interval`: the maximum amount of time between sending reports to the
/// controller.
pub (super) fn new(
pub(super) fn new(
rx: Receiver<Event>,
flush_interval: Duration,
process_ctx: &Arc<ctx::Process>,
@ -138,7 +138,8 @@ impl Control {
/// Reset the flush timeout.
fn reset_timeout(&mut self) {
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>> {
@ -185,7 +186,9 @@ impl Stream for Control {
}
Async::Ready(None) => {
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() {
return Ok(Async::Ready(None));
}
@ -226,7 +229,10 @@ impl fmt::Debug for Control {
.field("rx", &self.rx)
.field("taps", &self.taps)
.field("flush_interval", &self.flush_interval)
.field("flush_timeout", &format!("Timeout({:?})", &self.flush_interval))
.field(
"flush_timeout",
&format!("Timeout({:?})", &self.flush_interval),
)
.finish()
}
}

View File

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

View File

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

View File

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

View File

@ -15,7 +15,7 @@ use telemetry::event;
pub mod http;
mod transport;
pub use self::http::{NewHttp, Http};
pub use self::http::{Http, NewHttp};
pub use self::transport::{Connect, Transport};
/// Accepts events from sensors.
@ -27,7 +27,10 @@ struct Handle(Option<Sender<event::Event>>);
pub struct Sensors(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() {
// We may want to capture timestamps here instead of on the consumer-side... That
// level of precision doesn't necessarily seem worth it yet.
@ -51,8 +54,14 @@ impl Sensors {
Sensors(Handle(None))
}
pub fn accept<T>(&self, io: T, opened_at: Instant, ctx: &Arc<ctx::transport::Server>) -> Transport<T>
where T: AsyncRead + AsyncWrite
pub fn accept<T>(
&self,
io: T,
opened_at: Instant,
ctx: &Arc<ctx::transport::Server>,
) -> Transport<T>
where
T: AsyncRead + AsyncWrite,
{
debug!("server connection open");
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>
where C: tokio_connect::Connect
where
C: tokio_connect::Connect,
{
Connect::new(connect, &self.0, ctx)
}
@ -69,15 +79,13 @@ impl Sensors {
&self,
next_id: Arc<AtomicUsize>,
new_service: N,
client_ctx: &Arc<ctx::transport::Client>
client_ctx: &Arc<ctx::transport::Client>,
) -> NewHttp<N, A, B>
where
A: Body + 'static,
B: Body + 'static,
N: NewService<
Request = Request<A>,
Response = Response<B>,
Error = client::Error> + 'static
N: NewService<Request = Request<A>, Response = Response<B>, Error = client::Error>
+ 'static,
{
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> {
/// 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();
handle.send(|| event::Event::TransportOpen(Arc::clone(&ctx)));
@ -70,27 +75,43 @@ impl<T: AsyncRead + AsyncWrite> Transport<T> {
Ok(v) => Ok(v),
Err(e) => {
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 || {
let duration = opened_at.elapsed();
let ev = event::TransportClose { duration, clean: false };
let ev = event::TransportClose {
duration,
clean: false,
};
event::Event::TransportClose(ctx, ev)
});
}
}
Err(e)
},
}
}
}
}
impl<T> Drop for Transport<T> {
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 || {
let duration = opened_at.elapsed();
let ev = event::TransportClose { clean: true, duration };
let ev = event::TransportClose {
clean: true,
duration,
};
event::Event::TransportClose(ctx, ev)
});
}

View File

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

View File

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

View File

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

View File

@ -54,8 +54,12 @@ impl Future for TcpStreamNewNoDelay {
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let tcp = try_ready!(self.0.poll());
if let Err(e) = tcp.set_nodelay(true) {
warn!("could not set TCP_NODELAY on {:?}/{:?}: {}",
tcp.local_addr(), tcp.peer_addr(), e);
warn!(
"could not set TCP_NODELAY on {:?}/{:?}: {}",
tcp.local_addr(),
tcp.peer_addr(),
e
);
}
Ok(Async::Ready(tcp))
}
@ -90,7 +94,7 @@ impl LookupAddressAndConnect {
pub fn new(
host_and_port: url::HostAndPort,
dns_resolver: dns::Resolver,
handle: &Handle
handle: &Handle,
) -> Self {
Self {
host_and_port,
@ -109,8 +113,11 @@ impl tokio_connect::Connect for LookupAddressAndConnect {
let port = self.host_and_port.port;
let handle = self.handle.clone();
let host = self.host_and_port.host.clone();
let c = self.dns_resolver.resolve_host(&self.host_and_port.host)
.map_err(|_| io::Error::new(io::ErrorKind::NotFound, "DNS resolution failed"))
let c = self.dns_resolver
.resolve_host(&self.host_and_port.host)
.map_err(|_| {
io::Error::new(io::ErrorKind::NotFound, "DNS resolution failed")
})
.and_then(move |ip_addr: IpAddr| {
info!("DNS resolved {} to {}", host, ip_addr);
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 duration = self.timeout;
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;
Ok(SocketAddr::V4(SocketAddrV4::new(ip, ntoh16(port))))
},
}
libc::AF_INET6 => {
assert!(len as usize >= mem::size_of::<libc::sockaddr_in6>());
@ -94,7 +94,7 @@ mod linux {
Ok(SocketAddr::V6(
SocketAddrV6::new(ip, ntoh16(port), flowinfo, scope_id),
))
},
}
_ => Err(io::Error::new(
io::ErrorKind::InvalidInput,
"invalid argument",

View File

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

View File

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

View File

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

View File

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

View File

@ -39,7 +39,11 @@ impl Server {
let mut core = Core::new().unwrap();
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 bind = TcpListener::bind(&addr, &reactor).expect("bind");
@ -60,12 +64,11 @@ impl Server {
Ok((h2, reactor))
});
core.handle()
.spawn(
serve
.map(|_| ())
.map_err(|e| println!("server error: {}", e))
);
core.handle().spawn(
serve
.map(|_| ())
.map_err(|e| println!("server error: {}", e)),
);
info!("running");
core.run(rx).unwrap();

View File

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