Browse Source

Start handling peer connect request.

wip
Titouan Rigoudy 4 years ago
parent
commit
82f4330545
8 changed files with 166 additions and 38 deletions
  1. +2
    -0
      client/src/context.rs
  2. +3
    -1
      client/src/control/request.rs
  3. +7
    -6
      client/src/dispatcher.rs
  4. +2
    -0
      client/src/handlers/mod.rs
  5. +81
    -0
      client/src/handlers/peer_connect_request_handler.rs
  6. +1
    -0
      client/src/main.rs
  7. +70
    -0
      client/src/peer.rs
  8. +0
    -31
      proto/src/peer/worker.rs

+ 2
- 0
client/src/context.rs View File

@ -8,6 +8,7 @@ use tokio::sync::mpsc::{channel, Receiver, Sender};
use crate::clock::SimulatedSystemClock;
use crate::clock::SystemClock;
use crate::control::Response as ControlResponse;
use crate::peer::PeerMap;
use crate::room::RoomMap;
use crate::user::UserMap;
use crate::Config;
@ -17,6 +18,7 @@ use crate::Config;
pub struct State {
pub rooms: RoomMap,
pub users: UserMap,
pub peers: PeerMap,
}
/// Holds process-wide context for message handlers to execute against.


+ 3
- 1
client/src/control/request.rs View File

@ -4,9 +4,11 @@ use serde::{Deserialize, Serialize};
/// controller client to the client.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum Request {
/// The controller wants to connect to a peer. Contains the peer name.
PeerConnectRequest(String),
/// The controller wants to join a room. Contains the room name.
RoomJoinRequest(String),
/// The controller wants to leave a rom. Contains the room name.
/// The controller wants to leave a room. Contains the room name.
RoomLeaveRequest(String),
/// The controller wants to know what the login status is.
LoginStatusRequest,


+ 7
- 6
client/src/dispatcher.rs View File

@ -7,12 +7,7 @@ use solstice_proto::server::ServerResponse;
use crate::context::Context;
use crate::control::Request as ControlRequest;
use crate::handlers::{
LoginStatusRequestHandler, PrivilegedUsersResponseHandler,
RoomJoinRequestHandler, RoomJoinResponseHandler, RoomListRequestHandler,
RoomListResponseHandler, RoomMessageRequestHandler,
RoomMessageResponseHandler, UserListRequestHandler,
};
use crate::handlers::*;
use crate::message_handler::MessageHandler;
/// The type of messages dispatched by a dispatcher.
@ -110,6 +105,12 @@ impl Dispatcher {
warn!("Unhandled server response: {:?}", response);
None
}
Message::ControlRequest(ControlRequest::PeerConnectRequest(request)) => {
Some(Box::new(DispatchedMessage {
message: request,
handler: PeerConnectRequestHandler::default(),
}))
}
Message::ControlRequest(ControlRequest::RoomListRequest) => {
Some(Box::new(DispatchedMessage {
message: (),


+ 2
- 0
client/src/handlers/mod.rs View File

@ -1,4 +1,5 @@
mod login_status_request_handler;
mod peer_connect_request_handler;
mod privileged_users_response_handler;
mod room_join_request_handler;
mod room_join_response_handler;
@ -9,6 +10,7 @@ mod room_message_response_handler;
mod user_list_request_handler;
pub use login_status_request_handler::LoginStatusRequestHandler;
pub use peer_connect_request_handler::PeerConnectRequestHandler;
pub use privileged_users_response_handler::PrivilegedUsersResponseHandler;
pub use room_join_request_handler::RoomJoinRequestHandler;
pub use room_join_response_handler::RoomJoinResponseHandler;


+ 81
- 0
client/src/handlers/peer_connect_request_handler.rs View File

@ -0,0 +1,81 @@
use anyhow::{bail, Context as AnyhowContext};
use solstice_proto::server::{PeerAddressRequest, ServerRequest};
use crate::context::Context;
use crate::message_handler::MessageHandler;
use crate::peer::PeerState;
#[derive(Debug, Default)]
pub struct PeerConnectRequestHandler;
impl MessageHandler for PeerConnectRequestHandler {
type Message = String;
fn run(
self,
context: &mut Context,
user_name: &String,
) -> anyhow::Result<()> {
let peer = match context.state.peers.peers.get_mut(user_name) {
Some(peer) => peer,
None => {
// Address is not even known, we need to ask for it first.
context
.state
.peers
.peers
.insert(user_name.clone(), PeerState::FetchingAddress);
let request = ServerRequest::PeerAddressRequest(PeerAddressRequest {
user_name: user_name.clone(),
});
context
.server_request_tx
.blocking_send(request)
.context("sending peer address request")?;
return Ok(());
}
};
bail!("Unimplemented. Peer = {:?}", peer);
}
fn name() -> String {
"PeerConnectRequestHandler".to_string()
}
}
#[cfg(test)]
mod tests {
use solstice_proto::server::{PeerAddressRequest, ServerRequest};
use crate::context::ContextBundle;
use crate::message_handler::MessageHandler;
use crate::peer::PeerState;
use super::PeerConnectRequestHandler;
#[test]
fn run_unknown_peer() {
let mut bundle = ContextBundle::default();
PeerConnectRequestHandler::default()
.run(&mut bundle.context, &"aisha".to_string())
.unwrap();
match bundle.context.state.peers.peers.get("aisha") {
Some(PeerState::FetchingAddress) => (),
None => panic!("Missing state"),
}
drop(bundle.context.server_request_tx);
match bundle.server_request_rx.blocking_recv() {
Some(ServerRequest::PeerAddressRequest(PeerAddressRequest {
user_name,
})) => assert_eq!(user_name, "aisha"),
Some(request) => panic!("Unexpected server request: {:?}", request),
None => panic!("Expected server request, got none"),
}
}
}

+ 1
- 0
client/src/main.rs View File

@ -16,6 +16,7 @@ mod dispatcher;
mod handlers;
mod login;
mod message_handler;
mod peer;
mod room;
#[cfg(test)]
mod testing;


+ 70
- 0
client/src/peer.rs View File

@ -0,0 +1,70 @@
//! This module provides abstractions for interacting with a set of peers.
use std::collections::HashMap;
// Peer states:
//
// - closed
// - opening
// - open
// - waiting for pierce firewall
// - cannot connect
//
// Transitions:
//
// - closed:
// -> fetching ip:
// request IP from server
// -> open:
// accept connection
// receive peerinit
// - fetching ip:
// -> opening:
// receive IP from server
// request connection
// - opening:
// -> open:
// connect
// send peerinit
// -> waiting for pierce firewall:
// connect failed, or send peerinit failed
// send connecttopeer to server
// - open:
// -> closed:
// connection closed
// - waiting for pierce firewall:
// -> open:
// accept connection
// receive pierce firewall
// -> cannot connect:
// receive cannot connect
//
/// The current state of a peer connection.
#[derive(Debug)]
pub enum PeerState {
FetchingAddress,
/*
Opening {
address: SocketAddr,
},
Waiting {
address: SocketAddr,
token: u32,
},
Failed {
address: SocketAddr,
token: u32,
},
// TODO: Handle cannot connect logic, add `Failed` state.
Open {
address: SocketAddr,
message_tx: Sender<Message>,
}
*/
}
#[derive(Debug, Default)]
pub struct PeerMap {
pub peers: HashMap<String, PeerState>,
}

+ 0
- 31
proto/src/peer/worker.rs View File

@ -9,37 +9,6 @@ use tokio::net::{TcpListener, TcpStream};
use crate::core::{FrameReader, FrameWriter, Worker};
use crate::peer::{InitialMessage, Message};
// Peer states:
//
// - closed
// - open
// - waiting for pierce firewall
// - cannot connect
//
// Transitions:
//
// - closed:
// -> open:
// connect
// send peerinit
// -> waiting for pierce firewall:
// connect failed, or send peerinit failed
// send connecttopeer to server
// -> open:
// accept connection
// receive peerinit
// - open:
// -> closed:
// connection closed
// - waiting for pierce firewall:
// -> open:
// accept connection
// receive pierce firewall
// ???send peer init???
// -> cannot connect:
// receive cannot connect
//
/// A peer to connect to.
#[derive(Debug)]
pub struct PeerConnection {


Loading…
Cancel
Save