#+INCLUDE: ../org-templates/level-1.org
#+title: peer-to-peer networks that worked
#+subtitle: core challenges, routing, and privacy.
#+author: Dr. Arne Babenhauserheide
#+date: <2025-01-24 Fr>
#+COLUMNS: %45ITEM %10BEAMER_env(Env) %10BEAMER_act(Act) %4BEAMER_col(Col) %8BEAMER_opt(Opt)
#+PROPERTY: BEAMER_col_ALL 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 0.0 :ETC
#+STARTUP: beamer
#+STARTUP: hidestars
#+SEQ_TODO: TODO ☯ Σ | ☺
#+LANGUAGE: en
#+latex: \iffalse
This 90 minutes talk describes how peer-to-peer networks managed to
interactively search 4 million computers with the bandwidth of 2004,
which goals they failed to reach, and what information the networks
expose as part of their operation.
#+begin_export html
<div class="sourcebox" markdown="1" style="max-width: 100%; text-align: center">
<a href="p2p-talk.pdf"><img width="378" height="283" title="PDF" src="p2p-talk-thumb.png" /></a><br />
<a href="p2p-talk.pdf">PDF</a>
</div>
<div style="clear: both"></div>
#+end_export
It starts with the core challenges all fully distributed systems face
and then describes how four peer to peer systems solved them: Gnutella
(for efficient keyword search), Kademlia (for efficient hash search),
BitTorrent (for its simplification), and Freenet/Hyphanet (for privacy
and small world routing).
I gave it as guest talk for a resilient networking lecture at KIT. The
[[https://www.draketo.de/software/p2p-talk.pdf][slides]] are created from the same [[https://hg.sr.ht/~arnebab/draketo/browse/software/p2p-talk.org][source]] as this article.
#+latex: \fi
* Intro
** intro
*** peer-to-peer: where decentralization works/worked
****
#+latex: \centering
/From Gnutella and Kademlia/ \\
/Over BitTorrent/ \\
/To Freenet/Hyphanet/
****
#+latex: \LARGE \centering \(\ddot \smile\)
****
#+begin_quote
Those who don’t learn from the tech of the past are doomed to repeat
its mistakes — with less time and brain share, since “the problems
are already solved”.
#+end_quote
*** DO NOT OBEY IN ADVANCE
- You are the ones who build the rules of the future.
- You are the last line of defense against horrors.
- If you do not build it, it will not be built (well enough to work).
- Whatever you are told: *you are not replaceable*.
/Do not obey in advance./
https://media.ccc.de/v/38c3-opening-ceremony#t=1343
/You knew whom you invited./
** Why?
*** Understand p2p-networks that worked in real life
#+begin_quote
after a few days (and especially nights) of nervous full-site
tinkering, it turned a 40 minute deploy process into one that lasted
just 12 seconds![fn:15]
#+end_quote
- Bittorrent-Deployment: https://vimeo.com/11280885
/Understand why deployment improved but did not match expectations./
Spoiler: Cut-through routing.
*** Me
- Since 2004 in p2p-Development
- Since 2013 with competence
- Since 2017 Release-Manager of the Freenet/Hyphanet project
- Until 2017 PhD and PostDoc in physics
- Since 2017 Software Developer as job
** Topics
*** Topics today
- Core challenges
- Gnutella (the first widespread, fully distributed p2p network)
- Kademlia (the most widespread DHT)
- BitTorrent
- Freenet/Hyphanet
*** p2p?
- *peer-to-peer (p2p)* :: peers (equal partners) cooperate to grant a service to each other.
**** *Why?*
Your programs popularity exceeded your wildest dreams. 50 million people want to download it. Size 100 GiB. How much do you pay?
/Relax: the game of the year in almost every award 2023/2024 launched with less than one million players./
**** *2025* quick checks: 5 million TB
:PROPERTIES:
:BEAMER_act: <2->
:END:
- AWS CloudFront: $100 million ([[https://aws.amazon.com/cloudfront/pricing/][$0.02/GB]])
- Hetzner: 6 million € ([[https://docs.hetzner.com/de/robot/general/traffic/][1.19€/TB]]) in 137 years (2000 dl/day)
- Gnutella worked with a handful of servers for 50 million users
# https://www.cloudflare.com/learning/cloud/what-is-aws-data-transfer-pricing/
# https://docs.hetzner.com/de/robot/general/traffic/
# https://news.ycombinator.com/item?id=29953834 $5400 for 70TB?
* Core challenges
** challenges
*** Topics
The core challenges p2p systems have to solve or circumvent.
*** Core problems in p2p networks
**** :B_columns:
:PROPERTIES:
:BEAMER_env: columns
:END:
***** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.454
:END:
- *Entry*: How to find the right place?\\
#+attr_latex: :width 0.3\linewidth
file:p2p-grundprobleme-schwarz-einstieg.png
- *Search*: Where do I find what I need?\\
#+attr_latex: :width 0.3\linewidth
file:p2p-grundprobleme-schwarz-suche.png
***** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.454
:END:
- *Distribution*: How to avoid bottlenecks?\\
#+attr_latex: :width 0.25\linewidth
file:p2p-grundprobleme-schwarz-verteilung.png
- *Communication*: How can information flow?\\
#+attr_latex: :width 0.4\linewidth
file:p2p-grundprobleme-schwarz-kommunikation.png
**** :B_ignoreheading:
:PROPERTIES:
:BEAMER_env: ignoreheading
:END:
- /*Resistance against disruption*: How can desired scale better than unwanted?/
** Core requirements
*** Entry: How to find the right place?
- *First addresses*: How to find addresses of other nodes?
- *Choose connections*: With whom should I connect?
- *Routing-Information*: Which data do nodes need?
#+attr_latex: :width 2cm
file:p2p-grundprobleme-schwarz-einstieg.png
*** Structured vs. unstructured
**** *Unstructured*
- *First addresses*: A Simple list
- *Choose connections*: Choose at will
- *Routing-Information*: Exchange explicitly
**** *Structured*
- *First addresses*: Needs topology[fn:25]
- *Choose connections*: Only some are useful
- *Routing-Information*: By choosing peers
**** /Can I reach all directly?/
*** Search: What to look for?
- *Keyword*: Gnutella, Skype (before MS)
- *Content-Hash*: Kademlia, BitTorrent VHT, Freenet/Hyphanet
- *Public Key*: Freenet/Hyphanet
#+latex: \vspace*{-0.5cm}\hfill
#+attr_latex: :width 1.5cm
file:p2p-grundprobleme-schwarz-suche.png
- *BitTorrent VHT* :: Distributed Hash Table, a DHT
- *DHT* :: Distributed Hash Table
- *Public Key* :: The mirror of the private key in asymmetric cryptography
*** Search: Where do I find what I need?
Two concepts:
- Search Paths to existing data: Gnutella
- Put the data in the right place: Kademlia, BitTorrent VHT, Freenet/Hyphanet
*** Distribution: How to avoid bottlenecks?
- Centralized: Streaming by the ISP via multicast
- Swarming: users take part in the distribution
- Coordinated by a central place: BitTorrent (Tracker)
- Coordinated by other users: Gnutella (Download-Mesh)
- Independently distributed chunks: Freenet/Hyphanet[fn:9]
#+latex: \vspace*{-0.75cm}\hfill
#+attr_latex: :width 1cm
file:p2p-grundprobleme-schwarz-verteilung.png
#+latex: \vspace*{-0.25cm}
- *Download-Mesh*: :: name of the protocol
- *Tracker*: :: A server coordinating a BitTorrent-Swarm
*** Communication: How can information flow?
- One-to-one (PM/DM/msg/Anruf/…)
- Group discussion (Chat, Forum, Video call, …)
- Public discourse
- Learn about new content
- Metadata about content (comments, rating, …)
#+attr_latex: :width 2cm
file:p2p-grundprobleme-schwarz-kommunikation.png
*** Resistance against disruption
**** *Disruption*
Anything that reduces the quality of the service for users
**** *Required on every level*
- *Entry*: connecting to attackers
- *Search*: spam, misinformation
- *Distribution*: poison files
- *Communication*: spam, harassment and censorship[fn:10]
**
*** Summary
**** :B_columns:
:PROPERTIES:
:BEAMER_env: columns
:END:
***** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.454
:END:
- *Entry*: First addresses and routing info\\
#+attr_latex: :width 0.3\linewidth
file:p2p-grundprobleme-schwarz-einstieg.png
- *Search*: Keyword, Content, Public Key\\
#+attr_latex: :width 0.3\linewidth
file:p2p-grundprobleme-schwarz-suche.png
***** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.454
:END:
- *Distribution*: Tracker, Download-Mesh, Cached fragments\\
#+attr_latex: :width 0.25\linewidth
file:p2p-grundprobleme-schwarz-verteilung.png
- *Communication*: One-to-one, Forum, News, Comments\\
#+attr_latex: :width 0.4\linewidth
file:p2p-grundprobleme-schwarz-kommunikation.png
**** :B_ignoreheading:
:PROPERTIES:
:BEAMER_env: ignoreheading
:END:
- /*Disruption*: connect to attackers, spam results, misinformation,
poison files, harassment./
* Gnutella
** Gnutella
*** Gnutella
#+latex: \vspace{0.1cm}
#+begin_quote
On March 14th, 2000, … an early version … with a note: “Justin and Tom
work for Nullsoft, makers of Winamp and Shoutcast. See? AOL can bring
you good things!” …\\
AOL ordered him to take the program down immediately … calling
Gnutella an “unauthorized freelance project.” … hackers had gone … to
reverse-engineer it … into the hands of the open-source community …\\
— [[https://archive.ph/20120630204949/http://74.220.215.94/~davidkus/index.php?option=com_content&view=article&id=82:the-worlds-most-dangerous-geek-&catid=35:articles&Itemid=54][The World's Most Dangerous Geek; Interviewed by David Kushner;
RollingStone.com; January 13, 2004.]]
#+end_quote
The simple TCP based protocol improved. By 2008 about 50 million
people used it every day. It mostly disappeared after the main
development companies lost in court. The tech is almost forgotten.
*** Topics
- *Users perspective*: this was Gnutella
- *Entry*: GWebCaches
- *Search*: Slow-Start + Keyword-Multicast
- *Distribution*: Download-Mesh
- *Communication*: See new files and brows the collection
- *Resistance against disruption*: Heuristics or rating matrices
*** Users perspective
- 50 million nodes
- Search by filename and ID3 tags
- Filter to see only creative commons licensed contentnp
- Search by newest files
- Download from many sources without central coordination
- Audio streaming around 2004 (“preview”)
- /LimeWire, Bearshare, Shareaza, Phex, gtk-gnutella, …/
*** How it looked
#+attr_latex: :width 0.6\linewidth
[[file:Limewire-screen-wikimedia-GPL.png]]
/von Wikipedia: [[https://upload.wikimedia.org/wikipedia/commons/1/1b/LimeWire_screen.png][LimeWire_screen.png]]/
** Entry
*** Entry: addresses
- List of the recently connected good nodes
- UDP Host-Caches: Tiny servers that collected IP-lists and provided
the most recent ones
- Example: GhostWhiteCrab[fn:12]
#+latex: \vspace*{-0.5cm}\hfill
#+attr_latex: :width 2cm :center nil
file:p2p-grundprobleme-schwarz-einstieg.png
*** Entry: Connecting
HTTP-Handshake with feature negotiation, then binary over TCP socket +
out of band answers via UDP.
** Search and distribution
*** Search process
**** :B_columns:
:PROPERTIES:
:BEAMER_env: columns
:END:
***** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.6
:END:
#+begin_src dot :file gnutella-suche.png :exports results
digraph {
rankdir=LR
UP1 [xlabel="3-5"]
UP2 [xlabel="<128"]
UP3 [xlabel="<4.096"]
UP4 [xlabel="<131.072"]
Leaf2 [xlabel="<128"]
Leaf3 [xlabel="<4.096"]
Leaf4 [xlabel="<131.072"]
Leaf5 [xlabel="<4.194.304"]
Leaf -> UP1 [label="3-5 x slow-start"]
Leaf -> UP2 [style=invis,weight=0]
Leaf -> UP3 [style=invis,weight=0]
Leaf -> UP4 [style=invis,weight=0]
UP1 -> UP2 [label="32 x slow-start",constraint=false]
UP2 -> UP3 [label="32 x flooding",constraint=false]
UP3 -> UP4 [label="32 x Intra-UP Keyword-Multicast",constraint=false]
UP4 -> Leaf5 [label="32 x Keyword-Multicast"]
UP1 -> Leaf2 [label="32 x Keyword-Multicast"]
UP2 -> Leaf3 [label="32 x Keyword-Multicast"]
UP3 -> Leaf4 [label="32 x Keyword-Multicast"]
}
#+end_src
#+RESULTS:
[[file:gnutella-suche.png]]
**** :B_ignoreheading:
:PROPERTIES:
:BEAMER_env: ignoreheading
:END:
Not existing file: 4 x 32 x 32 = 4.096 nodes
Load (empirical): <1kiB/s Leaf, <14kiB/s Ultrapeer
- *Ultrapeer (UP)* :: A communication hub (32 peers)
- *Leaf* :: An edge node, searches via Ultrapeers
- *Knoten* :: A Peer or Ultrapeer.
#+latex: \vspace*{-1.5cm}\hfill
#+attr_latex: :width 1.5cm :center nil
file:p2p-grundprobleme-schwarz-suche.png
# TODO: LimeWire-Entwickler fragen, wie gut Intra-UP-QRP funktionierte.
*** Distribution in Gnutella: Out-of-Band
Originally sent back via the search path, but:
- 5 Steps
- Average life time of a node:[fn:11] 2h
- => Half the connections broke after 24 minutes
Solution: Download-Mesh, independent of the search.
Disadvantage: All IPs always visible.
#+latex: \vspace*{-0.5cm}\hfill
#+attr_latex: :width 1.5cm :center nil
file:p2p-grundprobleme-schwarz-verteilung.png
*** Distribution: Download-Mesh
#+latex: \scriptsize
- Standard HTTP Range-Requests
- Content-Addressed: HOST/uri-res/raw/urn:sha1:HASH[fn:13]
- 5 additional Headers:[fn:14]
- *X-Alt* :: Checked source for the file, IP/Port
- *X-NAlt* :: Unreachable source or node with corrupted data. IP/Port
- *X-Gnutella-Content-URN* :: Merkle-Tree Root-Hash
- *X-Thex-URI* :: /uri-res/N2X?urn:sha1:HASH;MERKLE_TREE_ROOT
- *X-Available-Ranges* :: bytes 0-10,20-30 (example)
** Limitations and summary
*** Communication: Weakness
- Chat never worked well
- No lasting contact to others
- Working:
- “What’s new?” (via LimeWire: See new files)
- Search collection (see all shared files)
#+latex: \hfill
#+attr_latex: :width 2cm :center nil
file:p2p-grundprobleme-schwarz-kommunikation.png
*** Resistance against disruption: Heuristics as Spam-Filter
Similar to E-Mail spam filters, partially user-configurable.
/Reduced Spam to 10-20% of the results./[fn:39]
*** Resistance against disruption: object trust via Credence
- Every correctly named/good file: 1.0
- Every falsely named/bad file: -1.0
- Ratings of others multiplied with the correlation of files both rated.
With proof that spammers would have to rate enough files correctly to
spread false ratings that multiple spamming parties would cancel each
other out.
→ http://credence-p2p.org
/Never added to a mainstream program; LimeWire already in court./
** Privacy and Summary
*** Privacy
- IP visible in searches and downloads (originally not; direct downloads as optimization)
- Ultrapeers know their leafs
- Downloader of a file knows all other downloaders (but not how much all have)
*** Remaining weaknesses 2010
- 10-20% Spam-Results despite 50 million users
- Credence was never widespread
- One step flooding: Windows (home)limited the connection count
- Required parameter-adaption during growth
- No comments, Peer-Chat never worked well
- Bad support for Asian fonts
*** Summary Gnutella
- Efficient Search for keywords
- TCP-based binary protocol, 50 mio users, 1kiB/s Leaf, 14kiB/s Ultrapeer
- Entry: WebCache-Server + Exchange QRT (like Bloom-Filters)[fn:20]
- Search: Slow-Start + QRT Routing
- Distribution: Download-Mesh (mini-network per download)
- Resistance against disruption: Heuristics or object trust
* Kademlia
** Kademlia
*** Kademlia
/Lookup in a distributed Hash-Table (DHT) with xor-metric./
- Users’ perspective
- Search
- Entry /(uses search)/
*** Users’ perspective
**** *Tools*
- Filesharing: :: Kad in aMule, VHT in Torrent clients
/Amazon Dynamo uses Chord, that works very similar./
**** *Usage*
- Searches for exact files or exact keyword
- Resolves Magnet-links
- Choose the server to write to; eventual consistency
** Search
*** Search in Kademlia
- Every node has a random ID
- Search by Hash → Distributed Hash Table
- Distance between Hash und ID via *xor-Metric*[fn:31]
- Step by step in O(log(N)) to the nearest node
/Simlar: Chord, Pastry./
#+latex: \vspace*{-1.5cm}\hfill
#+attr_latex: :width 1.5cm :center nil
file:p2p-grundprobleme-schwarz-suche.png
*** Prefix-Buckets
**** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.4
:END:
#+begin_src dot :file kademlia-peers.png :exports results
digraph {
ABC
subgraph cluster_b {
label=Axx
subgraph cluster_a {
label=ABx
ABC -> ABa
ABC -> ABf
}
ABC -> Aca
ABC -> Aa2
}
ABC -> be5
ABC -> 543
// fix ranks
edge [style=invis]
ABC -> Aca
ABC -> Aa2
ABa -> Aca
ABa -> Aa2
Aa2 -> be5
Aa2 -> 543
}
#+end_src
#+RESULTS:
[[file:kademlia-peers.png]]
*** Search for b91
#+begin_src dot :file kademlia-peers-full.png :exports results
digraph {
ABC [style=bold]
be5 [color=red,style=bold]
subgraph cluster_b {
label=Axx
subgraph cluster_a {
label=ABx
ABC -> ABa
ABC -> ABf
}
ABC -> Aca
ABC -> Aa2
}
ABC -> be5
ABC -> 543
BE5 [color=red,style=bold]
B9f [color=blue,style=bold]
subgraph cluster_d {
label=Bxx
subgraph cluster_c {
label=BEx
BE5 -> BE3
BE5 -> BEa
}
BE5 -> Bf0
BE5 -> B9f
}
BE5 -> abc
BE5 -> 123
B9F [color=blue,style=bold]
B91 [color=green,style=bold]
subgraph cluster_f {
label=Bxx
subgraph cluster_e {
label=B9x
B9F -> B9b
B9F -> B91
}
B9F -> Bb0
B9F -> Baf
}
B9F -> 001
B9F -> ffd
be5 -> BE5 [constraint=false]
B9f -> B9F [constraint=false]
// fix ranks
edge [style=invis]
ABC -> Aca
ABC -> Aa2
ABa -> Aca
ABa -> Aa2
Aa2 -> be5
Aa2 -> 543
B91 -> Bb0
B91 -> Baf
Baf -> 001
Baf -> ffd
BE3 -> Bf0
BE3 -> B9f
Bf0 -> abc
Bf0 -> 123
}
#+end_src
#+RESULTS:
[[file:kademlia-peers-full.png]]
*** Store
- Search for node nearest to the hash.
- STORE: Hash + Value.
/Think =put(key, value)= ⇒ “Distributed Hash Table”./
** Entry
*** Entry in Kademlia
- Needs contact to at least one existing node.
- Search your own ID: =FIND_NODE=\\
(near = responsible for ID)
- Response contains addresses and IDs\\
of nodes touched
- Contacted nodes also keep your address and ID.
#+latex: \vspace*{-2cm}\hfill
#+attr_latex: :width 2cm :center nil
file:p2p-grundprobleme-schwarz-einstieg.png
** Privacy and Sumary
*** Privacy
- IPs of downloaders and uploaders known to responsible nodes
- Hashes of searches & searcher IP known to nodes on the path
- All addresses must be reachable globally
*** Summary
- Distance: key-hash XOR node-ID
- Search: ask closest known node for better nodes
- knows more close nodes than remote nodes
- Store works like searching: store where a search would land
- Entry:
- Search for own ID
- Touched nodes use address and ID
* BitTorrent Downloads
** BitTorrent
*** BitTorrent
- Most widespread solution for swarming
- BitTorrent, IPFS, Blizzard-Updater
- Upload to get faster Downloads
- Coordinated by centralized Tracker: avoids complexity
- No decentralized search
*** Users’ perspective
- Information from Tracker-sites
- Download with torrent-file or Magnet-Link
- Supports folders
- Today: ipfs: Websites via BitTorrent
- Supports NAT-Traversal
- Can hide the IP via Tor (as SOCKS5 proxy)
** Distribution
*** Concept of BitTorrent
**** Structure :B_block:BMCOL:
:PROPERTIES:
:BEAMER_env: block
:BEAMER_col: 0.3
:END:
#+begin_src dot :file bittorrent-struktur.png :exports results
graph {
{rank=same; client5 Tracker}
Tracker [shape=diamond]
{rank=same; Tracker client4}
client1 -- Tracker
client2 -- Tracker
client3 -- Tracker
client5 -- Tracker [constraint=false]
Tracker -- client4 [constraint=false]
Tracker -- client6
Tracker -- client7
Tracker -- client8
}
#+end_src
#+RESULTS:
[[file:bittorrent-struktur.png]]
**** Tracker: Website :B_block:BMCOL:
:PROPERTIES:
:BEAMER_col: 0.7
:BEAMER_env: block
:END:
- Coordinates Swarms
- Search, Forum, Rating, Validation, Community
- Statistics: Seeder, Leecher
- Does not provide Data
- Aggregates how much nodes upload\\
→ Incentive
#+latex: \hfill
#+attr_latex: :width 1.5cm :center nil
file:p2p-grundprobleme-schwarz-suche.png
#+attr_latex: :width 2cm :center nil
file:p2p-grundprobleme-schwarz-kommunikation.png
#+attr_latex: :width 2cm :center nil
file:p2p-grundprobleme-schwarz-einstieg.png
*** Torrent-File
- Tracker URL(-s)
- Hashes for Chunks
- Names of the File(-s)
- Can contain folders[fn:18]
#+latex: \vspace*{-0.5cm}\hfill
#+attr_latex: :width 1.5cm :center nil
file:p2p-grundprobleme-schwarz-verteilung.png
*** Incentive to Upload
- Fraction Upload/Download is checked
- Freeloaders[fn:32] are throttled by other clients (choked: lower download rate)
- Published research gave strong focus on the incentive, in practical use the forums make more of a difference
- Tracker with login: private groups
** Extended usage
*** Related
- VHT in addition/instead of Tracker possible (Kademlia)
- Free and Open Protocol with many implementations
- Development within the Community
- IPFS uses Torrents as decentralized cache for Websites
*** Torrent for Twitter-Deployment
- Cost at Twitter: Transport over many steps
- Torrent transmits in fragments.
**** :B_columns:
:PROPERTIES:
:BEAMER_env: columns
:END:
***** Wish :B_block:BMCOL:
:PROPERTIES:
:BEAMER_act: <1->
:BEAMER_col: 0.3
:BEAMER_env: block
:END:
#+begin_src dot :file twitter-torrent-mesh.png :exports results
digraph {
A -> B
A -> C
B -> D
B -> E
C -> F
}
#+end_src
#+RESULTS:
[[file:twitter-torrent-mesh.png]]
***** Reality :B_block:BMCOL:
:PROPERTIES:
:BEAMER_act: <2->
:BEAMER_col: 0.3
:BEAMER_env: block
:END:
#+begin_src dot :file twitter-torrent-ring.png :exports results
digraph {
{rank=same; A B C}
{rank=same; D E F}
A -> B
B -> C
C -> D
E -> D [dir=back]
F -> E [dir=back]
}
#+end_src
#+RESULTS:
[[file:twitter-torrent-ring.png]]
/cat … ssh tee …/
/Cut-through / streaming./
** Privacy and summary
*** Privacy
- Tracker knows
- who downloads
- how much they have
- how much they upload
- Users know what the tracker tells them
- No search, except by Hash: private trackers stay private
- IP hiding via Tor is possible but blocked by most trackers
*** Summary
- Tracker and Clients
- Tracker: statistics and coordination
- Torrent-File with Piece-Info
* Freenet/Hyphanet
** Hyphanet
*** Freenet/Hyphanet
/Censorship-resistant, privacy respecting communication on friend-to-friend network/
/Decentralized database with pubkey-access./
**** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.5
:END:
- Users’ perspective
- Entry
- Small-World
- Search
**** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.5
:END:
- Distribution
- Communication
- Usage
- Privacy
*** Users’ perspective
- Web-interface: decentralized websites
- Plugins with E-Mail and Microblogging
- External programs like Chat and forums with Freenet/Hyphanet as database using HTTP-like API (FCP)
** Entry
*** Entry in Freenet/Hyphanet
- Opennet:
- Similar to Kademlia: choose known Seednode[fn:33], Seednode searches ID → node references
- Difference to Kademlia: Not just IP: referenz with keys
- Friend-to-Friend:
- Fixed connections
- Knoten swap their IDs, to reconstruct\\
the social Small-World-Network\\
⇒ minimize Overlay-costs.
#+latex: \vspace*{-2cm}\hfill
#+attr_latex: :width 2cm :center nil
file:p2p-grundprobleme-schwarz-einstieg.png
*** Small-World-Network (scale free network)
- Many short and few long connections.
- 6 deegrees of separation via snail mail: Our acquaintances formm a small-world network
- Kleinberg-Network: Probability to be connected: \(\frac{1}{d^x}\), d = distance, x = dimension.
- Freenet/Hyphanet: \(x=1\)
** Search
*** Freenet/Hyphanet Search
- Like Kademlia, but forwarded hop by hop → no global reachability or visibility
- Can search by public key
- Keyspace: [0.0 : 0.1)
#+BEGIN_SRC dot :file freenet-keyspace.png :cmd circo :exports results
digraph {
0.1 [color=red]
0.1 -> 0.5 [color=red]
0.5 -> 0.6 [color=red]
0.6 -> 0.4 [color=red]
0.7 [color=blue]
0.7 -> 0.3 [color=blue]
0.3 -> 0.2 [color=blue]
edge [style=invis]
0.0 -> 0.1
0.1 -> 0.2
0.2 -> 0.3
0.3 -> 0.4
0.4 -> 0.5
0.5 -> 0.6
0.6 -> 0.7
0.7 -> 0.8
0.8 -> 0.9
0.9 -> 0.0
}
#+END_SRC
#+attr_latex: :width 0.3\textwidth
#+RESULTS:
[[file:freenet-keyspace.png]]
#+latex: \vspace*{-1.5cm}\hfill
#+attr_latex: :width 1.5cm :center nil
file:p2p-grundprobleme-schwarz-suche.png
*** Types of Keys
- CHK: Content Hash
- KSK: Keyword Subspace: Password
- SSK: Signed Subspace: Public Key
- USK: Updatable Subspace: SSK with version
Format: =XXK@routing,encryption/tarball-name/path/to/file.ext=
Can omit path and name (smaller → optimization).
** Distribution
*** Distribution in Freenet/Hyphanet
- Network saves content → distributed Cache
- Files saved encrypted, as 32 kiB fragments with 100% redundancy
- Manifest contains keys of the fragments as CHKs
- Limited lifetime: Effectively LRU-Cache:[fn:34]
- Saving overwrites randomly chosen fragments
- Access restores overwritten fragments
- Upload to exsting key+path: collision\\
→ Effectively immutable
#+latex: \vspace*{-1.5cm}\hfill
#+attr_latex: :width 1.5cm :center nil
file:p2p-grundprobleme-schwarz-verteilung.png
** Usage
*** Freenet/Hyphanet as Database
- Search by Public Key + Path
- → personal keyspace
- → tarballs for structured data (i.e. website)
- → pub-sub-protocols on decentralized database
- → Websites, Forums, Chat, …
/Optimization: Subscribe to keys to be able to watch 10k keys and see updates quickly./
*** Getting low latency
- Up to 1kiB, raw, realtime mode: <20s; 30s -- 90s RTT
- Larger files, in manifest (folder): ~5 min
/Must do it exactly right or it will be slow. Like [[https://dev.to/shadowfaxrodeo/why-your-website-should-be-under-14kb-in-size-398n][14kB websites]]./
**** :B_columns:
:PROPERTIES:
:BEAMER_env: columns
:BEAMER_opt: t
:END:
***** *Realtime* (small, interactive) :B_block:BMCOL:
:PROPERTIES:
:BEAMER_col: 0.5
:BEAMER_env: block
:END:
#+begin_src scheme
PriorityClass . 2 ;; high
MaxRetries . 0 ;; default: 10
RealTimeFlag . true
DontCompress . true
ExtraInsertsSingleBlock . 0
ExtraInsertsSplitfileHeaderBlock . 0
#+end_src
***** *Bulk* (large, slower) :B_block:BMCOL:
:PROPERTIES:
:BEAMER_col: 0.5
:BEAMER_env: block
:END:
#+begin_src scheme
PriorityClass . 3 ;; medium
RealTimeFlag . false
DontCompress . false
#+end_src
*** Spam-protection
/WoT (Web of Trust): One of two possibilities in actual use. The other is FMS (Freenet/Hyphanet Message System)./
- ID = USK
- Trust -100 to 100
- Rank: Distance → capacity
- Rank 1 40 % to 1 %
- rank 1: 100 trust = +40 points score.
- Score: Sum of all ratings: trust * rank
- Can scale to arbitrary size at 22 messages per day and person[fn:21]
*** Communication via Freenet/Hyphanet
- Entry: Seed-keys + Captcha[fn:35]-Queue: KSK-Prefix
- Search: User-specific pages with links, update-infos
- Distribution: Gossip[fn:36] keys, just upload files
- Resistance against disruption: Web of Trust with visibility increasing by interaction
/Autospawn node => Freenet/Hyphanet transparently as backend./
#+latex: \vspace*{-1.3cm}\hfill
#+attr_latex: :width 2cm :center nil
file:p2p-grundprobleme-schwarz-kommunikation.png
*** Stats
**** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.05
:END:
**** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.45
:END:
#+latex: \vspace{-1.5cm}
#+attr_latex: :height 0.37\paperheight
[[./freenet-fetchpull-get.png]]
#+attr_latex: :height 0.37\paperheight
[[./freenet-fetchpull-put.png]]
**** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.5
:END:
#+latex: \vspace{-1.5cm}
#+attr_latex: :height 0.37\paperheight
[[./freenet-weekly-uptime.png]]
#+attr_latex: :height 0.37\paperheight
[[./freenet-peer-count.png]]
** Privacy and Summary
*** Privacy
- Seednodes can enumerate all opennet nodes.
- With pure Friend-to-Friend mode, ISPs may recognize a high volume of
encrypted UDP packets.
- Directly connected peers can see that a search was *started by or
forwarded by* a node (HTL with randomized decrement).
- With friend-to-friend mode, only trusted nodes can be directly
connected. Needs key exchange with friends.
- Nodes can see whether chunks for which they are the best location
are accessed but not by whom or how often.
- IDs in communication are stable pseudonyms: rotated session keys —
ratchet — only in custom implementations.
*** Summary
- Entry: Search at a seednode for my ID
- Search: Greedy Hash search on Small World Network
- Distribution: Chunk-Tree with Redundancy
- Communication:
- Entry: Seed-keys + CAPTCHA-Queue
- Search: Index-Pages, Subscribe for Updates
- Distribution: Upload files, websites
- Propagating Trust with slowly rising visibility
* Closing
** Aside
*** Aside
- Guarantees
- Magnet-Links
- WebRTC
- Lessons learned
*** Guarantees
/They scale by giving few guarantees. From strong to weak:/
- Tampering: All networks here prevent tampering with a file being downloaded.
- Access control: You need the keys to files to gain access: hashes or public keys.
- Availability: None of the p2p networks here guarantee it:
- Data may not exist
- Connections may break
- Names may be wrong
/To give availability guarantees, take CRDTs or similar as starting point for proofs./
*** Magnet-Links
#+begin_example
magnet:?xt=urn:bitprint:TIGER_TREE.SHA1
&xt=urn:btih:BITTORRENT_INFO_HASH
&xt=urn:sha1:HASH
&xl=LENGTH
&dn=NAME
&as=LINK_WITHOUT_HASH
&xs=LINK_WITH_HASH
&kt=SEARCH_STRING
#+end_example
/Netzwerk-unabhängig, Link zu HTTP und p2p-Quellen, weitverbreitet/
*** WebRTC
- Runs in the Browser (Javascript)
- Provides Audio, Video, …, and *Peer-Socket*
- First connection moderated by server -- avoids many problems
- p2p-Systems, that don’t need installation
- Example: WebTorrent https://webtorrent.io/
** Lessons Learned
*** Thoughts
# TODO: Wie heißt Optimierung für Netzbetreiber bei BitTorrent
- All Upload Queues are always full. Like all disks are always full.
Ask the Large Scale Data Facility at KIT/SCC.
- Optimization for ISPs often thought about: Prefer clients in same
(sub-)net. Gnutella: „p4p“. Pastry (Windows) uses it according to Ghosh.
- Example for non-greedy routing[fn:37]: Random Walk in ants (programm). Did not gain traction.
- Throwing money on problems: MaidSafe had 2000$ hardware cost per
month. Shut that down 2019.[fn:22] Freenet/Hyphanet has <20$ cost
per month.
*** Fallacies of distributed Systems, extended version
**** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.5
:END:
1. The network is reliable
2. The network is secure
3. The network is homogeneous
4. Topology does not change
5. Latency is zero
6. Bandwidth is infinite
7. Transport cost is zero
8. There is one administrator
**** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.5
:END:
1. Hard disks don’t fail\\
Files stay intact
2. Power is stable
3. IPs are reachable
4. Constant factors are negligible
5. APIs stay compatible
6. Textfiles are simple
** Legacy
*** Current developments
/What’s happening today:/
- Spritely Golem: p2p distributable content for the fediverse[fn:16]
- Decentralized Internet and Privacy at FOSDEM[fn:17]
- DAT, GNUnet, Fediverse, Tor, …
- In Karlsuhe: 23. Gulaschprogrammiernacht: https://entropia.de/GPN23/en 19. bis 22. Juni 2025
** Summary
*** Summary: Core challenges
**** :B_columns:
:PROPERTIES:
:BEAMER_env: columns
:END:
***** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.454
:END:
- *Entry*: First addresses and routing info\\
#+attr_latex: :width 0.3\linewidth
file:p2p-grundprobleme-schwarz-einstieg.png
- *Search*: Keyword, Content, Public Key\\
#+attr_latex: :width 0.3\linewidth
file:p2p-grundprobleme-schwarz-suche.png
***** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.454
:END:
- *Distribution*: Tracker, Download-Mesh, Cached fragments\\
#+attr_latex: :width 0.25\linewidth
file:p2p-grundprobleme-schwarz-verteilung.png
- *Communication*: One-to-one, Forum, News, Comments\\
#+attr_latex: :width 0.4\linewidth
file:p2p-grundprobleme-schwarz-kommunikation.png
**** :B_ignoreheading:
:PROPERTIES:
:BEAMER_env: ignoreheading
:END:
- /*Disruption*: connect to attackers, spam results, misinformation,
poison files, harassment./
*** Summary: Implementations
#+latex: \small
#+attr_latex: :center nil
| | Einstieg | Suche |
|------------------+----------------------+--------------------------------|
| Gnutella | WebCache | Slow-Start + Keyword-Multicast |
| Kademlia | Search own ID | xor-Hash-hierarchy |
| BitTorrent | Tracker-URL | Kademlia / Tracker / Web |
| Freenet/Hyphanet | Seed-Nodes search ID | Greedy on Small World |
| WebRTC | WebRTC Server | - |
#+attr_latex: :center nil
| | Verteilung | Störung |
|------------------+------------------------------+--------------------|
| Gnutella | Alt+NAlt, Range, Merkle-Tree | Heuristik/Credence |
| Kademlia | /various/ | - |
| BitTorrent | Torrent | Rating on Tracker |
| Freenet/Hyphanet | Chunk-Tree with Redundancy | Propagating Trust |
| WebRTC | - | - |
*** Good luck! @@latex:\hspace{3.25cm} \(\ddot \smile\)@@
#+latex: \centering
# #+latex: \(\ddot \smile\)
My wish is that 5 years from now\\
some of you look back and say:
#+latex: \vspace{0.5cm}
#+begin_quote
@@latex:\centering@@
“What I learned in the p2p lecture@@latex:\phantom{”}@@\\
@@latex:\phantom{„}@@was one of the pillars of my success.”
#+end_quote
# #+latex: \vspace{0.5cm}
# #+latex: \centering \(\ddot \smile\)
* Appendix :B_ignoreheading:
:PROPERTIES:
:BEAMER_env: ignoreheading
:BEAMER_opt: allowframebreaks
:END:
\appendix
**
*** Verweise
:PROPERTIES:
:BEAMER_opt: allowframebreaks,label=
:END:
\bibliographystyle{apalike}
\bibliography{ref}
**** Bilder :B_ignoreheading:
:PROPERTIES:
:BEAMER_env: ignoreheading
:END:
#+latex: \tiny Bilder: \citet{}
**** Merkle Tree Patent 1982
https://worldwide.espacenet.com/patent/search/family/022107098/publication/US4309569A?q=pn%3DUS4309569
Eingereicht 1979 als Methode Diffie-Authentication günstiger zu machen.
[fn:6] Static NAT, Dynamic NAT und Port-Mapping NAT erklärt: https://www.geeksforgeeks.org/computer-network-types-network-address-translation-nat/
* German Backup Slides
** Weiteres
*** Weitere Knoten finden: X-Try
Beim Handshake (wie HTTP):
#+latex: \scriptsize
#+begin_example
When rejecting a connection, a servent MUST, if possible, provide the
remote host with a list of other Gnutella hosts, so it can try
connecting to them. This SHOULD be done using the X-Try header.
An X-Try header can look like:
X-Try:1.2.3.4:1234,3.4.5.6:3456
#+end_example
*** Weitere Knoten finden: Pong
#+latex: \scriptsize
#+begin_example
Pong messages contains information about a Gnutella host. The
message has the following fields
Bytes: Description:
0-1 Port number. The port number on which the responding
host can accept incoming connections.
2-5 IP Address. The IP address of the responding host.
Note: This field is in big-endian format.
…
* When a Ping message is received (TTL>1 and it was at least one
second since another Ping was received on that connection), a
servent MUST, if possible, respond with a number of Pong
Messages. These pongs MUST have the same message ID as the
incoming ping, and a TTL no lower than the hops value of the
ping.
#+end_example
→ http://rfc-gnutella.sourceforge.net/src/rfc-0_6-draft.html
*** Größe der Query Routing Tabellen in Gnutella
- Hashes: Normalisierte Suchwörter in der Suchanfrage oder im Dateinamen
- Größe: Variabel, Default in LimeWire 128kiB, interpolation auf größere und kleinere Tabellen möglich.
- Aktuell verfügbare Quelle: [[https://github.com/metapirate/LimeWire-Pirate-Edition/blob/master/components/gnutella-core/src/main/java/com/limegroup/gnutella/routing/BitSetQRTTableStorage.java#L87][BitSetQRTTableStorage.java]]
- Hash-Funktion pro Suchwort: [[https://github.com/metapirate/LimeWire-Pirate-Edition/blob/master/components/gnutella-core/src/main/java/com/limegroup/gnutella/routing/HashFunction.java][HashFunction.java]]
*** Suche 4: Dateien nach Hash finden
- Zugriff auf Magnet-Links[fn:27] brauchte exakte Dateisuche.[fn:23]
- Angepasstes Kademlia ⇒ im Abschnitt zu Kademlia.
*** Gnutella Routing Experiment
- Peers: Tisch + davor + dahinter
- Letzte 2 Hops
- Suche nach Namen
- Hash = 1. Buchstabe
- QRT[fn:28]: Hash der Namen der Peers
- Intra-UP QRT: QRTs der Peers, zusammengefasst
/Was müsst ihr vorher austauschen?/
*** Warum p2p?
- *Skalierbarkeit* :: Ein einzelner Server bricht bei etwa 100k Anfragen pro Sekunde ein. /dwd bei Sturm Sabine 2020?/
- *Mit Nutzung wachsen* :: Ähnliche Infrastruktur für 1000 Leute oder 10 Millionen Leute
- *Infrastrukturkosten* :: 100k€ pro Jahr = Entwickler oder Entwicklerin
# TODO: Benchmark wrk
*** Warum nicht p2p?
- Gestiegende Leistung von Servern. /Sturm: dwd[fn:19] hielt größtenteils Stand (durch vereinfachte Seite[fn:30])/
- Handies sind durch Batterie und Netz begrenzt → keine kontinuierliche Leistung. (Nachts möglich?)
- Viele der einfachen Lösungen unmöglich, z.B. Geld auf Probleme werfen.
****
*** Schlüssel zum Licht
#+attr_latex: :width 0.5\textwidth
[[file:schluessel-zum-licht.png]]
*** Störquellen
**** Sammeln am Flipchart
**** Quellen
:PROPERTIES:
:BEAMER_act: <2->
:END:
- *Parasiten*: Bessere Leistung auf Kosten Anderer (leecher).
- *Trolle*: Kein Finanzinteresse, minimale Resourcen, nutzen jegliche Lücke.
- *Spammer*: Erfolg durch Verbreitung eigener Inhalte.[fn:8]
- *Konkurrenten*: Erfolg durch verringerte Qualität des Systems.
- *Angreifer*: Erfolg durch Schädigung von Nutzern.
*** Weitere Eigenschaft: Grad der Verteilung
/Serverkoordinierte Teilgruppen bis vollständig dezentrale Interaktion./
*** Suche 1: Slow-Start
„Dynamic Querying“ (DQ)
- Leaf fragt einen UP nach dem anderen. Stoppt nach „genug“ Ergebnissen (um die 100).
- UP fragt Leafs und andere UPs. Stoppt nach „genug“ Ergebnissen.
*** Suche 2: Keyword-Multicast
Query Routing Protocol (QRP)
- Suchwörter normalisiert:[fn:38] lowercase, keine Akzente, …
- Query Routing Table (QRT): Set mit schwachen Hashes von normalisierten Suchwörtern
- Automatisch hochskaliert für gewünschten Füllgrad
Intra-Ultrapeer-QRP:
- Vereinigung der Tabellen
/Ähnlich: Bloom-Filter/
*** Suche abschicken
#+begin_example
<15 bytes GUID>0x00
0x80 ; message type: Query
0x07 ; TTL: 7
0x00 ; Hops 0
0x00,0x00,0x09 ; payload length, max: 4kiB
0x00,0x00 ; min speed
test foo ; payload: search criteria
0x00 ; null-terminator, begins extensions
#+end_example
- *GUID* :: Globally Unique ID. Zufällig erstellt, um Schleifen zu vermeiden.
*** Mutability: O(1) Zugriff auf neuste Version
- Nutzende: =SSK@…/meine-seite-1/...= → =SSK@…/meine-seite-2/activelink.png=
- Optimiert: =USK@…/meine/seite/1=
- =SSK@[key]/[sitename]-DATEHINT-[year]=
#+BEGIN_EXAMPLE
HINT
46
2013-7-5
#+END_EXAMPLE
/DATEHINT-[year], DATEHINT-[year]-WEEK-[week], DATEHINT-[year]-[month], DATEHINT-[year]-[month]-[day]/
*** Capacity
#+BEGIN_SRC dot :file freenet-wot-rank.png :exports results
digraph {
rankdir=LR
"0:100%" -> "1: 40%"
"1: 40%" -> "2: 16%"
"2: 16%" -> "3: 6%"
"3: 6%"-> "4: 2%"
"4: 2%" -> "1%"
}
#+END_SRC
#+RESULTS:
[[file:freenet-wot-rank.png]]
- Rank 1 40 %. rank 1: 100 trust, 40 Punkte als Score.
- Rank 2 16 %
- Rank 3 6 %
- Rank 4 2 %
- Rank 5 und niedriger: 1 %
/Integer-Mathematik: =2 * 6 / 100 = 0=./
*** Theoretische und gemessene Link-Längen
[[./freenet-link-length.png]]
*** Swapping: Friend-to-Friend wird Small World
**** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.5
:END:
#+latex: \LARGE
| *9* | 4 | *3* |
| 5 | 2 | 8 |
| 1 | 6 | 7 |
------
| 6 | *4* | 9 |
| 5 | 2 | 8 |
| 1 | 3 | *7* |
**** :BMCOL:
:PROPERTIES:
:BEAMER_col: 0.5
:END:
#+latex: \LARGE
| *3* | 4 | 9 |
| 5 | 2 | 8 |
| 1 | *6* | 7 |
------
| 6 | 7 | 9 |
| 5 | 2 | 8 |
| 1 | 3 | 4 |
*** Mein Ziel
Ich will, dass Sie die Fähigkeiten erwerben, unter denen zu sein, die
die Deployment Zeit um Größenordnungen verringern, ohne dabei die
Kosten dafür zu zahlen, Torrents als Blackbox zu sehen.
- *Torrent* :: Bezeichnung für eine BitTorrent-Datei oder eine von BitTorrent verwaltete Datei.
- *BitTorrent* :: Ein p2p-System zum Verteilen großer Datenmengen; Verwaltung läuft auf zentralisierten Trackern
*** Projektideen
- Download-Mesh implementieren
- Nur Range-Requests + magnet für Quellen
- Quellen-Gossip via XAlt[fn:29]
- Mit Merkle-Tree oder hashliste für chunks und mit XNalt
- Suche über WebRTC in Javascript
- flooding über vereinfachtes Binärprotokoll
- QRP / QRT
- Sharing als Upload in local storage
- GGEP: Generic Gnutella Extension Protocol; Binarprotokoll für beliebige Daten.
* Footnotes
[fn:40] ⇒ shared state, global; in Realität stattdessen: Hash.
[fn:39] Could this be used in a webshop? Who needs which guarantees?
[fn:38] ungelöst: Japanische oder Chinesische Zeichen.
[fn:30] ⇒ gibt es eine einfachere Lösung?
[fn:37] Greedy-Routing: forward requests with local information to the best node.
[fn:36] Gossip: attach information to normal communication to distribute it.
[fn:35] CAPTCHA: Usually images with letters that are part of a watched key.
[fn:34] LRU: Least Recently Used. Delete oldest first.
[fn:33] Seednode: known node that arranges connections to others.
[fn:32] Freeloader: People who don’t upload. Also: „Leech“. Inverse: „Seed“.
[fn:31] xor-Metric: 4 xor 2 ⇒ 100 xor 010 ⇒ 110 ⇒ 6.
[fn:29] XAlt/XNalt: Header, der gute / kaputte Quellen beschreibt.
[fn:28] QRT: Query Routing Table.
[fn:27] Magnet-Links liefern Infos für Downloads in leicht kopierbarem Link.
[fn:26] Tauschbörse: Ein Dienst, in dem Nutzerinnen und Nutzer Inhalte anbieten und von anderen Nutzern herunterladen.
[fn:25] Topology: structure of the network.
[fn:19] dwd: Deutscher Wetterdienst.
[fn:24] History of LimeWire: https://melmagazine.com/en-us/story/an-oral-history-of-limewire-the-little-app-that-changed-the-music-industry-forever
[fn:23] kt=…: Suchanfrage, wurde kaum genutzt. Weiteres: https://en.wikipedia.org/wiki/Magnet_URI_scheme#Design
[fn:22] Source: \tiny https://www.reddit.com/r/safenetwork/comments/erpvee/dumb_question_is_safe_live/
[fn:20] Set of weak hashes of the search words, number of keys scaled and interpolated dynamically
[fn:21] \tiny https://www.draketo.de/english/freenet/deterministic-load-decentralized-spam-filter
[fn:18] \tiny http://www.bittorrent.org/beps/bep_0003.html
[fn:7] \tiny Teile der Spezifikation: http://rfc-gnutella.sourceforge.net/rfc-gnutella.zip und https://web.archive.org/web/20070429042042/http://www.the-gdf.org/index.php?title=Main_Page
[fn:17] \tiny https://fosdem.org/ — viele Vorträge zu decentralization, privacy, …
[fn:16] \tiny https://gitlab.com/spritely/golem/blob/master/README.org
[fn:15] \tiny https://web.archive.org/web/20120807165933/http://engineering.twitter.com/2010/07/murder-fast-datacenter-code-deploys.html
[fn:14] \tiny http://rfc-gnutella.sourceforge.net/src/Partial_File_Sharing_Protocol_1.0.txt
[fn:13] \tiny https://www.ietf.org/rfc/rfc2169.txt und http://www.nuke24.net/docs/2015/HashURNs.html
[fn:2] Wenn der Name im package steht, ist es nicht anonym :-)
[fn:3] Das war mit der Benennung nicht gemeint, aber hiermit haben Sie bereits die Grundlagen für Übungen zu Anwendungen
[fn:1] Beispiel nach RFC 2210 und 2211.
[fn:4] \tiny https://www.akamai.com/de/de/about/our-thinking/state-of-the-internet-report/state-of-the-internet-ipv6-adoption-visualization.jsp
[fn:5] IANA: Internet Assigned Numbers Authority
[fn:8] Werbung ist Spam durch die genutzte Plattform.
[fn:9] Reduces Swarming to downloading many single files but requires caching: saving transported files temporarily.
[fn:10] “The Internet treats censorship as a malfunction and routes around it.” -- John Perry Barlow
[fn:11] 2h lifetime are surprisingly persistent.
[fn:12] gwc resource: https://github.com/gtk-gnutella/gwc
# #+toc: headlines 2
#+setupfile: ../org-templates/level-1-software.org
#+LaTeX_CLASS: beamer
#+LaTeX_CLASS_OPTIONS: [presentation]
#+beamer_header: \setbeameroption{show notes}
# #+beamer_header: \setbeameroption{hide notes}
# #+beamer_header: \setbeameroption{show only notes}
#+beamer_header: \setbeamertemplate{navigation symbols}{}
# add appendix
#+LaTeX_HEADER:\newcounter{framenumberwithoutappendix}
#+latex_header: \usetheme{Berlin}\usecolortheme{dove}
#+latex_header: \newcommand{\carlo}[1]{\color{blue!65!black}{#1}}
#+latex_header: \newcommand{\arne}[1]{\color{red!50!black}{#1}}
#+LaTeX: \definecolor{bg}{rgb}{0.98,0.98,0.98}
#+latex_header: \usepackage{hyperref}
#+LATEX_HEADER: \usepackage{xcolor}
#+LATEX_HEADER: \usepackage[ngerman]{babel}
#+LATEX_HEADER: \usepackage{tikz}
#+LATEX_HEADER: \setlength{\parindent}{0cm}
#+LATEX_HEADER: \setlength{\parskip}{0.5em}
# unicode input
#+LATEX_HEADER: \usepackage{uniinput}
#+LATEX_HEADER: \DeclareUnicodeCharacter{B7}{\ensuremath{\cdot}}
#+LATEX_HEADER: \usepackage{natbib}
#+LATEX_HEADER: \usepackage{morefloats}
#+LATEX_HEADER: \hypersetup{
#+LATEX_HEADER: colorlinks,
#+LATEX_HEADER: linkcolor={red!50!black},
#+LATEX_HEADER: citecolor={blue!30!black},
#+LATEX_HEADER: urlcolor={blue!50!black}
#+LATEX_HEADER: }
#+LATEX_HEADER: \usepackage{lmodern}
#+LATEX_HEADER: \usepackage[protrusion=true,expansion=true]{microtype}
#+LATEX_HEADER: \usepackage{pdfpages}
#+LATEX_HEADER: % make PDF reproducible as by https://tex.stackexchange.com/questions/229605/reproducible-latex-builds-compile-to-a-file-which-always-hashes-to-the-same-va/313605#313605
#+LATEX_HEADER: % For pdfTex:
#+LATEX_HEADER: \pdfinfoomitdate=1
#+LATEX_HEADER: \pdftrailerid{}
#+LATEX_HEADER: \pdfinfo{ /Producer () /Creator () }
# Local Variables:
# org-confirm-babel-evaluate: nil
# org-export-default-language: de
# org-babel-noweb-wrap-start: "{{{"
# org-babel-noweb-wrap-end: "}}}"
# org-latex-images-centered: nil
# End:
# override template options:
#+options: toc:nil H:3 num:nil ^:nil
#+MACRO: if-latex-else (eval (if (org-export-derived-backend-p org-export-current-backend 'latex) "" "#+OPTIONS: tags:nil"))
{{{if-latex-else}}}