1
0
mirror of https://git.ngram.ca/OpenJam/rc-servers synced 2026-08-23 23:08:52 +00:00

Update to work with polariton v0.2

This commit is contained in:
NGnius (Graham)
2025-03-08 17:16:02 -05:00
parent f004ca8565
commit be37f8913a
83 changed files with 428 additions and 1202 deletions

View File

@@ -1,14 +1,10 @@
mod cli;
mod state;
use std::num::NonZero;
use std::sync::Arc;
use polariton_auth::Handshake;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net;
use polariton::packet::{Cryptographer, Data, Message, Packet, Ping, StandardMessage, StandardPacket};
use polariton::packet::{Data, Message, Packet, StandardMessage};
use polariton::operation::{OperationResponse, Typed};
#[tokio::main]
@@ -28,21 +24,20 @@ async fn main() -> std::io::Result<()> {
#[cfg(not(debug_assertions))]
loop {
let (socket, address) = listener.accept().await?;
tokio::spawn(process_socket(socket, address, NonZero::new(args.retries), op_handler.clone(), redirect_static, room_name_static));
tokio::spawn(process_socket(socket, address, op_handler.clone(), redirect_static, room_name_static));
}
#[cfg(debug_assertions)]
{
let (socket, address) = listener.accept().await?;
process_socket(socket, address, NonZero::new(args.retries), redirect_static, room_name_static).await;
process_socket(socket, address, redirect_static, room_name_static).await;
Ok(())
}
}
async fn process_socket(mut socket: net::TcpStream, address: std::net::SocketAddr, retries: Option<NonZero<usize>>, redirect_url: &str, lobby_name: &str) {
async fn process_socket(mut socket: net::TcpStream, address: std::net::SocketAddr, redirect_url: &str, lobby_name: &str) {
log::debug!("Accepting connection from address {}", address);
let mut buf = Vec::new();
let enc = match do_connect_handshake(&mut buf, &mut socket, retries, lobby_name, redirect_url).await {
let enc = match do_connect_handshake(&mut socket, lobby_name, redirect_url).await {
Some(x) => x,
None => {
log::error!("Failed to do connect handshake with {}", address);
@@ -50,10 +45,10 @@ async fn process_socket(mut socket: net::TcpStream, address: std::net::SocketAdd
}
};
let sock_state = state::State::new(enc);
while let Ok(packet) = receive_packet(&mut buf, &mut socket, retries, sock_state.binrw_args()).await {
while let Ok(packet) = polariton_server::utils::receive_packet_async(&mut socket, &sock_state.serdes_ctx()).await {
match packet {
Packet::Ping(ping) => {
handle_ping(ping, &mut buf, &mut socket).await;
polariton_server::utils::handle_ping_async(ping, &mut socket, &sock_state.serdes_ctx()).await.unwrap_or_default();
},
Packet::Packet(packet) => log::warn!("Not handling packet {:?}", packet),
}
@@ -61,91 +56,6 @@ async fn process_socket(mut socket: net::TcpStream, address: std::net::SocketAdd
log::debug!("Goodbye connection from address {}", address);
}
async fn handle_ping(ping: Ping, buf: &mut Vec<u8>, socket: &mut net::TcpStream) {
buf.clear();
let resp = Packet::Ping(polariton_auth::ping_pong(ping));
resp.to_buf(buf, None).unwrap();
let write_count = socket.write(buf).await.unwrap();
log::debug!("(ping) Write {} bytes to socket: {:?}", write_count, buf);
buf.clear();
}
fn buf_likely_valid(buf: &[u8]) -> bool {
buf.is_empty() || buf[0] == Packet::PING_MAGIC || buf[0] == Packet::FRAMED_MAGIC
}
async fn read_more(buf: &mut Vec<u8>, socket: &mut net::TcpStream) -> Result<usize, std::io::Error> {
let read_count = socket.read_buf(buf).await?;
log::debug!("Read {} bytes from socket: {:?}", read_count, buf);
Ok(read_count)
}
async fn receive_packet(buf: &mut Vec<u8>, socket: &mut net::TcpStream, max_retries: Option<NonZero<usize>>, args: Option<Box<Arc<dyn Cryptographer + 'static>>>) -> Result<Packet, std::io::Error> {
if buf.is_empty() {
let read_count = read_more(buf, socket).await?;
if read_count == 0 { return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "socket did not read any bytes")); } // bad packet
}
let mut last_err = None;
let mut must_succeed_next = false;
if let Some(max_retries) = max_retries {
for _ in 0..max_retries.get() {
match Packet::from_buf(&buf, args.clone()) {
Ok(packet) => {
log::debug!("Received packet {:?}", packet);
return Ok(packet);
},
Err(e) => last_err = Some(e),
}
if must_succeed_next {
break;
}
must_succeed_next = read_more(buf, socket).await? == 0;
}
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, last_err.unwrap()));
} else {
while buf_likely_valid(buf.as_slice()) {
match Packet::from_buf(&buf, args.clone()) {
Ok(packet) => {
log::debug!("Received packet {:?}", packet);
return Ok(packet);
},
Err(e) => last_err = Some(e),
}
if must_succeed_next {
break;
}
must_succeed_next = read_more(buf, socket).await? == 0;
}
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, last_err.unwrap()));
}
}
async fn send_packet(packet: Packet, buf: &mut Vec<u8>, socket: &mut net::TcpStream, args: Option<Box<Arc<dyn Cryptographer>>>) -> Result<(), std::io::Error> {
log::debug!("Sending packet {:?}", packet);
buf.clear();
packet.to_buf(buf, args).map_err(|e| std::io::Error::new(std::io::ErrorKind::NotFound, e))?;
let write_count = socket.write(buf).await?;
log::debug!("Write {} bytes to socket: {:?}", write_count, buf);
#[cfg(debug_assertions)]
{
// print out unencrypted packet too
if let Packet::Packet(standard_p) = packet {
if let Message::Standard(standard_m) = standard_p.message {
if standard_m.is_encrypted() {
let standard_m = standard_m.encrypt(false);
let packet = Packet::Packet(StandardPacket { header: standard_p.header, message: Message::Standard(standard_m) });
packet.to_buf(buf, None).map_err(|e| std::io::Error::new(std::io::ErrorKind::NotFound, e))?;
log::debug!("Unencrypted bytes of packet: {:?} (len: {})", buf, buf.len());
}
}
}
}
buf.clear();
Ok(())
}
const APP_ID: &str = "SocialServer";
struct AuthImpl;
@@ -194,23 +104,20 @@ impl polariton_auth::AuthProvider<AuthError> for AuthImpl {
}
async fn do_connect_handshake(
buf: &mut Vec<u8>,
socket: &mut net::TcpStream,
max_retries: Option<NonZero<usize>>,
game_server_name: &str,
game_server_url: &str,
) -> Option<Box<std::sync::Arc<dyn Cryptographer>>> {
) -> Option<polariton_auth::CryptoImpl> {
let handshake = Handshake::new(APP_ID);
// connect
log::debug!("(connect) Handling first packet");
let packet1 = match receive_packet(buf, socket, max_retries, None).await {
let packet1 = match polariton_server::utils::receive_packet_async(socket, &Default::default()).await {
Ok(x) => x,
Err(e) => {
log::error!("Failed to read connect packet: {}", e);
return None;
}
};
buf.clear();
let (handshake, to_send) = match handshake.connect(&packet1) {
Ok(x) => (x.handshake, x.extra),
Err(e) => {
@@ -218,7 +125,7 @@ async fn do_connect_handshake(
return None;
}
};
match send_packet(to_send, buf, socket, None).await {
match polariton_server::utils::send_packet_async(&to_send, socket, &Default::default()).await {
Ok(_) => {},
Err(e) => {
log::error!("Failed to send connect ack packet: {}", e);
@@ -227,24 +134,22 @@ async fn do_connect_handshake(
}
// encrypt
log::debug!("(connect) Handling second packet");
let mut packet2 = match receive_packet(buf, socket, max_retries, None).await {
let mut packet2 = match polariton_server::utils::receive_packet_async(socket, &Default::default()).await {
Ok(x) => x,
Err(e) => {
log::error!("Failed to read (maybe) public key packet: {}", e);
return None;
}
};
buf.clear();
while let Packet::Ping(ping) = packet2 {
handle_ping(ping, buf, socket).await;
packet2 = match receive_packet(buf, socket, max_retries, None).await {
polariton_server::utils::handle_ping_async(ping, socket, &Default::default()).await.unwrap_or_default();
packet2 = match polariton_server::utils::receive_packet_async(socket, &Default::default()).await {
Ok(x) => x,
Err(e) => {
log::error!("Failed to read (maybe) public key packet: {}", e);
return None;
}
};
buf.clear();
}
let (handshake, to_send, crypto) = match handshake.encrypt(&packet2) {
Ok(x) => (x.handshake, x.extra.0, x.extra.1),
@@ -253,7 +158,7 @@ async fn do_connect_handshake(
return None;
}
};
match send_packet(to_send, buf, socket, None).await {
match polariton_server::utils::send_packet_async(&to_send, socket, &Default::default()).await {
Ok(_) => {},
Err(e) => {
log::error!("Failed to send encryption ack packet: {}", e);
@@ -262,28 +167,28 @@ async fn do_connect_handshake(
}
// pre-auth
let handshake = handshake.with_auth(AuthImpl);
let op_ctx = polariton::serdes::SerdesContext::default();
let ctx = polariton::packet::SerdesContext::new(&op_ctx, &crypto);
// authenticate
log::debug!("(connect) Handling third packet");
let mut packet3 = match receive_packet(buf, socket, max_retries, Some(crypto.clone())).await {
let mut packet3 = match polariton_server::utils::receive_packet_async(socket, &ctx).await {
Ok(x) => x,
Err(e) => {
log::error!("Failed to read (maybe) auth packet: {}", e);
return None;
}
};
buf.clear();
while let Packet::Ping(ping) = packet3 {
handle_ping(ping, buf, socket).await;
packet3 = match receive_packet(buf, socket, max_retries, Some(crypto.clone())).await {
polariton_server::utils::handle_ping_async(ping, socket, &Default::default()).await.unwrap_or_default();
packet3 = match polariton_server::utils::receive_packet_async(socket, &ctx).await {
Ok(x) => x,
Err(e) => {
log::error!("Failed to read (maybe) auth packet: {}", e);
return None;
}
};
buf.clear();
}
let to_send = match handshake.authenticate(&packet3, crypto.clone()) {
let to_send = match handshake.authenticate(&packet3, &crypto) {
Ok(x) => x,
Err(h) => match h.extra {
polariton_auth::AuthError::Validation(e) => {
@@ -296,7 +201,7 @@ async fn do_connect_handshake(
},
},
};
match send_packet(to_send, buf, socket, Some(crypto.clone())).await {
match polariton_server::utils::send_packet_async(&to_send, socket, &ctx).await {
Ok(_) => {},
Err(e) => {
log::error!("Failed to send auth ack packet: {}", e);
@@ -305,7 +210,7 @@ async fn do_connect_handshake(
}
// redirect to lobby
let mut packet_j = match receive_packet(buf, socket, max_retries, Some(crypto.clone())).await {
let mut packet_j = match polariton_server::utils::receive_packet_async(socket, &ctx).await {
Ok(x) => x,
Err(e) => {
log::error!("Failed to read (maybe) join packet: {}", e);
@@ -313,8 +218,8 @@ async fn do_connect_handshake(
}
};
while let Packet::Ping(ping) = packet_j {
handle_ping(ping, buf, socket).await;
packet_j = match receive_packet(buf, socket, max_retries, Some(crypto.clone())).await {
polariton_server::utils::handle_ping_async(ping, socket, &Default::default()).await.unwrap_or_default();
packet_j = match polariton_server::utils::receive_packet_async(socket, &ctx).await {
Ok(x) => x,
Err(e) => {
log::error!("Failed to read (maybe) join packet: {}", e);
@@ -339,8 +244,8 @@ async fn do_connect_handshake(
message: Typed::Null,
params: params.into(),
}),
}.encrypt(true)), 0, true, Some(crypto.clone())).unwrap();
match send_packet(resp, buf, socket, Some(crypto.clone())).await {
}.encrypt(true)), 0, true, &ctx).unwrap();
match polariton_server::utils::send_packet_async(&resp, socket, &ctx).await {
Ok(_) => {},
Err(e) => {
log::error!("Failed to send lobby ack packet: {}", e);

View File

@@ -1,17 +1,17 @@
use std::sync::Arc;
const SERDES_SERDES_CTX_REF: &'static polariton::serdes::SerdesContext<(), polariton::serdes::NoCustomSerdes> = &polariton::serdes::SerdesContext::default_const();
pub struct State {
pub crypto: Box<Arc<dyn polariton::packet::Cryptographer>>,
pub crypto: polariton_auth::CryptoImpl,
}
impl State {
pub fn new(c: Box<Arc<dyn polariton::packet::Cryptographer>>) -> Self {
pub fn new(c: polariton_auth::CryptoImpl) -> Self {
Self {
crypto: c,
}
}
pub fn binrw_args(&self) -> polariton::packet::WriteArgs {
Some(self.crypto.clone())
pub fn serdes_ctx(&self) -> polariton::packet::SerdesContext<'_, (), polariton::serdes::NoCustomSerdes> {
polariton::packet::SerdesContext::new(SERDES_SERDES_CTX_REF, &self.crypto)
}
}