From 9821aabf0b50d2487b07502d3d2cd89e7d62bdbe Mon Sep 17 00:00:00 2001 From: murilo ijanc Date: Tue, 24 Mar 2026 15:04:03 -0300 Subject: Initial commit NAT-aware Kademlia DHT library for peer-to-peer networks. Features: - Distributed key-value storage (iterative FIND_NODE, FIND_VALUE, STORE) - NAT traversal via DTUN hole-punching and proxy relay - Reliable Datagram Protocol (RDP) with 7-state connection machine - Datagram transport with automatic fragmentation/reassembly - Ed25519 packet authentication - 256-bit node IDs (Ed25519 public keys) - Rate limiting, ban list, and eclipse attack mitigation - Persistence and metrics - OpenBSD and Linux support --- examples/put_get.rs | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 examples/put_get.rs (limited to 'examples/put_get.rs') diff --git a/examples/put_get.rs b/examples/put_get.rs new file mode 100644 index 0000000..e2bfaca --- /dev/null +++ b/examples/put_get.rs @@ -0,0 +1,93 @@ +//! DHT put/get example (equivalent to example3.cpp). +//! +//! Creates a small network, stores key-value pairs from +//! one node, and retrieves them from another. +//! +//! Usage: +//! cargo run --example put_get + +use std::time::Duration; +use tesseras_dht::Node; +use tesseras_dht::nat::NatState; + +const NUM_NODES: usize = 5; + +fn main() { + env_logger::Builder::from_env( + env_logger::Env::default().default_filter_or("info"), + ) + .format(|buf, record| { + use std::io::Write; + writeln!( + buf, + "{} [{}] {}", + record.level(), + record.target(), + record.args() + ) + }) + .init(); + + // Create network + let mut nodes: Vec = Vec::new(); + let bootstrap = Node::bind(0).expect("bind"); + let bp = bootstrap.local_addr().unwrap().port(); + nodes.push(bootstrap); + nodes[0].set_nat_state(NatState::Global); + + for _ in 1..NUM_NODES { + let mut n = Node::bind(0).expect("bind"); + n.set_nat_state(NatState::Global); + n.join("127.0.0.1", bp).expect("join"); + nodes.push(n); + } + + // Poll to establish routing + for _ in 0..20 { + for n in nodes.iter_mut() { + n.poll().ok(); + } + std::thread::sleep(Duration::from_millis(50)); + } + + println!("Network ready: {NUM_NODES} nodes"); + + // Node 0 stores several key-value pairs + println!("\n--- Storing values from Node 0 ---"); + for i in 0..5u32 { + let key = format!("key-{i}"); + let val = format!("value-{i}"); + nodes[0].put(key.as_bytes(), val.as_bytes(), 300, false); + println!(" put({key}, {val})"); + } + + // Poll to distribute stores + for _ in 0..20 { + for n in nodes.iter_mut() { + n.poll().ok(); + } + std::thread::sleep(Duration::from_millis(50)); + } + + // Each node retrieves values + println!("\n--- Retrieving values ---"); + for (ni, node) in nodes.iter_mut().enumerate() { + for i in 0..5u32 { + let key = format!("key-{i}"); + let vals = node.get(key.as_bytes()); + let found: Vec = vals + .iter() + .map(|v| String::from_utf8_lossy(v).to_string()) + .collect(); + if !found.is_empty() { + println!(" Node {ni} get({key}) = {:?}", found); + } + } + } + + // Summary + println!("\n--- Storage summary ---"); + for (i, n) in nodes.iter().enumerate() { + println!(" Node {i}: {} values stored", n.storage_count()); + } +} -- cgit v1.2.3