(fix): broken connections
This commit is contained in:
parent
0d5e48ec8f
commit
f15dc46d4a
1 changed files with 58 additions and 15 deletions
|
|
@ -20,6 +20,14 @@ use mtp::webserver::{WebMTPConnection, WebMtpReceiver, WebMtpSender};
|
||||||
pub type MtpSender = WebMtpSender;
|
pub type MtpSender = WebMtpSender;
|
||||||
pub type MtpReceiver = WebMtpReceiver;
|
pub type MtpReceiver = WebMtpReceiver;
|
||||||
|
|
||||||
|
fn data_i64(value: &DataValue) -> Option<i64> {
|
||||||
|
match value {
|
||||||
|
DataValue::SignedNumber(number) => i64::try_from(*number).ok(),
|
||||||
|
DataValue::UnsignedNumber(number) => i64::try_from(*number).ok(),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* How a connection identified itself during the mtp handshake driven by
|
* How a connection identified itself during the mtp handshake driven by
|
||||||
* `server.rs` ("iota" / "client" authenticated logins, "anonymous"
|
* `server.rs` ("iota" / "client" authenticated logins, "anonymous"
|
||||||
|
|
@ -105,27 +113,35 @@ impl GeneralConnection {
|
||||||
async fn migrate(self: &Arc<Self>) -> bool {
|
async fn migrate(self: &Arc<Self>) -> bool {
|
||||||
match self.connection_kind {
|
match self.connection_kind {
|
||||||
ConnectionKind::Client => self.migrate_client().await,
|
ConnectionKind::Client => self.migrate_client().await,
|
||||||
ConnectionKind::Iota => self.migrate_iota().await,
|
ConnectionKind::Iota => {
|
||||||
ConnectionKind::AnonymousClient => self.migrate_anonymous_client().await,
|
self.migrate_iota().await;
|
||||||
ConnectionKind::Phi => self.migrate_phi().await,
|
|
||||||
}
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
ConnectionKind::AnonymousClient => {
|
||||||
|
self.migrate_anonymous_client().await;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
ConnectionKind::Phi => {
|
||||||
|
self.migrate_phi().await;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn migrate_client(self: &Arc<Self>) {
|
async fn migrate_client(self: &Arc<Self>) -> bool {
|
||||||
let id = self.id;
|
let id = self.id;
|
||||||
let user_id = id as i64;
|
let user_id = id as i64;
|
||||||
|
|
||||||
let Ok(handshake) = self.receiver.receive().await else {
|
let Ok(handshake) = self.receiver.receive().await else {
|
||||||
return;
|
return false;
|
||||||
};
|
};
|
||||||
if !handshake.is_type(CommunicationType::ClientConnected) {
|
if !handshake.is_type(CommunicationType::ClientConnected) {
|
||||||
let error = CommunicationValue::new(CommunicationType::ErrorInvalidData)
|
let error = CommunicationValue::new(CommunicationType::ErrorInvalidData)
|
||||||
.with_id(handshake.get_id());
|
.with_id(handshake.get_id());
|
||||||
let _ = self.sender.send(&error).await;
|
let _ = self.sender.send(&error).await;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
let Some(session_id) = handshake.get_data(DataType::SessionId).as_signed_number() else {
|
let Some(session_id) = data_i64(handshake.get_data(DataType::SessionId)) else {
|
||||||
let _ = self
|
let _ = self
|
||||||
.sender
|
.sender
|
||||||
.send(
|
.send(
|
||||||
|
|
@ -133,9 +149,9 @@ impl GeneralConnection {
|
||||||
.with_id(handshake.get_id()),
|
.with_id(handshake.get_id()),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
return;
|
return false;
|
||||||
};
|
};
|
||||||
if !(1..=i64::MAX as i128).contains(&session_id) {
|
if session_id <= 0 {
|
||||||
let _ = self
|
let _ = self
|
||||||
.sender
|
.sender
|
||||||
.send(
|
.send(
|
||||||
|
|
@ -143,11 +159,9 @@ impl GeneralConnection {
|
||||||
.with_id(handshake.get_id()),
|
.with_id(handshake.get_id()),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
let version = handshake
|
let version = data_i64(handshake.get_data(DataType::VersionNumber));
|
||||||
.get_data(DataType::VersionNumber)
|
|
||||||
.as_signed_number();
|
|
||||||
if !matches!(version, Some(version) if version >= 0) {
|
if !matches!(version, Some(version) if version >= 0) {
|
||||||
let _ = self
|
let _ = self
|
||||||
.sender
|
.sender
|
||||||
|
|
@ -156,9 +170,10 @@ impl GeneralConnection {
|
||||||
.with_id(handshake.get_id()),
|
.with_id(handshake.get_id()),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
*self.session_id.write().await = session_id as u64;
|
*self.session_id.write().await = session_id as u64;
|
||||||
|
let request_id = handshake.get_id();
|
||||||
|
|
||||||
let client = ClientConnection::from_general(self.clone(), id).await;
|
let client = ClientConnection::from_general(self.clone(), id).await;
|
||||||
let rho = self.find_user_rho(user_id).await;
|
let rho = self.find_user_rho(user_id).await;
|
||||||
|
|
@ -176,6 +191,16 @@ impl GeneralConnection {
|
||||||
let response = self.add_call_state(response, user_id).await;
|
let response = self.add_call_state(response, user_id).await;
|
||||||
log_cv_out!(response);
|
log_cv_out!(response);
|
||||||
let _ = self.sender.send(&response).await;
|
let _ = self.sender.send(&response).await;
|
||||||
|
} else {
|
||||||
|
let error =
|
||||||
|
CommunicationValue::new(CommunicationType::ErrorNoIota).with_id(request_id);
|
||||||
|
log_err!(
|
||||||
|
user_id,
|
||||||
|
PrintType::Client,
|
||||||
|
"Initial state request failed for user {}",
|
||||||
|
id
|
||||||
|
);
|
||||||
|
let _ = self.sender.send(&error).await;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log_err!(
|
log_err!(
|
||||||
|
|
@ -184,9 +209,12 @@ impl GeneralConnection {
|
||||||
"No RhoConnection found for user {}, client not attached to iota",
|
"No RhoConnection found for user {}, client not attached to iota",
|
||||||
id
|
id
|
||||||
);
|
);
|
||||||
|
let error = CommunicationValue::new(CommunicationType::ErrorNoIota).with_id(request_id);
|
||||||
|
let _ = self.sender.send(&error).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
client.start();
|
client.start();
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn notify_user_connected(&self, user_id: i64, iota_id: i64) {
|
async fn notify_user_connected(&self, user_id: i64, iota_id: i64) {
|
||||||
|
|
@ -251,6 +279,8 @@ impl GeneralConnection {
|
||||||
) -> Option<CommunicationValue> {
|
) -> Option<CommunicationValue> {
|
||||||
let session_id = *self.session_id.read().await as i64;
|
let session_id = *self.session_id.read().await as i64;
|
||||||
let request = CommunicationValue::new(CommunicationType::ClientConnected)
|
let request = CommunicationValue::new(CommunicationType::ClientConnected)
|
||||||
|
.with_id(handshake.get_id())
|
||||||
|
.with_sender(user_id as u64)
|
||||||
.add_typed_default(DataType::UserId, DataValue::SignedNumber(user_id.into()))
|
.add_typed_default(DataType::UserId, DataValue::SignedNumber(user_id.into()))
|
||||||
.add_typed_default(
|
.add_typed_default(
|
||||||
DataType::SessionId,
|
DataType::SessionId,
|
||||||
|
|
@ -361,3 +391,16 @@ impl GeneralConnection {
|
||||||
app_conn.start();
|
app_conn.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::data_i64;
|
||||||
|
use mtp::codec::DataValue;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn data_i64_accepts_signed_and_unsigned_values() {
|
||||||
|
assert_eq!(data_i64(&DataValue::SignedNumber(42)), Some(42));
|
||||||
|
assert_eq!(data_i64(&DataValue::UnsignedNumber(42)), Some(42));
|
||||||
|
assert_eq!(data_i64(&DataValue::UnsignedNumber(u128::MAX)), None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue