aboutsummaryrefslogtreecommitdiffstats
path: root/examples/put_get.rs
diff options
context:
space:
mode:
authormurilo ijanc2026-03-24 15:04:03 -0300
committermurilo ijanc2026-03-24 15:04:03 -0300
commit9821aabf0b50d2487b07502d3d2cd89e7d62bdbe (patch)
tree53da095ff90cc755bac3d4bf699172b5e8cd07d6 /examples/put_get.rs
downloadtesseras-dht-e908bc01403f4b8ef2a65fa6be43716fd1c6e003.tar.gz
Initial commitv0.1.0
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
Diffstat (limited to 'examples/put_get.rs')
-rw-r--r--examples/put_get.rs93
1 files changed, 93 insertions, 0 deletions
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<Node> = 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<String> = 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());
+ }
+}