feat: firewalled peer connections via server-brokered connect
Implement the FIREWALLED connection mode: when a direct outbound connection to a peer fails (peer unreachable), fall back to asking the server to broker it. - Add MessageFactory::build_connect_to_peer (server code 18). - A pre-established outbound failure now emits ClientOperation::PeerConnectFailed instead of a normal disconnect; the client registers a correlation token and sends ConnectToPeer so the peer connects back. - The listener accepts the peer's PierceFirewall (peer code 0) connect-back, matches the pending token, registers it as the P control connection, and fires PeerConnected to flush the queued download. Fix a latent aliasing bug this surfaced: a peer actor could emit two terminal notifications (a connect-failure, then a disconnect when later replaced and stopped), and the second removed the *newer* actor registered under the same username, killing the brokered connection mid-transfer. An actor now reports a terminal outcome at most once (disconnect_reported guard). Verified end to end against soulfind: the mock advertises an unlistened port so the direct connect is refused, the server brokers the connection, the mock pierces back, and the file transfers — bytes match. A companion test (soulfind_brokers_connect_to_peer_between_users) pins the server behaviour the mode relies on.
This commit is contained in:
@@ -80,6 +80,22 @@ impl MessageFactory {
|
||||
Message::new().write_int32(23).write_int32(id).clone()
|
||||
}
|
||||
|
||||
/// Ask the server (code 18) to broker a connection to a firewalled peer:
|
||||
/// the server tells that peer to connect back to us, quoting `token`.
|
||||
#[must_use]
|
||||
pub fn build_connect_to_peer(
|
||||
token: u32,
|
||||
username: &str,
|
||||
connection_type: ConnectionType,
|
||||
) -> Message {
|
||||
Message::new()
|
||||
.write_int32(18)
|
||||
.write_int32(token)
|
||||
.write_string(username)
|
||||
.write_string(&connection_type.to_string())
|
||||
.clone()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn build_set_status_message(status_code: u32) -> Message {
|
||||
Message::new()
|
||||
|
||||
Reference in New Issue
Block a user