feat: direct peer connections — download() connects to unconnected peers
Implement the DIRECT connection-initiation mode so a download can target a peer the client is not already connected to: - Fix the outbound peer handshake. on_connection_established sent build_watch_user() (a server WatchUser message, wrongly framed with get_data()) for outbound connections; it now sends a proper length-prefixed PeerInit (peer code 1) with our own username. own_username is plumbed in via PeerRegistry -> PeerActor; inbound peers (outbound=false) are unchanged. - download() now auto-connects: if there is no control connection to the peer it sends GetPeerAddress and defers the QueueUpload until the outbound stream handshakes, signalled by a new ClientOperation::PeerConnected. A never- connected client still resolves the download to Failed (unit test). - Add Client::connect_peer(username) to open/pre-warm a control connection. Verified end to end against soulfind: a_file_downloads_from_a_peer_via_direct_connection logs a mock peer into the server, advertises its port via SetWaitPort, and the client resolves the address, dials it, and downloads the file — bytes match. The F-serve leg is shared with the passive-download mock.
This commit is contained in:
@@ -142,7 +142,6 @@ impl MessageFactory {
|
||||
.clone()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[must_use]
|
||||
pub fn build_peer_init_message(
|
||||
own_username: &str,
|
||||
@@ -184,6 +183,22 @@ fn test_build_login_message() {
|
||||
assert_eq!(expect, message.get_data());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_peer_init_message() {
|
||||
use crate::peer::ConnectionType;
|
||||
let message =
|
||||
MessageFactory::build_peer_init_message("bob", ConnectionType::P, 7);
|
||||
// [1][len=3]"bob"[len=1]"P"[token=7] — no length prefix in get_data()
|
||||
let expect: Vec<u8> = [
|
||||
1, // PeerInit code (int8)
|
||||
3, 0, 0, 0, 98, 111, 98, // username "bob"
|
||||
1, 0, 0, 0, 80, // connection type "P"
|
||||
7, 0, 0, 0, // token
|
||||
]
|
||||
.to_vec();
|
||||
assert_eq!(expect, message.get_data());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_message_user() {
|
||||
let message = MessageFactory::build_message_user("bob", "hi");
|
||||
|
||||
Reference in New Issue
Block a user