2018-07-17 16:31:32 +02:00
|
|
|
// Copyright 2018 Parity Technologies (UK) Ltd.
|
2017-11-22 18:01:28 +01:00
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
|
|
// to deal in the Software without restriction, including without limitation
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
|
2018-07-17 16:31:32 +02:00
|
|
|
mod codec;
|
2020-09-28 10:30:49 +02:00
|
|
|
mod config;
|
|
|
|
mod io;
|
2017-11-01 11:59:52 +01:00
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
pub use config::{MaxBufferBehaviour, MplexConfig};
|
2020-09-28 10:30:49 +02:00
|
|
|
|
2018-07-17 16:31:32 +02:00
|
|
|
use bytes::Bytes;
|
2021-08-11 13:12:12 +02:00
|
|
|
use codec::LocalStreamId;
|
|
|
|
use futures::{future, prelude::*, ready};
|
2018-12-18 11:06:37 +01:00
|
|
|
use libp2p_core::{
|
2020-06-30 17:10:53 +02:00
|
|
|
muxing::StreamMuxerEvent,
|
2020-01-13 14:34:43 +01:00
|
|
|
upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo},
|
2021-08-11 13:12:12 +02:00
|
|
|
StreamMuxer,
|
2018-11-15 17:41:11 +01:00
|
|
|
};
|
2018-07-17 16:31:32 +02:00
|
|
|
use parking_lot::Mutex;
|
2021-08-11 13:12:12 +02:00
|
|
|
use std::{cmp, iter, task::Context, task::Poll};
|
2017-11-01 11:59:52 +01:00
|
|
|
|
2018-11-15 17:41:11 +01:00
|
|
|
impl UpgradeInfo for MplexConfig {
|
2018-12-11 15:13:10 +01:00
|
|
|
type Info = &'static [u8];
|
|
|
|
type InfoIter = iter::Once<Self::Info>;
|
2018-11-15 17:41:11 +01:00
|
|
|
|
2018-12-11 15:13:10 +01:00
|
|
|
fn protocol_info(&self) -> Self::InfoIter {
|
2021-11-24 00:57:17 +08:00
|
|
|
iter::once(self.protocol_name)
|
2018-11-15 17:41:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<C> InboundUpgrade<C> for MplexConfig
|
2018-07-17 16:31:32 +02:00
|
|
|
where
|
2019-09-16 11:08:44 +02:00
|
|
|
C: AsyncRead + AsyncWrite + Unpin,
|
2018-07-17 16:31:32 +02:00
|
|
|
{
|
2020-01-13 14:34:43 +01:00
|
|
|
type Output = Multiplex<C>;
|
2020-09-28 10:30:49 +02:00
|
|
|
type Error = io::Error;
|
|
|
|
type Future = future::Ready<Result<Self::Output, io::Error>>;
|
2017-12-14 17:37:32 +01:00
|
|
|
|
2020-01-13 14:34:43 +01:00
|
|
|
fn upgrade_inbound(self, socket: C, _: Self::Info) -> Self::Future {
|
2020-09-28 10:30:49 +02:00
|
|
|
future::ready(Ok(Multiplex {
|
|
|
|
io: Mutex::new(io::Multiplexed::new(socket, self)),
|
|
|
|
}))
|
2017-11-01 11:59:52 +01:00
|
|
|
}
|
2018-11-15 17:41:11 +01:00
|
|
|
}
|
2017-11-01 11:59:52 +01:00
|
|
|
|
2018-11-15 17:41:11 +01:00
|
|
|
impl<C> OutboundUpgrade<C> for MplexConfig
|
|
|
|
where
|
2019-09-16 11:08:44 +02:00
|
|
|
C: AsyncRead + AsyncWrite + Unpin,
|
2018-11-15 17:41:11 +01:00
|
|
|
{
|
2020-01-13 14:34:43 +01:00
|
|
|
type Output = Multiplex<C>;
|
2020-09-28 10:30:49 +02:00
|
|
|
type Error = io::Error;
|
|
|
|
type Future = future::Ready<Result<Self::Output, io::Error>>;
|
2018-11-15 17:41:11 +01:00
|
|
|
|
2020-01-13 14:34:43 +01:00
|
|
|
fn upgrade_outbound(self, socket: C, _: Self::Info) -> Self::Future {
|
2020-09-28 10:30:49 +02:00
|
|
|
future::ready(Ok(Multiplex {
|
2021-08-11 13:12:12 +02:00
|
|
|
io: Mutex::new(io::Multiplexed::new(socket, self)),
|
2020-09-28 10:30:49 +02:00
|
|
|
}))
|
2017-11-01 11:59:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-17 16:31:32 +02:00
|
|
|
/// Multiplexer. Implements the `StreamMuxer` trait.
|
2020-06-30 17:10:53 +02:00
|
|
|
///
|
|
|
|
/// This implementation isn't capable of detecting when the underlying socket changes its address,
|
|
|
|
/// and no [`StreamMuxerEvent::AddressChange`] event is ever emitted.
|
2018-07-17 16:31:32 +02:00
|
|
|
pub struct Multiplex<C> {
|
2021-08-11 13:12:12 +02:00
|
|
|
io: Mutex<io::Multiplexed<C>>,
|
2017-11-01 11:59:52 +01:00
|
|
|
}
|
|
|
|
|
2020-09-28 10:30:49 +02:00
|
|
|
impl<C> StreamMuxer for Multiplex<C>
|
2020-04-01 14:28:59 +02:00
|
|
|
where
|
2021-08-11 13:12:12 +02:00
|
|
|
C: AsyncRead + AsyncWrite + Unpin,
|
2017-11-22 18:01:28 +01:00
|
|
|
{
|
2018-08-31 10:31:34 +02:00
|
|
|
type Substream = Substream;
|
|
|
|
type OutboundSubstream = OutboundSubstream;
|
2020-09-28 10:30:49 +02:00
|
|
|
type Error = io::Error;
|
2019-09-16 11:08:44 +02:00
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn poll_event(
|
|
|
|
&self,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
) -> Poll<io::Result<StreamMuxerEvent<Self::Substream>>> {
|
2020-09-28 10:30:49 +02:00
|
|
|
let stream_id = ready!(self.io.lock().poll_next_stream(cx))?;
|
|
|
|
let stream = Substream::new(stream_id);
|
|
|
|
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(stream)))
|
2017-11-22 18:01:28 +01:00
|
|
|
}
|
|
|
|
|
2018-08-31 10:31:34 +02:00
|
|
|
fn open_outbound(&self) -> Self::OutboundSubstream {
|
2020-09-28 10:30:49 +02:00
|
|
|
OutboundSubstream {}
|
2018-08-31 10:31:34 +02:00
|
|
|
}
|
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn poll_outbound(
|
|
|
|
&self,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
_: &mut Self::OutboundSubstream,
|
|
|
|
) -> Poll<Result<Self::Substream, io::Error>> {
|
2020-09-28 10:30:49 +02:00
|
|
|
let stream_id = ready!(self.io.lock().poll_open_stream(cx))?;
|
2021-02-15 11:59:51 +01:00
|
|
|
Poll::Ready(Ok(Substream::new(stream_id)))
|
2018-08-31 10:31:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fn destroy_outbound(&self, _substream: Self::OutboundSubstream) {
|
2020-09-28 10:30:49 +02:00
|
|
|
// Nothing to do, since `open_outbound` creates no new local state.
|
2018-08-31 10:31:34 +02:00
|
|
|
}
|
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn read_substream(
|
|
|
|
&self,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
substream: &mut Self::Substream,
|
|
|
|
buf: &mut [u8],
|
|
|
|
) -> Poll<Result<usize, io::Error>> {
|
2018-07-17 16:31:32 +02:00
|
|
|
loop {
|
2020-09-28 10:30:49 +02:00
|
|
|
// Try to read from the current (i.e. last received) frame.
|
2019-01-30 15:41:54 +01:00
|
|
|
if !substream.current_data.is_empty() {
|
2018-08-31 10:31:34 +02:00
|
|
|
let len = cmp::min(substream.current_data.len(), buf.len());
|
|
|
|
buf[..len].copy_from_slice(&substream.current_data.split_to(len));
|
2019-09-16 11:08:44 +02:00
|
|
|
return Poll::Ready(Ok(len));
|
2018-07-17 16:31:32 +02:00
|
|
|
}
|
2017-11-22 18:01:28 +01:00
|
|
|
|
2020-09-28 10:30:49 +02:00
|
|
|
// Read the next data frame from the multiplexed stream.
|
|
|
|
match ready!(self.io.lock().poll_read_stream(cx, substream.id))? {
|
2021-08-11 13:12:12 +02:00
|
|
|
Some(data) => {
|
|
|
|
substream.current_data = data;
|
|
|
|
}
|
|
|
|
None => return Poll::Ready(Ok(0)),
|
2018-07-17 16:31:32 +02:00
|
|
|
}
|
2017-11-22 18:01:28 +01:00
|
|
|
}
|
2017-11-01 11:59:52 +01:00
|
|
|
}
|
2018-03-21 15:41:24 +01:00
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn write_substream(
|
|
|
|
&self,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
substream: &mut Self::Substream,
|
|
|
|
buf: &[u8],
|
|
|
|
) -> Poll<Result<usize, io::Error>> {
|
2020-09-28 10:30:49 +02:00
|
|
|
self.io.lock().poll_write_stream(cx, substream.id, buf)
|
2018-07-17 16:31:32 +02:00
|
|
|
}
|
2018-03-21 15:41:24 +01:00
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn flush_substream(
|
|
|
|
&self,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
substream: &mut Self::Substream,
|
|
|
|
) -> Poll<Result<(), io::Error>> {
|
2020-09-28 10:30:49 +02:00
|
|
|
self.io.lock().poll_flush_stream(cx, substream.id)
|
2018-07-17 16:31:32 +02:00
|
|
|
}
|
2018-03-21 15:41:24 +01:00
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn shutdown_substream(
|
|
|
|
&self,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
substream: &mut Self::Substream,
|
|
|
|
) -> Poll<Result<(), io::Error>> {
|
2020-09-28 10:30:49 +02:00
|
|
|
self.io.lock().poll_close_stream(cx, substream.id)
|
2018-07-17 16:31:32 +02:00
|
|
|
}
|
2018-03-21 15:41:24 +01:00
|
|
|
|
2018-10-11 10:35:14 +02:00
|
|
|
fn destroy_substream(&self, sub: Self::Substream) {
|
2020-09-28 10:30:49 +02:00
|
|
|
self.io.lock().drop_stream(sub.id);
|
2018-03-21 15:41:24 +01:00
|
|
|
}
|
2018-09-14 13:18:10 +02:00
|
|
|
|
2020-09-28 10:30:49 +02:00
|
|
|
fn close(&self, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
|
|
|
self.io.lock().poll_close(cx)
|
2018-09-14 13:18:10 +02:00
|
|
|
}
|
|
|
|
|
2020-09-28 10:30:49 +02:00
|
|
|
fn flush_all(&self, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
|
|
|
self.io.lock().poll_flush(cx)
|
2018-09-14 13:18:10 +02:00
|
|
|
}
|
2017-11-01 11:59:52 +01:00
|
|
|
}
|
2018-08-31 10:31:34 +02:00
|
|
|
|
|
|
|
/// Active attempt to open an outbound substream.
|
2020-09-28 10:30:49 +02:00
|
|
|
pub struct OutboundSubstream {}
|
2018-08-31 10:31:34 +02:00
|
|
|
|
|
|
|
/// Active substream to the remote.
|
|
|
|
pub struct Substream {
|
2020-09-28 10:30:49 +02:00
|
|
|
/// The unique, local identifier of the substream.
|
|
|
|
id: LocalStreamId,
|
|
|
|
/// The current data frame the substream is reading from.
|
2018-08-31 10:31:34 +02:00
|
|
|
current_data: Bytes,
|
2020-09-28 10:30:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Substream {
|
|
|
|
fn new(id: LocalStreamId) -> Self {
|
2021-08-11 13:12:12 +02:00
|
|
|
Self {
|
|
|
|
id,
|
|
|
|
current_data: Bytes::new(),
|
|
|
|
}
|
2020-09-28 10:30:49 +02:00
|
|
|
}
|
2018-08-31 10:31:34 +02:00
|
|
|
}
|