Commonized networking (#3310)

* Fix not being able to connect to local friends socket

* Start basic work on tunneling protocol and move some code into a common crate

* Commonize message serialization logic

* Serialize Base62Ids as u64 when human-readability is not required

* Move ActiveSockets tuple into struct

* Make CI run when rust-common is updated

CI is currently broken for labrinth, however

* Fix theseus-release.yml to reference itself correctly

* Implement Labrinth side of tunneling

* Implement non-friend part of theseus tunneling

* Implement client-side except for socket loop

* Implement the socket loop

Doesn't work though. Debugging time!

* Fix config.rs

* Fix deadlock in labrinth socket handling

* Update dockerfile

* switch to workspace prepare at root level

* Wait for connection before tunneling in playground

* Move rust-common into labrinth

* Remove rust-common references from Actions

* Revert "Update dockerfile"

This reverts commit 3caad59bb474ce425d0b8928d7cee7ae1a5011bd.

* Fix Docker build

* Rebuild Theseus if common code changes

* Allow multiple connections from the same user

* Fix test building

* Move FriendSocketListening and FriendSocketStoppedListening to non-panicking TODO for now

* Make message_serialization macro take varargs for binary messages

* Improve syntax of message_serialization macro

* Remove the ability to connect to a virtual socket, and disable the ability to listen on one

* Allow the app to compile without running labrinth

* Clippy fix

* Update Rust and Clippy fix again

---------

Co-authored-by: Jai A <jaiagr+gpg@pm.me>
This commit is contained in:
Josiah Glosson
2025-02-28 12:52:47 -06:00
committed by GitHub
parent 90def724c2
commit 650ab71a83
72 changed files with 1132 additions and 584 deletions

View File

@@ -0,0 +1,61 @@
use crate::state::friends::{TunnelSockets, WriteSocket};
use crate::state::FriendsSocket;
use labrinth::common::networking::message::ClientToServerMessage;
use std::net::SocketAddr;
use std::sync::Arc;
use tokio::io::AsyncWriteExt;
use tokio::net::tcp::OwnedWriteHalf;
use tokio::sync::Mutex;
use uuid::Uuid;
pub(super) enum InternalTunnelSocket {
Listening(SocketAddr),
Connected(Mutex<OwnedWriteHalf>),
}
pub struct TunnelSocket {
pub(super) socket_id: Uuid,
pub(super) write: WriteSocket,
pub(super) sockets: TunnelSockets,
pub(super) internal: Arc<InternalTunnelSocket>,
}
impl TunnelSocket {
pub fn socket_id(&self) -> Uuid {
self.socket_id
}
pub async fn shutdown(self) -> crate::Result<()> {
if self.sockets.remove(&self.socket_id).is_some() {
FriendsSocket::send_message(
&self.write,
ClientToServerMessage::SocketClose {
socket: self.socket_id,
},
)
.await?;
if let InternalTunnelSocket::Connected(ref stream) =
*self.internal.clone()
{
stream.lock().await.shutdown().await?
}
}
Ok(())
}
}
impl Drop for TunnelSocket {
fn drop(&mut self) {
if self.sockets.remove(&self.socket_id).is_some() {
let write = self.write.clone();
let socket_id = self.socket_id;
tokio::spawn(async move {
let _ = FriendsSocket::send_message(
&write,
ClientToServerMessage::SocketClose { socket: socket_id },
)
.await;
});
}
}
}