feat: add logging support

This commit is contained in:
Michel de Graaf
2025-07-05 23:16:05 +02:00
parent 57dafaf8ab
commit 956cb824bd
28 changed files with 765 additions and 203 deletions
+96 -37
View File
@@ -1,8 +1,11 @@
use crate::dispatcher::MessageDispatcher;
use crate::message::peer::get_share_file_list::GetShareFileList;
use crate::message::peer::transfer_request::TransferRequest;
use crate::message::peer::upload_failed::UploadFailedHandler;
use crate::message::peer::FileSearchResponse;
use crate::message::server::MessageFactory;
use crate::message::{Handlers, Message, MessageReader};
use crate::types::FileSearchResult;
use crate::message::{Handlers, Message, MessageReader, MessageType};
use crate::types::{FileSearchResult, Transfer};
use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender};
@@ -20,7 +23,6 @@ pub struct DefaultPeer {
peer: Peer,
peer_channel: Option<Sender<PeerOperation>>,
client_channel: Sender<ClientOperation>,
// Store thread handles for proper lifecycle management
read_thread: Option<JoinHandle<()>>,
write_thread: Option<JoinHandle<()>>,
}
@@ -29,6 +31,7 @@ pub struct DefaultPeer {
pub enum PeerOperation {
SendMessage(Message),
FileSearchResult(FileSearchResult),
TransferRequest(Transfer),
}
impl DefaultPeer {
pub fn new(peer: Peer, client_channel: Sender<ClientOperation>) -> Self {
@@ -46,13 +49,14 @@ impl DefaultPeer {
.next()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "Invalid address"))?;
let mut stream = TcpStream::connect_timeout(&socket_address, Duration::from_secs(10))?;
let mut stream = TcpStream::connect_timeout(&socket_address, Duration::from_secs(20))?;
stream.set_read_timeout(Some(Duration::from_secs(5)))?;
stream.set_write_timeout(Some(Duration::from_secs(5)))?;
if let Some(token) = self.peer.token.clone() {
if let Some(token) = self.peer.token {
stream
.write_all(&MessageFactory::build_watch_user(token.as_str()).get_data())
.write_all(&MessageFactory::build_watch_user(token).get_data())
.unwrap();
}
self.start_read_write_loops(stream)?;
@@ -64,6 +68,9 @@ impl DefaultPeer {
let (peer_sender, peer_reader): (Sender<PeerOperation>, Receiver<PeerOperation>) =
mpsc::channel();
// Set the peer_channel so transfer_request can send messages
self.peer_channel = Some(peer_sender.clone());
let mut read_stream = stream.try_clone()?;
let mut write_stream = stream; // Use the original stream for writing
@@ -74,6 +81,9 @@ impl DefaultPeer {
self.read_thread = Some(thread::spawn(move || {
let mut handlers = Handlers::new();
handlers.register_handler(FileSearchResponse);
handlers.register_handler(TransferRequest);
handlers.register_handler(GetShareFileList);
handlers.register_handler(UploadFailedHandler);
let dispatcher = MessageDispatcher::new(peer_sender, handlers);
@@ -83,27 +93,41 @@ impl DefaultPeer {
Ok(_) => {}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => continue,
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => {
println!(
debug!(
"Read operation timed out in default peer {:}:{:}",
peer.host, peer.port
);
continue;
}
Err(e) => {
eprintln!("Error reading from peer: {}. Terminating read loop.", e);
let _ = client_channel_for_read.send(ClientOperation::PeerDisconnected(peer.username.clone()));
error!("Error reading from peer: {}. Terminating read loop.", e);
let _ = client_channel_for_read
.send(ClientOperation::PeerDisconnected(peer.username.clone()));
break;
}
}
match buffered_reader.extract_message() {
Ok(Some(mut message)) => dispatcher.dispatch(&mut message),
Ok(Some(mut message)) => {
trace!(
"[default_peer:{:?}] ← {:?}",
peer.username,
message
.get_message_name(
MessageType::Peer,
message.get_message_code() as u32
)
.map_err(|e| e.to_string())
);
dispatcher.dispatch(&mut message)
}
Err(e) => {
println!(
warn!(
"Error extracting message in default peer: {}. Terminating read loop.",
e
);
let _ = client_channel_for_read.send(ClientOperation::PeerDisconnected(peer.username.clone()));
let _ = client_channel_for_read
.send(ClientOperation::PeerDisconnected(peer.username.clone()));
break;
}
Ok(None) => continue,
@@ -112,29 +136,62 @@ impl DefaultPeer {
}));
let client_channel = self.client_channel.clone();
let peer_channel = self.peer_channel.clone();
let peer_username = self.peer.username.clone();
self.write_thread = Some(thread::spawn(move || {
loop {
match peer_reader.recv() {
Ok(operation) => {
match operation {
PeerOperation::SendMessage(message) => {
if let Err(e) = write_stream.write_all(&message.get_buffer()) {
eprintln!("Error writing message to stream: {}. Terminating write loop.", e);
let _ = client_channel.send(ClientOperation::PeerDisconnected(peer_username.clone()));
break;
}
Ok(operation) => match operation {
PeerOperation::SendMessage(message) => {
trace!(
"[default_peer:{:?}] ➡ {:?} - {:?}",
peer_username,
message
.get_message_name(
MessageType::Peer,
u32::from_le_bytes(
message.get_slice(0, 4).try_into().unwrap()
)
)
.map_err(|e| e.to_string()),
message
);
if let Err(e) = write_stream.write_all(&message.get_buffer()) {
error!("Error writing message to stream: {} - {}. Terminating write loop.", peer_username, e);
let _ = client_channel
.send(ClientOperation::PeerDisconnected(peer_username.clone()));
break;
}
PeerOperation::FileSearchResult(file_search) => {
client_channel
.send(ClientOperation::SearchResult(file_search))
}
PeerOperation::FileSearchResult(file_search) => {
client_channel
.send(ClientOperation::SearchResult(file_search))
.unwrap();
}
PeerOperation::TransferRequest(transfer) => {
debug!(
"[default_peer:{}] transfer request: {:?}",
peer_username, transfer
);
client_channel
.send(ClientOperation::TransferRequest(transfer.clone()))
.unwrap();
let transfer_response =
MessageFactory::build_transfer_response_message(transfer.clone());
if let Some(sender) = peer_channel.clone() {
sender
.send(PeerOperation::SendMessage(transfer_response))
.unwrap();
}
}
}
},
Err(_) => {
// The sender has been dropped, the peer is shutting down.
println!("Peer channel closed. Terminating write loop.");
debug!("Peer channel closed. Terminating write loop.");
break;
}
}
@@ -143,31 +200,33 @@ impl DefaultPeer {
Ok(())
}
pub fn transfer_request(&self, filename: String) -> Result<(), io::Error> {
let message = MessageFactory::build_queue_upload_message(&filename);
if let Some(sender) = &self.peer_channel {
sender.send(PeerOperation::SendMessage(message)).unwrap();
}
Ok(())
}
}
impl Drop for DefaultPeer {
fn drop(&mut self) {
// Signal threads to shut down (e.g., by dropping the sender half of the channel)
// For now, we'll just drop the peer_channel, which will cause the writer thread
// to exit its loop. A more robust solution might involve a shared AtomicBool
// or a dedicated shutdown channel.
self.peer_channel = None;
// Join the read thread
if let Some(handle) = self.read_thread.take() {
println!("Joining read thread...");
debug!("Joining read thread...");
match handle.join() {
Ok(_) => println!("Read thread joined successfully."),
Err(e) => eprintln!("Read thread panicked: {:?}", e),
Ok(_) => debug!("Read thread joined successfully."),
Err(e) => error!("Read thread panicked: {:?}", e),
}
}
// Join the write thread
if let Some(handle) = self.write_thread.take() {
println!("Joining write thread...");
debug!("Joining write thread...");
match handle.join() {
Ok(_) => println!("Write thread joined successfully."),
Err(e) => eprintln!("Write thread panicked: {:?}", e),
Ok(_) => debug!("Write thread joined successfully."),
Err(e) => error!("Write thread panicked: {:?}", e),
}
}
}
+9 -9
View File
@@ -8,7 +8,7 @@ pub struct Listen {}
impl Listen {
pub fn start(port: u32, _server_channel: Sender<ServerOperation>) {
println!("starting listener on port {port}");
info!("starting listener on port {port}");
let listener = TcpListener::bind(format!("0.0.0.0:{port}")).unwrap();
for stream in listener.incoming() {
let mut read_stream = stream.unwrap();
@@ -20,19 +20,19 @@ impl Listen {
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => continue,
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => continue,
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => {
println!("Read operation timed out");
debug!("Read operation timed out");
continue;
}
Err(e) => {
eprintln!("Error reading from server: {}", e);
error!("Error reading from server: {}", e);
break;
}
}
match buffered_reader.extract_message() {
Ok(Some(mut message)) => {
println!("Received message: {:?}", message.get_message_code());
println!("{:?}", message.get_data());
debug!("Received message: {:?}", message.get_message_code());
trace!("{:?}", message.get_data());
message.print_hex();
if message.get_message_code() == 1 {
@@ -45,8 +45,8 @@ impl Listen {
// // message.read_string().parse().unwrap();
// // let token = message.read_int32();
//
println!("type: {:?}", typex);
println!("user: {:?}", size);
debug!("type: {:?}", typex);
debug!("user: {:?}", size);
// server_channel
// .send(ServerOperation::ConnectToPeer(peer))
@@ -54,13 +54,13 @@ impl Listen {
}
}
Err(e) => {
println!("Error extracting message: {}", e)
warn!("Error extracting message: {}", e)
}
Ok(None) => continue,
}
}
println!("Connection established!");
info!("Connection established!");
}
}
}
+12 -13
View File
@@ -46,11 +46,11 @@ pub struct Peer {
pub username: String,
pub connection_type: ConnectionType,
pub host: String,
pub port: i32,
pub token: Option<String>,
pub privileged: i8,
pub unknown: i8,
pub obfuscated_port: i8,
pub port: u32,
pub token: Option<u32>,
pub privileged: u8,
pub unknown: u8,
pub obfuscated_port: u8,
}
impl Peer {
#[allow(clippy::too_many_arguments, dead_code)]
@@ -58,11 +58,11 @@ impl Peer {
username: String,
connection_type: ConnectionType,
host: String,
port: i32,
token: String,
privileged: i8,
unknown: i8,
obfuscated_port: i8,
port: u32,
token: u32,
privileged: u8,
unknown: u8,
obfuscated_port: u8,
) -> Self {
Self {
username,
@@ -78,7 +78,7 @@ impl Peer {
#[allow(dead_code)]
pub fn new_from_message(message: &mut Message) -> Self {
let username = message.read_string();
let connection_type: ConnectionType = message.read_string().parse().unwrap();
let connection_type = message.read_string().parse().unwrap();
let mut ip: Vec<i32> = vec![];
for _ in 0..4 {
@@ -94,7 +94,7 @@ impl Peer {
let (port, token, privileged, unknown, obfuscated_port) = (
message.read_int32(),
message.read_raw_hex_str(4),
message.read_int32(),
message.read_int8(),
message.read_int8(),
message.read_int8(),
@@ -155,4 +155,3 @@ fn test_new_from_message2() {
assert_eq!(peer.unknown, 1);
assert_eq!(peer.obfuscated_port, 0);
}
View File