|
|
@@ -1,13 +1,24 @@
|
|
|
use async_std::{
|
|
|
- net::{TcpListener, TcpStream},
|
|
|
+ net::TcpStream,
|
|
|
sync::{Arc, Mutex},
|
|
|
};
|
|
|
use std::net::SocketAddr;
|
|
|
|
|
|
use async_channel::{Receiver, Sender};
|
|
|
use async_executor::Executor;
|
|
|
+use easy_parallel::Parallel;
|
|
|
+use futures::{
|
|
|
+ io::BufReader, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, FutureExt, StreamExt,
|
|
|
+};
|
|
|
+use futures_rustls::TlsStream;
|
|
|
+use log::{debug, error, info, warn};
|
|
|
+use simplelog::{ColorChoice, TermLogger, TerminalMode};
|
|
|
+use smol::future;
|
|
|
+use structopt_toml::StructOptToml;
|
|
|
+
|
|
|
use darkfi::{
|
|
|
async_daemonize,
|
|
|
+ net::transport::{TcpTransport, TlsTransport, Transport},
|
|
|
raft::Raft,
|
|
|
rpc::rpcserver::{listen_and_serve, RpcServerConfig},
|
|
|
util::{
|
|
|
@@ -16,12 +27,6 @@ use darkfi::{
|
|
|
},
|
|
|
Error, Result,
|
|
|
};
|
|
|
-use easy_parallel::Parallel;
|
|
|
-use futures::{io::BufReader, AsyncBufReadExt, AsyncReadExt, FutureExt};
|
|
|
-use log::{debug, error, info, warn};
|
|
|
-use simplelog::{ColorChoice, TermLogger, TerminalMode};
|
|
|
-use smol::future;
|
|
|
-use structopt_toml::StructOptToml;
|
|
|
|
|
|
pub mod privmsg;
|
|
|
pub mod rpc;
|
|
|
@@ -35,6 +40,12 @@ use crate::{
|
|
|
settings::{Args, CONFIG_FILE, CONFIG_FILE_CONTENTS},
|
|
|
};
|
|
|
|
|
|
+// TODO should using Stream from net3 instead
|
|
|
+pub trait Stream: AsyncWrite + AsyncRead + Unpin + Send + Sync {}
|
|
|
+
|
|
|
+impl Stream for TcpStream {}
|
|
|
+impl<T: Stream> Stream for TlsStream<T> {}
|
|
|
+
|
|
|
pub type SeenMsgIds = Arc<Mutex<Vec<u32>>>;
|
|
|
|
|
|
fn build_irc_msg(msg: &Privmsg) -> String {
|
|
|
@@ -79,7 +90,7 @@ async fn broadcast_msg(
|
|
|
|
|
|
async fn process(
|
|
|
raft_receiver: Receiver<Privmsg>,
|
|
|
- stream: TcpStream,
|
|
|
+ stream: Box<dyn Stream>,
|
|
|
peer_addr: SocketAddr,
|
|
|
raft_sender: Sender<Privmsg>,
|
|
|
seen_msg_id: SeenMsgIds,
|
|
|
@@ -98,7 +109,7 @@ async fn process(
|
|
|
|
|
|
let mut smi = seen_msg_id.lock().await;
|
|
|
if smi.contains(&msg.id) {
|
|
|
- continue
|
|
|
+ continue
|
|
|
}
|
|
|
smi.push(msg.id);
|
|
|
drop(smi);
|
|
|
@@ -124,10 +135,6 @@ async fn process(
|
|
|
|
|
|
async_daemonize!(realmain);
|
|
|
async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
|
|
|
- let listener = TcpListener::bind(settings.irc_listen).await?;
|
|
|
- let local_addr = listener.local_addr()?;
|
|
|
- info!("IRC listening on {}", local_addr);
|
|
|
-
|
|
|
let seen_msg_id: SeenMsgIds = Arc::new(Mutex::new(vec![]));
|
|
|
|
|
|
//
|
|
|
@@ -160,27 +167,60 @@ async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
|
|
|
//
|
|
|
let executor_cloned = executor.clone();
|
|
|
let irc_task: smol::Task<Result<()>> = executor.spawn(async move {
|
|
|
- loop {
|
|
|
- let (stream, peer_addr) = match listener.accept().await {
|
|
|
- Ok((s, a)) => (s, a),
|
|
|
- Err(e) => {
|
|
|
- error!("Failed listening for connections: {}", e);
|
|
|
- return Err(Error::ServiceStopped)
|
|
|
+ let irc_listen_url = url::Url::parse(&settings.irc_listen)?;
|
|
|
+
|
|
|
+ match irc_listen_url.scheme() {
|
|
|
+ "tcp" => {
|
|
|
+ let transport = TcpTransport::new(None, 1024);
|
|
|
+ let listener = transport.listen_on(irc_listen_url.clone()).unwrap().await.unwrap();
|
|
|
+ let mut incoming = listener.incoming();
|
|
|
+ info!("IRC start a TCP connection {}", &irc_listen_url.to_string());
|
|
|
+ while let Some(stream) = incoming.next().await {
|
|
|
+ let stream = stream.unwrap();
|
|
|
+ let peer_addr = stream.peer_addr()?;
|
|
|
+ info!("IRC Accepted TCP connection {}", peer_addr);
|
|
|
+ executor_cloned
|
|
|
+ .spawn(process(
|
|
|
+ raft_receiver.clone(),
|
|
|
+ Box::new(stream),
|
|
|
+ peer_addr,
|
|
|
+ raft_sender.clone(),
|
|
|
+ seen_msg_id.clone(),
|
|
|
+ ))
|
|
|
+ .detach();
|
|
|
}
|
|
|
- };
|
|
|
-
|
|
|
- info!("IRC Accepted client: {}", peer_addr);
|
|
|
-
|
|
|
- executor_cloned
|
|
|
- .spawn(process(
|
|
|
- raft_receiver.clone(),
|
|
|
- stream,
|
|
|
- peer_addr,
|
|
|
- raft_sender.clone(),
|
|
|
- seen_msg_id.clone(),
|
|
|
- ))
|
|
|
- .detach();
|
|
|
+ }
|
|
|
+
|
|
|
+ "tls" => {
|
|
|
+ let transport = TlsTransport::new(None, 1024);
|
|
|
+ let (acceptor, listener) =
|
|
|
+ transport.listen_on(irc_listen_url.clone()).unwrap().await.unwrap();
|
|
|
+ let mut incoming = listener.incoming();
|
|
|
+ info!("IRC bind a TLS connection {}", &irc_listen_url.to_string());
|
|
|
+ while let Some(stream) = incoming.next().await {
|
|
|
+ let stream = stream.unwrap();
|
|
|
+ let peer_addr = stream.peer_addr()?;
|
|
|
+ info!("IRC Accepted TLS connection {}", peer_addr);
|
|
|
+ let stream = acceptor.accept(stream).await?;
|
|
|
+ executor_cloned
|
|
|
+ .spawn(process(
|
|
|
+ raft_receiver.clone(),
|
|
|
+ Box::new(TlsStream::Server(stream)),
|
|
|
+ peer_addr,
|
|
|
+ raft_sender.clone(),
|
|
|
+ seen_msg_id.clone(),
|
|
|
+ ))
|
|
|
+ .detach();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ x => {
|
|
|
+ error!("Transport protocol '{}' isn't implemented", x);
|
|
|
+ return Err(Error::UnsupportedTransport(x.to_string()))
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ Ok(())
|
|
|
});
|
|
|
|
|
|
let (signal, shutdown) = async_channel::bounded::<()>(1);
|