diff options
Diffstat (limited to 'src/daemon.rs')
| -rw-r--r-- | src/daemon.rs | 155 |
1 files changed, 152 insertions, 3 deletions
diff --git a/src/daemon.rs b/src/daemon.rs index 4895a48..8952d78 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -36,6 +36,143 @@ const REJOIN_INTERVAL: Duration = Duration::from_secs(60); /// How often to sync DHT-replicated values to local store (5 s). const SYNC_INTERVAL: Duration = Duration::from_secs(5); +const INDEX_PAGE: &str = "\ +tesseras-paste + + Decentralized pastebin built on the tesseras-dht + Kademlia DHT. Pastes are encrypted with XChaCha20- + Poly1305, content-addressed via SHA-256, and + replicated across the network. No accounts, no + databases, no JavaScript. + + \"In the beginning there was the server, + and the server was centralized, + and the centralized was fragile, + and the fragile was doomed.\" + + -- Apocrypha of the Lost Nodes + + +Why + + Pastebin.com sold out and filled with ads. + Ghostbin shut down. Hastebin went offline. + ZeroBin stopped being maintained. + PrivateBin requires a server you must trust. + + Every centralized pastebin is one decision away + from disappearing, censoring, or monetizing your + content. + + We got tired of renting someone else's clipboard. + + tesseras-paste has no single point of failure. + No company can shut it down. No server can be + seized. Your paste lives as long as the network + has nodes. + + +Philosophy + + We believe in: + - Code you can read in an afternoon + - Protocols you can implement in a weekend + - Systems that work without permission + - Networks that survive their creators + + We do not believe in: + - Move fast and break things + - Microservices for a text file + - 400MB Docker images to serve hello world + - npm install the-entire-internet + + +How it works + + 1. You write text (or pipe it from stdin) + 2. tp encrypts it with a random key + 3. SHA-256 hashes the ciphertext into a content + address + 4. The encrypted blob is stored on the K-closest + DHT nodes + 5. The URL contains the only key that decrypts it + 6. The network never sees your plaintext + + +Quick start + + Install from crates.io: + + $ cargo install tesseras-paste + + Start the daemon (connects to the public bootstrap + nodes automatically via DNS SRV): + + $ tpd -d /var/tesseras-paste -w 9999 + + Create a paste: + + $ echo 'hello world' | tp put + 4zxDwJQEte37CQE4xzVCB1GaNodBprLUHjHcWzhTqP7Y#... + + Retrieve it: + + $ tp get 4zxDwJQEte37CQE4xzVCB1GaNodBprLUHjHcWzhTqP7Y#... + hello world + + Public (unencrypted) paste: + + $ echo 'visible to all' | tp put -p + EbpnKntDRBkuDKJuFKY7Ke7jM9ygtLCSYpmykXvzWb8U + + Pin a paste so it never expires: + + $ tp pin <key> + + +Bootstrap nodes + + bootstrap1.tesseras.net port 4433 + bootstrap2.tesseras.net port 4433 + + +Source code + + official https://got.tesseras.net + mirror https://git.tesseras.net + sourcehut https://git.sr.ht/~ijanc/tesseras + github https://github.com/tesseras-net + + +Donate + + Bitcoin bc1qm3srpwnpe3y58mhn7lp37lyw0s45tfdganvat5 + + +Website + + https://tesseras.net + + +Greets + + To my beloved Aninha, for the patience and love. + + To the cypherpunks, for writing code instead + of laws. + + To OpenBSD, for building an OS where security + is not a feature but a principle. + + To everyone running a node: you ARE the network. + + +See also + + tp(1) https://p.tesseras.net/64RQsdrPsmtdYzLQX9SQN3NBkuU1fD1pQMGdYkUXERV5 + tpd(1) https://p.tesseras.net/Ho4jVs1tj4endcZ3ymus3Tm33XGze2tz2K8Qey4EMTRD +"; + /// A request from the socket thread to the main thread. pub struct DaemonRequest { pub cmd: Request, @@ -56,6 +193,15 @@ pub fn run_daemon( let mut last_sync = Instant::now(); let mut last_rejoin = Instant::now(); + // Block + remove paste on disk when a remote + // delete (store TTL=0) arrives from the DHT. + let del_store = store.clone(); + node.set_delete_callback(move |key: &[u8]| { + del_store.block(key); + del_store.remove_paste(key); + log::info!("remote delete: blocked key {}", crate::base58::encode(key)); + }); + log::info!("daemon main loop started"); while !shutdown.load(Ordering::Relaxed) { @@ -189,8 +335,8 @@ fn handle_request( store.paste_count(), m.messages_sent, m.messages_received, - m.lookups_completed, m.lookups_started, + m.lookups_completed, ); Response::Ok(status) } @@ -205,6 +351,9 @@ fn sync_dht_to_store(node: &Node, store: &PasteStore) { if key.len() != 32 { continue; } + if store.is_blocked(&key) { + continue; + } if store.get_paste(&key).is_none() { let _ = store.put_paste(&key, &value); } @@ -473,8 +622,8 @@ fn handle_http( http_response( &mut stream, 200, - "text/plain", - b"Hello Tesseras World\n", + "text/plain; charset=utf-8", + INDEX_PAGE.as_bytes(), ); return; } |