From 9d2e6e64fa73205c352586ec8793c34ec265ba5c Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 26 Jun 2015 14:58:48 +0100 Subject: [PATCH 01/37] add initial DHT spec with some questions --- protocol/routing/README.md | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 protocol/routing/README.md diff --git a/protocol/routing/README.md b/protocol/routing/README.md new file mode 100644 index 000000000..b3f0b4f1c --- /dev/null +++ b/protocol/routing/README.md @@ -0,0 +1,80 @@ +IPFS Routing Protocol Spec +========================== + +Authors: David Dias + +Reviewers: + +TODOS: + +----------------------- + +> This spec defines the routing protocol spec, covering `Peer discovery`, `Routing` and the `DHT`. The spec is a **Work In Progress**. + +## Supports + +- Peer discovery through + - mdns + - custom peers list + - random walking on the network +- Routing primitives + - Publish and fetch content (also providing) +- Maintaining partial state of the network + - DHT + - kbucket + +### Overview + +The Routing Protocol is divided in three major components, these are: +- Peer Discovery: Responsible for filling our kbucket with best candidates. +- Interface: Our routing primitives that are offered for the user, such as finding and publishing content, including the storage and lookup of metadata (Providers). +- Peer-to-peer Structured Overlay Network: Algorithm for the implicit network organization, based on [Coral](http://iptps03.cs.berkeley.edu/final-papers/coral.pdf) and [mainlineDHT](http://www.bittorrent.org/beps/bep_0005.html) + +Bootstrapping the routing happens by connecting to a predefined "railing" peers list, shipped with the go-ipfs release and/or by discovery through mDNS. Once at least one peer is found and added to the kbucket, the routing changes to an active state and our peer becomes able to route and receive messages. + +### Peer Discovery + +#### bootstrap peer list + +List with known and trusted peers shipped with IPFS. + +- _How is this list updated?_ +- _Is this list updated periodically_? + +#### random walk + +IPFS issues random Peer lookups periodically to refresh our kbucket if needed. For impl reference, see: https://github.com/ipfs/go-ipfs/blob/master/routing/dht/dht_bootstrap.go#L88-L109. + +#### mDNS + +In addition to known peers and random lookups, IPFS also performs Peer Discovery through mDNS ([MultiCast DNS](https://tools.ietf.org/html/rfc6762)) + +-_How offen do we issue this searches?_ + +### Routing + +For impl reference, check: https://github.com/ipfs/go-ipfs/blob/master/routing/routing.go#L19-L49 + +#### Find a peer + +_When searching for a peer, do we fetch the kbucket from a peer and see which peer we want to ping next or do we ask for a given Id to a peer and that peer replies to us with the best candidate (or itself if it is the case)?_ + +#### Ping + +#### Provide + +#### Get value + +#### Put value + +1. find peer +2. transfer +3. provide + +### DHT + +explain: +- dht/coral, how the algo works +- kbucket +- each time a contact is made with a new peer, we check to see if it is a better candidate for our kbucket +- xor metric From 1feb2cf7ccab75e6042d3c57a9ba741f46c82029 Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 26 Jun 2015 14:59:00 +0100 Subject: [PATCH 02/37] add initial DHT spec with some questions --- protocol/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/README.md b/protocol/README.md index 9559a2f14..17eea286d 100644 --- a/protocol/README.md +++ b/protocol/README.md @@ -122,7 +122,7 @@ of implementations. For example: to one of a set of supernodes. This is roughly like federated routing. - **dns:** ipfs routing could even happen over dns. -See more in the routing spec (TODO). +See more in the [routing spec](https://github.com/ipfs/specs/tree/master/protocol/routing). ### Block Exchange -- transfering content-addressed data From 213573677832a7083d56ad1b5137464bb8c6ba08 Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 26 Jun 2015 15:07:55 +0100 Subject: [PATCH 03/37] add ping --- protocol/routing/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/protocol/routing/README.md b/protocol/routing/README.md index b3f0b4f1c..076859902 100644 --- a/protocol/routing/README.md +++ b/protocol/routing/README.md @@ -61,6 +61,10 @@ _When searching for a peer, do we fetch the kbucket from a peer and see which pe #### Ping +Ping mechanism (for heartbeats). Ping a peer and log the time it took to answer. + +_what if the Id doesn't exist? Is there any rule for non existing peers? Should we log time for best matches as well?_ + #### Provide #### Get value From 751c906bf8e1feafabf673f7f218e2307be3ea61 Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 26 Jun 2015 15:15:28 +0100 Subject: [PATCH 04/37] provinding segment --- protocol/routing/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/protocol/routing/README.md b/protocol/routing/README.md index 076859902..80cb3192a 100644 --- a/protocol/routing/README.md +++ b/protocol/routing/README.md @@ -67,6 +67,15 @@ _what if the Id doesn't exist? Is there any rule for non existing peers? Should #### Provide +Providing is the process of storing/updating the metadata (pointers) of where the blocks of a given file are stored/available in the IPFS network. What this means is that the DHT is not used for block discovery, but for the metadata which identifies where they are, instead. +When a node advertises a block available for download, IPFS stores a record in the DHT with its own Peer.ID. This is termed "providing". the node becomes a "provider". Requesters who wish to retrieve the content, query the DHT (or DSHT) and need only to retrieve a subset of providers, not all of them. (this works better with huge DHTs, and latency-aware DHTs like coral). + +We provide once per block, because every block (even sub-blocks) are independently addressable by their hash. (yes, this is expensive, but we can mitigate the cost with better DHT + record designs, bloom filters, and more) + +There is an optimistic optimization -- which is that if a node is storing a node that is the parent (root/ancestor) of other nodes, then it is much more likely to also be storing the children. So when a requester attempts to pull down a large dag, it first queries the DHT for providers of the root. Once the requester finds some and connects directly to retrieve the blocks, bitswap will optimistically send them the "wantlist", which will usually obviate any more dht queries for that dag. we haven't measured this to be true yet -- we need to -- but in practice it seems to work quite well, else we wouldnt see as quick download speeds. (one way to look at it, is "per-dag swarms that overlap", but it's not a fully correct statement as having a root doesn't necessarily mean a node has any or all children.) + +Providing a block happens as it gets added. Reproviding happens periodically, currently 0.5 * dht record timeout ~= 12 hours. + #### Get value #### Put value From 0e260f7b43ab583aadd500a540404af0b1d9749b Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 26 Jun 2015 19:01:51 +0100 Subject: [PATCH 05/37] put question --- protocol/routing/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/protocol/routing/README.md b/protocol/routing/README.md index 80cb3192a..4fa8f1373 100644 --- a/protocol/routing/README.md +++ b/protocol/routing/README.md @@ -78,11 +78,11 @@ Providing a block happens as it gets added. Reproviding happens periodically, cu #### Get value + + #### Put value -1. find peer -2. transfer -3. provide +_not 100% about this happens exactly. From what I understand, the IPFS node that is adding the file, breaks the file into blocks, creates the hashes and provides each single one of them. When do we execute a Put? Replicas are done through "Get", right?_ ### DHT From dad0bb74735f4b9b473b088abb668d9d583bd31c Mon Sep 17 00:00:00 2001 From: David Dias Date: Tue, 30 Jun 2015 12:30:42 -0700 Subject: [PATCH 06/37] separate DHT, discovery and routing specs --- protocol/routing/DHT.md | 28 ++++++++ protocol/routing/README.md | 61 ++++++------------ protocol/routing/discovery.md | 41 ++++++++++++ .../routing/figs/routing-overview.monopic | Bin 0 -> 920 bytes protocol/routing/figs/routing-overview.txt | 6 ++ 5 files changed, 95 insertions(+), 41 deletions(-) create mode 100644 protocol/routing/DHT.md create mode 100644 protocol/routing/discovery.md create mode 100644 protocol/routing/figs/routing-overview.monopic create mode 100644 protocol/routing/figs/routing-overview.txt diff --git a/protocol/routing/DHT.md b/protocol/routing/DHT.md new file mode 100644 index 000000000..0f9ef8935 --- /dev/null +++ b/protocol/routing/DHT.md @@ -0,0 +1,28 @@ +IPFS DHT Protocol Spec +====================== + +Authors: David Dias + +Reviewers: + +TODOS: + +----------------------- + +> + +## Supports + +- Maintaining partial state of the network + - DHT + - kbucket + +## Overview + + + +explain: +- dht/coral, how the algo works +- kbucket +- each time a contact is made with a new peer, we check to see if it is a better candidate for our kbucket +- xor metric diff --git a/protocol/routing/README.md b/protocol/routing/README.md index 4fa8f1373..8f51666c7 100644 --- a/protocol/routing/README.md +++ b/protocol/routing/README.md @@ -9,63 +9,49 @@ TODOS: ----------------------- -> This spec defines the routing protocol spec, covering `Peer discovery`, `Routing` and the `DHT`. The spec is a **Work In Progress**. +> This spec defines the routing protocol spec. Routing offers an interface for the features exposed by `Peer discovery` and `DHT`. The spec is a **Work In Progress**. ## Supports -- Peer discovery through - - mdns - - custom peers list - - random walking on the network - Routing primitives - Publish and fetch content (also providing) - Maintaining partial state of the network - DHT - kbucket -### Overview +## Overview -The Routing Protocol is divided in three major components, these are: -- Peer Discovery: Responsible for filling our kbucket with best candidates. +The Routing Protocol is composed by three componenets, these are: - Interface: Our routing primitives that are offered for the user, such as finding and publishing content, including the storage and lookup of metadata (Providers). -- Peer-to-peer Structured Overlay Network: Algorithm for the implicit network organization, based on [Coral](http://iptps03.cs.berkeley.edu/final-papers/coral.pdf) and [mainlineDHT](http://www.bittorrent.org/beps/bep_0005.html) - -Bootstrapping the routing happens by connecting to a predefined "railing" peers list, shipped with the go-ipfs release and/or by discovery through mDNS. Once at least one peer is found and added to the kbucket, the routing changes to an active state and our peer becomes able to route and receive messages. - -### Peer Discovery - -#### bootstrap peer list - -List with known and trusted peers shipped with IPFS. - -- _How is this list updated?_ -- _Is this list updated periodically_? - -#### random walk - -IPFS issues random Peer lookups periodically to refresh our kbucket if needed. For impl reference, see: https://github.com/ipfs/go-ipfs/blob/master/routing/dht/dht_bootstrap.go#L88-L109. - -#### mDNS +- Peer Discovery: Responsible for filling our kbucket with best candidates. +- Peer-to-peer Structured Overlay Network (DHT): Algorithm for the implicit network organization, based on [Coral](http://iptps03.cs.berkeley.edu/final-papers/coral.pdf) and [mainlineDHT](http://www.bittorrent.org/beps/bep_0005.html) -In addition to known peers and random lookups, IPFS also performs Peer Discovery through mDNS ([MultiCast DNS](https://tools.ietf.org/html/rfc6762)) +``` +┌──────────────┐ +│ routing │ +└──────────────┘ +┌─────────┐┌───┐ +│discovery││DHT│ +└─────────┘└───┘ +``` --_How offen do we issue this searches?_ +In order for routing to work, we first have to pass the bootstrap state. Bootstrapping happens by connecting to a predefined "railing" peers list, shipped with the go-ipfs release and/or by discovery through mDNS. Once at least one peer is found and added to the kbucket, the routing changes to an active state and our peer becomes able to route and receive messages. -### Routing +## Routing For impl reference, check: https://github.com/ipfs/go-ipfs/blob/master/routing/routing.go#L19-L49 -#### Find a peer +### Find a peer _When searching for a peer, do we fetch the kbucket from a peer and see which peer we want to ping next or do we ask for a given Id to a peer and that peer replies to us with the best candidate (or itself if it is the case)?_ -#### Ping +### Ping Ping mechanism (for heartbeats). Ping a peer and log the time it took to answer. _what if the Id doesn't exist? Is there any rule for non existing peers? Should we log time for best matches as well?_ -#### Provide +### Provide Providing is the process of storing/updating the metadata (pointers) of where the blocks of a given file are stored/available in the IPFS network. What this means is that the DHT is not used for block discovery, but for the metadata which identifies where they are, instead. When a node advertises a block available for download, IPFS stores a record in the DHT with its own Peer.ID. This is termed "providing". the node becomes a "provider". Requesters who wish to retrieve the content, query the DHT (or DSHT) and need only to retrieve a subset of providers, not all of them. (this works better with huge DHTs, and latency-aware DHTs like coral). @@ -76,18 +62,11 @@ There is an optimistic optimization -- which is that if a node is storing a node Providing a block happens as it gets added. Reproviding happens periodically, currently 0.5 * dht record timeout ~= 12 hours. -#### Get value +### Get value -#### Put value +### Put value _not 100% about this happens exactly. From what I understand, the IPFS node that is adding the file, breaks the file into blocks, creates the hashes and provides each single one of them. When do we execute a Put? Replicas are done through "Get", right?_ -### DHT - -explain: -- dht/coral, how the algo works -- kbucket -- each time a contact is made with a new peer, we check to see if it is a better candidate for our kbucket -- xor metric diff --git a/protocol/routing/discovery.md b/protocol/routing/discovery.md new file mode 100644 index 000000000..88fac3897 --- /dev/null +++ b/protocol/routing/discovery.md @@ -0,0 +1,41 @@ +IPFS Peer Discovery Protocol Spec +================================= + +Authors: David Dias + +Reviewers: + +TODOS: + +----------------------- + +> + +## Supports + +- Peer discovery through + - mdns + - custom peers list + - random walking on the network + +## Overview + + +### bootstrap peer list + +List with known and trusted peers shipped with IPFS. + +- _How is this list updated?_ +- _Is this list updated periodically_? + +### random walk + +IPFS issues random Peer lookups periodically to refresh our kbucket if needed. For impl reference, see: https://github.com/ipfs/go-ipfs/blob/master/routing/dht/dht_bootstrap.go#L88-L109. + +### mDNS + +In addition to known peers and random lookups, IPFS also performs Peer Discovery through mDNS ([MultiCast DNS](https://tools.ietf.org/html/rfc6762)) + +-_How offen do we issue this searches?_ + + diff --git a/protocol/routing/figs/routing-overview.monopic b/protocol/routing/figs/routing-overview.monopic new file mode 100644 index 0000000000000000000000000000000000000000..631136ca66cc20e3d0fede6347a0cdb531ad8507 GIT binary patch literal 920 zcmV;J184mIO;1iwP)S1pABzY8000000t4k(%W|7A6#bQq)?@~WM{IA~Mc19~IvGZQ z3~DgA5_Xb$^6$M8k_^~MoCo7cvOrc8=|0YV9KjAX=^vK05-oOWdKsum+K8Nqq~&+4 zN?L&y2zjVwcWpu|UeqgAw`k#eC~N8#=1E$yI%hdrv|_`|PF_o%GrJ^9nm4zd#7-P- zTbh*=j@mr~t*Ox}z&KhLn~I90+kh6Khn9k_SVHTpY(yg15;iOAF+n3amF(nHO?IO! zT+&K{uDr?m$6!Or^PJUggYuy}nbPd05Y48}llFcM))H{MEn%f7-S*xlRx79WV9-Ki zrOqZCmWl7+XqHRKlp5djk#$P)f1m_m>;?B6lPJ2#ex!1QtYaODE9vc`R#t>Bl+|=>D znGl{XHLwbpSkjCoVCXm%hOSqK>9wy84aln5GFNLVItj~p+e4@?(1l`VkIP%eI>+>% z7CF6gSXM)09}H-|LdT^po*kywc-Lk8?d@AAYVMjBzui^3a@|3!QJq%bwpj?v)`Xy<}Qev;ZrxkxcN5MMo!! zhDv!0qPam)!jl(5DGL+VHQ0$$-%5SbL1>qqwBCaL_ zlYDHlntvLyiq6he!O2`j!t-*~+z=A+k?S^QVrh&7UxTYi^p0Fbf*1Fh`Ke8N{<~B(URw)yjOJe;m*c?3c1gp+S>n)XoEcJl_JR74o z5Y_=3Ibw-l3 Date: Tue, 30 Jun 2015 16:54:16 -0700 Subject: [PATCH 07/37] landing ideas --- protocol/figs/overview.monopic | Bin 0 -> 2548 bytes protocol/figs/overview.txt | 21 ++++++++ protocol/layers.md | 85 +++++++++++++++++++++++++++++++++ protocol/routing/README.md | 2 + 4 files changed, 108 insertions(+) create mode 100644 protocol/figs/overview.monopic create mode 100644 protocol/figs/overview.txt create mode 100644 protocol/layers.md diff --git a/protocol/figs/overview.monopic b/protocol/figs/overview.monopic new file mode 100644 index 0000000000000000000000000000000000000000..598bf1d8b8b7199d67d22744194a4235b649b74e GIT binary patch literal 2548 zcmV`kcKmsdA^ zn9S+zo9?tKX8L(gq*jHPg6MtH@6u$m(tQGVIBt_2*0oDCdiwaOoDqj12&KU|4&iu^ z)_gXt5kbM0p&ViohDP)o_H~Pk4ArY+4p+!u#UdRUphud0K31=PJw_SrUnG$T;ms7JH9->3N|Rn1g~=d^w@ z%gbz&y06MzvMIjX8f|q+RVC|PqF!~+bXvWyTh%>G^6m3JIjrmh;EqP%;gCG0t0Z6V zibHEuT!5o`H0^ag`(pi7_wXUvmuVj{cG+f==KcXa2K(lHvi`a~6wkSrLTcdEPJOf8 z`NvxirMVtdLyTnGoiYqPIf{n|Got`T5V%2=+5c1{0ON>h4f}kr9#*fa-jX&^x zbr;-Z997z(#-XN0cY^CLbJe;k{o7J}pMIjgPwV24Ys#ah8OPWbn-TSBamcorq98z# zp{RZJz3$wXE!H|7Pd&^`H>Xzi4>Rv=No>%CpLJ7^bs>hXfLsAOL8KeUJc&VVRs9%W% z^uAaywL6qR4dUKsxf)WXNWV9)zYAI1!`bEq+H9YDs&<6-Pe#Fwa^V#C6DQ6-kh zxQ~0_hwGgZawE3{@nZDw5$;5oO_g?hsG%o3`ShGA4{u<-;S)s#3MgFG63aKsF0jfJlc7; zB?g*R;z~Yl0L5*{NG;ZubZ8CO*>*&~Ftd@NDf&y9*$53=*?7px=FZUN&a&o??Klf) zVYizbXxi4KZcGF!~X^P(M}j&j#^ z)Z?)yx?zJAHdZ0b=i7LPS1deS_=3Q2x!H(^O0b8)oT4~TpG}YZmdiU!^Nl!fuWH_l z?D}PJzg%yty6%JRHDBwAesFfA1uO-fY;*B@;8Olvz|5KXwL8iAj=X{7V>v#V3iupi zZw=H1Z)$l<%NtrgKg-pu*yc-1AJiDMtAUU8t!IQmSW)Yzza{y%q%_LuSRH(EqGiY* z6N}mY7>ol2e`%O{1zI5Pf{+LYIWe7|GA6<$5{RpdJHKNOv%#n{^wI*NkP+tNc1A^* zAvr^Y8R9WEFvSZ5vWN({A&5_2eo9~XY$Z59u~LLXUveJUe5wIvQE!^m_jP^Wo3t8x zJp#SlBk)phu*}u9?E$4W$;Rf`*c2O^VPg|)eg#>Ld4p&n7SdgHe?7 zU=kN$F>&V;4u-L1JUy!2WDe^(lKqpC5~Ki;PY!+pqrPHrBc=2MM} zzqVS?z83?7I+97DE;sM9zy#RT>|3_j{97x#>_-nvk73|ej#udJ^%Ht|vmnsTUH;T|$S_=X5gnTz?tI)Atm64aCF( zl^}LYAwo1{5;5lqVa^l6oF|0IfF@GYoE#k@L}v&Q!ZGHNyh7`Gh?D3LCrRgAla8en z+ziJ+?dC=@kd)yWNQyBGgeab9EQmp29nTMLg!A@uK5e}6qVY8rzazUJ5!ofA8`(WC zzQ#_WVi#H<&OJyR^d>iw3QLwug~j2{CW`|FGH{?nvq-pezVKCUSu?@Gaa-1WLI&~~ z8P+6nW>a%0LBP;L(>8^pLksjAp#?fBv>?LefyEQ;M5WuBs3Dn{>?R{0R}iyIb?>~) z>np7tnpN%Kw7)ItpZ9V_hJ%1ahTFYG!UcLE8bI8X&)v@^11TLkOX>KS(Q}LE24g}e z?zL7o+2%8b!X*~LK!+R1X#pO_LhXBH0n;0<&RK>dlY7($0mu*ph@HZr*H1 z-fq{?`sV1^ChT(?r@5J2_2o`;gK;n;mdT;bt+SIUIT$9$XK9&~Dr z{4|k(`7w0DXGBiet$*y+KXzaVy9^`DZUZ#ocu~xR(ENP|2$AX8)2(xgX8nT$u&don zrExQjaV>clNE|K-!UF|vaJaME5Mq-YRPjWQH$m;qHW-CFa8t~7$&+wrupt!B-$g*L zGU&!e$K1Sn(ElbWYW=Go_wRfHM%r2}j&{2te1;q&y~W@p$J?tVk_HGr!8gsSum1 this is a temporary doc, just so I can write down all the spec/notes that has been talked and iterate over it until we figure out how to organize it. + +# Layers + +``` + ┌──────────────────────────────────────────────┐ + │ MerkleDAG │ + └──────────────────────────────────────────────┘ + ▷ ┌──────────────────────────────────────────────┐ + │ │ bitswap │ +exchange│ └──────────────────────────────────────────────┘ + │ ┌──────────────────────────────────────────────┐ + │ │ host │ + ▷ └──────────────────────────────────────────────┘ + ▷ ┌──────────────────────────────────────────────┐ + │ │ routing │ + routing│ └──────────────────────────────────────────────┘ + │ ┌────────────────────┐ ▲ ┌ ─ ─ ─ ─ ─ ─ ─ ─ + │ │ swarm │ │ ┌───────────────┐ + │ │ │◀─┴─────┤│ discovery │ + │ │ │ └───────────────┘ + ▷ └────────────────────┘ └ ─ ─ ─ ─ ─ ─ ─ ─ + ▷ ┌──────────┐┌────────┐ + │ │connection││protocol│ + network│ │ ││muxing │ + ▷ └──────────┘└────────┘ +``` + +## MerkleDAG layer + +## exchange layer + +### bitswap + +### host + +- holds connections open +- announces block interest to connections open +- api + - .openStream() + +## routing layer + +### routing + +![](https://cldup.com/gifxf20TnJ-3000x3000.png) + +- routing interface +- DHT (Kademlia) +- mDNS +- Delegated +- Tracker + +### discovery + +![](https://cldup.com/q3JsosI5zo-3000x3000.png) + +### swarm + +![](https://cldup.com/As4HG0h4d9-3000x3000.png) + +## network layer + +### protocol muxing + +![](https://cldup.com/o8CRUe2Y2U-1200x1200.png) + +### connection + +![](https://cldup.com/JpaKDIUxRS-1200x1200.png) + +### nat traversal + +![](https://cldup.com/3KMuGu3tEb-2000x2000.png) + +# execution example + + + +# refs + +- https://github.com/ipfs/specs/pull/15/files +- https://github.com/ipfs/go-ipfs/blob/master/routing/dht/dht.go +- https://github.com/ipfs/go-ipfs/blob/master/p2p/host/host.go +- https://github.com/ipfs/go-ipfs/blob/master/routing/dht/notif.go diff --git a/protocol/routing/README.md b/protocol/routing/README.md index 8f51666c7..e4c0a1e12 100644 --- a/protocol/routing/README.md +++ b/protocol/routing/README.md @@ -43,6 +43,8 @@ For impl reference, check: https://github.com/ipfs/go-ipfs/blob/master/routing/r ### Find a peer +Finding a peer happens through an iterative process. We query the best candidate in our kbucket for the awarness of the peer we are looking for, if that peer isn't the ideal candidate, it will return 3 possible candidates from his kbucket and it will query those to check for the best candidate. We repeat the process until we find that peer + _When searching for a peer, do we fetch the kbucket from a peer and see which peer we want to ping next or do we ask for a given Id to a peer and that peer replies to us with the best candidate (or itself if it is the case)?_ ### Ping From aae56f2917a7a3ca1c44d668168766426000c0ba Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 5 Jul 2015 17:42:07 -0700 Subject: [PATCH 08/37] layers --- protocol/layers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/layers.md b/protocol/layers.md index fa6eb45d5..2bd57867f 100644 --- a/protocol/layers.md +++ b/protocol/layers.md @@ -41,7 +41,7 @@ exchange│ └───────────────────── ## routing layer -### routing +### router ![](https://cldup.com/gifxf20TnJ-3000x3000.png) From 2546f85710f4b27bd729637f96d81f347c2db30c Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 5 Jul 2015 18:30:54 -0700 Subject: [PATCH 09/37] make swarm part of the network layer and put NAT traversal, connection, and protocol muxing as building blocks of swarm --- protocol/layers.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/protocol/layers.md b/protocol/layers.md index 2bd57867f..eb444548f 100644 --- a/protocol/layers.md +++ b/protocol/layers.md @@ -55,21 +55,21 @@ exchange│ └───────────────────── ![](https://cldup.com/q3JsosI5zo-3000x3000.png) +## network layer + ### swarm ![](https://cldup.com/As4HG0h4d9-3000x3000.png) -## network layer - -### protocol muxing +#### protocol muxing ![](https://cldup.com/o8CRUe2Y2U-1200x1200.png) -### connection +#### connection ![](https://cldup.com/JpaKDIUxRS-1200x1200.png) -### nat traversal +#### nat traversal ![](https://cldup.com/3KMuGu3tEb-2000x2000.png) From a601ddc62f47bc39ef6fd3e5ae98d5057830d6ba Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 5 Jul 2015 18:35:29 -0700 Subject: [PATCH 10/37] some notes on swarm --- protocol/layers.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/protocol/layers.md b/protocol/layers.md index eb444548f..f822b4b9c 100644 --- a/protocol/layers.md +++ b/protocol/layers.md @@ -61,6 +61,14 @@ exchange│ └───────────────────── ![](https://cldup.com/As4HG0h4d9-3000x3000.png) +swarms offers the API for routing layer be able to open "streams" with other peers. The API should look like: + +- `.openStream(multiaddr, protocol)` +- `.registerHandle(protocol, cb)` + +swarm holds the collection of connections and respective open streams on top of these connections (for reusing purposes) +a connection should be an abstraction of a socket where spdy was already negotiated + #### protocol muxing ![](https://cldup.com/o8CRUe2Y2U-1200x1200.png) From 61bfe395745b2ab81f5f17601a32cdd631a394dd Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 17 Jul 2015 17:08:49 -0700 Subject: [PATCH 11/37] add chapters numbers to sections on the readme so it is more clear how they are separated --- protocol/README.md | 54 +++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/protocol/README.md b/protocol/README.md index f67822978..75cdebc3b 100644 --- a/protocol/README.md +++ b/protocol/README.md @@ -1,22 +1,31 @@ -# IPFS Protocol Spec (WIP!) +IPFS Protocol Spec +================== -Authors: [@jbenet](http://github.com/jbenet) +> **This spec is an Work In Progress (WIP)** + +Authors: + +- [@jbenet](http://github.com/jbenet) Reviewers: * * * -This [spec](../) document defines the IPFS protocol stack, the subsystems, the +This spec document defines the IPFS protocol stack, the subsystems, the interfaces, and how it all fits together. It delegates non-interface details to other specs as much as possible. This is meant as a top-level view of the protocol and how the system fits together. - Note, this document is not meant to be an introduction of the concepts in IPFS and is not recommended as a first pass to understanding how IPFS works. For that, please refer to the [IPFS paper](http://static.benet.ai/t/ipfs.pdf). -## IPFS and the Merkle DAG +# Index + +- []() +- []() + +## 1. IPFS and the Merkle DAG At the heart of IPFS is the MerkleDAG, a directed acyclic graph whose links are hashes. This gives all objects in IPFS useful properties: @@ -41,7 +50,7 @@ publish, distribute, serve, and download merkledags. It is the authenticated, decentralized, permanent web. -## Nodes and Network Model +## 2. Nodes and Network Model The IPFS network uses PKI based identity. An "ipfs node" is a program that can find, publish, and replicate merkledag objects. Its identity is defined @@ -54,7 +63,7 @@ nodeID := multihash(publicKey) TODO: constraints on keygen. -### multihash and upgradeable hashing +### 2.1 multihash and upgradeable hashing All hashes in ipfs are encoded with [multihash](https://github.com/jbenet/multihash/), a self-describing hash @@ -75,7 +84,7 @@ sha3 ``` -## The Stack +## 3. The Stack IPFS has a stack of modular protocols. Each layer may have multiple implementations, all in different modules. This spec will only address the @@ -94,7 +103,7 @@ IPFS has five layers: These are briefly described bottom-up. -### Network -- connecting to peers +### [3.1 Network](network) The **network** provides point-to-point transports (reliable and unreliable) between any two IPFS nodes in the network. It handles: @@ -105,7 +114,7 @@ between any two IPFS nodes in the network. It handles: See more in the [network spec](network). -### Routing -- finding peers and data +### [3.2 Routing -- finding peers and data](routing) The IPFS **Routing** layer serves two important purposes: - **peer routing** -- to find other nodes @@ -124,7 +133,7 @@ of implementations. For example: See more in the [routing spec](https://github.com/ipfs/specs/tree/master/protocol/routing). -### Block Exchange -- transfering content-addressed data +### [3.3 Block Exchange -- transfering content-addressed data](exchange) The IPFS **Block Exchange** takes care of negotiating bulk data transfers. Once nodes know each other -- and are connected -- the exchange protocols @@ -137,7 +146,7 @@ of implementations. For example: of BitTorrent to work with arbitrary (and not known apriori) DAGs. - **HTTP:** a simple exchange can be implemented with HTTP clients and servers. -### Merkledag -- making sense of data +### [3.4. Merkledag -- making sense of data](../merkledag) [As discussed above](#IPFS-and-the-Merkle-DAG), the IPFS **merkledag** is the datastructure at the heart of IPFS. It is an @@ -170,7 +179,7 @@ on top of the merkledag, such as: See more in the merkledag spec (TODO). -### Merkledag Paths +### [3.4.1 Merkledag Paths](../merkledag) The merkledag is enough to resolve paths: @@ -186,7 +195,7 @@ See more in the path resolution spec (TODO). ![](../media/ipfs-resolve/ipfs-resolve.gif) -### Naming -- PKI namespace and mutable pointers +### [3.5 Naming -- PKI namespace and mutable pointers]() IPFS is mostly concerned with content-addressed data, which by nature is immutable: changing an object would change its hash -- and thus its @@ -209,7 +218,7 @@ See more in the namin spec (TODO). -## Applications and Datastructures -- on top of IPFS +## [4. Applications and Datastructures -- on top of IPFS]() The stack described so far is enough to represent arbitrary datastructures and replicate them accross the internet. It is also enough to build and @@ -222,7 +231,7 @@ them to the rest of the world using any of the tools that understand IPFS. See more in the datastructures and applications specs (TODO). -### unixfs -- representing traditional files +### [4.1 unixfs -- representing traditional files]() The unix filesystem abstractions -- files and directories -- are the main way people conceive of files in the internet. In IPFS, `unixfs` is a datastructure @@ -235,7 +244,7 @@ to carry over information like: See more in the unixfs spec (TODO). -## Lifetime of fetching an object. +## [5 Lifetime of fetching an object.]() Suppose we ask an IPFS node to retrieve @@ -253,11 +262,7 @@ Then, the IPFS node resolves the components. The first component in an `/ipfs/...` path is always a multihash. The rest are names of links, to be resolved into multihashes. - - - - -## IPFS User Interfaces +## [6 IPFS User Interfaces]() IPFS is not just a protocol. It is also a toolset. IPFS implementations include various tools for working with the merkledag, how to publish @@ -271,9 +276,10 @@ design and implementation. Examples: - The IPFS libs - implementations in various languages - The IPFS gateways - nodes in the internet that serve HTTP over IPFS -## ~~WIP~~ +* * * + +### WIP Stack Dump: -WIP Stack Dump: - How the layers fit together - How they call on each other - Mention all the ports From c67ca713f25833d98c1452f436ff30953995a4ca Mon Sep 17 00:00:00 2001 From: David Dias Date: Sat, 18 Jul 2015 11:09:17 -0700 Subject: [PATCH 12/37] moved the network layer part to its own spec/readme --- protocol/layers.md | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/protocol/layers.md b/protocol/layers.md index f822b4b9c..c41e10ce8 100644 --- a/protocol/layers.md +++ b/protocol/layers.md @@ -55,39 +55,3 @@ exchange│ └───────────────────── ![](https://cldup.com/q3JsosI5zo-3000x3000.png) -## network layer - -### swarm - -![](https://cldup.com/As4HG0h4d9-3000x3000.png) - -swarms offers the API for routing layer be able to open "streams" with other peers. The API should look like: - -- `.openStream(multiaddr, protocol)` -- `.registerHandle(protocol, cb)` - -swarm holds the collection of connections and respective open streams on top of these connections (for reusing purposes) -a connection should be an abstraction of a socket where spdy was already negotiated - -#### protocol muxing - -![](https://cldup.com/o8CRUe2Y2U-1200x1200.png) - -#### connection - -![](https://cldup.com/JpaKDIUxRS-1200x1200.png) - -#### nat traversal - -![](https://cldup.com/3KMuGu3tEb-2000x2000.png) - -# execution example - - - -# refs - -- https://github.com/ipfs/specs/pull/15/files -- https://github.com/ipfs/go-ipfs/blob/master/routing/dht/dht.go -- https://github.com/ipfs/go-ipfs/blob/master/p2p/host/host.go -- https://github.com/ipfs/go-ipfs/blob/master/routing/dht/notif.go From 6c508c6e91498ec7927c34318fd88e8b34932788 Mon Sep 17 00:00:00 2001 From: David Dias Date: Sat, 18 Jul 2015 11:12:01 -0700 Subject: [PATCH 13/37] update network spec to latest --- protocol/network/README.md | 161 +++++++++++++++---------- protocol/network/figs/overview.monopic | Bin 0 -> 2011 bytes protocol/network/figs/overview.txt | 27 +++++ 3 files changed, 122 insertions(+), 66 deletions(-) create mode 100644 protocol/network/figs/overview.monopic create mode 100644 protocol/network/figs/overview.txt diff --git a/protocol/network/README.md b/protocol/network/README.md index a5141877f..72857ed15 100644 --- a/protocol/network/README.md +++ b/protocol/network/README.md @@ -1,20 +1,26 @@ -# IPFS Protocol Network Spec or `libp2p` +IPFS Protocol Network Spec +========================= -Authors: [Juan Benet](http://github.com/jbenet) +> This spec is a Work In Progress (WIP) -Reviewers: +Authors: +- [Juan Benet](http://github.com/jbenet) -TODOS: -- incorporate peer-routing, as discussed in https://github.com/ipfs/specs/issues/1 +Reviewers: * * * -This [spec](../../) describes the IPFS network protocol. The network layer -provides point-to-point transports (reliable and unreliable) between any two -IPFS nodes in the network. +This describes the IPFS network protocol. The network layer provides point-to-point transports (reliable and unreliable) between any two IPFS nodes in the network. + +# Index +- [1. Introduction and Goals]() +- [2. Requirements]() + - [2.1 NAT traversal] () +- [3. Datastructures]() +- ... -## Supports +## 1. Introduction and Goals It SHOULD support: - [NAT traversal](#NAT-traversal) @@ -23,35 +29,21 @@ It SHOULD support: - [Multiple Transports](#Transport-Agnostic) - [Multi-Multiplexing](#Multi-multiplexing) +## 2. Requirements -### NAT traversal +### 2.1 NAT traversal -Network Address Translation is ubiquitous in the internet. Not only are most -consumer devices behind many layers of NATs, but most datacenter nodes are -often behind NAT for security or virtualization reasons. As we move into -containerized deployments, this is getting worse. IPFS implementations SHOULD -provide a way to traverse NATs, otherwise it is likely that operation will be -affected. Even nodes meant to run with real IP addresses must implement NAT -traversal techniques, as they may need to establish connections to peers -behind NAT. +Network Address Translation is ubiquitous in the internet. Not only are most consumer devices behind many layers of NATs, but most datacenter nodes are often behind NAT for security or virtualization reasons. As we move into containerized deployments, this is getting worse. IPFS implementations SHOULD provide a way to traverse NATs, otherwise it is likely that operation will be affected. Even nodes meant to run with real IP addresses must implement NAT traversal techniques, as they may need to establish connections to peers behind NAT. -IPFS accomplishes full NAT traversal using an ICE-like protocol. It is not -exactly ICE, as ipfs networks provide the possibility of relaying communications over the IPFS protocol itself, for coordinating hole- -punching or even relaying communication. +IPFS accomplishes full NAT traversal using an ICE-like protocol. It is not exactly ICE, as ipfs networks provide the possibility of relaying communications over the IPFS protocol itself, for coordinating hole-punching or even relaying communication. -It is recommended that implementations use one of the many NAT traversal -libraries available, such as `libnice`, `libwebrtc`, or `natty`. However, -NAT traversal must be interoperable. +It is recommended that implementations use one of the many NAT traversal libraries available, such as `libnice`, `libwebrtc`, or `natty`. However, NAT traversal must be interoperable. -### Relay +### 2.2 Relay -Unfortunately, due to symmetric NATs, container and VM NATs, and other -impossible-to-bypass NATs, IPFS MUST fallback to relaying communication -to establish a full connectivity graph. To be complete, implementations -MUST support relay, though it SHOULD be optional and able to be turned -off by end users. +Unfortunately, due to symmetric NATs, container and VM NATs, and other impossible-to-bypass NATs, IPFS MUST fallback to relaying communication to establish a full connectivity graph. To be complete, implementations MUST support relay, though it SHOULD be optional and able to be turned off by end users. -### Encryption +### 2.3 Encryption Communications on IPFS may be: @@ -69,23 +61,13 @@ We recommend that: IPFS uses cyphersuites like TLS. -**NOTE:** we do not use TLS directly, because we do not want the CA system -baggage. Most TLS implementations are very big. Since the IPFS model begins -with keys, IPFS only needs to apply ciphers. This is a minimal portion of the -whole TLS standard. +**NOTE:** we do not use TLS directly, because we do not want the CA system baggage. Most TLS implementations are very big. Since the IPFS model begins with keys, IPFS only needs to apply ciphers. This is a minimal portion of the whole TLS standard. -### Transport Agnostic +### 2.4 Transport Agnostic -IPFS is transport agnostic, so it can run over any transport protocol. It does -not even depend on IP; it may run on top of NDN, XIA, and other new internet -architectures. +IPFS is transport agnostic, so it can run over any transport protocol. It does not even depend on IP; it may run on top of NDN, XIA, and other new internet architectures. -In order to reason about possible transports, IPFS uses -[multiaddr](https://github.com/jbenet/multiaddr), a self-describing addressing -format. This makes it possible for IPFS to treat addresses opaquely everywhere -in the system, and have support various transport protocols in the network -layer. The actual format of addresses in IPFS is `ipfs-addr`, a multiaddr that -ends with an ipfs nodeid. For example, these are all valid `ipfs-addrs`: +In order to reason about possible transports, IPFS uses [multiaddr](https://github.com/jbenet/multiaddr), a self-describing addressing format. This makes it possible for IPFS to treat addresses opaquely everywhere in the system, and have support various transport protocols in the network layer. The actual format of addresses in IPFS is `ipfs-addr`, a multiaddr that ends with an ipfs nodeid. For example, these are all valid `ipfs-addrs`: ``` # ipfs over tcp over ipv6 (typical tcp) @@ -104,19 +86,13 @@ ends with an ipfs nodeid. For example, these are all valid `ipfs-addrs`: /ether/ac:fd:ec:0b:7c:fe/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu ``` -**Note:** at this time, no unreliable implementations exist. The protocol's -interface for defining and using unreliable transport has not been defined. +**Note:** at this time, no unreliable implementations exist. The protocol's interface for defining and using unreliable transport has not been defined. **TODO:** define how unreliable transport would work. base it on webrtc. +### 2.5 Multi-Multiplexing -### Multi-Multiplexing - -The IPFS Protocol is a collection of multiple protocols available at the same -IPFS Node. In order to conserve resources, and to make connectivity easier, -the IPFS network layer can perform all its operations through a single TCP or -UDP port, depending on the transports used. IPFS can multiplex its many -protocols through point-to-point connections. This multiplexing is for both +The IPFS Protocol is a collection of multiple protocols available at the same IPFS Node. In order to conserve resources, and to make connectivity easier, the IPFS network layer can perform all its operations through a single TCP or UDP port, depending on the transports used. IPFS can multiplex its many protocols through point-to-point connections. This multiplexing is for both reliable streams and unreliable datagrams. IPFS is pragmatic. It seeks to be usable in as many settings as possible, to @@ -154,26 +130,27 @@ ensures that complex user or application constraints do not rule out IPFS as an option. -## Datastructures +## 3. Datastructures The network protocol deals with these datastructures: - a `PrivateKey`, the private key of a node. - a `PublicKey`, the public key of a node. - a `PeerID`, a hash of a node's public key. -- a `Node`[*], has a PeerID, and open connections to other `Nodes`. +- a `Node`[1], has a PeerID, and open connections to other `Nodes`. - a `Connection`, a point-to-point link between two Nodes (muxes 1 or more streams) - a `Stream`, a duplex message channel. -[*] currently called `PeerHost` in go-ipfs. +[1] currently called `PeerHost` in go-ipfs. + +## 4. Interface -## Interface +The network protocol's interface has two parts:A -The network protocol's interface has two parts: 1. the _client interface_, for clients (e.g. higher layers of IPFS) 2. the _service interface_, for remote peers (e.g. other IPFS nodes) -### Client Interface +### 4.1 Client Interface The **Client Interface** is exposed to the higher layers of IPFS. It is the entry point for other parts to open + handle streams. @@ -221,7 +198,7 @@ type StreamHandler func (Stream) TODO: incorporate unreliable message / packet streams. -### Protocol Interface +### 4.2 Protocol Interface The network protocol consists of: @@ -246,9 +223,9 @@ for interoperability. These are the default (TODO: unreliable transport) -## Properties +## 5 Properties -### Communication Model - Streams +### 5.1 Communication Model - Streams The Network layer handles all the problems of connecting to a peer, and exposes simple bidirectional streams. Users can both open a new stream @@ -282,7 +259,7 @@ stream.Read(buf2) // read what was sent back fmt.Println(buf2) // print what was sent back ``` -### Ports - Constrained Entrypoints +### 5.2 Ports - Constrained Entrypoints In the internet of 2015, we have a processing model where a program may be running without the ability to open multiple -- or even single -- network @@ -299,7 +276,7 @@ through Websockets or WebRTC. In a sense, the role of the TCP/UDP network stack -- i.e. multiplexing applications and connections -- may now be forced to happen at the application level. -### Transport Protocols +### 5.3 Transport Protocols IPFS is transport agnostic. It can run on any transport protocol. The `ipfs-addr` format (which is an ipfs-specific @@ -334,7 +311,7 @@ Some of the transport protocols we will be using: - Websockets - TCP Remy -### Non-IP Networks +### 5.4 Non-IP Networks Efforts like [NDN](http://named-data.net) and [XIA](http://www.cs.cmu.edu/~xia/) are new architectures for the internet, @@ -343,3 +320,55 @@ will be able to operate on top of these architectures trivially, as there is no assumptions made about the network stack in the protocol. Implementations will likley need to change, but changing implementations is vastly easier than changing protocols. + +## 6 Overview of the Software Stack + +The network is abstracted through the swarm which presents a simplified interface for the remaining layers to have access to the network. This interface should look like: + +- `.openStream(peer, protocol)` - peer should contain the ID of the peer and its respective multiaddrs known. +- `.registerHandler(protocol, handlerFunc)` - enable a protocol to be registered, so that another peer can open a stream to talk with us to that specific protocol +- `.listen()` - to start listening for incoming connections and therefore opening of streams + +The following figure represents how the network level pieces, are tied together: + +``` +┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌───────────┐ + mounted │ mounted │ mounted ││Identify │ +│protocol │protocol │protocol │(mounted │ + 1 │ 2 │ ... ││ protocol) │ +└ ─ ─ ─ ─ └ ─ ─ ─ ─ └ ─ ─ ─ ─ └───────────┘ +┌─────────────────────────────────────────┐ +│ swarm │ +└─────────────────────────────────────────┘ +┌─────────────────────────────────────────┐ +│ connection │ +└─────────────────────────────────────────┘ +┌───────────────┐┌───────────┐┌───────────┐ +│Transport ││multistream││ stream │ +│(TCP, UDP, etc)││ ││ muxer │ +└───────────────┘└───────────┘│┌ ─ ─ ─ ─ ┐│ + │ spdy │ + │└ ─ ─ ─ ─ ┘│ + │┌ ─ ─ ─ ─ ┐│ + │ multiplex │ + │└ ─ ─ ─ ─ ┘│ + │┌ ─ ─ ─ ─ ┐│ + │ QUIC │ + │└ ─ ─ ─ ─ ┘│ + │┌ ─ ─ ─ ─ ┐│ + │ others │ + │└ ─ ─ ─ ─ ┘│ + └───────────┘ +``` + +**Identify** is one of the protocols mounted on top of swarm, our Connection handler, however, it follows and respects the same pattern as any other protocol when it comes to mounting it on top of swarm. Identify enables us to trade listenAddrs and observedAddrs between peers, this is crucial for the working of IPFS, since every socket open implements REUSEPORT, an observedAddr by another peer can enable a third peer to connect to us, since the port will be already open and redirect to us on a NAT. + +The stream muxer must implement the interface offered by [abstract-stream-muxer](https://github.com/diasdavid/abstract-stream-muxer). + +Every socket open (through the transport chosen), is "multistream'ed" into the stream muxer used, once a stream muxer connection + +## 7 Implementation Details + +Identify stream requests should be issued by the listenner as soon as it receives a valid connection, otherwise the listenner won't be able to identify who is that stream comming, disabling its ability for connection reuse. Identify is responsible for 'tagging' the incomming connection on swarm with the right Id. + +A peer only updates its own multiaddrs list with observedAddrs if it receives the same observedAddr twice, avoiding addr explosion (a phenomenon that happens when both peers are behind symmetric NAT). diff --git a/protocol/network/figs/overview.monopic b/protocol/network/figs/overview.monopic new file mode 100644 index 0000000000000000000000000000000000000000..c54bb898fde4f2ca56b1fbbf8995049099f03c14 GIT binary patch literal 2011 zcmV<12PF9aO;1iwP)S1pABzY8000000t4+_OK;;g5dJF*omxO!h)#ISBjMZBk;O@6CZR#+Q#yP3?&VxvqW z|N0!eC$`bGdGG*y$%~uJ4s0?;ftt*R@Qq6It1e4jlrEJnb@ZsZ2*rjEwpU`W)Lxmr za(!)DglRA#rZU)wx9Z7O>t!}Iob;HkmzjRAR{u4;_YERsU9|X9oZI-+aDTwCD04l6>re!r()x=6+vZ*vpTOldPC6%c|2|PNN+@MvI2es+@f>EnH-)TJ2N$GM~>?(GZwExHqTS?8|jkZj1TE zh%dU*LwB}W>L=IBhP*?h3e%}p7}<4S^jd`=j&iZEnu(G)iJ((;{;x9ljbdUDU^{iA z-;d_c&C5+az6qd=9i}~LR9+f=1^b7Eu3g{#?j*ia9}sC8H7l#ah#s}|z#MUcmuAdY z`E{;E80oRv_UF0wOzY0r+U=0${KEwr5*=Ew#EHc15)6$<4gp8QEGpZe$p!+E$BfrVQ@wj)Z>CSC2zs;r1gT!GtPAupx#L6i#9MbyCF|8d20VkPfm%elZn#+oR~%9t&OWbooJ- z8*htjJ2c9_XY81@w=}`}EIYQ%N|zsBWr4<#GhV#y5@Sn`Ej_mM*wSN5k1aj6^w`o9 zOHV94vGl~!6H8AlJ+buWD(w{|`lG=CB7==9jt6P&#%p8M(b(F5H=4N}LE^IK1)Q}> zC*|8Q=}62@ZPL+$O*(^49h(lj(RVbP&g$K@BZ*o-hdbQdk+JQ%wyFOo!ww~EM9U5( zXAKIJyd6+TV>%2JKBB>>fDT3lD!QQXkuVEsM?(dxcpq`~H{kM7aQSHZJR&3(5t6e< z1S&@a1kS?6^T=6a4aRQ#EaGf3#WEcdenTVPgqhF7~>EY-i;?|suY0QXV@k+$Q?evG+ ztwl1JKqwA_=Q14}WqT^_`MsFuPfZyTi5nXAY$QQhxLtfS!j>@=gEaMr*GA?wReKGU z{`tm7vJKrQU4GRi_R;G` zR_ZBp3CPI!h{!0CU~UFWM{qL)IhjLbS z*~F=F(r_9F(q?|Q;p%V^8IlH*Jx>B=>xD})sSi# z9tGq}2-t-XunVEV=^`9UG-gH>I%_Z>{4J$fB7X9es^svLD%AI;j+*B{00ju3009&r zuop>_3rVQLW9~unaJzZuZFeB{o=`QO-H{%iP?elAp$dWBfdFw3APxe=LGnTps>U=t zxE$mU|K_(*f3e%Ehx)wjHa#Bx_cD|QgG!o&i=Bttv83d6Le+58{<};D+UcM?T)$Zz#H_f7|B`^kchc1(haFcrfg1oLoz`#o!8D;4iSo|6Q5 z1lh5+jvD1j!K6yTi4(AGCSco4;ERaz2s&o^!0S(AYFB24!|k-O!OPLwZ;IU=oIBSh zL5Oh27@%NQhoE7s4uZoqIh@5zSQu%Tzw8Ff@Dstr!BH^7!di~|Q0y7Re6-AV!Itk+ z)e~#u{`IzNg7gWyQ0&+5y{pmg>g-P-fJ{u-Hv`kk3mFzGSeYQft@)F8)CAf6P4oY6 z;E8O?N3-C%{_NN|yB1BOr6&zHZvlL=CyISAweK#spPTU=XyR}>Lh=MU??WK)n>qx7 zp4f_&2OF`3o^Wdd!}KRG{RvEe(jW@CjEEr_^Y90L-X1M_&-y$`)@RCh&iEro^=M)4 zr!e txXIYOZ4O3$tlLAfF`v_9yPp*zkgRzxRc6<<`{=8E@*mb0b5%oJ000l;@gD#H literal 0 HcmV?d00001 diff --git a/protocol/network/figs/overview.txt b/protocol/network/figs/overview.txt new file mode 100644 index 000000000..ecc37f9a6 --- /dev/null +++ b/protocol/network/figs/overview.txt @@ -0,0 +1,27 @@ +┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌───────────┐ + mounted │ mounted │ mounted ││Identify │ +│protocol │protocol │protocol │(mounted │ + 1 │ 2 │ ... ││ protocol) │ +└ ─ ─ ─ ─ └ ─ ─ ─ ─ └ ─ ─ ─ ─ └───────────┘ +┌─────────────────────────────────────────┐ +│ swarm │ +└─────────────────────────────────────────┘ +┌─────────────────────────────────────────┐ +│ connection │ +└─────────────────────────────────────────┘ +┌───────────────┐┌───────────┐┌───────────┐ +│Transport ││multistream││ stream │ +│(TCP, UDP, etc)││ ││ muxer │ +└───────────────┘└───────────┘│┌ ─ ─ ─ ─ ┐│ + │ spdy │ + │└ ─ ─ ─ ─ ┘│ + │┌ ─ ─ ─ ─ ┐│ + │ multiplex │ + │└ ─ ─ ─ ─ ┘│ + │┌ ─ ─ ─ ─ ┐│ + │ QUIC │ + │└ ─ ─ ─ ─ ┘│ + │┌ ─ ─ ─ ─ ┐│ + │ others │ + │└ ─ ─ ─ ─ ┘│ + └───────────┘ \ No newline at end of file From 1c17e08282c32a67249f5c05f61dd04a2dcf21f4 Mon Sep 17 00:00:00 2001 From: David Dias Date: Sat, 18 Jul 2015 11:13:01 -0700 Subject: [PATCH 14/37] remove layers.md --- protocol/layers.md | 57 ---------------------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 protocol/layers.md diff --git a/protocol/layers.md b/protocol/layers.md deleted file mode 100644 index c41e10ce8..000000000 --- a/protocol/layers.md +++ /dev/null @@ -1,57 +0,0 @@ -> this is a temporary doc, just so I can write down all the spec/notes that has been talked and iterate over it until we figure out how to organize it. - -# Layers - -``` - ┌──────────────────────────────────────────────┐ - │ MerkleDAG │ - └──────────────────────────────────────────────┘ - ▷ ┌──────────────────────────────────────────────┐ - │ │ bitswap │ -exchange│ └──────────────────────────────────────────────┘ - │ ┌──────────────────────────────────────────────┐ - │ │ host │ - ▷ └──────────────────────────────────────────────┘ - ▷ ┌──────────────────────────────────────────────┐ - │ │ routing │ - routing│ └──────────────────────────────────────────────┘ - │ ┌────────────────────┐ ▲ ┌ ─ ─ ─ ─ ─ ─ ─ ─ - │ │ swarm │ │ ┌───────────────┐ - │ │ │◀─┴─────┤│ discovery │ - │ │ │ └───────────────┘ - ▷ └────────────────────┘ └ ─ ─ ─ ─ ─ ─ ─ ─ - ▷ ┌──────────┐┌────────┐ - │ │connection││protocol│ - network│ │ ││muxing │ - ▷ └──────────┘└────────┘ -``` - -## MerkleDAG layer - -## exchange layer - -### bitswap - -### host - -- holds connections open -- announces block interest to connections open -- api - - .openStream() - -## routing layer - -### router - -![](https://cldup.com/gifxf20TnJ-3000x3000.png) - -- routing interface -- DHT (Kademlia) -- mDNS -- Delegated -- Tracker - -### discovery - -![](https://cldup.com/q3JsosI5zo-3000x3000.png) - From 5a108f6be63a780d4e56b1f821dd4b50fff580d2 Mon Sep 17 00:00:00 2001 From: David Dias Date: Sat, 18 Jul 2015 11:14:06 -0700 Subject: [PATCH 15/37] remove outdated protocol overview --- protocol/figs/overview.monopic | Bin 2548 -> 0 bytes protocol/figs/overview.txt | 21 --------------------- 2 files changed, 21 deletions(-) delete mode 100644 protocol/figs/overview.monopic delete mode 100644 protocol/figs/overview.txt diff --git a/protocol/figs/overview.monopic b/protocol/figs/overview.monopic deleted file mode 100644 index 598bf1d8b8b7199d67d22744194a4235b649b74e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2548 zcmV`kcKmsdA^ zn9S+zo9?tKX8L(gq*jHPg6MtH@6u$m(tQGVIBt_2*0oDCdiwaOoDqj12&KU|4&iu^ z)_gXt5kbM0p&ViohDP)o_H~Pk4ArY+4p+!u#UdRUphud0K31=PJw_SrUnG$T;ms7JH9->3N|Rn1g~=d^w@ z%gbz&y06MzvMIjX8f|q+RVC|PqF!~+bXvWyTh%>G^6m3JIjrmh;EqP%;gCG0t0Z6V zibHEuT!5o`H0^ag`(pi7_wXUvmuVj{cG+f==KcXa2K(lHvi`a~6wkSrLTcdEPJOf8 z`NvxirMVtdLyTnGoiYqPIf{n|Got`T5V%2=+5c1{0ON>h4f}kr9#*fa-jX&^x zbr;-Z997z(#-XN0cY^CLbJe;k{o7J}pMIjgPwV24Ys#ah8OPWbn-TSBamcorq98z# zp{RZJz3$wXE!H|7Pd&^`H>Xzi4>Rv=No>%CpLJ7^bs>hXfLsAOL8KeUJc&VVRs9%W% z^uAaywL6qR4dUKsxf)WXNWV9)zYAI1!`bEq+H9YDs&<6-Pe#Fwa^V#C6DQ6-kh zxQ~0_hwGgZawE3{@nZDw5$;5oO_g?hsG%o3`ShGA4{u<-;S)s#3MgFG63aKsF0jfJlc7; zB?g*R;z~Yl0L5*{NG;ZubZ8CO*>*&~Ftd@NDf&y9*$53=*?7px=FZUN&a&o??Klf) zVYizbXxi4KZcGF!~X^P(M}j&j#^ z)Z?)yx?zJAHdZ0b=i7LPS1deS_=3Q2x!H(^O0b8)oT4~TpG}YZmdiU!^Nl!fuWH_l z?D}PJzg%yty6%JRHDBwAesFfA1uO-fY;*B@;8Olvz|5KXwL8iAj=X{7V>v#V3iupi zZw=H1Z)$l<%NtrgKg-pu*yc-1AJiDMtAUU8t!IQmSW)Yzza{y%q%_LuSRH(EqGiY* z6N}mY7>ol2e`%O{1zI5Pf{+LYIWe7|GA6<$5{RpdJHKNOv%#n{^wI*NkP+tNc1A^* zAvr^Y8R9WEFvSZ5vWN({A&5_2eo9~XY$Z59u~LLXUveJUe5wIvQE!^m_jP^Wo3t8x zJp#SlBk)phu*}u9?E$4W$;Rf`*c2O^VPg|)eg#>Ld4p&n7SdgHe?7 zU=kN$F>&V;4u-L1JUy!2WDe^(lKqpC5~Ki;PY!+pqrPHrBc=2MM} zzqVS?z83?7I+97DE;sM9zy#RT>|3_j{97x#>_-nvk73|ej#udJ^%Ht|vmnsTUH;T|$S_=X5gnTz?tI)Atm64aCF( zl^}LYAwo1{5;5lqVa^l6oF|0IfF@GYoE#k@L}v&Q!ZGHNyh7`Gh?D3LCrRgAla8en z+ziJ+?dC=@kd)yWNQyBGgeab9EQmp29nTMLg!A@uK5e}6qVY8rzazUJ5!ofA8`(WC zzQ#_WVi#H<&OJyR^d>iw3QLwug~j2{CW`|FGH{?nvq-pezVKCUSu?@Gaa-1WLI&~~ z8P+6nW>a%0LBP;L(>8^pLksjAp#?fBv>?LefyEQ;M5WuBs3Dn{>?R{0R}iyIb?>~) z>np7tnpN%Kw7)ItpZ9V_hJ%1ahTFYG!UcLE8bI8X&)v@^11TLkOX>KS(Q}LE24g}e z?zL7o+2%8b!X*~LK!+R1X#pO_LhXBH0n;0<&RK>dlY7($0mu*ph@HZr*H1 z-fq{?`sV1^ChT(?r@5J2_2o`;gK;n;mdT;bt+SIUIT$9$XK9&~Dr z{4|k(`7w0DXGBiet$*y+KXzaVy9^`DZUZ#ocu~xR(ENP|2$AX8)2(xgX8nT$u&don zrExQjaV>clNE|K-!UF|vaJaME5Mq-YRPjWQH$m;qHW-CFa8t~7$&+wrupt!B-$g*L zGU&!e$K1Sn(ElbWYW=Go_wRfHM%r2}j&{2te1;q&y~W@p$J?tVk_HGr!8gsSum1 Date: Sat, 18 Jul 2015 22:37:20 -0700 Subject: [PATCH 16/37] add myself as an author, normalize how authors are written --- protocol/README.md | 3 ++- protocol/network/README.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/protocol/README.md b/protocol/README.md index 75cdebc3b..ab31eac4e 100644 --- a/protocol/README.md +++ b/protocol/README.md @@ -5,7 +5,8 @@ IPFS Protocol Spec Authors: -- [@jbenet](http://github.com/jbenet) +- [Juan Benet](https://github.com/jbenet) +- [David Dias](https://github.com/diasdavid) Reviewers: diff --git a/protocol/network/README.md b/protocol/network/README.md index 72857ed15..9b0ad3172 100644 --- a/protocol/network/README.md +++ b/protocol/network/README.md @@ -4,7 +4,8 @@ IPFS Protocol Network Spec > This spec is a Work In Progress (WIP) Authors: -- [Juan Benet](http://github.com/jbenet) +- [Juan Benet](https://github.com/jbenet) +- [David Dias](https://github.com/diasdavid) Reviewers: From fea3fde95e4c68ff249ef95e4f9ae3854ec5a210 Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 24 Jul 2015 13:50:59 -0700 Subject: [PATCH 17/37] merge wire in, first steps on the libp2p full spec --- protocol/network/README.md | 108 +++++++++++++++++++++++++++++++++++-- protocol/network/wire.md | 105 ------------------------------------ 2 files changed, 104 insertions(+), 109 deletions(-) delete mode 100644 protocol/network/wire.md diff --git a/protocol/network/README.md b/protocol/network/README.md index 9b0ad3172..3696e8d48 100644 --- a/protocol/network/README.md +++ b/protocol/network/README.md @@ -1,8 +1,6 @@ IPFS Protocol Network Spec ========================= -> This spec is a Work In Progress (WIP) - Authors: - [Juan Benet](https://github.com/jbenet) - [David Dias](https://github.com/diasdavid) @@ -11,9 +9,17 @@ Reviewers: * * * +# Abstract + This describes the IPFS network protocol. The network layer provides point-to-point transports (reliable and unreliable) between any two IPFS nodes in the network. -# Index +This document defines the spec implemented in libp2p. + +# Status of this spec + +> This spec is a Work In Progress (WIP) + +# Table of Contents - [1. Introduction and Goals]() - [2. Requirements]() @@ -322,7 +328,98 @@ is no assumptions made about the network stack in the protocol. Implementations will likley need to change, but changing implementations is vastly easier than changing protocols. -## 6 Overview of the Software Stack +### 5.5 On the wire + +We have the **hard constraint** of making IPFS work across _any_ duplex stream (an outgoing and an incoming stream pair, any arbitrary connection) and work on _any_ platform. + +To make this work, IPFS has to solve a few problems: + +- [Protocol Multiplexing](#protocol-multiplexing) - running multiple protocols over the same stream + - [multistream](#multistream) - self-describing protocol streams + - [multistream-select](#multistream-select) - a self-describing protocol selector + - [Stream Multiplexing](#stream-multiplexing) - running many independent streams over the same wire. +- [Portable Encodings](#portable-encodings) - using portable serialization formats +- [Secure Communications](#secure-communication) - using ciphersuites to establish security and privacy (like TLS). + +#### 5.5.1 Protocol-Multiplexing + +Protocol Multiplexing means running multiple different protocols over the same stream. This could happen sequentially (one after the other), or concurrently (at the same time, with their messages interleaved). We achieve protocol multiplexing using three pieces: + +- [multistream](#multistream) - self-describing protocol streams +- [multistream-select](#multistream-select) - a self-describing protocol selector +- [Stream Multiplexing](#stream-multiplexing) - running many independent streams over the same wire. + +#### 5.5.2 multistream - self-describing protocol stream + +[multistream](https://github.com/jbenet/multistream) is a self-describing protocol stream format. It is extremely simple. Its goal is to define a way to add headers to protocols that describe the protocol itself. It is sort of like adding versions to a protocol, but being extremely explicit. + +For example: + +``` +/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-dht/0.2.3 + + +... +``` + +#### 5.5.3 multistream-selector - self-describing protocol stream selector + +[multistream-select](https://github.com/jbenet/multistream/tree/master/multistream-select) is a simple [multistream](https://github.com/jbenet/multistream) protocol that allows listing and selecting other protocols. This means that Protomux has a list of registered protocols, listens for one, and then _nests_ (or upgrades) the connection to speak the registered protocol. This takes direct advantage of multistream: it enables interleaving multiple protocols, as well as inspecting what protocols might be spoken by the remote endpoint. + +For example: + +``` +/ipfs/QmdRKVhvzyATs3L6dosSb6w8hKuqfZK2SyPVqcYJ5VLYa2/multistream-select/0.3.0 +/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-dht/0.2.3 + + +... +``` + +#### 5.5.4 Stream Multiplexing + +Stream Multiplexing is the process of multiplexing (or combining) many different streams into a single one. This is a complicated subject because it enables protocols to run concurrently over the same wire. And all sorts of notions regarding fairness, flow control, head-of-line blocking, etc. start affecting the protocols. In practice, stream multiplexing is well understood and there are many stream multiplexing protocols. To name a few: + +- HTTP/2 +- SPDY +- QUIC +- SSH + +IPFS nodes are free to support whatever stream multiplexors they wish, on top of the default one. The default one is there to enable even the simplest of nodes to speak multiple protocols at once. The default multiplexor will be HTTP/2 (or maybe QUIC?), but implementations for it are sparse, so we are beginning with SPDY. We simply select which protocol to use with a multistream header. + +For example: + +``` +/ipfs/QmdRKVhvzyATs3L6dosSb6w8hKuqfZK2SyPVqcYJ5VLYa2/multistream-select/0.3.0 +/ipfs/Qmb4d8ZLuqnnVptqTxwqt3aFqgPYruAbfeksvRV1Ds8Gri/spdy/3 + +/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-dht/0.2.3 + + + +/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-bitswap/0.3.0 + + + + + + + + + + + + +... +``` + +#### 5.5.5 Portable Encodings + +In order to be ubiquitous, we _must_ use hyper-portable format encodings, those that are easy to use in various other platforms. Ideally these encodings are well-tested in the wild, and widely used. There may be cases where multiple encodings have to be supported (and hence we may need a [multicodec](https://github.com/jbenet/multicodec) self-describing encoding), but this has so far not been needed. + +For now, we use [protobuf](https://github.com/google/protobuf) for all protocol messages exclusively, but other good candidates are [capnp](https://capnproto.org), [bson](http://bsonspec.org/), [ubjson](http://ubjson.org/). + +## 6 Software Stack The network is abstracted through the swarm which presents a simplified interface for the remaining layers to have access to the network. This interface should look like: @@ -373,3 +470,6 @@ Every socket open (through the transport chosen), is "multistream'ed" into the s Identify stream requests should be issued by the listenner as soon as it receives a valid connection, otherwise the listenner won't be able to identify who is that stream comming, disabling its ability for connection reuse. Identify is responsible for 'tagging' the incomming connection on swarm with the right Id. A peer only updates its own multiaddrs list with observedAddrs if it receives the same observedAddr twice, avoiding addr explosion (a phenomenon that happens when both peers are behind symmetric NAT). + + +## References diff --git a/protocol/network/wire.md b/protocol/network/wire.md deleted file mode 100644 index 9f4ad61b2..000000000 --- a/protocol/network/wire.md +++ /dev/null @@ -1,105 +0,0 @@ - -# IPFS Protocol on the Wire - -Authors: [Juan Benet](http://github.com/jbenet) - -Reviewers: - - -* * * - -This [spec](../../) describes the IPFS protocol on the wire. - -As explained in the [network spec](./), IPFS is [transport agnostic](./#transport-agnostic). We have the **hard constraint** of making IPFS work across _any_ duplex stream (an outgoing and an incoming stream pair, any arbitrary connection) and work on _any_ platform. - -To make this work, IPFS has to solve a few problems: - -- [Protocol Multiplexing](#protocol-multiplexing) - running multiple protocols over the same stream - - [multistream](#multistream) - self-describing protocol streams - - [multistream-select](#multistream-select) - a self-describing protocol selector - - [Stream Multiplexing](#stream-multiplexing) - running many independent streams over the same wire. -- [Portable Encodings](#portable-encodings) - using portable serialization formats -- [Secure Communications](#secure-communication) - using ciphersuites to establish security and privacy (like TLS). - -## Protocol-Multiplexing - -Protocol Multiplexing means running multiple different protocols over the same stream. This could happen sequentially (one after the other), or concurrently (at the same time, with their messages interleaved). We achieve protocol multiplexing using three pieces: - -- [multistream](#multistream) - self-describing protocol streams -- [multistream-select](#multistream-select) - a self-describing protocol selector -- [Stream Multiplexing](#stream-multiplexing) - running many independent streams over the same wire. - -### multistream - self-describing protocol stream - -[multistream](https://github.com/jbenet/multistream) is a self-describing protocol stream format. It is extremely simple. Its goal is to define a way to add headers to protocols that describe the protocol itself. It is sort of like adding versions to a protocol, but being extremely explicit. - -For example: - -``` -/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-dht/0.2.3 - - -... -``` - -### multistream-selector - self-describing protocol stream selector - -[multistream-select](https://github.com/jbenet/multistream/tree/master/multistream-select) is a simple [multistream](https://github.com/jbenet/multistream) protocol that allows listing and selecting other protocols. This means that Protomux has a list of registered protocols, listens for one, and then _nests_ (or upgrades) the connection to speak the registered protocol. This takes direct advantage of multistream: it enables interleaving multiple protocols, as well as inspecting what protocols might be spoken by the remote endpoint. - -For example: - -``` -/ipfs/QmdRKVhvzyATs3L6dosSb6w8hKuqfZK2SyPVqcYJ5VLYa2/multistream-select/0.3.0 -/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-dht/0.2.3 - - -... -``` - -### Stream Multiplexing - -Stream Multiplexing is the process of multiplexing (or combining) many different streams into a single one. This is a complicated subject because it enables protocols to run concurrently over the same wire. And all sorts of notions regarding fairness, flow control, head-of-line blocking, etc. start affecting the protocols. In practice, stream multiplexing is well understood and there are many stream multiplexing protocols. To name a few: - -- HTTP/2 -- SPDY -- QUIC -- SSH - -IPFS nodes are free to support whatever stream multiplexors they wish, on top of the default one. The default one is there to enable even the simplest of nodes to speak multiple protocols at once. The default multiplexor will be HTTP/2 (or maybe QUIC?), but implementations for it are sparse, so we are beginning with SPDY. We simply select which protocol to use with a multistream header. - -For example: - -``` -/ipfs/QmdRKVhvzyATs3L6dosSb6w8hKuqfZK2SyPVqcYJ5VLYa2/multistream-select/0.3.0 -/ipfs/Qmb4d8ZLuqnnVptqTxwqt3aFqgPYruAbfeksvRV1Ds8Gri/spdy/3 - -/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-dht/0.2.3 - - - -/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-bitswap/0.3.0 - - - - - - - - - - - - -... -``` - -## Portable Encodings - -In order to be ubiquitous, we _must_ use hyper-portable format encodings, those that are easy to use in various other platforms. Ideally these encodings are well-tested in the wild, and widely used. There may be cases where multiple encodings have to be supported (and hence we may need a [multicodec](https://github.com/jbenet/multicodec) self-describing encoding), but this has so far not been needed. - -For now, we use [protobuf](https://github.com/google/protobuf) for all protocol messages exclusively, but other good candidates are [capnp](https://capnproto.org), [bson](http://bsonspec.org/), [ubjson](http://ubjson.org/). - - -## Secure Communications - -The wire protocol is -- of course -- wrapped with encryption. We use cyphersuites similar to TLS. This is explained further in the [network spec](./#encryption). From 7117a9b48dbbaffe273202d996e6a90dda074679 Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 24 Jul 2015 14:48:55 -0700 Subject: [PATCH 18/37] moar stuff --- protocol/network/README.md | 54 ++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/protocol/network/README.md b/protocol/network/README.md index 3696e8d48..42bd2a6cd 100644 --- a/protocol/network/README.md +++ b/protocol/network/README.md @@ -21,11 +21,31 @@ This document defines the spec implemented in libp2p. # Table of Contents -- [1. Introduction and Goals]() -- [2. Requirements]() +- [1 Introduction and Goals]() +- [2 Requirements]() - [2.1 NAT traversal] () -- [3. Datastructures]() -- ... + - [2.2 Relay]() + - [2.3 Ecryption]() + - [2.4 Transport Agnostic]() + - [2.5 Multi-Multiplexing]() +- [3 Datastructures]() +- [4 Interface]() + - [4.1 Client Interface]() + - [4.2 Protocol Interface]() +- [5 Properties]() + - [5.1 Communication Model - Streams]() + - [5.2 Ports - Constrained Entrypoints]() + - [5.3 Transport Protocol]() + - [5.4 Non-IP Networks]() + - [5.5 On the wire]() + - [5.5.1 Protocol-Multiplexing]() + - [5.5.2 multistream - self-describing protocol stream]() + - [5.5.3 multistream-selector - self-describing protocol stream selector]() + - [5.5.4 Stream Multiplexing]() + - [5.5.5 Portable Encodings]() +- [6 Software Stack]() +- [7 Implementation Details]() +- [References]() ## 1. Introduction and Goals @@ -421,7 +441,21 @@ For now, we use [protobuf](https://github.com/google/protobuf) for all protocol ## 6 Software Stack -The network is abstracted through the swarm which presents a simplified interface for the remaining layers to have access to the network. This interface should look like: +### 6.1 Overview + +### 6.2 Discovery + +goal: find more peers, keep routing table fresh (if Kad-Router is not being used, discovery doens't necessary has a use) + +### 6.3 Peer Routing + +goal: get ref to other peers, that then can be used by swarm to open a stream. Also is free to open streams to other peers to traverse the DHT + +### 6.4 Swarm (aka Connectivity) + +goal: open stream, NAT traversal, Relay + +~~The network is abstracted through the swarm which presents a simplified interface for the remaining layers to have access to the network. This interface should look like:~~ - `.openStream(peer, protocol)` - peer should contain the ID of the peer and its respective multiaddrs known. - `.registerHandler(protocol, handlerFunc)` - enable a protocol to be registered, so that another peer can open a stream to talk with us to that specific protocol @@ -465,11 +499,21 @@ The stream muxer must implement the interface offered by [abstract-stream-muxer] Every socket open (through the transport chosen), is "multistream'ed" into the stream muxer used, once a stream muxer connection +### 6.5 libp2p + ## 7 Implementation Details +### 7.1 Discovery + +### 7.2 Peer Routing + +### 7.3 Swarm + Identify stream requests should be issued by the listenner as soon as it receives a valid connection, otherwise the listenner won't be able to identify who is that stream comming, disabling its ability for connection reuse. Identify is responsible for 'tagging' the incomming connection on swarm with the right Id. A peer only updates its own multiaddrs list with observedAddrs if it receives the same observedAddr twice, avoiding addr explosion (a phenomenon that happens when both peers are behind symmetric NAT). +### 7.4 libp2p + ## References From 52cc3fbfdd394f0c15d9b871824771fd813a7f9d Mon Sep 17 00:00:00 2001 From: David Dias Date: Sat, 25 Jul 2015 22:28:14 -0700 Subject: [PATCH 19/37] add bits to the discovery section --- protocol/network/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/protocol/network/README.md b/protocol/network/README.md index 42bd2a6cd..4a1d154e2 100644 --- a/protocol/network/README.md +++ b/protocol/network/README.md @@ -505,6 +505,8 @@ Every socket open (through the transport chosen), is "multistream'ed" into the s ### 7.1 Discovery +A discovery service must have return new peers as they are found. It must implement a feature to `verify` if we can open a Connection, using swarm, before returning it as a "new peer found" + ### 7.2 Peer Routing ### 7.3 Swarm From 5713fbe55538ac46af3f1bf375c5c6b568fb0219 Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 23 Aug 2015 13:25:14 +0100 Subject: [PATCH 20/37] restructure + intro + architecture --- protocol/network/1-introduction.md | 27 + protocol/network/2-current-network-stack.md | 0 protocol/network/3-requirements.md | 100 ++++ protocol/network/4-architecture.md | 72 +++ protocol/network/5-datastructures.md | 13 + protocol/network/6-interfaces.md | 82 +++ protocol/network/7-properties.md | 188 +++++++ protocol/network/8-implementations.md | 16 + protocol/network/9-references.md | 0 protocol/network/README.md | 542 ++------------------ 10 files changed, 540 insertions(+), 500 deletions(-) create mode 100644 protocol/network/1-introduction.md create mode 100644 protocol/network/2-current-network-stack.md create mode 100644 protocol/network/3-requirements.md create mode 100644 protocol/network/4-architecture.md create mode 100644 protocol/network/5-datastructures.md create mode 100644 protocol/network/6-interfaces.md create mode 100644 protocol/network/7-properties.md create mode 100644 protocol/network/8-implementations.md create mode 100644 protocol/network/9-references.md diff --git a/protocol/network/1-introduction.md b/protocol/network/1-introduction.md new file mode 100644 index 000000000..014c0125a --- /dev/null +++ b/protocol/network/1-introduction.md @@ -0,0 +1,27 @@ +1 Introduction +============== + +With the developement of building IPFS, the InterPlanetary FileSystem[?], we came to learn about the several challenges imposed by having to run a distributed file system on top of heterogeneous devices, with diferent network setups and capabilities. During this process, we had to revisit the whole network stack and elaborate solutions to overcome the obstacles imposed by design decisions of the several layers and protocols, without breaking compatibility or recreating technologies. + +In order to build this library, we focused on tackling problems independently, creating less complex solutions with powerful abstractions, that when composed, can offer an environment for a Peer-to-Peer application to work sucessfuly. + +## 1.1 Motivation + +`libp2p` is the result of the collective experience while building a distributed system, that puts the responsability on the developers on how they want their app to interop with others in the network, favoring configuration and extensibility instead of assumptions about how the network setup. + +In essence, a peer using libp2p should be able to communicate with another peer using different transports, including connection relay, and talk over different protocols, negotiated in demand. + +## 1.2 Goals + +Our goals for libp2p specification and its implementations are: + +- Enable the use of various transports (TCP, UDP, DTLS, uTP, etc) +- Efficient use of sockets (connection reuse) +- Enable communications between peers to be multiplex over one socket (avoiding handshake overhead) +- Enable multiprotocols and respective versions to be used between peers, using a negotiation process. +- Be backwards compatible +- Work in current systems +- Use the current network technologies to its best capability +- Have NAT Traversal +- Enable connections to be relayed +- Enable encrypted channels diff --git a/protocol/network/2-current-network-stack.md b/protocol/network/2-current-network-stack.md new file mode 100644 index 000000000..e69de29bb diff --git a/protocol/network/3-requirements.md b/protocol/network/3-requirements.md new file mode 100644 index 000000000..742c33a3c --- /dev/null +++ b/protocol/network/3-requirements.md @@ -0,0 +1,100 @@ +3 Requirements +============== + +## 3.1 NAT traversal + +Network Address Translation is ubiquitous in the internet. Not only are most consumer devices behind many layers of NATs, but most datacenter nodes are often behind NAT for security or virtualization reasons. As we move into containerized deployments, this is getting worse. IPFS implementations SHOULD provide a way to traverse NATs, otherwise it is likely that operation will be affected. Even nodes meant to run with real IP addresses must implement NAT traversal techniques, as they may need to establish connections to peers behind NAT. + +IPFS accomplishes full NAT traversal using an ICE-like protocol. It is not exactly ICE, as ipfs networks provide the possibility of relaying communications over the IPFS protocol itself, for coordinating hole-punching or even relaying communication. + +It is recommended that implementations use one of the many NAT traversal libraries available, such as `libnice`, `libwebrtc`, or `natty`. However, NAT traversal must be interoperable. + +## 3.2 Relay + +Unfortunately, due to symmetric NATs, container and VM NATs, and other impossible-to-bypass NATs, IPFS MUST fallback to relaying communication to establish a full connectivity graph. To be complete, implementations MUST support relay, though it SHOULD be optional and able to be turned off by end users. + +## 3.3 Encryption + +Communications on IPFS may be: + +- **encrypted** +- **signed** (not encrypted) +- **clear** (not encrypted, not signed) + +We take both security and performance seriously. We recognize that encryption +is not viable for some in-datacenter high performance use cases. + +We recommend that: +- implementations encrypt all communications by default +- implementations are audited +- unless absolutely necessary, users normally operate with encrypted communications only. + +IPFS uses cyphersuites like TLS. + +**NOTE:** we do not use TLS directly, because we do not want the CA system baggage. Most TLS implementations are very big. Since the IPFS model begins with keys, IPFS only needs to apply ciphers. This is a minimal portion of the whole TLS standard. + +## 3.4 Transport Agnostic + +IPFS is transport agnostic, so it can run over any transport protocol. It does not even depend on IP; it may run on top of NDN, XIA, and other new internet architectures. + +In order to reason about possible transports, IPFS uses [multiaddr](https://github.com/jbenet/multiaddr), a self-describing addressing format. This makes it possible for IPFS to treat addresses opaquely everywhere in the system, and have support various transport protocols in the network layer. The actual format of addresses in IPFS is `ipfs-addr`, a multiaddr that ends with an ipfs nodeid. For example, these are all valid `ipfs-addrs`: + +``` +# ipfs over tcp over ipv6 (typical tcp) +/ip6/fe80::8823:6dff:fee7:f172/tcp/4001/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu + +# ipfs over utp over udp over ipv4 (udp-shimmed transport) +/ip4/162.246.145.218/udp/4001/utp/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu + +# ipfs over ipv6 (unreliable) +/ip6/fe80::8823:6dff:fee7:f172/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu + +# ipfs over tcp over ip4 over tcp over ip4 (proxy) +/ip4/162.246.145.218/tcp/7650/ip4/192.168.0.1/tcp/4001/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu + +# ipfs over ethernet (no ip) +/ether/ac:fd:ec:0b:7c:fe/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu +``` + +**Note:** at this time, no unreliable implementations exist. The protocol's interface for defining and using unreliable transport has not been defined. + +**TODO:** define how unreliable transport would work. base it on webrtc. + +## 3.5 Multi-Multiplexing + +The IPFS Protocol is a collection of multiple protocols available at the same IPFS Node. In order to conserve resources, and to make connectivity easier, the IPFS network layer can perform all its operations through a single TCP or UDP port, depending on the transports used. IPFS can multiplex its many protocols through point-to-point connections. This multiplexing is for both +reliable streams and unreliable datagrams. + +IPFS is pragmatic. It seeks to be usable in as many settings as possible, to +be modular and flexible to fit various use cases, and to force as few choices +as possible. Thus the IPFS network layer provides what we're loosely referring +to as "multi-multiplexing": + +- can multiplex multiple listen network interfaces +- can multiplex multiple transport protocols +- can multiplex multiple connections per peer +- can multiplex multiple client protocols +- can multiples multiple streams per protocol, per connection (SPDY, HTTP2, QUIC, SSH) +- has flow control (backpressure, fairness) +- encrypts each connection with a different ephemeral key + +To give an example, imagine a single IPFS node that: + +- listens on a particular TCP/IP address +- listens on a different TCP/IP address +- listens on a SCTP/UDP/IP address +- listens on a UDT/UDP/IP address +- has multiple connections to another node X +- has multiple connections to another node Y +- has multiple streams open per connection +- multiplexes streams over http2 to node X +- multiplexes streams over ssh to node Y +- one IPFS protocol uses one stream per peer +- one IPFS protocol uses multiple streams per peer + +Not providing this level of flexbility makes it impossible to use IPFS in +various platforms, use cases, or network setups. It is not important that all +implementations support all choices; what is critical is that the spec is +flexible enough to allow implementations to use precisely what they need. This +ensures that complex user or application constraints do not rule out IPFS as an +option. diff --git a/protocol/network/4-architecture.md b/protocol/network/4-architecture.md new file mode 100644 index 000000000..d9f61cf08 --- /dev/null +++ b/protocol/network/4-architecture.md @@ -0,0 +1,72 @@ +4 Architecture +============== + +libp2p was designed around the Unix Philosophy, creating smaller components, easier to understand and to test that can be swapped or added in order to accomodate different technologies or scenarios and also make it that it is upgradable over time. +Although different Peers can support different protocols depending on their capabilities, any Peer can act as a dialer and/or a listener for connections from other Peers, connections that once established can be reused from both ends, removing the distinction between clients and servers. + +libp2p interface acts as a thin veneer to four subsystems that are required in order for peers to be able to communicate. These subsystems are allowed to be built on top of other subsystems as long as they respect the standardized interface. The main 4 subsystems are: + +- Peer Discovery - Ability to discovery of new peers in the network, so that a routing table can be generated and refreshed. +- Peer Routing - Mechanism to find a Peer in a network. This Routing can be done recursively, iteratively or even in a broadcast/multicast mode. +- Swarm - Handles everything that touches the 'opening a stream' part of libp2p, from protocol muxing, stream muxing, NAT Traversal, Connection Relaying, while being multitransport +- Record Store - A system to store provider records and relay recordes + +## 4.1 Peer Discovery + +> goal: find more peers, keep routing table fresh (if Kad-Router is not being used, discovery doens't necessary has a use) + +## 4.2 Peer Routing + +> goal: get ref to other peers, that then can be used by swarm to open a stream. Also is free to open streams to other peers to traverse the DHT + +## 4.3 Swarm + +goal: open stream, NAT traversal, Relay + +~~The network is abstracted through the swarm which presents a simplified interface for the remaining layers to have access to the network. This interface should look like:~~ + +- `.openStream(peer, protocol)` - peer should contain the ID of the peer and its respective multiaddrs known. +- `.registerHandler(protocol, handlerFunc)` - enable a protocol to be registered, so that another peer can open a stream to talk with us to that specific protocol +- `.listen()` - to start listening for incoming connections and therefore opening of streams + +The following figure represents how the network level pieces, are tied together: + +``` +┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌───────────┐ + mounted │ mounted │ mounted ││Identify │ +│protocol │protocol │protocol │(mounted │ + 1 │ 2 │ ... ││ protocol) │ +└ ─ ─ ─ ─ └ ─ ─ ─ ─ └ ─ ─ ─ ─ └───────────┘ +┌─────────────────────────────────────────┐ +│ swarm │ +└─────────────────────────────────────────┘ +┌─────────────────────────────────────────┐ +│ connection │ +└─────────────────────────────────────────┘ +┌───────────────┐┌───────────┐┌───────────┐ +│Transport ││multistream││ stream │ +│(TCP, UDP, etc)││ ││ muxer │ +└───────────────┘└───────────┘│┌ ─ ─ ─ ─ ┐│ + │ spdy │ + │└ ─ ─ ─ ─ ┘│ + │┌ ─ ─ ─ ─ ┐│ + │ multiplex │ + │└ ─ ─ ─ ─ ┘│ + │┌ ─ ─ ─ ─ ┐│ + │ QUIC │ + │└ ─ ─ ─ ─ ┘│ + │┌ ─ ─ ─ ─ ┐│ + │ others │ + │└ ─ ─ ─ ─ ┘│ + └───────────┘ +``` + +**Identify** is one of the protocols mounted on top of swarm, our Connection handler, however, it follows and respects the same pattern as any other protocol when it comes to mounting it on top of swarm. Identify enables us to trade listenAddrs and observedAddrs between peers, this is crucial for the working of IPFS, since every socket open implements REUSEPORT, an observedAddr by another peer can enable a third peer to connect to us, since the port will be already open and redirect to us on a NAT. + +The stream muxer must implement the interface offered by [abstract-stream-muxer](https://github.com/diasdavid/abstract-stream-muxer). + +Every socket open (through the transport chosen), is "multistream'ed" into the stream muxer used, once a stream muxer connection + +## 4.4 Record Store + + diff --git a/protocol/network/5-datastructures.md b/protocol/network/5-datastructures.md new file mode 100644 index 000000000..e090d38df --- /dev/null +++ b/protocol/network/5-datastructures.md @@ -0,0 +1,13 @@ +5 Datastructures +================ + +The network protocol deals with these datastructures: + +- a `PrivateKey`, the private key of a node. +- a `PublicKey`, the public key of a node. +- a `PeerID`, a hash of a node's public key. +- a `Node`[1], has a PeerID, and open connections to other `Nodes`. +- a `Connection`, a point-to-point link between two Nodes (muxes 1 or more streams) +- a `Stream`, a duplex message channel. + +[1] currently called `PeerHost` in go-ipfs. diff --git a/protocol/network/6-interfaces.md b/protocol/network/6-interfaces.md new file mode 100644 index 000000000..b54ea1c0e --- /dev/null +++ b/protocol/network/6-interfaces.md @@ -0,0 +1,82 @@ +6 Interfaces +============ + +The network protocol's interface has two parts:A + +1. the _client interface_, for clients (e.g. higher layers of IPFS) +2. the _service interface_, for remote peers (e.g. other IPFS nodes) + +### 4.1 Client Interface + +The **Client Interface** is exposed to the higher layers of IPFS. It is the entry point for other parts to open + handle streams. + +This type system represents the interface exposed to clients. Actual implementations will likely be more complicated, but they should aim to cover this. + +```go +type PrivateKey interface { + PublicKey() PublicKey + + Sign(data []byte) Signature + Decrypt(ciphertext []byte) (plaintext []byte) +} + +type PublicKey interface { + PeerID() PeerID + + Verify(Signature) (ok bool) + Encrypt(plaintext []byte) (ciphertext []byte) +} + +// PeerID is a hash of a PublicKey, encoded in multihash +// It represents the identity of a node. +type PeerID Multihash + +// Node is a peer in the network. It is both a client and server. +// Users may open streams to remote peers, or set handlers for protocols. +type Node interface { + // ID returns the PeerID of this Node + ID() PeerID + + // NewStream creates a new stream to given peerID. + // It may have to establish a new connection to given peer. + // (This includes finding the addresses of a peer, and NAT Traversal.) + NewStream(Protocol, PeerID) (Stream, error) + + // SetStreamHandler sets a callback for remote-opened streams for a protocol + // Thus clients register "protocol handlers", much like URL route handlers + SetStreamHandler(Protocol, StreamHandler) + + // Raw connections are not exported to the user, only streams. +} + +type StreamHandler func (Stream) +``` + +TODO: incorporate unreliable message / packet streams. + +### 4.2 Protocol Interface + +The network protocol consists of: + +- Any secure, reliable, stream transport: + - a reliable transport protocol (TCP, QUIC, SCTP, UDT, UTP, ...) + - a secure PKI based transport protocol (SSH, TLS, ...) + - a stream transport (with flow control, etc) (HTTP2, SSH, QUIC) +- Protocol stream framing, to multiplex services +- Auxiliary protocols for connectivity: + - Identify - exchange node information + - NAT - NAT Traversal (ICE) + - Relay - for when NAT Traversal fails + +Both the transport and stream muxer are pluggable. Unless +constraints dictate otherwise, implementations SHOULD implement TCP and HTTP/2 +for interoperability. These are the default + +- any reliable transport protocol +- a secure channel encryption +- a stream multiplexor with flow control (e.g. HTTP/2, SPDY, QUIC, SSH) +- every stream protocol header + +(TODO: unreliable transport) + + diff --git a/protocol/network/7-properties.md b/protocol/network/7-properties.md new file mode 100644 index 000000000..873c93022 --- /dev/null +++ b/protocol/network/7-properties.md @@ -0,0 +1,188 @@ +7 Properties +============ + +## 7.1 Communication Model - Streams + +The Network layer handles all the problems of connecting to a peer, and exposes +simple bidirectional streams. Users can both open a new stream +(`NewStream()`) and register a stream handler (`SetStreamHandler`). The user +is then free to implement whatever wire messaging protocol she desires. This +makes it easy to build peer-to-peer protocols, as the complexities of +connectivity, multi-transport support, flow control, and so on, are handled. + +To help capture the model, consider that: + +- `NewStream` is similar to making a Request in an HTTP client. +- `SetStreamHandler` is similar to registering a URL handler in an HTTP server + +So a protocol, such as a DHT, could: + +```go +node := p2p.NewNode(peerid) + +// register a handler, here it is simply echoing everything. +node.SetStreamHandler("/helloworld", func (s Stream) { + io.Copy(s, s) +}) + +// make a request. +buf1 := []byte("Hello World!") +buf2 := make([]byte, len(buf1)) + +stream, _ := node.NewStream("/helloworld", peerid) // open a new stream +stream.Write(buf1) // write to the remote +stream.Read(buf2) // read what was sent back +fmt.Println(buf2) // print what was sent back +``` + +## 7.2 Ports - Constrained Entrypoints + +In the internet of 2015, we have a processing model where a program may be +running without the ability to open multiple -- or even single -- network +ports. Most hosts are behind NAT, whether of household ISP variety or new +containerized data-center type. And some programs may even be running in +browsers, with no ability to open sockets directly (sort of). This presents +challenges to completely peer-to-peer networks who aspire to connect _any_ +hosts together -- whether they're running on a page in the browser, or in +a container within a container. + +IPFS only needs a single channel of communication with the rest of the +network. This may be a single TCP or UDP port, or a single connection +through Websockets or WebRTC. In a sense, the role of the TCP/UDP network +stack -- i.e. multiplexing applications and connections -- may now be forced +to happen at the application level. + +## 7.3 Transport Protocols + +IPFS is transport agnostic. It can run on any transport protocol. The +`ipfs-addr` format (which is an ipfs-specific +[multiaddr](https://github.com/jbenet/multiaddr)) describes the transport. +For example: + +```sh +# ipv4 + tcp +/ip4/10.1.10.10/tcp/29087/ipfs/QmVcSqVEsvm5RR9mBLjwpb2XjFVn5bPdPL69mL8PH45pPC + +# ipv6 + tcp +/ip6/2601:9:4f82:5fff:aefd:ecff:fe0b:7cfe/tcp/1031/ipfs/QmRzjtZsTqL1bMdoJDwsC6ZnDX1PW1vTiav1xewHYAPJNT + +# ipv4 + udp + udt +/ip4/104.131.131.82/udp/4001/udt/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ + +# ipv4 + udp + utp +/ip4/104.131.67.168/udp/1038/utp/ipfs/QmU184wLPg7afQjBjwUUFkeJ98Fp81GhHGurWvMqwvWEQN +``` + +IPFS delegtes the transport dialing to a multiaddr-based network pkg, such +as [go-multiaddr-net](https://github.com/jbenet/go-multiaddr-net). It is +advisable to build modules like this in other languages, and scope the +implementation of other transport protocols. + +Some of the transport protocols we will be using: + +- UTP +- UDT +- SCTP +- WebRTC (SCTP, etc) +- Websockets +- TCP Remy + +## 7.4 Non-IP Networks + +Efforts like [NDN](http://named-data.net) and +[XIA](http://www.cs.cmu.edu/~xia/) are new architectures for the internet, +which are closer to the model IPFS uses than what IP provides today. IPFS +will be able to operate on top of these architectures trivially, as there +is no assumptions made about the network stack in the protocol. Implementations +will likley need to change, but changing implementations is vastly easier than +changing protocols. + +## 7.5 On the wire + +We have the **hard constraint** of making IPFS work across _any_ duplex stream (an outgoing and an incoming stream pair, any arbitrary connection) and work on _any_ platform. + +To make this work, IPFS has to solve a few problems: + +- [Protocol Multiplexing](#protocol-multiplexing) - running multiple protocols over the same stream + - [multistream](#multistream) - self-describing protocol streams + - [multistream-select](#multistream-select) - a self-describing protocol selector + - [Stream Multiplexing](#stream-multiplexing) - running many independent streams over the same wire. +- [Portable Encodings](#portable-encodings) - using portable serialization formats +- [Secure Communications](#secure-communication) - using ciphersuites to establish security and privacy (like TLS). + +### 7.5.1 Protocol-Multiplexing + +Protocol Multiplexing means running multiple different protocols over the same stream. This could happen sequentially (one after the other), or concurrently (at the same time, with their messages interleaved). We achieve protocol multiplexing using three pieces: + +- [multistream](#multistream) - self-describing protocol streams +- [multistream-select](#multistream-select) - a self-describing protocol selector +- [Stream Multiplexing](#stream-multiplexing) - running many independent streams over the same wire. + +### 7.5.2 multistream - self-describing protocol stream + +[multistream](https://github.com/jbenet/multistream) is a self-describing protocol stream format. It is extremely simple. Its goal is to define a way to add headers to protocols that describe the protocol itself. It is sort of like adding versions to a protocol, but being extremely explicit. + +For example: + +``` +/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-dht/0.2.3 + + +... +``` + +### 7.5.3 multistream-selector - self-describing protocol stream selector + +[multistream-select](https://github.com/jbenet/multistream/tree/master/multistream-select) is a simple [multistream](https://github.com/jbenet/multistream) protocol that allows listing and selecting other protocols. This means that Protomux has a list of registered protocols, listens for one, and then _nests_ (or upgrades) the connection to speak the registered protocol. This takes direct advantage of multistream: it enables interleaving multiple protocols, as well as inspecting what protocols might be spoken by the remote endpoint. + +For example: + +``` +/ipfs/QmdRKVhvzyATs3L6dosSb6w8hKuqfZK2SyPVqcYJ5VLYa2/multistream-select/0.3.0 +/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-dht/0.2.3 + + +... +``` + +### 7.5.4 Stream Multiplexing + +Stream Multiplexing is the process of multiplexing (or combining) many different streams into a single one. This is a complicated subject because it enables protocols to run concurrently over the same wire. And all sorts of notions regarding fairness, flow control, head-of-line blocking, etc. start affecting the protocols. In practice, stream multiplexing is well understood and there are many stream multiplexing protocols. To name a few: + +- HTTP/2 +- SPDY +- QUIC +- SSH + +IPFS nodes are free to support whatever stream multiplexors they wish, on top of the default one. The default one is there to enable even the simplest of nodes to speak multiple protocols at once. The default multiplexor will be HTTP/2 (or maybe QUIC?), but implementations for it are sparse, so we are beginning with SPDY. We simply select which protocol to use with a multistream header. + +For example: + +``` +/ipfs/QmdRKVhvzyATs3L6dosSb6w8hKuqfZK2SyPVqcYJ5VLYa2/multistream-select/0.3.0 +/ipfs/Qmb4d8ZLuqnnVptqTxwqt3aFqgPYruAbfeksvRV1Ds8Gri/spdy/3 + +/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-dht/0.2.3 + + + +/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-bitswap/0.3.0 + + + + + + + + + + + + +... +``` + +### 7.5.5 Portable Encodings + +In order to be ubiquitous, we _must_ use hyper-portable format encodings, those that are easy to use in various other platforms. Ideally these encodings are well-tested in the wild, and widely used. There may be cases where multiple encodings have to be supported (and hence we may need a [multicodec](https://github.com/jbenet/multicodec) self-describing encoding), but this has so far not been needed. +For now, we use [protobuf](https://github.com/google/protobuf) for all protocol messages exclusively, but other good candidates are [capnp](https://capnproto.org), [bson](http://bsonspec.org/), [ubjson](http://ubjson.org/). diff --git a/protocol/network/8-implementations.md b/protocol/network/8-implementations.md new file mode 100644 index 000000000..7535458eb --- /dev/null +++ b/protocol/network/8-implementations.md @@ -0,0 +1,16 @@ +8 Implementations +================= + +These are the list of known libp2p, or in another words, the components that respect the interfaces and expectations defined in the Interfaces chapter, that can be composed to make a working libp2p. + +## 8.1 libp2p + +## 8.2 Peer Discovery + +## 8.3 Peer Routing + +## 8.4 Swarm + +## 8.5 Record Store + +## 8.6 Data Structures diff --git a/protocol/network/9-references.md b/protocol/network/9-references.md new file mode 100644 index 000000000..e69de29bb diff --git a/protocol/network/README.md b/protocol/network/README.md index 4a1d154e2..90769b6c9 100644 --- a/protocol/network/README.md +++ b/protocol/network/README.md @@ -1,5 +1,5 @@ -IPFS Protocol Network Spec -========================= +IPFS Protocol Network Spec = libp2p RFC +=================================== Authors: - [Juan Benet](https://github.com/jbenet) @@ -7,6 +7,9 @@ Authors: Reviewers: + +> tl;dr; This document presents libp2p, a modularized and extensible network stack to overcome the networking challenges faced when doing Peer-to-Peer applications. libp2p is used by IPFS as its networking library. + * * * # Abstract @@ -17,505 +20,44 @@ This document defines the spec implemented in libp2p. # Status of this spec -> This spec is a Work In Progress (WIP) - -# Table of Contents - -- [1 Introduction and Goals]() -- [2 Requirements]() - - [2.1 NAT traversal] () - - [2.2 Relay]() - - [2.3 Ecryption]() - - [2.4 Transport Agnostic]() - - [2.5 Multi-Multiplexing]() -- [3 Datastructures]() -- [4 Interface]() - - [4.1 Client Interface]() - - [4.2 Protocol Interface]() -- [5 Properties]() - - [5.1 Communication Model - Streams]() - - [5.2 Ports - Constrained Entrypoints]() - - [5.3 Transport Protocol]() - - [5.4 Non-IP Networks]() - - [5.5 On the wire]() - - [5.5.1 Protocol-Multiplexing]() - - [5.5.2 multistream - self-describing protocol stream]() - - [5.5.3 multistream-selector - self-describing protocol stream selector]() - - [5.5.4 Stream Multiplexing]() - - [5.5.5 Portable Encodings]() -- [6 Software Stack]() -- [7 Implementation Details]() -- [References]() - -## 1. Introduction and Goals - -It SHOULD support: -- [NAT traversal](#NAT-traversal) -- [Connection Relaying](#Relay-is-unavoidable) -- [Encryption](#Encryption) -- [Multiple Transports](#Transport-Agnostic) -- [Multi-Multiplexing](#Multi-multiplexing) - -## 2. Requirements - -### 2.1 NAT traversal - -Network Address Translation is ubiquitous in the internet. Not only are most consumer devices behind many layers of NATs, but most datacenter nodes are often behind NAT for security or virtualization reasons. As we move into containerized deployments, this is getting worse. IPFS implementations SHOULD provide a way to traverse NATs, otherwise it is likely that operation will be affected. Even nodes meant to run with real IP addresses must implement NAT traversal techniques, as they may need to establish connections to peers behind NAT. - -IPFS accomplishes full NAT traversal using an ICE-like protocol. It is not exactly ICE, as ipfs networks provide the possibility of relaying communications over the IPFS protocol itself, for coordinating hole-punching or even relaying communication. - -It is recommended that implementations use one of the many NAT traversal libraries available, such as `libnice`, `libwebrtc`, or `natty`. However, NAT traversal must be interoperable. - -### 2.2 Relay - -Unfortunately, due to symmetric NATs, container and VM NATs, and other impossible-to-bypass NATs, IPFS MUST fallback to relaying communication to establish a full connectivity graph. To be complete, implementations MUST support relay, though it SHOULD be optional and able to be turned off by end users. - -### 2.3 Encryption - -Communications on IPFS may be: - -- **encrypted** -- **signed** (not encrypted) -- **clear** (not encrypted, not signed) - -We take both security and performance seriously. We recognize that encryption -is not viable for some in-datacenter high performance use cases. - -We recommend that: -- implementations encrypt all communications by default -- implementations are audited -- unless absolutely necessary, users normally operate with encrypted communications only. - -IPFS uses cyphersuites like TLS. - -**NOTE:** we do not use TLS directly, because we do not want the CA system baggage. Most TLS implementations are very big. Since the IPFS model begins with keys, IPFS only needs to apply ciphers. This is a minimal portion of the whole TLS standard. - -### 2.4 Transport Agnostic - -IPFS is transport agnostic, so it can run over any transport protocol. It does not even depend on IP; it may run on top of NDN, XIA, and other new internet architectures. - -In order to reason about possible transports, IPFS uses [multiaddr](https://github.com/jbenet/multiaddr), a self-describing addressing format. This makes it possible for IPFS to treat addresses opaquely everywhere in the system, and have support various transport protocols in the network layer. The actual format of addresses in IPFS is `ipfs-addr`, a multiaddr that ends with an ipfs nodeid. For example, these are all valid `ipfs-addrs`: - -``` -# ipfs over tcp over ipv6 (typical tcp) -/ip6/fe80::8823:6dff:fee7:f172/tcp/4001/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu - -# ipfs over utp over udp over ipv4 (udp-shimmed transport) -/ip4/162.246.145.218/udp/4001/utp/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu - -# ipfs over ipv6 (unreliable) -/ip6/fe80::8823:6dff:fee7:f172/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu - -# ipfs over tcp over ip4 over tcp over ip4 (proxy) -/ip4/162.246.145.218/tcp/7650/ip4/192.168.0.1/tcp/4001/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu - -# ipfs over ethernet (no ip) -/ether/ac:fd:ec:0b:7c:fe/ipfs/QmYJyUMAcXEw1b5bFfbBbzYu5wyyjLMRHXGUkCXpag74Fu -``` - -**Note:** at this time, no unreliable implementations exist. The protocol's interface for defining and using unreliable transport has not been defined. - -**TODO:** define how unreliable transport would work. base it on webrtc. - -### 2.5 Multi-Multiplexing - -The IPFS Protocol is a collection of multiple protocols available at the same IPFS Node. In order to conserve resources, and to make connectivity easier, the IPFS network layer can perform all its operations through a single TCP or UDP port, depending on the transports used. IPFS can multiplex its many protocols through point-to-point connections. This multiplexing is for both -reliable streams and unreliable datagrams. - -IPFS is pragmatic. It seeks to be usable in as many settings as possible, to -be modular and flexible to fit various use cases, and to force as few choices -as possible. Thus the IPFS network layer provides what we're loosely referring -to as "multi-multiplexing": - -- can multiplex multiple listen network interfaces -- can multiplex multiple transport protocols -- can multiplex multiple connections per peer -- can multiplex multiple client protocols -- can multiples multiple streams per protocol, per connection (SPDY, HTTP2, QUIC, SSH) -- has flow control (backpressure, fairness) -- encrypts each connection with a different ephemeral key - -To give an example, imagine a single IPFS node that: - -- listens on a particular TCP/IP address -- listens on a different TCP/IP address -- listens on a SCTP/UDP/IP address -- listens on a UDT/UDP/IP address -- has multiple connections to another node X -- has multiple connections to another node Y -- has multiple streams open per connection -- multiplexes streams over http2 to node X -- multiplexes streams over ssh to node Y -- one IPFS protocol uses one stream per peer -- one IPFS protocol uses multiple streams per peer - -Not providing this level of flexbility makes it impossible to use IPFS in -various platforms, use cases, or network setups. It is not important that all -implementations support all choices; what is critical is that the spec is -flexible enough to allow implementations to use precisely what they need. This -ensures that complex user or application constraints do not rule out IPFS as an -option. - - -## 3. Datastructures - -The network protocol deals with these datastructures: - -- a `PrivateKey`, the private key of a node. -- a `PublicKey`, the public key of a node. -- a `PeerID`, a hash of a node's public key. -- a `Node`[1], has a PeerID, and open connections to other `Nodes`. -- a `Connection`, a point-to-point link between two Nodes (muxes 1 or more streams) -- a `Stream`, a duplex message channel. - -[1] currently called `PeerHost` in go-ipfs. - -## 4. Interface - -The network protocol's interface has two parts:A - -1. the _client interface_, for clients (e.g. higher layers of IPFS) -2. the _service interface_, for remote peers (e.g. other IPFS nodes) - -### 4.1 Client Interface - -The **Client Interface** is exposed to the higher layers of IPFS. It is the entry point for other parts to open + handle streams. - -This type system represents the interface exposed to clients. Actual implementations will likely be more complicated, but they should aim to cover this. - -```go -type PrivateKey interface { - PublicKey() PublicKey - - Sign(data []byte) Signature - Decrypt(ciphertext []byte) (plaintext []byte) -} - -type PublicKey interface { - PeerID() PeerID - - Verify(Signature) (ok bool) - Encrypt(plaintext []byte) (ciphertext []byte) -} - -// PeerID is a hash of a PublicKey, encoded in multihash -// It represents the identity of a node. -type PeerID Multihash - -// Node is a peer in the network. It is both a client and server. -// Users may open streams to remote peers, or set handlers for protocols. -type Node interface { - // ID returns the PeerID of this Node - ID() PeerID - - // NewStream creates a new stream to given peerID. - // It may have to establish a new connection to given peer. - // (This includes finding the addresses of a peer, and NAT Traversal.) - NewStream(Protocol, PeerID) (Stream, error) - - // SetStreamHandler sets a callback for remote-opened streams for a protocol - // Thus clients register "protocol handlers", much like URL route handlers - SetStreamHandler(Protocol, StreamHandler) - - // Raw connections are not exported to the user, only streams. -} - -type StreamHandler func (Stream) -``` - -TODO: incorporate unreliable message / packet streams. - -### 4.2 Protocol Interface - -The network protocol consists of: - -- Any secure, reliable, stream transport: - - a reliable transport protocol (TCP, QUIC, SCTP, UDT, UTP, ...) - - a secure PKI based transport protocol (SSH, TLS, ...) - - a stream transport (with flow control, etc) (HTTP2, SSH, QUIC) -- Protocol stream framing, to multiplex services -- Auxiliary protocols for connectivity: - - Identify - exchange node information - - NAT - NAT Traversal (ICE) - - Relay - for when NAT Traversal fails - -Both the transport and stream muxer are pluggable. Unless -constraints dictate otherwise, implementations SHOULD implement TCP and HTTP/2 -for interoperability. These are the default - -- any reliable transport protocol -- a secure channel encryption -- a stream multiplexor with flow control (e.g. HTTP/2, SPDY, QUIC, SSH) -- every stream protocol header - -(TODO: unreliable transport) - -## 5 Properties - -### 5.1 Communication Model - Streams - -The Network layer handles all the problems of connecting to a peer, and exposes -simple bidirectional streams. Users can both open a new stream -(`NewStream()`) and register a stream handler (`SetStreamHandler`). The user -is then free to implement whatever wire messaging protocol she desires. This -makes it easy to build peer-to-peer protocols, as the complexities of -connectivity, multi-transport support, flow control, and so on, are handled. +> This spec is a Work In Progress (WIP). -To help capture the model, consider that: +# Organization of this document -- `NewStream` is similar to making a Request in an HTTP client. -- `SetStreamHandler` is similar to registering a URL handler in an HTTP server - -So a protocol, such as a DHT, could: - -```go -node := p2p.NewNode(peerid) - -// register a handler, here it is simply echoing everything. -node.SetStreamHandler("/helloworld", func (s Stream) { - io.Copy(s, s) -}) - -// make a request. -buf1 := []byte("Hello World!") -buf2 := make([]byte, len(buf1)) - -stream, _ := node.NewStream("/helloworld", peerid) // open a new stream -stream.Write(buf1) // write to the remote -stream.Read(buf2) // read what was sent back -fmt.Println(buf2) // print what was sent back -``` - -### 5.2 Ports - Constrained Entrypoints - -In the internet of 2015, we have a processing model where a program may be -running without the ability to open multiple -- or even single -- network -ports. Most hosts are behind NAT, whether of household ISP variety or new -containerized data-center type. And some programs may even be running in -browsers, with no ability to open sockets directly (sort of). This presents -challenges to completely peer-to-peer networks who aspire to connect _any_ -hosts together -- whether they're running on a page in the browser, or in -a container within a container. - -IPFS only needs a single channel of communication with the rest of the -network. This may be a single TCP or UDP port, or a single connection -through Websockets or WebRTC. In a sense, the role of the TCP/UDP network -stack -- i.e. multiplexing applications and connections -- may now be forced -to happen at the application level. - -### 5.3 Transport Protocols - -IPFS is transport agnostic. It can run on any transport protocol. The -`ipfs-addr` format (which is an ipfs-specific -[multiaddr](https://github.com/jbenet/multiaddr)) describes the transport. -For example: - -```sh -# ipv4 + tcp -/ip4/10.1.10.10/tcp/29087/ipfs/QmVcSqVEsvm5RR9mBLjwpb2XjFVn5bPdPL69mL8PH45pPC - -# ipv6 + tcp -/ip6/2601:9:4f82:5fff:aefd:ecff:fe0b:7cfe/tcp/1031/ipfs/QmRzjtZsTqL1bMdoJDwsC6ZnDX1PW1vTiav1xewHYAPJNT - -# ipv4 + udp + udt -/ip4/104.131.131.82/udp/4001/udt/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ - -# ipv4 + udp + utp -/ip4/104.131.67.168/udp/1038/utp/ipfs/QmU184wLPg7afQjBjwUUFkeJ98Fp81GhHGurWvMqwvWEQN -``` - -IPFS delegtes the transport dialing to a multiaddr-based network pkg, such -as [go-multiaddr-net](https://github.com/jbenet/go-multiaddr-net). It is -advisable to build modules like this in other languages, and scope the -implementation of other transport protocols. - -Some of the transport protocols we will be using: - -- UTP -- UDT -- SCTP -- WebRTC (SCTP, etc) -- Websockets -- TCP Remy - -### 5.4 Non-IP Networks - -Efforts like [NDN](http://named-data.net) and -[XIA](http://www.cs.cmu.edu/~xia/) are new architectures for the internet, -which are closer to the model IPFS uses than what IP provides today. IPFS -will be able to operate on top of these architectures trivially, as there -is no assumptions made about the network stack in the protocol. Implementations -will likley need to change, but changing implementations is vastly easier than -changing protocols. - -### 5.5 On the wire - -We have the **hard constraint** of making IPFS work across _any_ duplex stream (an outgoing and an incoming stream pair, any arbitrary connection) and work on _any_ platform. - -To make this work, IPFS has to solve a few problems: - -- [Protocol Multiplexing](#protocol-multiplexing) - running multiple protocols over the same stream - - [multistream](#multistream) - self-describing protocol streams - - [multistream-select](#multistream-select) - a self-describing protocol selector - - [Stream Multiplexing](#stream-multiplexing) - running many independent streams over the same wire. -- [Portable Encodings](#portable-encodings) - using portable serialization formats -- [Secure Communications](#secure-communication) - using ciphersuites to establish security and privacy (like TLS). - -#### 5.5.1 Protocol-Multiplexing - -Protocol Multiplexing means running multiple different protocols over the same stream. This could happen sequentially (one after the other), or concurrently (at the same time, with their messages interleaved). We achieve protocol multiplexing using three pieces: - -- [multistream](#multistream) - self-describing protocol streams -- [multistream-select](#multistream-select) - a self-describing protocol selector -- [Stream Multiplexing](#stream-multiplexing) - running many independent streams over the same wire. - -#### 5.5.2 multistream - self-describing protocol stream - -[multistream](https://github.com/jbenet/multistream) is a self-describing protocol stream format. It is extremely simple. Its goal is to define a way to add headers to protocols that describe the protocol itself. It is sort of like adding versions to a protocol, but being extremely explicit. - -For example: - -``` -/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-dht/0.2.3 - - -... -``` - -#### 5.5.3 multistream-selector - self-describing protocol stream selector - -[multistream-select](https://github.com/jbenet/multistream/tree/master/multistream-select) is a simple [multistream](https://github.com/jbenet/multistream) protocol that allows listing and selecting other protocols. This means that Protomux has a list of registered protocols, listens for one, and then _nests_ (or upgrades) the connection to speak the registered protocol. This takes direct advantage of multistream: it enables interleaving multiple protocols, as well as inspecting what protocols might be spoken by the remote endpoint. - -For example: - -``` -/ipfs/QmdRKVhvzyATs3L6dosSb6w8hKuqfZK2SyPVqcYJ5VLYa2/multistream-select/0.3.0 -/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-dht/0.2.3 - - -... -``` - -#### 5.5.4 Stream Multiplexing - -Stream Multiplexing is the process of multiplexing (or combining) many different streams into a single one. This is a complicated subject because it enables protocols to run concurrently over the same wire. And all sorts of notions regarding fairness, flow control, head-of-line blocking, etc. start affecting the protocols. In practice, stream multiplexing is well understood and there are many stream multiplexing protocols. To name a few: - -- HTTP/2 -- SPDY -- QUIC -- SSH - -IPFS nodes are free to support whatever stream multiplexors they wish, on top of the default one. The default one is there to enable even the simplest of nodes to speak multiple protocols at once. The default multiplexor will be HTTP/2 (or maybe QUIC?), but implementations for it are sparse, so we are beginning with SPDY. We simply select which protocol to use with a multistream header. - -For example: - -``` -/ipfs/QmdRKVhvzyATs3L6dosSb6w8hKuqfZK2SyPVqcYJ5VLYa2/multistream-select/0.3.0 -/ipfs/Qmb4d8ZLuqnnVptqTxwqt3aFqgPYruAbfeksvRV1Ds8Gri/spdy/3 - -/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-dht/0.2.3 - - - -/ipfs/QmVXZiejj3sXEmxuQxF2RjmFbEiE9w7T82xDn3uYNuhbFb/ipfs-bitswap/0.3.0 - - - - - - - - - - - - -... -``` - -#### 5.5.5 Portable Encodings - -In order to be ubiquitous, we _must_ use hyper-portable format encodings, those that are easy to use in various other platforms. Ideally these encodings are well-tested in the wild, and widely used. There may be cases where multiple encodings have to be supported (and hence we may need a [multicodec](https://github.com/jbenet/multicodec) self-describing encoding), but this has so far not been needed. - -For now, we use [protobuf](https://github.com/google/protobuf) for all protocol messages exclusively, but other good candidates are [capnp](https://capnproto.org), [bson](http://bsonspec.org/), [ubjson](http://ubjson.org/). - -## 6 Software Stack - -### 6.1 Overview - -### 6.2 Discovery - -goal: find more peers, keep routing table fresh (if Kad-Router is not being used, discovery doens't necessary has a use) - -### 6.3 Peer Routing - -goal: get ref to other peers, that then can be used by swarm to open a stream. Also is free to open streams to other peers to traverse the DHT - -### 6.4 Swarm (aka Connectivity) - -goal: open stream, NAT traversal, Relay - -~~The network is abstracted through the swarm which presents a simplified interface for the remaining layers to have access to the network. This interface should look like:~~ - -- `.openStream(peer, protocol)` - peer should contain the ID of the peer and its respective multiaddrs known. -- `.registerHandler(protocol, handlerFunc)` - enable a protocol to be registered, so that another peer can open a stream to talk with us to that specific protocol -- `.listen()` - to start listening for incoming connections and therefore opening of streams - -The following figure represents how the network level pieces, are tied together: - -``` -┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌───────────┐ - mounted │ mounted │ mounted ││Identify │ -│protocol │protocol │protocol │(mounted │ - 1 │ 2 │ ... ││ protocol) │ -└ ─ ─ ─ ─ └ ─ ─ ─ ─ └ ─ ─ ─ ─ └───────────┘ -┌─────────────────────────────────────────┐ -│ swarm │ -└─────────────────────────────────────────┘ -┌─────────────────────────────────────────┐ -│ connection │ -└─────────────────────────────────────────┘ -┌───────────────┐┌───────────┐┌───────────┐ -│Transport ││multistream││ stream │ -│(TCP, UDP, etc)││ ││ muxer │ -└───────────────┘└───────────┘│┌ ─ ─ ─ ─ ┐│ - │ spdy │ - │└ ─ ─ ─ ─ ┘│ - │┌ ─ ─ ─ ─ ┐│ - │ multiplex │ - │└ ─ ─ ─ ─ ┘│ - │┌ ─ ─ ─ ─ ┐│ - │ QUIC │ - │└ ─ ─ ─ ─ ┘│ - │┌ ─ ─ ─ ─ ┐│ - │ others │ - │└ ─ ─ ─ ─ ┘│ - └───────────┘ -``` - -**Identify** is one of the protocols mounted on top of swarm, our Connection handler, however, it follows and respects the same pattern as any other protocol when it comes to mounting it on top of swarm. Identify enables us to trade listenAddrs and observedAddrs between peers, this is crucial for the working of IPFS, since every socket open implements REUSEPORT, an observedAddr by another peer can enable a third peer to connect to us, since the port will be already open and redirect to us on a NAT. - -The stream muxer must implement the interface offered by [abstract-stream-muxer](https://github.com/diasdavid/abstract-stream-muxer). - -Every socket open (through the transport chosen), is "multistream'ed" into the stream muxer used, once a stream muxer connection - -### 6.5 libp2p - -## 7 Implementation Details - -### 7.1 Discovery - -A discovery service must have return new peers as they are found. It must implement a feature to `verify` if we can open a Connection, using swarm, before returning it as a "new peer found" - -### 7.2 Peer Routing - -### 7.3 Swarm - -Identify stream requests should be issued by the listenner as soon as it receives a valid connection, otherwise the listenner won't be able to identify who is that stream comming, disabling its ability for connection reuse. Identify is responsible for 'tagging' the incomming connection on swarm with the right Id. - -A peer only updates its own multiaddrs list with observedAddrs if it receives the same observedAddr twice, avoiding addr explosion (a phenomenon that happens when both peers are behind symmetric NAT). - -### 7.4 libp2p +This RFC is organized by chapters described on the `Table of Contents` section. Each of the chapters can be found in each own file. +# Table of Contents -## References +- [1 Introduction](/1-introduction.md) + - [1.1 Motivation]() + - [1.2 Goals]() +- [2 Overview of current Network Stack](/2-current-network-stack.md) + - [2.1 Current Shortcommings]() +- [3 Requirements](/3-requirements.md) + - [3.1 NAT traversal] () + - [3.2 Relay]() + - [3.3 Encryption]() + - [3.4 Transport Agnostic]() + - [3.5 Multi-Multiplexing]() +- [4 Architecture](/4-arquitecture.md) + - [4.1 Peer Discovery]() + - [4.2 Peer Routing]() + - [4.3 Swarm]() + - [4.4 Record Store]() +- [5 Datastructures](/5-datastructures.md) +- [6 Interfaces](/6-interfaces.md) + - [6.1 Client Interface]() + - [6.2 Protocol Interface]() +- [7 Properties](/7-properties.md) + - [7.1 Communication Model - Streams]() + - [7.2 Ports - Constrained Entrypoints]() + - [7.3 Transport Protocol]() + - [7.4 Non-IP Networks]() + - [7.5 On the wire]() + - [7.5.1 Protocol-Multiplexing]() + - [7.5.2 multistream - self-describing protocol stream]() + - [7.5.3 multistream-selector - self-describing protocol stream selector]() + - [7.5.4 Stream Multiplexing]() + - [7.5.5 Portable Encodings]() +- [8 Implementations](/8-implementations.md) +- [9 References](/9-references.md) From ec1cea942c4e7c3e888f3331eb35b617d424e7b2 Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 23 Aug 2015 13:44:30 +0100 Subject: [PATCH 21/37] try relative path --- protocol/network/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/network/README.md b/protocol/network/README.md index 90769b6c9..c4ae0e097 100644 --- a/protocol/network/README.md +++ b/protocol/network/README.md @@ -48,7 +48,7 @@ This RFC is organized by chapters described on the `Table of Contents` section. - [6 Interfaces](/6-interfaces.md) - [6.1 Client Interface]() - [6.2 Protocol Interface]() -- [7 Properties](/7-properties.md) +- [7 Properties](7-properties.md) - [7.1 Communication Model - Streams]() - [7.2 Ports - Constrained Entrypoints]() - [7.3 Transport Protocol]() From 29b83fcfca8424fc13a1fa087bf33721e4ea83c3 Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 23 Aug 2015 13:46:01 +0100 Subject: [PATCH 22/37] try relative path --- protocol/network/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocol/network/README.md b/protocol/network/README.md index c4ae0e097..64ea3e5fd 100644 --- a/protocol/network/README.md +++ b/protocol/network/README.md @@ -28,7 +28,7 @@ This RFC is organized by chapters described on the `Table of Contents` section. # Table of Contents -- [1 Introduction](/1-introduction.md) +- [1 Introduction](protocol/network/1-introduction.md) - [1.1 Motivation]() - [1.2 Goals]() - [2 Overview of current Network Stack](/2-current-network-stack.md) @@ -48,7 +48,7 @@ This RFC is organized by chapters described on the `Table of Contents` section. - [6 Interfaces](/6-interfaces.md) - [6.1 Client Interface]() - [6.2 Protocol Interface]() -- [7 Properties](7-properties.md) +- [7 Properties](/7-properties.md) - [7.1 Communication Model - Streams]() - [7.2 Ports - Constrained Entrypoints]() - [7.3 Transport Protocol]() From bf3e6de583f4f6ad2bf197d3da6339005a69d21e Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 23 Aug 2015 13:55:22 +0100 Subject: [PATCH 23/37] fix relative links --- protocol/network/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/protocol/network/README.md b/protocol/network/README.md index 64ea3e5fd..e9949b3d0 100644 --- a/protocol/network/README.md +++ b/protocol/network/README.md @@ -20,7 +20,7 @@ This document defines the spec implemented in libp2p. # Status of this spec -> This spec is a Work In Progress (WIP). +> **This spec is a Work In Progress (WIP).** # Organization of this document @@ -28,27 +28,27 @@ This RFC is organized by chapters described on the `Table of Contents` section. # Table of Contents -- [1 Introduction](protocol/network/1-introduction.md) +- [1 Introduction](1-introduction.md) - [1.1 Motivation]() - [1.2 Goals]() -- [2 Overview of current Network Stack](/2-current-network-stack.md) +- [2 Overview of current Network Stack](2-current-network-stack.md) - [2.1 Current Shortcommings]() -- [3 Requirements](/3-requirements.md) +- [3 Requirements](3-requirements.md) - [3.1 NAT traversal] () - [3.2 Relay]() - [3.3 Encryption]() - [3.4 Transport Agnostic]() - [3.5 Multi-Multiplexing]() -- [4 Architecture](/4-arquitecture.md) +- [4 Architecture](4-arquitecture.md) - [4.1 Peer Discovery]() - [4.2 Peer Routing]() - [4.3 Swarm]() - [4.4 Record Store]() -- [5 Datastructures](/5-datastructures.md) -- [6 Interfaces](/6-interfaces.md) +- [5 Datastructures](5-datastructures.md) +- [6 Interfaces](6-interfaces.md) - [6.1 Client Interface]() - [6.2 Protocol Interface]() -- [7 Properties](/7-properties.md) +- [7 Properties](7-properties.md) - [7.1 Communication Model - Streams]() - [7.2 Ports - Constrained Entrypoints]() - [7.3 Transport Protocol]() @@ -59,5 +59,5 @@ This RFC is organized by chapters described on the `Table of Contents` section. - [7.5.3 multistream-selector - self-describing protocol stream selector]() - [7.5.4 Stream Multiplexing]() - [7.5.5 Portable Encodings]() -- [8 Implementations](/8-implementations.md) -- [9 References](/9-references.md) +- [8 Implementations](8-implementations.md) +- [9 References](9-references.md) From d7faeacf9358fee85a66a9ef2edc7c609572306d Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 23 Aug 2015 14:08:37 +0100 Subject: [PATCH 24/37] add implemenations list --- protocol/network/8-implementations.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/protocol/network/8-implementations.md b/protocol/network/8-implementations.md index 7535458eb..753068197 100644 --- a/protocol/network/8-implementations.md +++ b/protocol/network/8-implementations.md @@ -5,12 +5,36 @@ These are the list of known libp2p, or in another words, the components that res ## 8.1 libp2p +- https://github.com/diasdavid/node-libp2p +- https://github.com/diasdavid/node-ipfs-logger + ## 8.2 Peer Discovery +- https://github.com/diasdavid/node-ipfs-mdns +- https://github.com/diasdavid/node-ipfs-railing +- https://github.com/diasdavid/node-ipfs-random-walk + ## 8.3 Peer Routing +- https://github.com/diasdavid/node-ipfs-kad-router + ## 8.4 Swarm +- https://github.com/diasdavid/node-ipfs-swarm +- https://github.com/diasdavid/node-ipfs-ping +- https://github.com/diasdavid/node-spdy-stream-muxer +- https://github.com/diasdavid/abstract-stream-muxer + ## 8.5 Record Store +- https://github.com/diasdavid/node-ipfs-record +- https://github.com/diasdavid/node-ipfs-record-store + ## 8.6 Data Structures + +- https://github.com/diasdavid/node-ipfs-peer-id +- https://github.com/diasdavid/node-ipfs-peer + +## 8.7 Implementations of Specs libp2p depends on + +- https://github.com/diasdavid/node-multistream From 26cef2d96df755c875bdae0ec3f0bcacf7272018 Mon Sep 17 00:00:00 2001 From: David Dias Date: Tue, 25 Aug 2015 01:36:36 +0100 Subject: [PATCH 25/37] add more juice on the architecture chapter --- protocol/network/4-architecture.md | 128 ++++++++++++------- protocol/network/6-interfaces.md | 55 ++++++++ protocol/network/README.md | 13 +- protocol/network/figs/architecture-1.monopic | Bin 0 -> 1102 bytes protocol/network/figs/architecture-1.txt | 6 + protocol/network/figs/peer-routing.monopic | Bin 0 -> 1428 bytes protocol/network/figs/peer-routing.txt | 19 +++ 7 files changed, 170 insertions(+), 51 deletions(-) create mode 100644 protocol/network/figs/architecture-1.monopic create mode 100644 protocol/network/figs/architecture-1.txt create mode 100644 protocol/network/figs/peer-routing.monopic create mode 100644 protocol/network/figs/peer-routing.txt diff --git a/protocol/network/4-architecture.md b/protocol/network/4-architecture.md index d9f61cf08..4b954c8c0 100644 --- a/protocol/network/4-architecture.md +++ b/protocol/network/4-architecture.md @@ -1,72 +1,110 @@ 4 Architecture ============== -libp2p was designed around the Unix Philosophy, creating smaller components, easier to understand and to test that can be swapped or added in order to accomodate different technologies or scenarios and also make it that it is upgradable over time. +libp2p was designed around the Unix Philosophy, creating smaller components, easier to understand and to test. These components should also be able to be swapped in order to accomodate different technologies or scenarios and also make it that it is upgradable over time. + Although different Peers can support different protocols depending on their capabilities, any Peer can act as a dialer and/or a listener for connections from other Peers, connections that once established can be reused from both ends, removing the distinction between clients and servers. -libp2p interface acts as a thin veneer to four subsystems that are required in order for peers to be able to communicate. These subsystems are allowed to be built on top of other subsystems as long as they respect the standardized interface. The main 4 subsystems are: +libp2p interface acts as a thin veneer to three subsystems that are required in order for peers to be able to communicate. These subsystems are allowed to be built on top of other subsystems as long as they respect the standardized interface. The main 3 subsystems are: -- Peer Discovery - Ability to discovery of new peers in the network, so that a routing table can be generated and refreshed. - Peer Routing - Mechanism to find a Peer in a network. This Routing can be done recursively, iteratively or even in a broadcast/multicast mode. - Swarm - Handles everything that touches the 'opening a stream' part of libp2p, from protocol muxing, stream muxing, NAT Traversal, Connection Relaying, while being multitransport -- Record Store - A system to store provider records and relay recordes +- Distributed Record Store - A system to store provider records and relay records + +Each of these subsystem exposes a well known interface (see chapter 6 for Interfaces) and may use eachother in order to fulfil their goal. A global overview of the system is: + +``` +┌─────────────────────────────────────────────────────────────────────────────────┐ +│ libp2p │ +└─────────────────────────────────────────────────────────────────────────────────┘ +┌─────────────────────────┐┌──────────────────────────┐┌──────────────────────────┐ +│ Peer Routing ││ Swarm ││ Distributed Record Store │ +└─────────────────────────┘└──────────────────────────┘└──────────────────────────┘ +``` -## 4.1 Peer Discovery +## 4.1 Peer Routing -> goal: find more peers, keep routing table fresh (if Kad-Router is not being used, discovery doens't necessary has a use) +A Peer Routing subsystem, exposes an interface to identify which peers should a message be routed in the DHT. It receives a key and must return one or more PeerInfo objects. -## 4.2 Peer Routing +We present two examples of possible Peer Routing subsystems, the first based on a the Kademlia DHT and the second based on mDNS. Nevertheless, other Peer Routing mechanisms might be implemented, as long as they fulfil the same expectation and interface. -> goal: get ref to other peers, that then can be used by swarm to open a stream. Also is free to open streams to other peers to traverse the DHT -## 4.3 Swarm -goal: open stream, NAT traversal, Relay -~~The network is abstracted through the swarm which presents a simplified interface for the remaining layers to have access to the network. This interface should look like:~~ +### 4.1.1 kad-routing -- `.openStream(peer, protocol)` - peer should contain the ID of the peer and its respective multiaddrs known. -- `.registerHandler(protocol, handlerFunc)` - enable a protocol to be registered, so that another peer can open a stream to talk with us to that specific protocol -- `.listen()` - to start listening for incoming connections and therefore opening of streams +kad-routing implements the Kademlia Routing table, where each peer holds a set of k-buckets, each of them containing several PeerInfo from other peers in the network. In order to find the whereabouts of these peers, it implements 3 discovery mechanisms: -The following figure represents how the network level pieces, are tied together: +- mDNS-discovery +- random-walk +- bootstrap-list ``` -┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌───────────┐ - mounted │ mounted │ mounted ││Identify │ -│protocol │protocol │protocol │(mounted │ - 1 │ 2 │ ... ││ protocol) │ -└ ─ ─ ─ ─ └ ─ ─ ─ ─ └ ─ ─ ─ ─ └───────────┘ -┌─────────────────────────────────────────┐ -│ swarm │ -└─────────────────────────────────────────┘ -┌─────────────────────────────────────────┐ -│ connection │ -└─────────────────────────────────────────┘ -┌───────────────┐┌───────────┐┌───────────┐ -│Transport ││multistream││ stream │ -│(TCP, UDP, etc)││ ││ muxer │ -└───────────────┘└───────────┘│┌ ─ ─ ─ ─ ┐│ - │ spdy │ - │└ ─ ─ ─ ─ ┘│ - │┌ ─ ─ ─ ─ ┐│ - │ multiplex │ - │└ ─ ─ ─ ─ ┘│ - │┌ ─ ─ ─ ─ ┐│ - │ QUIC │ - │└ ─ ─ ─ ─ ┘│ - │┌ ─ ─ ─ ─ ┐│ - │ others │ - │└ ─ ─ ─ ─ ┘│ - └───────────┘ +┌────────────────────────────────────────────────────────────────┐ +│ Peer Routing │ +│┌──────────────────────────────────────────────────────────────┐│ +││ kad-routing ┌──────────────┐┌──────────────┐┌──────────────┐ ││ +││ │mDNS-discovery││random-walk ││bootstrap-list│ ││ +││ └──────────────┘└──────────────┘└──────────────┘ ││ +│└──────────────────────────────────────────────────────────────┘│ +│┌──────────────────────────────────────────────────────────────┐│ +││ mDNS-routing ││ +│└──────────────────────────────────────────────────────────────┘│ +│┌──────────────────────────────────────────────────────────────┐│ +││ other-routing-mechanisms ││ +│└──────────────────────────────────────────────────────────────┘│ +└────────────────────────────────────────────────────────────────┘ ``` -**Identify** is one of the protocols mounted on top of swarm, our Connection handler, however, it follows and respects the same pattern as any other protocol when it comes to mounting it on top of swarm. Identify enables us to trade listenAddrs and observedAddrs between peers, this is crucial for the working of IPFS, since every socket open implements REUSEPORT, an observedAddr by another peer can enable a third peer to connect to us, since the port will be already open and redirect to us on a NAT. +#### 4.1.1.1 mDNS-discovery + +mDNS-discovery uses mDNS to emit beacons in the local area network to find if there are more peers available, these peers are extremely interesting because our link to them will have an low latency, plus if we are disconnected from the network, we will be leverage the content on those peers have cached. + +#### 4.1.1.2 random-walk + +Random walking consists on traversing the routing tables of the peers available in the network, learning about new peers along the way. + +#### 4.1.1.3 bootstrap-list + +A predefined set of peers available on the network in well known locations, so that a new created node can easily find more peers to connect in the network. + +### 4.1.2 mDNS-routing + +mDNS-routing uses mDNS probes to identify if local area network peers that have a given key or simply are present. + +## 4.2 Swarm + + +### 4.2.1 Stream Muxer The stream muxer must implement the interface offered by [abstract-stream-muxer](https://github.com/diasdavid/abstract-stream-muxer). -Every socket open (through the transport chosen), is "multistream'ed" into the stream muxer used, once a stream muxer connection +### 4.2.2 Protocol Muxer + +### 4.2.3 Transport + +### 4.2.4 Crypto + +### 4.2.5 Identify + +**Identify** is one of the protocols mounted on top of swarm, our Connection handler, however, it follows and respects the same pattern as any other protocol when it comes to mounting it on top of swarm. Identify enables us to trade listenAddrs and observedAddrs between peers, this is crucial for the working of IPFS, since every socket open implements REUSEPORT, an observedAddr by another peer can enable a third peer to connect to us, since the port will be already open and redirect to us on a NAT. + +### 4.2.6 Relay + + + +## 4.3 Distributed Record Store + +### 4.3.1 Record + +Follows [IPRS](https://github.com/ipfs/specs/tree/master/records) + +### 4.3.2 abstract-record-store + +### 4.3.3 kad-record-store + +### 4.3.4 mDNS-record-store -## 4.4 Record Store +### 4.3.5 s3-record-store diff --git a/protocol/network/6-interfaces.md b/protocol/network/6-interfaces.md index b54ea1c0e..5476a6903 100644 --- a/protocol/network/6-interfaces.md +++ b/protocol/network/6-interfaces.md @@ -1,6 +1,61 @@ 6 Interfaces ============ +## 6.1 libp2p + +## 6.2 Peer Routing + +## 6.3 Swarm + +~~The network is abstracted through the swarm which presents a simplified interface for the remaining layers to have access to the network. This interface should look like:~~ + +- `.openStream(peer, protocol)` - peer should contain the ID of the peer and its respective multiaddrs known. +- `.registerHandler(protocol, handlerFunc)` - enable a protocol to be registered, so that another peer can open a stream to talk with us to that specific protocol +- `.listen()` - to start listening for incoming connections and therefore opening of streams + +The following figure represents how the network level pieces, are tied together: + +``` +┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌ ─ ─ ─ ─ ┌───────────┐ + mounted │ mounted │ mounted ││Identify │ +│protocol │protocol │protocol │(mounted │ + 1 │ 2 │ ... ││ protocol) │ +└ ─ ─ ─ ─ └ ─ ─ ─ ─ └ ─ ─ ─ ─ └───────────┘ +┌─────────────────────────────────────────┐ +│ swarm │ +└─────────────────────────────────────────┘ +┌─────────────────────────────────────────┐ +│ connection │ +└─────────────────────────────────────────┘ +┌───────────────┐┌───────────┐┌───────────┐ +│Transport ││multistream││ stream │ +│(TCP, UDP, etc)││ ││ muxer │ +└───────────────┘└───────────┘│┌ ─ ─ ─ ─ ┐│ + │ spdy │ + │└ ─ ─ ─ ─ ┘│ + │┌ ─ ─ ─ ─ ┐│ + │ multiplex │ + │└ ─ ─ ─ ─ ┘│ + │┌ ─ ─ ─ ─ ┐│ + │ QUIC │ + │└ ─ ─ ─ ─ ┘│ + │┌ ─ ─ ─ ─ ┐│ + │ others │ + │└ ─ ─ ─ ─ ┘│ + └───────────┘ +``` + +## 6.4 Distributed Record Store + + + + + + + + +---------------------------- +OLD The network protocol's interface has two parts:A 1. the _client interface_, for clients (e.g. higher layers of IPFS) diff --git a/protocol/network/README.md b/protocol/network/README.md index e9949b3d0..84e1eaa01 100644 --- a/protocol/network/README.md +++ b/protocol/network/README.md @@ -40,14 +40,15 @@ This RFC is organized by chapters described on the `Table of Contents` section. - [3.4 Transport Agnostic]() - [3.5 Multi-Multiplexing]() - [4 Architecture](4-arquitecture.md) - - [4.1 Peer Discovery]() - - [4.2 Peer Routing]() - - [4.3 Swarm]() - - [4.4 Record Store]() + - [4.1 Peer Routing]() + - [4.2 Swarm]() + - [4.3 Distributed Record Store]() - [5 Datastructures](5-datastructures.md) - [6 Interfaces](6-interfaces.md) - - [6.1 Client Interface]() - - [6.2 Protocol Interface]() + - [6.1 libp2p]() + - [6.2 Peer Routing]() + - [6.3 Swarm]() + - [6.4 Distributed Record Store]() - [7 Properties](7-properties.md) - [7.1 Communication Model - Streams]() - [7.2 Ports - Constrained Entrypoints]() diff --git a/protocol/network/figs/architecture-1.monopic b/protocol/network/figs/architecture-1.monopic new file mode 100644 index 0000000000000000000000000000000000000000..64c392c527dd663d3766425f515d1bd4018c0414 GIT binary patch literal 1102 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 literal 0 HcmV?d00001 diff --git a/protocol/network/figs/peer-routing.txt b/protocol/network/figs/peer-routing.txt new file mode 100644 index 000000000..4de2fbb47 --- /dev/null +++ b/protocol/network/figs/peer-routing.txt @@ -0,0 +1,19 @@ +┌────────────────────────────────────────────────────────────────┐ +│ Peer Routing │ +│ │ +│┌──────────────────────────────────────────────────────────────┐│ +││ kad-routing ┌──────────────┐┌──────────────┐┌──────────────┐ ││ +││ │mDNS-discovery││random-walk ││bootstrap-list│ ││ +││ └──────────────┘└──────────────┘└──────────────┘ ││ +│└──────────────────────────────────────────────────────────────┘│ +│┌──────────────────────────────────────────────────────────────┐│ +││ mDNS-routing ││ +││ ││ +││ ││ +│└──────────────────────────────────────────────────────────────┘│ +│┌──────────────────────────────────────────────────────────────┐│ +││ other-routing-mechanisms ││ +││ ││ +││ ││ +│└──────────────────────────────────────────────────────────────┘│ +└────────────────────────────────────────────────────────────────┘ \ No newline at end of file From 9bd5e6909a4f58f7dabfe82c2e36a4a6ff79a5af Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 13 Sep 2015 12:54:39 +0100 Subject: [PATCH 26/37] add stream muxing and protocol muxing notes --- protocol/network/4-architecture.md | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/protocol/network/4-architecture.md b/protocol/network/4-architecture.md index 4b954c8c0..35e9adfc9 100644 --- a/protocol/network/4-architecture.md +++ b/protocol/network/4-architecture.md @@ -28,9 +28,6 @@ A Peer Routing subsystem, exposes an interface to identify which peers should a We present two examples of possible Peer Routing subsystems, the first based on a the Kademlia DHT and the second based on mDNS. Nevertheless, other Peer Routing mechanisms might be implemented, as long as they fulfil the same expectation and interface. - - - ### 4.1.1 kad-routing kad-routing implements the Kademlia Routing table, where each peer holds a set of k-buckets, each of them containing several PeerInfo from other peers in the network. In order to find the whereabouts of these peers, it implements 3 discovery mechanisms: @@ -72,15 +69,25 @@ A predefined set of peers available on the network in well known locations, so t mDNS-routing uses mDNS probes to identify if local area network peers that have a given key or simply are present. -## 4.2 Swarm + + + + + +## 4.2 Swarm + ### 4.2.1 Stream Muxer The stream muxer must implement the interface offered by [abstract-stream-muxer](https://github.com/diasdavid/abstract-stream-muxer). ### 4.2.2 Protocol Muxer +Protocol muxing is handled on the application level instead of the conventional way at the port level (where a different services/protocols listen at different ports). This enables us to support several protocols to be muxed in the same socket, saving the cost of doing NAT traversal for more than one port. + +Protocol multiplexing is done through [`multistream`](https://github.com/jbenet/multistream), a protocol to negoatiate different types of streams (protocols) using [`multicodec`](https://github.com/jbenet/multicodec) + ### 4.2.3 Transport ### 4.2.4 Crypto @@ -93,6 +100,15 @@ The stream muxer must implement the interface offered by [abstract-stream-muxer] + + + + + + + + + ## 4.3 Distributed Record Store ### 4.3.1 Record From 4fe489a23892177e9eed315510c38379b623a060 Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 27 Sep 2015 02:51:20 +0100 Subject: [PATCH 27/37] add pseudo logo --- protocol/network/figs/logo.png | Bin 0 -> 9445 bytes protocol/network/figs/logo.sketch | Bin 0 -> 24576 bytes protocol/network/figs/logo.svg | 13 +++++++++++++ 3 files changed, 13 insertions(+) create mode 100644 protocol/network/figs/logo.png create mode 100644 protocol/network/figs/logo.sketch create mode 100644 protocol/network/figs/logo.svg diff --git a/protocol/network/figs/logo.png b/protocol/network/figs/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..368108591059d3b26d446ba07fe66fa8ae301631 GIT binary patch literal 9445 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 a$NP?t9j6_iE4iLw`j3^$ap2W)=05<$)+fIJ literal 0 HcmV?d00001 diff --git a/protocol/network/figs/logo.svg b/protocol/network/figs/logo.svg new file mode 100644 index 000000000..7025a36c8 --- /dev/null +++ b/protocol/network/figs/logo.svg @@ -0,0 +1,13 @@ + + + + logo + Created with Sketch. + + + + lib + p2p + + + \ No newline at end of file From 2a51b32aeb58e22f8153ed64907caadd0073b512 Mon Sep 17 00:00:00 2001 From: David Dias Date: Thu, 1 Oct 2015 01:52:33 +0100 Subject: [PATCH 28/37] update requirements references and add .6 and .7 --- protocol/network/2-current-network-stack.md | 0 protocol/network/2-state-of-the-art.md | 5 ++ protocol/network/3-requirements.md | 56 +++++++++++---------- 3 files changed, 35 insertions(+), 26 deletions(-) delete mode 100644 protocol/network/2-current-network-stack.md create mode 100644 protocol/network/2-state-of-the-art.md diff --git a/protocol/network/2-current-network-stack.md b/protocol/network/2-current-network-stack.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/protocol/network/2-state-of-the-art.md b/protocol/network/2-state-of-the-art.md new file mode 100644 index 000000000..a5bcad585 --- /dev/null +++ b/protocol/network/2-state-of-the-art.md @@ -0,0 +1,5 @@ +2 An analysis the State of the Art in Network Stacks +==================================================== + +- Illustrate with the client server model and all the network steps for a connection actually happen +then move into de dialer-listener mode diff --git a/protocol/network/3-requirements.md b/protocol/network/3-requirements.md index 742c33a3c..8bff9c696 100644 --- a/protocol/network/3-requirements.md +++ b/protocol/network/3-requirements.md @@ -1,43 +1,42 @@ -3 Requirements -============== +3 Requirements and considerations +================================= ## 3.1 NAT traversal Network Address Translation is ubiquitous in the internet. Not only are most consumer devices behind many layers of NATs, but most datacenter nodes are often behind NAT for security or virtualization reasons. As we move into containerized deployments, this is getting worse. IPFS implementations SHOULD provide a way to traverse NATs, otherwise it is likely that operation will be affected. Even nodes meant to run with real IP addresses must implement NAT traversal techniques, as they may need to establish connections to peers behind NAT. -IPFS accomplishes full NAT traversal using an ICE-like protocol. It is not exactly ICE, as ipfs networks provide the possibility of relaying communications over the IPFS protocol itself, for coordinating hole-punching or even relaying communication. +libp2p accomplishes full NAT traversal using an ICE-like protocol. It is not exactly ICE, as ipfs networks provide the possibility of relaying communications over the IPFS protocol itself, for coordinating hole-punching or even relaying communication. It is recommended that implementations use one of the many NAT traversal libraries available, such as `libnice`, `libwebrtc`, or `natty`. However, NAT traversal must be interoperable. ## 3.2 Relay -Unfortunately, due to symmetric NATs, container and VM NATs, and other impossible-to-bypass NATs, IPFS MUST fallback to relaying communication to establish a full connectivity graph. To be complete, implementations MUST support relay, though it SHOULD be optional and able to be turned off by end users. +Unfortunately, due to symmetric NATs, container and VM NATs, and other impossible-to-bypass NATs, libp2p MUST fallback to relaying communication to establish a full connectivity graph. To be complete, implementations MUST support relay, though it SHOULD be optional and able to be turned off by end users. ## 3.3 Encryption -Communications on IPFS may be: +Communications on libp2p may be: - **encrypted** - **signed** (not encrypted) - **clear** (not encrypted, not signed) -We take both security and performance seriously. We recognize that encryption -is not viable for some in-datacenter high performance use cases. +We take both security and performance seriously. We recognize that encryption is not viable for some in-datacenter high performance use cases. We recommend that: - implementations encrypt all communications by default - implementations are audited - unless absolutely necessary, users normally operate with encrypted communications only. -IPFS uses cyphersuites like TLS. +libp2p uses cyphersuites like TLS. -**NOTE:** we do not use TLS directly, because we do not want the CA system baggage. Most TLS implementations are very big. Since the IPFS model begins with keys, IPFS only needs to apply ciphers. This is a minimal portion of the whole TLS standard. +**NOTE:** we do not use lib2p directly, because we do not want the CA system baggage. Most libp2p implementations are very big. Since the lib2p model begins with keys, libp2p only needs to apply ciphers. This is a minimal portion of the whole TLS standard. ## 3.4 Transport Agnostic -IPFS is transport agnostic, so it can run over any transport protocol. It does not even depend on IP; it may run on top of NDN, XIA, and other new internet architectures. +libp2p is transport agnostic, so it can run over any transport protocol. It does not even depend on IP; it may run on top of NDN, XIA, and other new internet architectures. -In order to reason about possible transports, IPFS uses [multiaddr](https://github.com/jbenet/multiaddr), a self-describing addressing format. This makes it possible for IPFS to treat addresses opaquely everywhere in the system, and have support various transport protocols in the network layer. The actual format of addresses in IPFS is `ipfs-addr`, a multiaddr that ends with an ipfs nodeid. For example, these are all valid `ipfs-addrs`: +In order to reason about possible transports, libp2p uses [multiaddr](https://github.com/jbenet/multiaddr), a self-describing addressing format. This makes it possible for libp2p to treat addresses opaquely everywhere in the system, and have support various transport protocols in the network layer. The actual format of addresses in libp2p is `ipfs-addr`, a multiaddr that ends with an ipfs nodeid. For example, these are all valid `ipfs-addrs`: ``` # ipfs over tcp over ipv6 (typical tcp) @@ -62,13 +61,9 @@ In order to reason about possible transports, IPFS uses [multiaddr](https://gith ## 3.5 Multi-Multiplexing -The IPFS Protocol is a collection of multiple protocols available at the same IPFS Node. In order to conserve resources, and to make connectivity easier, the IPFS network layer can perform all its operations through a single TCP or UDP port, depending on the transports used. IPFS can multiplex its many protocols through point-to-point connections. This multiplexing is for both -reliable streams and unreliable datagrams. +The libp2p Protocol is a collection of multiple protocols. In order to conserve resources, and to make connectivity easier, libp2p can perform all its operations through a single port, such as TCP or UDP port, depending on the transports used. libp2p can multiplex its many protocols through point-to-point connections. This multiplexing is for both reliable streams and unreliable datagrams. -IPFS is pragmatic. It seeks to be usable in as many settings as possible, to -be modular and flexible to fit various use cases, and to force as few choices -as possible. Thus the IPFS network layer provides what we're loosely referring -to as "multi-multiplexing": +libp2p is pragmatic. It seeks to be usable in as many settings as possible, to be modular and flexible to fit various use cases, and to force as few choices as possible. Thus the libp2p network layer provides what we're loosely referring to as "multi-multiplexing": - can multiplex multiple listen network interfaces - can multiplex multiple transport protocols @@ -89,12 +84,21 @@ To give an example, imagine a single IPFS node that: - has multiple streams open per connection - multiplexes streams over http2 to node X - multiplexes streams over ssh to node Y -- one IPFS protocol uses one stream per peer -- one IPFS protocol uses multiple streams per peer - -Not providing this level of flexbility makes it impossible to use IPFS in -various platforms, use cases, or network setups. It is not important that all -implementations support all choices; what is critical is that the spec is -flexible enough to allow implementations to use precisely what they need. This -ensures that complex user or application constraints do not rule out IPFS as an -option. +- one protocol mounted on top of libp2p uses one stream per peer +- one protocol mounted on top of libp2p uses multiple streams per peer + +Not providing this level of flexbility makes it impossible to use libp2p in various platforms, use cases, or network setups. It is not important that all implementations support all choices; what is critical is that the spec is flexible enough to allow implementations to use precisely what they need. This ensures that complex user or application constraints do not rule out libp2p as an option. + +## 3.6 Enable several network topologies + +Differents systems have different requirements and with that comes different topologies. In the P2P literature we can find these topologies being enumerated as: Unstructured, Structured, Hybrid and Centralised. + +Centralised topologies are the most common to find in Web Applications infrastructures, it requires for a given service or services to be present at all times in a known static location, so that other services can access them. Unstructured networks represent a type of P2P networks where the network topology is completely random, or at least non deterministic, while structured networks have a implicit way of organizing themselves, hybrid networks are a mix of the last two. + +With this in consideration, libp2p must be ready to perform different routing mechanisms and peer discovery, in order to build the routing tables that will enable services to propagate messages or to find each other. + +## 3.7 Resource Discovery + +libp2p also solves the problem with discoverability of resources inside of a network through Records, a record is a unit of data that can be digitally signed, timestamp and/or used with other methods to give it a ephemeral validity. These Records hold pieces of information, such as location of availability of resources present in the network, these resources can be data, storage, CPU cycles and other types of services. + +libp2p must not put a constraint on the location of resources, instead offer ways to find them easily in the network or use a sidechannel. From f94e004d9d932e74f0bdeb715e63601db1e69710 Mon Sep 17 00:00:00 2001 From: David Dias Date: Thu, 1 Oct 2015 04:30:14 +0100 Subject: [PATCH 29/37] add content to chapter 2 --- protocol/network/2-state-of-the-art.md | 69 +++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/protocol/network/2-state-of-the-art.md b/protocol/network/2-state-of-the-art.md index a5bcad585..979055edc 100644 --- a/protocol/network/2-state-of-the-art.md +++ b/protocol/network/2-state-of-the-art.md @@ -1,5 +1,70 @@ 2 An analysis the State of the Art in Network Stacks ==================================================== -- Illustrate with the client server model and all the network steps for a connection actually happen -then move into de dialer-listener mode +This section presents to the reader an analysis of the available protocols and arquitectures for a Network Stack. The goal is to provide the foundations from which to infer the conclusions and understand what are libp2p requirements and its designed arquitecture. + +## 2.1 The client-server model + +The client-server model indicates that both parties that ends of the channel have different roles, that support different services and/or have different capabilities, or in another words, speak different protocols. + +Building client-server applications has been natural tendency for a number of reasons: + +- The bandwidth inside a DataCenter is considerably high compared to the one available for clients to connect between each other +- DataCenter resources are considerably cheaper, due to efficient usage and bulk stocking +- Enables easier methods for the developer and system admin to have a fine grained control over the application +- Reduces the number of heteregeneus systems to be handled (although it is still considerably high) +- Systems like NAT make it really hard for client machines to find and talk with each other, forcing a developer to perform very clever hacks to traverse these obstacles. +- Protocols started to be designed with the assumption that a developer will create a client-server application from the start. + +We even learned how to hide all of the complexity of a distributed system behind gateways on the Internet, using protocols that were designed to perform a point-to-point operation, such as HTTP, making it opaque for the application to see and understand how the cascade of service calls made for each request. + +`libp2p` offers a move towards dialer-listener interactions, from the client-server listener, where it is not implicit which of the entities, dialer or listener, has which capabilities or is enabled to perform which actions. Setting up a connection between two applications today is a multilayered problem to solve, and these connections should not have a purpose bias, instead support to several other protocols to work on top of the established connection. In a client-server model, a server sending data without a prior request from the client is known as a push model, which typically adds more complexity, in a dialer-listener model, both entities can perform requests independently. + +## 2.2 Categorizing the network stack protocols by solutions + +### 2.2.1 Establishing the phisical Link + +- ethernet +- wifi +- bluetooth +- usb + +### 2.2.2 Addressing a machine or process + +- IPv4 +- IPv6 +- Hidden Addressing, like SDP + +### 2.2.3 Discovering other peers or services + +- ARP +- DHCP +- DNS + +### 2.2.4 Routing messages through the Network + +- RIP(1, 2) +- OSPF +- PPP + +### 2.2.5 Transport + +- TCP +- UDP +- UDT +- QUIC +- WebRTC DataChannel + +### 2.2.6 Agreed semantics for applications to talk to each other + +- RMI +- Remoting +- RPC +- HTTP + + +## 2.3 Current Shortcommings + +Although we currently have a panoply of protocols available for our services the communicate, the abundance and the variety of solutions is also its shortfall. It is currently dificult for an application to be able to support and be available through several transports (for e.g. the lack of TCP/UDP stack in browser applications). + +There is also no 'presence linking', meaning that isn't a notion for a peer to announce itself in several transports, so that other peer can guarantee that it is always the same peer. From 33000b3983089e6afa0ba19f8b9c8f72c45c3b5a Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 2 Oct 2015 00:43:53 +0100 Subject: [PATCH 30/37] add Juan's review --- protocol/network/1-introduction.md | 9 +++-- protocol/network/2-state-of-the-art.md | 12 ++++-- protocol/network/4-architecture.md | 44 ++++++++++++--------- protocol/network/figs/peer-routing.monopic | Bin 1428 -> 1094 bytes protocol/network/figs/peer-routing.txt | 28 +++++-------- 5 files changed, 49 insertions(+), 44 deletions(-) diff --git a/protocol/network/1-introduction.md b/protocol/network/1-introduction.md index 014c0125a..774bdc9b5 100644 --- a/protocol/network/1-introduction.md +++ b/protocol/network/1-introduction.md @@ -7,15 +7,17 @@ In order to build this library, we focused on tackling problems independently, c ## 1.1 Motivation -`libp2p` is the result of the collective experience while building a distributed system, that puts the responsability on the developers on how they want their app to interop with others in the network, favoring configuration and extensibility instead of assumptions about how the network setup. +`libp2p` is the result of the collective experience while building a distributed system, that puts the responsability on the developers on how they want their app to interop with others in the network, favoring configuration and extensibility instead of assumptions about the network setup. -In essence, a peer using libp2p should be able to communicate with another peer using different transports, including connection relay, and talk over different protocols, negotiated in demand. +In essence, a peer using libp2p should be able to communicate with another peer using different transports, including connection relay, and talk over different protocols, negotiated on demand. ## 1.2 Goals Our goals for libp2p specification and its implementations are: -- Enable the use of various transports (TCP, UDP, DTLS, uTP, etc) +- Enable the use of various: + - transports: TCP, UDP, SCTP, UDT, uTP, QUIC, SSH, etc. + - authenticated transports: TLS, DTLS, CurveCP, SSH - Efficient use of sockets (connection reuse) - Enable communications between peers to be multiplex over one socket (avoiding handshake overhead) - Enable multiprotocols and respective versions to be used between peers, using a negotiation process. @@ -25,3 +27,4 @@ Our goals for libp2p specification and its implementations are: - Have NAT Traversal - Enable connections to be relayed - Enable encrypted channels +- Efficient use of underlying transport (e.g. native stream muxing, native auth, etc) diff --git a/protocol/network/2-state-of-the-art.md b/protocol/network/2-state-of-the-art.md index 979055edc..c0ae5af34 100644 --- a/protocol/network/2-state-of-the-art.md +++ b/protocol/network/2-state-of-the-art.md @@ -1,7 +1,7 @@ 2 An analysis the State of the Art in Network Stacks ==================================================== -This section presents to the reader an analysis of the available protocols and arquitectures for a Network Stack. The goal is to provide the foundations from which to infer the conclusions and understand what are libp2p requirements and its designed arquitecture. +This section presents to the reader an analysis of the available protocols and architectures for a Network Stack. The goal is to provide the foundations from which to infer the conclusions and understand what are libp2p requirements and its designed architecture. ## 2.1 The client-server model @@ -22,7 +22,11 @@ We even learned how to hide all of the complexity of a distributed system behind ## 2.2 Categorizing the network stack protocols by solutions -### 2.2.1 Establishing the phisical Link +Before diving into the libp2p protocols, it is important to understand the large diversity of protocols already in wide use and deployment that help maintain today's simple abstractions. For example, when one thinks about an HTTP connection, one might naively just think HTTP/TCP/IP as the main protocols involved, but in reality many more participate, all depending on the usage, the networks involved, and so on. Protocols like DNS, DHCP, ARP, OSPF, Ethernet, 802.11 (WiFI), ... and many others get involved. Looking inside ISPs' own networks would reveal dozens more. + +Additionally, it's worth noting that the traditional 7-layer OSI model characterization does not fit libp2p. Instead, we categorize protocols based on their role, the problem they solve. The upper layers of the OSI model are geared towards point-to-point links between applications, whereas the libp2p protocols speak more towards various sizes of networks, with various properties, under various different security models. Different libp2p protocols can have the same role (in the OSI model, this would be "address the same layer"), meaning that multiple protocols can run simultaneously, all addressing one role (instead of one-protocol-per-layer in traditional OSI stacking) For example, bootstrap lists, mDNS, DHT Discovery, and PEX are all forms of the role "Peer Discovery"; they can coexist and even synergize. + +### 2.2.1 Establishing the physical Link - ethernet - wifi @@ -44,8 +48,10 @@ We even learned how to hide all of the complexity of a distributed system behind ### 2.2.4 Routing messages through the Network - RIP(1, 2) -- OSPF +- OSP - PPP +- Tor +- I2P ### 2.2.5 Transport diff --git a/protocol/network/4-architecture.md b/protocol/network/4-architecture.md index 35e9adfc9..8f36fb6c1 100644 --- a/protocol/network/4-architecture.md +++ b/protocol/network/4-architecture.md @@ -9,7 +9,7 @@ libp2p interface acts as a thin veneer to three subsystems that are required in - Peer Routing - Mechanism to find a Peer in a network. This Routing can be done recursively, iteratively or even in a broadcast/multicast mode. - Swarm - Handles everything that touches the 'opening a stream' part of libp2p, from protocol muxing, stream muxing, NAT Traversal, Connection Relaying, while being multitransport -- Distributed Record Store - A system to store provider records and relay records +- Distributed Record Store - A system to store and distribute records. Records are small entries used by other systems for signaling, establishing links, announcing peers or content, and so on. It has a similar role to DNS in the broader internet. Each of these subsystem exposes a well known interface (see chapter 6 for Interfaces) and may use eachother in order to fulfil their goal. A global overview of the system is: @@ -26,7 +26,7 @@ Each of these subsystem exposes a well known interface (see chapter 6 for Interf A Peer Routing subsystem, exposes an interface to identify which peers should a message be routed in the DHT. It receives a key and must return one or more PeerInfo objects. -We present two examples of possible Peer Routing subsystems, the first based on a the Kademlia DHT and the second based on mDNS. Nevertheless, other Peer Routing mechanisms might be implemented, as long as they fulfil the same expectation and interface. +We present two examples of possible Peer Routing subsystems, the first based on a the Kademlia DHT and the second based on mDNS. Nevertheless, other Peer Routing mechanisms can be implemented, as long as they fulfil the same expectation and interface. ### 4.1.1 kad-routing @@ -37,33 +37,39 @@ kad-routing implements the Kademlia Routing table, where each peer holds a set o - bootstrap-list ``` -┌────────────────────────────────────────────────────────────────┐ -│ Peer Routing │ -│┌──────────────────────────────────────────────────────────────┐│ -││ kad-routing ┌──────────────┐┌──────────────┐┌──────────────┐ ││ -││ │mDNS-discovery││random-walk ││bootstrap-list│ ││ -││ └──────────────┘└──────────────┘└──────────────┘ ││ -│└──────────────────────────────────────────────────────────────┘│ -│┌──────────────────────────────────────────────────────────────┐│ -││ mDNS-routing ││ -│└──────────────────────────────────────────────────────────────┘│ -│┌──────────────────────────────────────────────────────────────┐│ -││ other-routing-mechanisms ││ -│└──────────────────────────────────────────────────────────────┘│ -└────────────────────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────────────────┐ +│ Peer Routing │ +│ │ +│┌──────────────┐┌────────────────┐┌──────────────────────────┐│ +││ kad-routing ││ mDNS-routing ││ other-routing-mechanisms ││ +││ ││ ││ ││ +││ ││ ││ ││ +│└──────────────┘└────────────────┘└──────────────────────────┘│ +└──────────────────────────────────────────────────────────────┘ ``` #### 4.1.1.1 mDNS-discovery -mDNS-discovery uses mDNS to emit beacons in the local area network to find if there are more peers available, these peers are extremely interesting because our link to them will have an low latency, plus if we are disconnected from the network, we will be leverage the content on those peers have cached. +mDNS-discovery is a Discovery Protocol that uses mDNS (link to wikipedia) over local area networks. It emits mDNS beacons to find if there are more peers available. Local area network peers are very useful to peer-to-peer protocols, as low latency links are very useful. + +mDNS-discovery is a standalone protocol and does not depend on any other libp2p protocol. mDNS-discovery can yield peers available in the local area network, without relying on other infrastructure. This is particularly useful in intranets, networks disconnected from the internet backbone, and networks who temporarily loose links. + +mDNS-discovery can be configured per-service (i.e. discover only peers participating in a specific protocol, like IPFS), and with private networks (discover peers belonging to a private network). + +We are exploring ways to make mDNS-discovery beacons encrypted (so that other nodes in the local network cannot discern what service is being used). Though the nature of mDNS will always reveal local IP addresses. + +Privacy Note: mDNS advertises in local area networks, which reveals IP addresses to listeners in the same local network. It is not recommended to use this with privacy-sensitive applications or oblivious routing protocols. #### 4.1.1.2 random-walk -Random walking consists on traversing the routing tables of the peers available in the network, learning about new peers along the way. +Random-Walk is a Discovery Protocol for DHTs (and other protocols with routing tables). It makes random DHT queries in order to learn about a large number of peers quickly. This causes the DHT (or other protocol) to converge much faster, at the expense of a small load at the very beginning. #### 4.1.1.3 bootstrap-list -A predefined set of peers available on the network in well known locations, so that a new created node can easily find more peers to connect in the network. +Bootstrap-List is a Discovery Protocol that uses local storage to cache the addresses of highly stable (and somewhat trusted) peers available in the network. This allows protocols to "find the rest of the network". This is essentially the same way that DNS bootstraps itself. (though note that changing the DNS bootstrap list --the "dot domain" addresses -- is not easy to do, by design). + - The list should be stored in long-term local storage, whatever that means to the local node (e.g. to disk) + - Protocols can ship a default list hardcoded or along with the standard code distribution (like DNS) + - In most cases (and certainly in the case of IPFS) the Bootstrap-List should be user configurable, as users may wish to establish separate networks, or place their reliance and trust in specific nodes. ### 4.1.2 mDNS-routing diff --git a/protocol/network/figs/peer-routing.monopic b/protocol/network/figs/peer-routing.monopic index 641e4088b8cfc7e8a47e2d8cc5ea7c73ef9a0893..2e565d8db448ecd361b992b82e88b81940d6ce3b 100644 GIT binary patch literal 1094 zcmV-M1iAbFO;1iwP)S1pABzY8000000t4k)OK;ma5dJFx&ki6`vMl-9o)<;;xCjJV zqAfMDl#+7#F!J9!!bt13PLd@dGt!CgUB>Hb(`-f4k!3I=dE0c*&sMc)3Q>?{CwIcmtQu7n!VRgC7wtDA z(TL++$Mcc{tD7^>y0Tg&7{{BwY|du?*JTl`yg?{q)`>(cqd6 zSn!R83VE{%hFRdzXxD2cP)#rkh+C7Yeu5GbN3#^h)NTcnffcNUrTlm2nY|usg7d{l z=l~6A(HQ#I4mO}2dY=v8wYXv4ro5F60#6TWG_P_1B7&`~HWeU9Zj;&V!t?&lo|Wo_ z)_6g7ofYa+Rrf>t{h@_!)iw?f?{%aLOA|{|OKCvvyyk+d@}O%^9<+OQ`nQGOr!hSB z05fFon+UEkVL{PZa?Nv*fsx}d7%sa$4z0t+&|qxaN8z^_dL|P^)%DQn3-oSaj$M5d z!YoYx=}^-n$2)3h?2`d4WQdLrTbi8OHBSBB=&`|pe)$Ang>4er4Ybeb4}xF=C$tKq z4%)_!<5=0_xwZ5;9{j$w^K;9~?RT7~?01Fkw?IHR>9|Q|Xn(4IXVMt;~Y6xm~>YaXPfV04v;B0V4I4hhP+72s^S$WLL zV^$us@|c!)_hkJ|7wE=g7Z;V(``1QJFP1=IFFsgrbFOQ?0hFl=rK>(uSny^J6$q92 z-ySNMO)qq;uzCMjNkMgV$zw%3UU#VLFxLrPCwd=83yaTrw9v^?4UJzdI)15Wl+5b~ z$S){~Iv*+VHEVX;m5}-%j17kui7AaYk6aC63n~&TmZh(@c>dD78%zhrd@`$9@@moS zrB+9iiDrL3J`Zvz%BgS*>eD|V&c5&rLXzn`6aP&~cvOQON)I-T-1vW^>A__4i&nu{ zt$u{|543+@PyyfgcGVT`$;#HdF}mvVk%n)le2lNEe5A?XRbp}J`jNUKQLDA5rY}?c zt?PX}O{8b6A1S?HQl37s`b5W~$?9Tu-B<9%o5`W*r8*@f^zBn=W&Yy3D=m zhVFU}*U5L0L&NZ#IW(9q*MyT@JGIfL@cNB!jy84Qt?{Xx@yt#upG5!YB!jQ=SL*+01Se#0ULOaf1+yH=}>8VAI_$>13Dl zbh>wtbegLx3(oKou$TnE(I) literal 1428 zcmV;F1#9~MO;1iwP)S1pABzY8000000t4+@OK;;g5dJFx&oUrB^vbn87sd8i1cGeQ zwi;PVB{|tN$baupoRQ^6c9V_iz;O=pFber`I4=%|dSdnTA3f_@cKu|U6JZ+Dy2*8u zcExvHrd`9X8S_}DzjtX?7K>`7tBzg!9-Gxw2kmrP>MGYcyY8B`#-2sh7P+QZ?J~>j z2a9OovaZW!%M6B6pRHM^IBNsUWz}L`W=(24uxsV9d6TVlnpLx9-K344LubQ%z}XH? z*;<^kp4}P_=ULgpTzNek4Kt&bMV{+w=wQ}hM^3ZZ?V_pIRi1W_cfhTHg?CGMvsez@ zN1b$K7PS#Zw&-PL#-;_l7XBcPdOmNpna1~gMvH2T|6mfvLr=oHc0Gm8Fci3jrTl#} z3?Ak|7DyQb=tL-Q!uKT7phUKnj4vzT09xOy)JuIO2EJx>QyJ;=%~bu^mSi77*SaYd zMP=9zU~V-G-dX9ks@su)?XC(JTbK#kqI>MMe^*1Zs4Ei6M)!R~P(xBfQ6peC!|Zw1 zE;sW%vAbSR>;AWf-{)N!m0N-{!^dobj;wufqqSz9&2$Qk?%Kol(#w4t+qg(CkX3!J z2ZuB2Np)UyBMFTG2VF!oynWExF0B8PB-g*$_pNPapRLfsvknPDewvUFDld3nNbtca z{Zj=55sw4HB=RQ7DdT}4?-%6#BA`Y{jp#Dsfk=)R55R&zI{WUD7fr8IL>ggpF*0`Z z$DpuznJs`xPSE1b(BW&Lm4V)LjSqP|3GK;B2hG}8)SvKQjZXv56+GXJ6)|HXFcO}^ z_zOG>V^k?6C$Px>}4a&_ku1oL}uFGS$CQciT zz%#)yFZI3Jd)&*#V=&ARX^FBVuq3o3vLv=7vBbsR?hC z#f`ldMic$?F+&jP9{~gc;1M`^yGI7E^hgNDuAqT`XIw{bhE84yt++F2shmN>-tvwB zv={Ldxy9sV%h(H-n<;jD2)_Vaw%%3Ez^u!-ob z^Ee)URZ>5wlFD~0si)22IOS}dayA}QBcW2Ne<7t*al|Yx5YDo=K8ZWDs2>P$&-2Ez z4-Yx^3+{5*1;8exbxCwAEWy#ioTZi$Bn_8ENeRvY&TvF z0)H_qqj&$7RrgtYWkj>?;PS}bO%QhmEtEUx&{=s_`R=|LNt{88_@u=_Q^@-r zorDm1vo7}i_(KgP&Zr%U&Y$v7xravQoEsxoaJcD&+KP{ z_M*`)mZRc6*~_Y@pV>Y*!g0hCh$j$FAf7-xp*D6k{-DcfF)Q!j)MTPQr{uHM|EAS? zHPub8=g>y?!7j`}tuF>`<;*@C%0TMZzRoh%nhalOMaKY1oaLKRy1SP>?=qVIb(iun zcPTR1y-PW535^cRk`Bvqs9#e7TdK=AHOugbr)Cwq`z|wd79fMb8P`GN=5(9<@>j*f iN5z43Cs6*b9T8BLI_rb?6Qt4r`}{w^NTi7)IRF4fwa4=S diff --git a/protocol/network/figs/peer-routing.txt b/protocol/network/figs/peer-routing.txt index 4de2fbb47..a01239a57 100644 --- a/protocol/network/figs/peer-routing.txt +++ b/protocol/network/figs/peer-routing.txt @@ -1,19 +1,9 @@ -┌────────────────────────────────────────────────────────────────┐ -│ Peer Routing │ -│ │ -│┌──────────────────────────────────────────────────────────────┐│ -││ kad-routing ┌──────────────┐┌──────────────┐┌──────────────┐ ││ -││ │mDNS-discovery││random-walk ││bootstrap-list│ ││ -││ └──────────────┘└──────────────┘└──────────────┘ ││ -│└──────────────────────────────────────────────────────────────┘│ -│┌──────────────────────────────────────────────────────────────┐│ -││ mDNS-routing ││ -││ ││ -││ ││ -│└──────────────────────────────────────────────────────────────┘│ -│┌──────────────────────────────────────────────────────────────┐│ -││ other-routing-mechanisms ││ -││ ││ -││ ││ -│└──────────────────────────────────────────────────────────────┘│ -└────────────────────────────────────────────────────────────────┘ \ No newline at end of file +┌──────────────────────────────────────────────────────────────┐ +│ Peer Routing │ +│ │ +│┌──────────────┐┌────────────────┐┌──────────────────────────┐│ +││ kad-routing ││ mDNS-routing ││ other-routing-mechanisms ││ +││ ││ ││ ││ +││ ││ ││ ││ +│└──────────────┘└────────────────┘└──────────────────────────┘│ +└──────────────────────────────────────────────────────────────┘ \ No newline at end of file From cfddc5823ada0ffa843dc4bee269d6859eadf3fb Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 2 Oct 2015 00:56:57 +0100 Subject: [PATCH 31/37] add onion to the list of addrs --- protocol/network/2-state-of-the-art.md | 1 + 1 file changed, 1 insertion(+) diff --git a/protocol/network/2-state-of-the-art.md b/protocol/network/2-state-of-the-art.md index c0ae5af34..6a4fc49d8 100644 --- a/protocol/network/2-state-of-the-art.md +++ b/protocol/network/2-state-of-the-art.md @@ -44,6 +44,7 @@ Additionally, it's worth noting that the traditional 7-layer OSI model character - ARP - DHCP - DNS +- Onion ### 2.2.4 Routing messages through the Network From 6a119c60a3854b60fe2527f37e358916c7ac8073 Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 2 Oct 2015 00:57:29 +0100 Subject: [PATCH 32/37] add cjdns --- protocol/network/2-state-of-the-art.md | 1 + 1 file changed, 1 insertion(+) diff --git a/protocol/network/2-state-of-the-art.md b/protocol/network/2-state-of-the-art.md index 6a4fc49d8..800ff59cc 100644 --- a/protocol/network/2-state-of-the-art.md +++ b/protocol/network/2-state-of-the-art.md @@ -53,6 +53,7 @@ Additionally, it's worth noting that the traditional 7-layer OSI model character - PPP - Tor - I2P +- cjdns ### 2.2.5 Transport From 0377fd72111e613556bec7c77669c30ea31bc696 Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 2 Oct 2015 08:10:24 +0100 Subject: [PATCH 33/37] remove way old /routing spec --- protocol/network/8-implementations.md | 2 +- protocol/routing/DHT.md | 28 ------- protocol/routing/README.md | 74 ------------------ protocol/routing/discovery.md | 41 ---------- .../routing/figs/routing-overview.monopic | Bin 920 -> 0 bytes protocol/routing/figs/routing-overview.txt | 6 -- 6 files changed, 1 insertion(+), 150 deletions(-) delete mode 100644 protocol/routing/DHT.md delete mode 100644 protocol/routing/README.md delete mode 100644 protocol/routing/discovery.md delete mode 100644 protocol/routing/figs/routing-overview.monopic delete mode 100644 protocol/routing/figs/routing-overview.txt diff --git a/protocol/network/8-implementations.md b/protocol/network/8-implementations.md index 753068197..ad0255db9 100644 --- a/protocol/network/8-implementations.md +++ b/protocol/network/8-implementations.md @@ -1,7 +1,7 @@ 8 Implementations ================= -These are the list of known libp2p, or in another words, the components that respect the interfaces and expectations defined in the Interfaces chapter, that can be composed to make a working libp2p. +This is a list of known libp2p module implementations. They are components that respect the interfaces and expectations defined in the "Interfaces" chapter, and can be composed to make a working libp2p library. ## 8.1 libp2p diff --git a/protocol/routing/DHT.md b/protocol/routing/DHT.md deleted file mode 100644 index 0f9ef8935..000000000 --- a/protocol/routing/DHT.md +++ /dev/null @@ -1,28 +0,0 @@ -IPFS DHT Protocol Spec -====================== - -Authors: David Dias - -Reviewers: - -TODOS: - ------------------------ - -> - -## Supports - -- Maintaining partial state of the network - - DHT - - kbucket - -## Overview - - - -explain: -- dht/coral, how the algo works -- kbucket -- each time a contact is made with a new peer, we check to see if it is a better candidate for our kbucket -- xor metric diff --git a/protocol/routing/README.md b/protocol/routing/README.md deleted file mode 100644 index e4c0a1e12..000000000 --- a/protocol/routing/README.md +++ /dev/null @@ -1,74 +0,0 @@ -IPFS Routing Protocol Spec -========================== - -Authors: David Dias - -Reviewers: - -TODOS: - ------------------------ - -> This spec defines the routing protocol spec. Routing offers an interface for the features exposed by `Peer discovery` and `DHT`. The spec is a **Work In Progress**. - -## Supports - -- Routing primitives - - Publish and fetch content (also providing) -- Maintaining partial state of the network - - DHT - - kbucket - -## Overview - -The Routing Protocol is composed by three componenets, these are: -- Interface: Our routing primitives that are offered for the user, such as finding and publishing content, including the storage and lookup of metadata (Providers). -- Peer Discovery: Responsible for filling our kbucket with best candidates. -- Peer-to-peer Structured Overlay Network (DHT): Algorithm for the implicit network organization, based on [Coral](http://iptps03.cs.berkeley.edu/final-papers/coral.pdf) and [mainlineDHT](http://www.bittorrent.org/beps/bep_0005.html) - -``` -┌──────────────┐ -│ routing │ -└──────────────┘ -┌─────────┐┌───┐ -│discovery││DHT│ -└─────────┘└───┘ -``` - -In order for routing to work, we first have to pass the bootstrap state. Bootstrapping happens by connecting to a predefined "railing" peers list, shipped with the go-ipfs release and/or by discovery through mDNS. Once at least one peer is found and added to the kbucket, the routing changes to an active state and our peer becomes able to route and receive messages. - -## Routing - -For impl reference, check: https://github.com/ipfs/go-ipfs/blob/master/routing/routing.go#L19-L49 - -### Find a peer - -Finding a peer happens through an iterative process. We query the best candidate in our kbucket for the awarness of the peer we are looking for, if that peer isn't the ideal candidate, it will return 3 possible candidates from his kbucket and it will query those to check for the best candidate. We repeat the process until we find that peer - -_When searching for a peer, do we fetch the kbucket from a peer and see which peer we want to ping next or do we ask for a given Id to a peer and that peer replies to us with the best candidate (or itself if it is the case)?_ - -### Ping - -Ping mechanism (for heartbeats). Ping a peer and log the time it took to answer. - -_what if the Id doesn't exist? Is there any rule for non existing peers? Should we log time for best matches as well?_ - -### Provide - -Providing is the process of storing/updating the metadata (pointers) of where the blocks of a given file are stored/available in the IPFS network. What this means is that the DHT is not used for block discovery, but for the metadata which identifies where they are, instead. -When a node advertises a block available for download, IPFS stores a record in the DHT with its own Peer.ID. This is termed "providing". the node becomes a "provider". Requesters who wish to retrieve the content, query the DHT (or DSHT) and need only to retrieve a subset of providers, not all of them. (this works better with huge DHTs, and latency-aware DHTs like coral). - -We provide once per block, because every block (even sub-blocks) are independently addressable by their hash. (yes, this is expensive, but we can mitigate the cost with better DHT + record designs, bloom filters, and more) - -There is an optimistic optimization -- which is that if a node is storing a node that is the parent (root/ancestor) of other nodes, then it is much more likely to also be storing the children. So when a requester attempts to pull down a large dag, it first queries the DHT for providers of the root. Once the requester finds some and connects directly to retrieve the blocks, bitswap will optimistically send them the "wantlist", which will usually obviate any more dht queries for that dag. we haven't measured this to be true yet -- we need to -- but in practice it seems to work quite well, else we wouldnt see as quick download speeds. (one way to look at it, is "per-dag swarms that overlap", but it's not a fully correct statement as having a root doesn't necessarily mean a node has any or all children.) - -Providing a block happens as it gets added. Reproviding happens periodically, currently 0.5 * dht record timeout ~= 12 hours. - -### Get value - - - -### Put value - -_not 100% about this happens exactly. From what I understand, the IPFS node that is adding the file, breaks the file into blocks, creates the hashes and provides each single one of them. When do we execute a Put? Replicas are done through "Get", right?_ - diff --git a/protocol/routing/discovery.md b/protocol/routing/discovery.md deleted file mode 100644 index 88fac3897..000000000 --- a/protocol/routing/discovery.md +++ /dev/null @@ -1,41 +0,0 @@ -IPFS Peer Discovery Protocol Spec -================================= - -Authors: David Dias - -Reviewers: - -TODOS: - ------------------------ - -> - -## Supports - -- Peer discovery through - - mdns - - custom peers list - - random walking on the network - -## Overview - - -### bootstrap peer list - -List with known and trusted peers shipped with IPFS. - -- _How is this list updated?_ -- _Is this list updated periodically_? - -### random walk - -IPFS issues random Peer lookups periodically to refresh our kbucket if needed. For impl reference, see: https://github.com/ipfs/go-ipfs/blob/master/routing/dht/dht_bootstrap.go#L88-L109. - -### mDNS - -In addition to known peers and random lookups, IPFS also performs Peer Discovery through mDNS ([MultiCast DNS](https://tools.ietf.org/html/rfc6762)) - --_How offen do we issue this searches?_ - - diff --git a/protocol/routing/figs/routing-overview.monopic b/protocol/routing/figs/routing-overview.monopic deleted file mode 100644 index 631136ca66cc20e3d0fede6347a0cdb531ad8507..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 920 zcmV;J184mIO;1iwP)S1pABzY8000000t4k(%W|7A6#bQq)?@~WM{IA~Mc19~IvGZQ z3~DgA5_Xb$^6$M8k_^~MoCo7cvOrc8=|0YV9KjAX=^vK05-oOWdKsum+K8Nqq~&+4 zN?L&y2zjVwcWpu|UeqgAw`k#eC~N8#=1E$yI%hdrv|_`|PF_o%GrJ^9nm4zd#7-P- zTbh*=j@mr~t*Ox}z&KhLn~I90+kh6Khn9k_SVHTpY(yg15;iOAF+n3amF(nHO?IO! zT+&K{uDr?m$6!Or^PJUggYuy}nbPd05Y48}llFcM))H{MEn%f7-S*xlRx79WV9-Ki zrOqZCmWl7+XqHRKlp5djk#$P)f1m_m>;?B6lPJ2#ex!1QtYaODE9vc`R#t>Bl+|=>D znGl{XHLwbpSkjCoVCXm%hOSqK>9wy84aln5GFNLVItj~p+e4@?(1l`VkIP%eI>+>% z7CF6gSXM)09}H-|LdT^po*kywc-Lk8?d@AAYVMjBzui^3a@|3!QJq%bwpj?v)`Xy<}Qev;ZrxkxcN5MMo!! zhDv!0qPam)!jl(5DGL+VHQ0$$-%5SbL1>qqwBCaL_ zlYDHlntvLyiq6he!O2`j!t-*~+z=A+k?S^QVrh&7UxTYi^p0Fbf*1Fh`Ke8N{<~B(URw)yjOJe;m*c?3c1gp+S>n)XoEcJl_JR74o z5Y_=3Ibw-l3 Date: Fri, 2 Oct 2015 08:21:09 +0100 Subject: [PATCH 34/37] update swarm interface --- protocol/network/6-interfaces.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/protocol/network/6-interfaces.md b/protocol/network/6-interfaces.md index 5476a6903..5826abb6a 100644 --- a/protocol/network/6-interfaces.md +++ b/protocol/network/6-interfaces.md @@ -9,9 +9,11 @@ ~~The network is abstracted through the swarm which presents a simplified interface for the remaining layers to have access to the network. This interface should look like:~~ -- `.openStream(peer, protocol)` - peer should contain the ID of the peer and its respective multiaddrs known. -- `.registerHandler(protocol, handlerFunc)` - enable a protocol to be registered, so that another peer can open a stream to talk with us to that specific protocol -- `.listen()` - to start listening for incoming connections and therefore opening of streams +- `sw.addTransport(transport, [options, dialOptions, listenOptions])` - Add a transport to be supported by this swarm instance. Swarm expects it to implement the [abstract-transport](https://github.com/diasdavid/abstract-transport) interface. +- `sw.addUpgrade(connUpgrade, [options])` - A connection upgrade must be able to receive and return something that implements the [abstract-connection](https://github.com/diasdavid/abstract-connection) interface. +- `sw.addStreamMuxer(streamMuxer, [options])` - Upgrading a connection to use a stream muxer is still considered an upgrade, but a special case since once this connection is applied, the returned obj will implement the abstract-stream-muxer interface. +- `sw.dial(PeerInfo, options, protocol, callback)` - PeerInfo should contain the ID of the peer and its respective multiaddrs known. +- `sw.handleProtocol(protocol, handlerFunction)` - enable a protocol to be registered, so that another peer can open a stream to talk with us to that specific protocol The following figure represents how the network level pieces, are tied together: From 8d6939b4a1e51b06f906d9f305bbb263ce2a9ffe Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 2 Oct 2015 09:18:45 +0100 Subject: [PATCH 35/37] readd the secure communications to properties --- protocol/network/7-properties.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/protocol/network/7-properties.md b/protocol/network/7-properties.md index 873c93022..5212dd052 100644 --- a/protocol/network/7-properties.md +++ b/protocol/network/7-properties.md @@ -186,3 +186,7 @@ For example: In order to be ubiquitous, we _must_ use hyper-portable format encodings, those that are easy to use in various other platforms. Ideally these encodings are well-tested in the wild, and widely used. There may be cases where multiple encodings have to be supported (and hence we may need a [multicodec](https://github.com/jbenet/multicodec) self-describing encoding), but this has so far not been needed. For now, we use [protobuf](https://github.com/google/protobuf) for all protocol messages exclusively, but other good candidates are [capnp](https://capnproto.org), [bson](http://bsonspec.org/), [ubjson](http://ubjson.org/). + +### 7.5.6 Secure Communications + +The wire protocol is -- of course -- wrapped with encryption. We use cyphersuites similar to TLS. This is explained further in the [network spec](./#encryption). From ad849da2941e9fda5f8ce262508bc924d301c39b Mon Sep 17 00:00:00 2001 From: David Dias Date: Fri, 2 Oct 2015 17:27:52 +0100 Subject: [PATCH 36/37] break discovery into its own thing --- protocol/network/4-architecture.md | 74 ++++++++++--------- protocol/network/figs/architecture-1.monopic | Bin 1102 -> 1219 bytes protocol/network/figs/architecture-1.txt | 6 +- 3 files changed, 41 insertions(+), 39 deletions(-) diff --git a/protocol/network/4-architecture.md b/protocol/network/4-architecture.md index 8f36fb6c1..aea39620b 100644 --- a/protocol/network/4-architecture.md +++ b/protocol/network/4-architecture.md @@ -5,11 +5,12 @@ libp2p was designed around the Unix Philosophy, creating smaller components, eas Although different Peers can support different protocols depending on their capabilities, any Peer can act as a dialer and/or a listener for connections from other Peers, connections that once established can be reused from both ends, removing the distinction between clients and servers. -libp2p interface acts as a thin veneer to three subsystems that are required in order for peers to be able to communicate. These subsystems are allowed to be built on top of other subsystems as long as they respect the standardized interface. The main 3 subsystems are: +libp2p interface acts as a thin veneer to a multitude of subsystems that are required in order for peers to be able to communicate. These subsystems are allowed to be built on top of other subsystems as long as they respect the standardized interface. The main areas where these subsystems fit are: - Peer Routing - Mechanism to find a Peer in a network. This Routing can be done recursively, iteratively or even in a broadcast/multicast mode. - Swarm - Handles everything that touches the 'opening a stream' part of libp2p, from protocol muxing, stream muxing, NAT Traversal, Connection Relaying, while being multitransport - Distributed Record Store - A system to store and distribute records. Records are small entries used by other systems for signaling, establishing links, announcing peers or content, and so on. It has a similar role to DNS in the broader internet. +- Discovery - Finding or identifying other peers in the network. Each of these subsystem exposes a well known interface (see chapter 6 for Interfaces) and may use eachother in order to fulfil their goal. A global overview of the system is: @@ -17,9 +18,9 @@ Each of these subsystem exposes a well known interface (see chapter 6 for Interf ┌─────────────────────────────────────────────────────────────────────────────────┐ │ libp2p │ └─────────────────────────────────────────────────────────────────────────────────┘ -┌─────────────────────────┐┌──────────────────────────┐┌──────────────────────────┐ -│ Peer Routing ││ Swarm ││ Distributed Record Store │ -└─────────────────────────┘└──────────────────────────┘└──────────────────────────┘ +┌─────────────────┐┌─────────────────┐┌──────────────────────────┐┌───────────────┐ +│ Peer Routing ││ Swarm ││ Distributed Record Store ││ Discovery │ +└─────────────────┘└─────────────────┘└──────────────────────────┘└───────────────┘ ``` ## 4.1 Peer Routing @@ -30,11 +31,7 @@ We present two examples of possible Peer Routing subsystems, the first based on ### 4.1.1 kad-routing -kad-routing implements the Kademlia Routing table, where each peer holds a set of k-buckets, each of them containing several PeerInfo from other peers in the network. In order to find the whereabouts of these peers, it implements 3 discovery mechanisms: - -- mDNS-discovery -- random-walk -- bootstrap-list +kad-routing implements the Kademlia Routing table, where each peer holds a set of k-buckets, each of them containing several PeerInfo from other peers in the network. ``` ┌──────────────────────────────────────────────────────────────┐ @@ -48,29 +45,6 @@ kad-routing implements the Kademlia Routing table, where each peer holds a set o └──────────────────────────────────────────────────────────────┘ ``` -#### 4.1.1.1 mDNS-discovery - -mDNS-discovery is a Discovery Protocol that uses mDNS (link to wikipedia) over local area networks. It emits mDNS beacons to find if there are more peers available. Local area network peers are very useful to peer-to-peer protocols, as low latency links are very useful. - -mDNS-discovery is a standalone protocol and does not depend on any other libp2p protocol. mDNS-discovery can yield peers available in the local area network, without relying on other infrastructure. This is particularly useful in intranets, networks disconnected from the internet backbone, and networks who temporarily loose links. - -mDNS-discovery can be configured per-service (i.e. discover only peers participating in a specific protocol, like IPFS), and with private networks (discover peers belonging to a private network). - -We are exploring ways to make mDNS-discovery beacons encrypted (so that other nodes in the local network cannot discern what service is being used). Though the nature of mDNS will always reveal local IP addresses. - -Privacy Note: mDNS advertises in local area networks, which reveals IP addresses to listeners in the same local network. It is not recommended to use this with privacy-sensitive applications or oblivious routing protocols. - -#### 4.1.1.2 random-walk - -Random-Walk is a Discovery Protocol for DHTs (and other protocols with routing tables). It makes random DHT queries in order to learn about a large number of peers quickly. This causes the DHT (or other protocol) to converge much faster, at the expense of a small load at the very beginning. - -#### 4.1.1.3 bootstrap-list - -Bootstrap-List is a Discovery Protocol that uses local storage to cache the addresses of highly stable (and somewhat trusted) peers available in the network. This allows protocols to "find the rest of the network". This is essentially the same way that DNS bootstraps itself. (though note that changing the DNS bootstrap list --the "dot domain" addresses -- is not easy to do, by design). - - The list should be stored in long-term local storage, whatever that means to the local node (e.g. to disk) - - Protocols can ship a default list hardcoded or along with the standard code distribution (like DNS) - - In most cases (and certainly in the case of IPFS) the Bootstrap-List should be user configurable, as users may wish to establish separate networks, or place their reliance and trust in specific nodes. - ### 4.1.2 mDNS-routing mDNS-routing uses mDNS probes to identify if local area network peers that have a given key or simply are present. @@ -78,10 +52,6 @@ mDNS-routing uses mDNS probes to identify if local area network peers that have - - - - ## 4.2 Swarm ### 4.2.1 Stream Muxer @@ -130,3 +100,35 @@ Follows [IPRS](https://github.com/ipfs/specs/tree/master/records) ### 4.3.5 s3-record-store + + + + + + + + +## 4.4 Discovery + +### 4.4.1 mDNS-discovery + +mDNS-discovery is a Discovery Protocol that uses mDNS (link to wikipedia) over local area networks. It emits mDNS beacons to find if there are more peers available. Local area network peers are very useful to peer-to-peer protocols, as low latency links are very useful. + +mDNS-discovery is a standalone protocol and does not depend on any other libp2p protocol. mDNS-discovery can yield peers available in the local area network, without relying on other infrastructure. This is particularly useful in intranets, networks disconnected from the internet backbone, and networks who temporarily loose links. + +mDNS-discovery can be configured per-service (i.e. discover only peers participating in a specific protocol, like IPFS), and with private networks (discover peers belonging to a private network). + +We are exploring ways to make mDNS-discovery beacons encrypted (so that other nodes in the local network cannot discern what service is being used). Though the nature of mDNS will always reveal local IP addresses. + +Privacy Note: mDNS advertises in local area networks, which reveals IP addresses to listeners in the same local network. It is not recommended to use this with privacy-sensitive applications or oblivious routing protocols. + +#### 4.4.2 random-walk + +Random-Walk is a Discovery Protocol for DHTs (and other protocols with routing tables). It makes random DHT queries in order to learn about a large number of peers quickly. This causes the DHT (or other protocol) to converge much faster, at the expense of a small load at the very beginning. + +#### 4.4.3 bootstrap-list + +Bootstrap-List is a Discovery Protocol that uses local storage to cache the addresses of highly stable (and somewhat trusted) peers available in the network. This allows protocols to "find the rest of the network". This is essentially the same way that DNS bootstraps itself. (though note that changing the DNS bootstrap list --the "dot domain" addresses -- is not easy to do, by design). + - The list should be stored in long-term local storage, whatever that means to the local node (e.g. to disk) + - Protocols can ship a default list hardcoded or along with the standard code distribution (like DNS) + - In most cases (and certainly in the case of IPFS) the Bootstrap-List should be user configurable, as users may wish to establish separate networks, or place their reliance and trust in specific nodes. diff --git a/protocol/network/figs/architecture-1.monopic b/protocol/network/figs/architecture-1.monopic index 64c392c527dd663d3766425f515d1bd4018c0414..0fa339c84a09ce6f664b80b5b52b84133faf0c29 100644 GIT binary patch delta 1214 zcmV;v1VQ`G2*U}G6@Sf=qc#wJl`Wl_DkK4hxh4;g+C8SGC=9Yq7J~zLW+yJcds;sY z!uD=Fw&kjs$pIt_=~Js)`qbUtk!Jpv$oq~w?qu~Ll$CkY7NSl2@`tF>z9o-@c%&CU z`ZTM`WxW=4Pab`b zt7vk27<5>bMIq{;gIt3iInVO%%eL9pMcTh^Kw1V1?^n>WTn*i=PNJ5J8kLbPm9FI2 zw1j5n59(+Zi+@hYX?)KoxTvoD2PPpj@i??~+c|WGp&%_R<Iu5i7#vrDsS3as-BMXsIeVtFoCX3TQ195&P=)Y5DbG4mN~U^ zXYH=TC7G3$a>B0cUzO=M4OGjfMvaVySCtSe5mshciGRt{Fnf`8t8u;^*(f7z)w_ZB z{!mBNL~(MsEhZR9Zw@L=)-JMKq#)?wW|%I$I^JO8`A`a3H_u`?ZPGlcD9YZ_kPV2o zU_K7-UWCvKQ$JC2s^$1#O@-ZSrEw;;b9`KivQ;)UNESA1+;Ov0W*KZzWlIo}?gzuX z6*@W-nt#7*7Gv>;VKEk8%VP9?B*wW-V%)zohbgnGN@6P9#|kCGar_h<#)DgO7 z&Ccas-PB}w zapzjGtCUy4*HW@NJR5kJDvuS&Lr;Fz09Y zM1QaI%jo&RC7T47iTA+n>6c;ri0&DBXB53NN*TIuZ z6T|Zik1$us>j@?d)x8m^_ph%ND3~s|eaZ0HnU5O0?_ikzpVAvsdi;LTFpF%~o!vVa z#)y|OtZ=Mgt`8{Wb0qX;H{@MPo$)RUoPTi`d)FMs!;iyZv#U9b-H*cp-{!C|yfcY$ z{4;{%pAj6LNsitmM1h}z!~%NDjNZ&$j>&gNV%(Y3O6XIj_=VYz*uvg1(J3>-c(RVX7Uh6t4>@&E@K3J}LqWf(lz*y< zTo2DXCRTamE+fX=3`?hZCeU+!(!w!^Xu^O&Em4u79a5e!wIo;Q@!fcE1E+7z*0LQobzQU^kCZ!TQ1jRSWBxqcP^_JJ@tq zFg>(BX^WTg9d$}&byK0`>1iG{wzU>S(Yh(t1(=ZB%z_){#tv55_j2p)t>KEyLJOR) zExHHg_+1UnqOPn#oZGRUnmRG{%+xd_3paBv+RbUM1Ao~m|Lj#+LwOvUr|j7bhx;mm zZ}h&P=&fcYGMR#s!+p?Sc6q+HPA5YdV_V-!ch1l=smzPcvyKnw+`#Pc_D)K@Fm-FK zrh3kgRA1SnHX3JW9k*|3a_QLE=?{7yvpLW&AK+<$I~b+#Ae;LoL1XJa30Dr+JGefX z`wV?%`SL;wsVu_MWfD(@s#H~n91`8^A5wR z6l<^mwXS>BB+kNrhQ(QOJ&T9ekvMxaiL;4M;(xHaZ=#nZapiW^ptiwmgWE>*Hi(?X z&q?HTG@_yLlcD3sLL;&$cfc-)M6Hin`8}=n+of#OYbREZK$smpV5Bus-HNui!ypPU z;B59}y(f?5-f%pVOh(h1B~ONCkJUOF4VwM=6?(#vrot~8MNu0n(TKRWhI?7N%;RmO!?S0MqA0zJmr5`F-C-`M>T_=5lK>y_SXWbB zCAylaDhi=;EXAVHqC57w)5z)nG}3|6mwzKb&U^xlrZ1gF+K+(Deg$OqGa$DaCS*i! zf&e*xP67w<-Cq)@TVf!v}6 Ok3RvY34HOT9RL6&eJpqY diff --git a/protocol/network/figs/architecture-1.txt b/protocol/network/figs/architecture-1.txt index 583db78d9..234504543 100644 --- a/protocol/network/figs/architecture-1.txt +++ b/protocol/network/figs/architecture-1.txt @@ -1,6 +1,6 @@ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ libp2p │ └─────────────────────────────────────────────────────────────────────────────────┘ -┌─────────────────────────┐┌──────────────────────────┐┌──────────────────────────┐ -│ Peer Routing ││ Swarm ││ Distributed Record Store │ -└─────────────────────────┘└──────────────────────────┘└──────────────────────────┘ \ No newline at end of file +┌─────────────────┐┌─────────────────┐┌──────────────────────────┐┌───────────────┐ +│ Peer Routing ││ Swarm ││ Distributed Record Store ││ Discovery │ +└─────────────────┘└─────────────────┘└──────────────────────────┘└───────────────┘ \ No newline at end of file From 39c6b677d13915f1cb34b885a927a3a839b11531 Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 11 Oct 2015 16:45:42 -0700 Subject: [PATCH 37/37] add ref to rfc5128 --- protocol/network/9-references.md | 1 + 1 file changed, 1 insertion(+) diff --git a/protocol/network/9-references.md b/protocol/network/9-references.md index e69de29bb..4815fc17e 100644 --- a/protocol/network/9-references.md +++ b/protocol/network/9-references.md @@ -0,0 +1 @@ +- State of Peer-to-Peer (P2P) Communication across Network Address Translators (NATs) https://tools.ietf.org/html/rfc5128