Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "freenet"
version = "0.1.38"
version = "0.1.39"
edition = "2021"
rust-version = "1.80"
publish = true
Expand Down
54 changes: 53 additions & 1 deletion crates/core/src/ring/connection_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,25 @@ impl ConnectionManager {
/// Will panic if the node checking for this condition has no location assigned.
pub fn should_accept(&self, location: Location, peer_id: &PeerId) -> bool {
// Don't accept connections from ourselves
// Primary check: compare full PeerId (address-based equality)
if let Some(own_id) = self.get_peer_key() {
if &own_id == peer_id {
tracing::warn!(%peer_id, "should_accept: rejecting self-connection attempt");
tracing::warn!(%peer_id, "should_accept: rejecting self-connection attempt (address match)");
return false;
}
}

// Secondary check: compare pub_key directly
// This catches self-connections even when peer_key is not yet set,
// which can happen early in initialization. Same pub_key means same node.
if *self.pub_key == peer_id.pub_key {
tracing::warn!(
%peer_id,
"should_accept: rejecting self-connection attempt (pub_key match)"
);
return false;
}

tracing::info!("Checking if should accept connection");
let open = self.connection_count();
let reserved_before = self.pending_reservations.read().len();
Expand Down Expand Up @@ -725,4 +737,44 @@ mod tests {
"should_accept must accept connection from different peer"
);
}

#[test]
fn rejects_self_connection_by_pubkey_when_peer_key_not_set() {
// Create a keypair for our node
let keypair = TransportKeypair::new();

// Create connection manager WITHOUT peer_id set (simulating early initialization)
let cm = ConnectionManager::init(
Rate::new_per_second(1_000_000.0),
Rate::new_per_second(1_000_000.0),
1,
10,
7,
(
keypair.public().clone(),
None, // peer_id is None - simulating early initialization
AtomicU64::new(u64::from_le_bytes(0.5f64.to_le_bytes())),
),
false,
10,
Duration::from_secs(60),
);

// Verify the connection manager does NOT have peer_key set
assert_eq!(cm.get_peer_key(), None);

// Create a PeerId with our pub_key but a different address
// This simulates a scenario where we receive a connection request
// that somehow references our own pub_key
let self_like_addr: SocketAddr = "127.0.0.1:9999".parse().unwrap();
let self_like_peer_id = PeerId::new(self_like_addr, keypair.public().clone());

// Attempt to accept - should be rejected because pub_key matches
let location = Location::new(0.5);
let accepted = cm.should_accept(location, &self_like_peer_id);
assert!(
!accepted,
"should_accept must reject self-connection by pub_key even when peer_key is not set"
);
}
}
4 changes: 2 additions & 2 deletions crates/fdev/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "fdev"
version = "0.3.16"
version = "0.3.17"
edition = "2021"
rust-version = "1.80"
publish = true
Expand Down Expand Up @@ -39,7 +39,7 @@ reqwest = { version = "0.12", features = ["json"] }
http = "1.4"

# internal
freenet = { path = "../core", version = "0.1.38" }
freenet = { path = "../core", version = "0.1.39" }
freenet-stdlib = { workspace = true }

[features]
Expand Down
Loading