@node Yggdrasil
@unnumbered Yggdrasil support
-NNCP is able to act itself as a client to
+NNCP is able to act as a node of
@url{https://yggdrasil-network.github.io/, Yggdrasil} overlay network.
Current IPv6 adoption for @strong{home} users is relatively bad in many
countries. That is why Yggdrasil overlay network uses dynamic spanning
tree mesh network for packets routing, making it useful for gaining
-hosts high availability reachability without complex manual manipulations.
-By default it creates 200::/7 IPv6 network, where each host's address is
-derived from the corresponding public key.
-
-NNCP's Yggdrasil support is fully based on and resembles the idea taken
-from @url{https://github.com/neilalexander/yggmail, yggmail} software,
-that does not use Yggdrasil's full-featured IP tunnelling capabilities,
-but rather uses it only as a generic packet transmission network,
-greatly simplifying the whole setup, without necessity to setup separate
-networking interface and operating system's routing tables with firewall.
-@url{http://bittorrent.org/beps/bep_0029.html, μTP} transport protocol
-is used over Yggdrasil's packet interface -- it is relatively simple and
-efficient enough.
-
-No separate explicit Yggdrasil daemon installation is necessary, however
-you should be able to interoperate with it too, using for example as an
-entry point to the global Yggdrasil network. You can reuse already
-existing Yggdrasil network, without colliding with its IP tunnelling
-features.
+hosts high reachability without complex manual manipulations. By default
+it creates 200::/7 IPv6 network, where each host's address is derived
+from its public key.
+
+NNCP reuses Yggdrasil's source code, but instead of relying on operating
+system's network stack, that would require use of some kind
+full-featured TUN network interface, there is pure Go built-in stack,
+responsible for IPv6 and TCP protocols support. You do not need to think
+about network interfaces, addressing and firewall setup at all:
+@ref{nncp-daemon} acts as Yggdrasil IPv6 reachable host, listening on
+single TCP port. You can reach it using ordinary non-Yggdrasil capable
+version of @ref{nncp-call}, calling corresponding 200::/7 IPv6 address
+through native Yggdrasil daemon created TUN interface.
+@ref{nncp-daemon}, @ref{nncp-call}* can freely peer with Yggdrasil
+nodes, reusing existing infrastructure.
Only minor modifications were done to current NNCP's tools:
@itemize
-@item @ref{nncp-daemon} has @option{-yggdrasil} option, making it acting
-as a Yggdrasil listener network node. It can automatically connect to
-other peers and participate in routing. It does not have to answer
-NNCP's online protocol requests at all and just can be some intermediate
-routing point in the whole mesh network.
+@item @ref{nncp-daemon} has @option{-yggdrasil yggdrasils://} option,
+making it also as a Yggdrasil listener network node. It can
+automatically connect to other peers and participate in routing. It does
+not have to answer NNCP's online protocol requests at all and just can
+be some intermediate routing point in the whole mesh network.
@item @ref{nncp-call}/@ref{nncp-caller} commands understand
-@code{yggdrasil:} addresses, pointing to the desired Yggdrasil's public
-key (that also acts as the destination host's address). Yggdrasil
+@code{yggdrasilc://} addresses, pointing to the desired Yggdrasil's
+public key (that also acts as the destination host's address). Yggdrasil
background goroutine is automatically started, connecting to the
-specified Yggdrasil entrypoints and making μTP connection with the hosts
-and initiating NNCP's native @ref{Sync, online protocol} handshake on
-top of that.
+specified Yggdrasil entrypoints, calling remote NNCP node and initiating
+NNCP's native @ref{Sync, online protocol} handshake on top of that.
@item @ref{nncp-cfgnew} is able to generate ed25519 keypair.
Private: 571fb05c81e62a572096566fd48e87ad47e706b1f600dd625ebbf86d310332624fd64130e23cf7abdbc0fabdf2ae12bbc2ab7179861efa296d2beb0181ae07ea
@end example
-You should share your public key with other NNCP peers.
+You should share that public key with other NNCP peers.
@item
Start @ref{nncp-daemon} listening on Yggdrasil's incoming connections.
-You have to specify the private key (generated above), list of bind
-addresses for incoming Yggdrasil's TCP connections, optional list of
-allowed incoming connections, identified by a public key, and optionally
-a list of another similar listening peers, through which you can route
-and discover packets to the other nodes. @option{-yggdrasil} option
-takes that information in form of:
-@code{PRV;BIND[,...];[PUB,...];[PEER,...]}, where @code{PEER} is in
-Yggdrasil's URL format, like @code{tcp://HOST:PORT} or
-@code{tcp://HOST:PORT?key=PUBKEY}.
+You have to specify:
+
+@itemize
+
+@item
+Your private key (generated above). Yggdrasil's @code{PrivateKey} analogue.
+
+@item
+Optional non-default port you will listen on Yggdrasil's IPv6 address.
+
+@item
+Optional list of bind addresses, used for peering between the nodes.
+Yggdrasil's @code{Listen} analogue.
+
+@item
+Optional list of peer addresses you should connect to.
+Yggdrasil's @code{Peers} analogue.
+
+@item
+Optional list of allowed peer public keys, allowed for incoming peering
+connections from. Yggdrasil's @code{AllowedPublicKeys} analogue.
+
+@item
+Optional list of multicast-related regular expressions to match desired
+network interfaces where Yggdrasil multicasting must be enabled. Beacon
+and listening are always enabled on them, but optionally you can specify
+port you forcefully want to listen on.
+
+@end itemize
@example
-$ nncp-daemon -yggdrasil "571f...07ea;[::]:1234,[::1]:2345;;tcp://some.peer?key=ITSPUBKEY"
+$ nncp-daemon -yggdrasil "yggdrasils://571f...07ea:6789"\
+"?bind=tcp://[::1]:1234"\
+"&bind=tcp://[2001::1]:1234"\
+"&pub=c6b7...9469"\
+"&pub=eb2d...ca07"\
+"&peer=tcp://example.com:2345"\
+"&peer=tcp://another.peer:3456%3Fkey=f879...2e9b"
+"&mcast=.*:5400"
+"&mcast=lo0"
@end example
-Here we did not specify any allowable public key -- anyone can connect
-to us and route packets through. As you can see, private key is in
-command line arguments, that could be treated as a security issue. That
-is why it is preferred to specify them in
-@ref{CfgYggdrasilAliases, configuration}'s @code{yggdrasil-aliases}
+That @code{yggdrasils://} is transformed to following Yggdrasil's
+configuration analogue:
+
+@verbatim
+{
+ PrivateKey: 571f...07ea
+ Listen: ["tcp://[::1]:1234", "tcp://[2001::1]:1234"]
+ AllowedPublicKeys: ["c6b7...9469", "eb2d...ca07"]
+ Peers: [
+ tcp://some.peer.be:2345
+ tcp://some.peer.ru:3456?key=f879...2e9b
+ ]
+ MulticastInterfaces: [
+ {
+ Regex: .*
+ Beacon: true
+ Listen: true
+ Port: 5400
+ }, {
+ Regex: lo0
+ Beacon: true
+ Listen: true
+ Port: 0
+ }
+ ]
+}
+@end verbatim
+
+Basically you have to specify only private key and either @code{bind} or
+@code{peer} address. Look for Yggdrasil's documentation for more
+description of each option and related behaviour.
+
+As you can see, private key is in command line arguments, that could be
+treated as a security issue. That is why it is preferred to specify them
+in @ref{CfgYggdrasilAliases, configuration}'s @code{yggdrasil-aliases}
section, where you can alias all of entities and reference them in
-@option{-yggdrasil} or @code{yggdrasil:}-addresses:
+@option{-yggdrasil} or @code{yggdrasilc://}-addresses:
@verbatim
yggdrasil-aliases: {
myprv: 571f...07ea
- bindPublic: [::]:1234
- bindLocalhost: [::1]:2345
- peerBE: tcp://some.peer.be?key=BEPUBKEY
- peerRU: tcp://some.peer.ru?key=RUPUBKEY
- defPeers: peerBE,peerRU
+ bindPublic: tcp://[2001::1]:1234
+ bindLocalhost: tcp://[::1]:2345
+ peerBE: tcp://some.peer.be:2345
+ peerRU: tcp://some.peer.ru:3456?key=f879...2e9b
+ somePeerPub1: c6b7...9469
+ somePeerPub2: eb2d...ca07
remoteAlicePub: 52be...3c14
+ mcastAll: .*:5400
}
@end verbatim
And now you can more conveniently and safely specify:
@example
-$ nncp-daemon -yggdrasil "myprv;bindPublic,bindLocalhost;;defPeers"
+$ nncp-daemon -yggdrasil "yggdrasils://myprv:6789"\
+"?bind=bindPublic&bind=bindLocalhost"\
+"&peer=peerBE&peer=peerRU"\
+"&pub=somePeerPub1&pub=somePeerPub2"\
+"&mcast=mcastAll&mcast=lo0"
@end example
@item
Make calls to that node from another ones, by using
-@code{yggdrasil:}-address, that takes remote host's public key, our
-host's private key and list of Yggdrasil peers entrypoints. Similarly to
-@option{-yggdrasil} option, it is ";"-separated list too:
+@code{yggdrasilc://}-address, similarly:
+
+@example
+yggdrasilc://PUB[:PORT]?prv=PRV[&peer=PEER][&mcast=REGEX[:PORT]]
+@end example
+
+where @code{PUB} is remote node's public key.
@example
-$ nncp-call alice "yggdrasil:remoteAlicePub;myprv;bindLocalhost,tcp://some.other.entrypoint"
+$ nncp-call alice "yggdrasilc://remoteAlicePub?prv=myprv&mcast=mcastAll"
@end example
@end enumerate
+
+Per private key Yggdrasil core goroutine is started when first call is
+initiated and stays until program is finished. You can have multiple
+Yggdrasil-related private keys and multiple (Yggdrasil) cores will work
+simultaneously. But running multiple cores for one private key with
+varying configuration (except for destination public key of course) is
+not supported.