mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
ircd: irc server support tls protocol
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2266,6 +2266,7 @@ dependencies = [
|
||||
"darkfi",
|
||||
"easy-parallel",
|
||||
"futures",
|
||||
"futures-rustls",
|
||||
"fxhash",
|
||||
"log",
|
||||
"rand",
|
||||
@@ -2275,6 +2276,7 @@ dependencies = [
|
||||
"smol",
|
||||
"structopt",
|
||||
"structopt-toml",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -13,6 +13,7 @@ darkfi = {path = "../../", features = ["net", "rpc", "raft"]}
|
||||
# Async
|
||||
smol = "1.2.5"
|
||||
futures = "0.3.21"
|
||||
futures-rustls = "0.22.1"
|
||||
async-std = "1.11.0"
|
||||
async-trait = "0.1.53"
|
||||
async-channel = "1.6.1"
|
||||
@@ -28,6 +29,7 @@ log = "0.4.16"
|
||||
simplelog = "0.12.0-alpha1"
|
||||
fxhash = "0.2.1"
|
||||
ctrlc-async = {version= "3.2.2", default-features = false, features = ["async-std", "termination"]}
|
||||
url = "2.2.2"
|
||||
|
||||
# Encoding and parsing
|
||||
serde_json = "1.0.79"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#rpc_listen="127.0.0.1:11055"
|
||||
|
||||
## IRC listen URL
|
||||
#irc_listen="127.0.0.1:11066"
|
||||
#irc_listen="tcp://127.0.0.1:11066"
|
||||
|
||||
## Sets Datastore Path
|
||||
#datastore="~/.config/ircd"
|
||||
|
||||
@@ -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);
|
||||
"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();
|
||||
}
|
||||
}
|
||||
|
||||
executor_cloned
|
||||
.spawn(process(
|
||||
raft_receiver.clone(),
|
||||
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);
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
use async_std::net::TcpStream;
|
||||
use futures::{io::WriteHalf, AsyncWriteExt};
|
||||
use log::{debug, info, warn};
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
|
||||
use darkfi::{Error, Result};
|
||||
|
||||
use crate::{privmsg::Privmsg, SeenMsgIds};
|
||||
use crate::{privmsg::Privmsg, SeenMsgIds, Stream};
|
||||
|
||||
pub struct IrcServerConnection {
|
||||
write_stream: WriteHalf<TcpStream>,
|
||||
write_stream: WriteHalf<Box<dyn Stream>>,
|
||||
is_nick_init: bool,
|
||||
is_user_init: bool,
|
||||
is_registered: bool,
|
||||
@@ -20,7 +19,7 @@ pub struct IrcServerConnection {
|
||||
|
||||
impl IrcServerConnection {
|
||||
pub fn new(
|
||||
write_stream: WriteHalf<TcpStream>,
|
||||
write_stream: WriteHalf<Box<dyn Stream>>,
|
||||
seen_msg_id: SeenMsgIds,
|
||||
p2p_sender: async_channel::Sender<Privmsg>,
|
||||
) -> Self {
|
||||
|
||||
@@ -21,8 +21,8 @@ pub struct Args {
|
||||
#[structopt(long = "rpc", default_value = "127.0.0.1:11055")]
|
||||
pub rpc_listen: SocketAddr,
|
||||
/// IRC listen URL
|
||||
#[structopt(long = "irc", default_value = "127.0.0.1:11066")]
|
||||
pub irc_listen: SocketAddr,
|
||||
#[structopt(long = "irc", default_value = "tcp://127.0.0.1:11066")]
|
||||
pub irc_listen: String,
|
||||
/// Sets Datastore Path
|
||||
#[structopt(long, default_value = "~/.config/ircd")]
|
||||
pub datastore: String,
|
||||
|
||||
@@ -89,7 +89,7 @@ pub mod settings;
|
||||
pub mod transport;
|
||||
|
||||
pub use acceptor::{Acceptor, AcceptorPtr};
|
||||
pub use channel::{Channel, ChannelPtr};
|
||||
pub use channel::{Channel, ChannelPtr, Stream};
|
||||
pub use connector::Connector;
|
||||
pub use hosts::{Hosts, HostsPtr};
|
||||
pub use message::Message;
|
||||
|
||||
Reference in New Issue
Block a user