diff options
| author | murilo ijanc | 2026-03-24 15:04:03 -0300 |
|---|---|---|
| committer | murilo ijanc | 2026-03-24 15:04:03 -0300 |
| commit | 9821aabf0b50d2487b07502d3d2cd89e7d62bdbe (patch) | |
| tree | 53da095ff90cc755bac3d4bf699172b5e8cd07d6 /examples/dgram.rs | |
| download | tesseras-dht-9821aabf0b50d2487b07502d3d2cd89e7d62bdbe.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/dgram.rs')
| -rw-r--r-- | examples/dgram.rs | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/examples/dgram.rs b/examples/dgram.rs new file mode 100644 index 0000000..ab25e78 --- /dev/null +++ b/examples/dgram.rs @@ -0,0 +1,100 @@ +//! Datagram transport example (equivalent to example4.cpp). +//! +//! Creates two nodes and sends datagrams between them +//! using the dgram callback API. +//! +//! Usage: +//! cargo run --example dgram + +use std::sync::{Arc, Mutex}; +use std::time::Duration; +use tesseras_dht::Node; +use tesseras_dht::id::NodeId; +use tesseras_dht::nat::NatState; + +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(); + + let mut node1 = Node::bind(0).expect("bind node1"); + node1.set_nat_state(NatState::Global); + let addr1 = node1.local_addr().unwrap(); + let id1 = *node1.id(); + + let mut node2 = Node::bind(0).expect("bind node2"); + node2.set_nat_state(NatState::Global); + let addr2 = node2.local_addr().unwrap(); + let id2 = *node2.id(); + + println!("Node 1: {} @ {addr1}", node1.id_hex()); + println!("Node 2: {} @ {addr2}", node2.id_hex()); + + // Join node2 to node1 + node2.join("127.0.0.1", addr1.port()).expect("join"); + + // Poll to establish routing + for _ in 0..10 { + node1.poll().ok(); + node2.poll().ok(); + std::thread::sleep(Duration::from_millis(50)); + } + + // Set up dgram callbacks + let received1: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(Vec::new())); + let received2: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(Vec::new())); + + let r1 = received1.clone(); + node1.set_dgram_callback(move |data: &[u8], from: &NodeId| { + let msg = String::from_utf8_lossy(data).to_string(); + println!("Node 1 received: '{msg}' from {from:?}"); + r1.lock().unwrap().push(msg); + }); + + let r2 = received2.clone(); + node2.set_dgram_callback(move |data: &[u8], from: &NodeId| { + let msg = String::from_utf8_lossy(data).to_string(); + println!("Node 2 received: '{msg}' from {from:?}"); + r2.lock().unwrap().push(msg); + }); + + // Send datagrams + println!("\n--- Sending datagrams ---"); + node1.send_dgram(b"hello from node1", &id2); + node2.send_dgram(b"hello from node2", &id1); + + // Poll to deliver + for _ in 0..10 { + node1.poll().ok(); + node2.poll().ok(); + std::thread::sleep(Duration::from_millis(50)); + } + + // Note: actual dgram delivery requires the full + // send queue → address resolution → send flow. + // This example demonstrates the API; full delivery + // is wired in integration. + + println!("\n--- Summary ---"); + println!( + "Node 1 received {} messages", + received1.lock().unwrap().len() + ); + println!( + "Node 2 received {} messages", + received2.lock().unwrap().len() + ); + println!("Node 1 send queue pending: queued for delivery"); + println!("Node 2 send queue pending: queued for delivery"); +} |