From 2d36105eebae954c39225fefdc829f1c76b1e28d Mon Sep 17 00:00:00 2001 From: vadym Date: Thu, 9 Sep 2021 10:55:30 +0300 Subject: [PATCH] cleaned up develop branch --- CHANGELOG.md | 64 ++--- README.md | 32 ++- build | 2 +- cmd/mesh/main.go | 8 +- cmd/meshctl/main.go | 2 +- contrib/deb/generate.sh | 8 +- contrib/macos/create-pkg.sh | 16 +- contrib/msi/build-msi.sh | 38 +-- src/config/config.go | 21 +- src/core/api.go | 6 +- src/core/core.go | 8 +- src/defaults/defaults_windows.go | 4 +- src/multicast/multicast.go | 4 +- src/tuntap/ckr.go | 430 ------------------------------- src/tuntap/conn.go | 227 ---------------- src/tuntap/tun.go | 6 +- src/util/util.go | 43 ---- 17 files changed, 102 insertions(+), 817 deletions(-) delete mode 100644 src/tuntap/ckr.go delete mode 100644 src/tuntap/conn.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c059959..761d97e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,9 +27,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.4.0] - 2021-07-04 ### Added -- New routing scheme, which is backwards incompatible with previous versions of Mesh +- New routing scheme, which is backwards incompatible with previous versions of Yggdrasil - The wire protocol version number, exchanged as part of the peer setup handshake, has been increased to 0.4 - - Nodes running this new version **will not** be able to peer with earlier versions of Mesh + - Nodes running this new version **will not** be able to peer with earlier versions of Yggdrasil - Please note that **the network may be temporarily unstable** while infrastructure is being upgraded to the new release - TLS connections now use public key pinning - If no public key was already pinned, then the public key received as part of the TLS handshake is pinned to the connection @@ -38,7 +38,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed - IP addresses are now derived from ed25519 public (signing) keys - Previously, addresses were derived from a hash of X25519 (Diffie-Hellman) keys - - Importantly, this means that **all internal IPv6 addresses will change with this release** — this will affect anyone running public services or relying on Mesh for remote access + - Importantly, this means that **all internal IPv6 addresses will change with this release** — this will affect anyone running public services or relying on Yggdrasil for remote access - It is now recommended to peer over TLS - Link-local peers from multicast peer discovery will now connect over TLS, with the key from the multicast beacon pinned to the connection - `socks://` peers now expect the destination endpoint to be a `tls://` listener, instead of a `tcp://` listener @@ -64,7 +64,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Removed - Tunnel routing (a.k.a. crypto-key routing or "CKR") has been removed - It was far too easy to accidentally break routing altogether by capturing the route to peers with the TUN adapter - - We recommend tunnelling an existing standard over Mesh instead (e.g. `ip6gre`, `ip6gretap` or other similar encapsulations, using Mesh IPv6 addresses as the tunnel endpoints) + - We recommend tunnelling an existing standard over Yggdrasil instead (e.g. `ip6gre`, `ip6gretap` or other similar encapsulations, using Yggdrasil IPv6 addresses as the tunnel endpoints) - All `TunnelRouting` configuration options will no longer take effect - Session firewall has been removed - This was never a true firewall — it didn't behave like a stateful IP firewall, often allowed return traffic unexpectedly and was simply a way to prevent a node from being flooded with unwanted sessions, so the name could be misleading and usually lead to a false sense of security @@ -109,7 +109,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - By encryption public key: `tcp://host:port?curve25519=key` - By both: `tcp://host:port?ed25519=key&curve25519=key` - By multiple, in case of DNS round-robin or similar: `tcp://host:port?curve25519=key&curve25519=key&ed25519=key&ed25519=key` -- Some checks to prevent Mesh-over-Mesh peerings have been added +- Some checks to prevent Yggdrasil-over-Yggdrasil peerings have been added - Added support for SOCKS proxy authentication, e.g. `socks://user@password:host/...` ### Fixed @@ -136,14 +136,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Windows `.msi` installer files are now supported (bundling the Wireguard TUN driver) - NodeInfo code is now actorised, should be more reliable - The DHT now tries to store the two closest nodes in either direction instead of one, such that if a node goes offline, the replacement is already known -- The Mesh API now supports dialing a remote node using the public key instead of the Node ID +- The Yggdrasil API now supports dialing a remote node using the public key instead of the Node ID ### Changed - The `-loglevel` command line parameter is now cumulative and automatically includes all levels below the one specified - DHT search code has been significantly simplified and processes rumoured nodes in parallel, speeding up search time - DHT search results are now sorted - The systemd service now handles configuration generation in a different unit -- The Mesh API now returns public keys instead of node IDs when querying for local and remote addresses +- The Yggdrasil API now returns public keys instead of node IDs when querying for local and remote addresses ### Fixed - The multicast code no longer panics when shutting down the node @@ -159,7 +159,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - New API functions `SetMaximumSessionMTU` and `GetMaximumSessionMTU` - New command line parameters `-address` and `-subnet` for getting the address/subnet from the config file, for use with `-useconffile` or `-useconf` -- A warning is now produced in the Mesh output at startup when the MTU in the config is invalid or has been adjusted for some reason +- A warning is now produced in the Yggdrasil output at startup when the MTU in the config is invalid or has been adjusted for some reason ### Changed - On Linux, outgoing `InterfacePeers` connections now use `SO_BINDTODEVICE` to prefer an outgoing interface @@ -175,10 +175,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.3.11] - 2019-10-25 ### Added -- Support for TLS listeners and peers has been added, allowing the use of `tls://host:port` in `Peers`, `InterfacePeers` and `Listen` configuration settings - this allows hiding Mesh peerings inside regular TLS connections +- Support for TLS listeners and peers has been added, allowing the use of `tls://host:port` in `Peers`, `InterfacePeers` and `Listen` configuration settings - this allows hiding Yggdrasil peerings inside regular TLS connections ### Changed -- Go 1.13 or later is now required for building Mesh +- Go 1.13 or later is now required for building Yggdrasil - Some exported API functions have been updated to work with standard Go interfaces: - `net.Conn` instead of `mesh.Conn` - `net.Dialer` (the interface it would satisfy if it wasn't a concrete type) instead of `mesh.Dialer` @@ -195,17 +195,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - The core library now includes several unit tests for peering and `mesh.Conn` connections ### Changed -- On recent Linux kernels, Mesh will now set the `tcp_congestion_control` algorithm used for its own TCP sockets to [BBR](https://github.com/google/bbr), which reduces latency under load -- The systemd service configuration in `contrib` (and, by extension, some of our packages) now attempts to load the `tun` module, in case TUN/TAP support is available but not loaded, and it restricts Mesh to the `CAP_NET_ADMIN` capability for managing the TUN/TAP adapter, rather than letting it do whatever the (typically `root`) user can do +- On recent Linux kernels, Yggdrasil will now set the `tcp_congestion_control` algorithm used for its own TCP sockets to [BBR](https://github.com/google/bbr), which reduces latency under load +- The systemd service configuration in `contrib` (and, by extension, some of our packages) now attempts to load the `tun` module, in case TUN/TAP support is available but not loaded, and it restricts Yggdrasil to the `CAP_NET_ADMIN` capability for managing the TUN/TAP adapter, rather than letting it do whatever the (typically `root`) user can do ### Fixed - The `mesh.Conn.RemoteAddr()` function no longer blocks, fixing a deadlock when CKR is used while under heavy load ## [0.3.9] - 2019-09-27 ### Added -- Mesh will now complain more verbosely when a peer URI is incorrectly formatted +- Yggdrasil will now complain more verbosely when a peer URI is incorrectly formatted - Soft-shutdown methods have been added, allowing a node to shut down gracefully when terminated -- New multicast interval logic which sends multicast beacons more often when Mesh is first started to increase the chance of finding nearby nodes quickly after startup +- New multicast interval logic which sends multicast beacons more often when Yggdrasil is first started to increase the chance of finding nearby nodes quickly after startup ### Changed - The switch now buffers packets more eagerly in an attempt to give the best link a chance to send, which appears to reduce packet reordering when crossing aggregate sets of peerings @@ -223,7 +223,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - A race condition when dialing a remote node by both the node address and routed prefix simultaneously has been fixed - A race condition between the router and the dial code resulting in a panic has been fixed - A panic which could occur when the TUN/TAP interface disappears (e.g. during soft-shutdown) has been fixed -- A bug in the semantic versioning script which accompanies Mesh for builds has been fixed +- A bug in the semantic versioning script which accompanies Yggdrasil for builds has been fixed - A panic which could occur when the TUN/TAP interface reads an undersized/corrupted packet has been fixed ### Removed @@ -231,7 +231,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.3.8] - 2019-08-21 ### Changed -- Mesh can now send multiple packets from the switch at once, which results in improved throughput with smaller packets or lower MTUs +- Yggdrasil can now send multiple packets from the switch at once, which results in improved throughput with smaller packets or lower MTUs - Performance has been slightly improved by not allocating cancellations where not necessary - Crypto-key routing options have been renamed for clarity - `IPv4Sources` is now named `IPv4LocalSubnets` @@ -243,10 +243,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - New nonce tracking should help to reduce the number of packets dropped as a result of multiple/aggregate paths or congestion control in the switch ### Fixed -- A deadlock was fixed in the session code which could result in Mesh failing to pass traffic after some time +- A deadlock was fixed in the session code which could result in Yggdrasil failing to pass traffic after some time ### Security -- Address verification was not strict enough, which could result in a malicious session sending traffic with unexpected or spoofed source or destination addresses which Mesh could fail to reject +- Address verification was not strict enough, which could result in a malicious session sending traffic with unexpected or spoofed source or destination addresses which Yggdrasil could fail to reject - Versions `0.3.6` and `0.3.7` are vulnerable - users of these versions should upgrade as soon as possible - Versions `0.3.5` and earlier are not affected @@ -259,7 +259,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed - A number of significant performance regressions introduced in version 0.3.6 have been fixed, resulting in better performance - Flow labels are now used to prioritise traffic flows again correctly -- In low-traffic scenarios where there are multiple peerings between a pair of nodes, Mesh now prefers the most active peering instead of the least active, helping to reduce packet reordering +- In low-traffic scenarios where there are multiple peerings between a pair of nodes, Yggdrasil now prefers the most active peering instead of the least active, helping to reduce packet reordering - The `Listen` statement, when configured as a string rather than an array, will now be parsed correctly - The admin socket now returns `coords` as a correct array of unsigned 64-bit integers, rather than the internal representation - The admin socket now returns `box_pub_key` in string format again @@ -271,18 +271,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.3.6] - 2019-08-03 ### Added -- Mesh now has a public API with interfaces such as `mesh.ConnDialer`, `mesh.ConnListener` and `mesh.Conn` for using Mesh as a transport directly within applications +- Yggdrasil now has a public API with interfaces such as `mesh.ConnDialer`, `mesh.ConnListener` and `mesh.Conn` for using Yggdrasil as a transport directly within applications - Session gatekeeper functions, part of the API, which can be used to control whether to allow or reject incoming or outgoing sessions dynamically (compared to the previous fixed whitelist/blacklist approach) - Support for logging to files or syslog (where supported) - Platform defaults now include the ability to set sane defaults for multicast interfaces ### Changed -- Following a massive refactoring exercise, Mesh's codebase has now been broken out into modules +- Following a massive refactoring exercise, Yggdrasil's codebase has now been broken out into modules - Core node functionality in the `mesh` package with a public API - - This allows Mesh to be integrated directly into other applications and used as a transport - - IP-specific code has now been moved out of the core `mesh` package, making Mesh effectively protocol-agnostic + - This allows Yggdrasil to be integrated directly into other applications and used as a transport + - IP-specific code has now been moved out of the core `mesh` package, making Yggdrasil effectively protocol-agnostic - Multicast peer discovery functionality is now in the `multicast` package -- Admin socket functionality is now in the `admin` package and uses the Mesh public API +- Admin socket functionality is now in the `admin` package and uses the Yggdrasil public API - TUN/TAP, ICMPv6 and all IP-specific functionality is now in the `tuntap` package - `PPROF` debug output is now sent to `stderr` instead of `stdout` - Node IPv6 addresses on macOS are now configured as `secured` @@ -290,7 +290,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed - Multicast discovery is no longer disabled if the nominated interfaces aren't available on the system yet, e.g. during boot -- Multicast interfaces are now re-evaluated more frequently so that Mesh doesn't need to be restarted to use interfaces that have become available since startup +- Multicast interfaces are now re-evaluated more frequently so that Yggdrasil doesn't need to be restarted to use interfaces that have become available since startup - Admin socket error cases are now handled better - Various fixes in the TUN/TAP module, particularly surrounding Windows platform support - Invalid keys will now cause the node to fail to start, rather than starting but silently not working as before @@ -313,9 +313,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - New multicast behaviour where each multicast interface is given its own link-local listener and does not depend on the `Listen` configuration - Blocking detection in the switch to avoid parenting a blocked peer - Support for adding and removing listeners and multicast interfaces when reloading configuration during runtime -- Mesh will now attempt to clean up UNIX admin sockets on startup if left behind by a previous crash +- Yggdrasil will now attempt to clean up UNIX admin sockets on startup if left behind by a previous crash - Admin socket `getTunnelRouting` and `setTunnelRouting` calls for enabling and disabling crypto-key routing during runtime -- On macOS, Mesh will now try to wake up AWDL on start-up when `awdl0` is a configured multicast interface, to keep it awake after system sleep, and to stop waking it when no longer needed +- On macOS, Yggdrasil will now try to wake up AWDL on start-up when `awdl0` is a configured multicast interface, to keep it awake after system sleep, and to stop waking it when no longer needed - Added `LinkLocalTCPPort` option for controlling the port number that link-local TCP listeners will listen on by default when setting up `MulticastInterfaces` (a node restart is currently required for changes to `LinkLocalTCPPort` to take effect - it cannot be updated by reloading config during runtime) ### Changed @@ -331,14 +331,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Handling of `getRoutes` etc in `meshctl` is now working - Local interface names are no longer leaked in multicast packets - Link-local TCP connections, particularly those initiated because of multicast beacons, are now always correctly scoped for the target interface -- Mesh now correctly responds to multicast interfaces going up and down during runtime +- Yggdrasil now correctly responds to multicast interfaces going up and down during runtime ## [0.3.3] - 2019-02-18 ### Added - Dynamic reconfiguration, which allows reloading the configuration file to make changes during runtime by sending a `SIGHUP` signal (note: this only works with `-useconffile` and not `-useconf` and currently reconfiguring TUN/TAP is not supported) -- Support for building Mesh as an iOS or Android framework if the appropriate tools (e.g. `gomobile`/`gobind` + SDKs) are available +- Support for building Yggdrasil as an iOS or Android framework if the appropriate tools (e.g. `gomobile`/`gobind` + SDKs) are available - Connection contexts used for TCP connections which allow more exotic socket options to be set, e.g. - - Reusing the multicast socket to allow multiple running Mesh instances without having to disable multicast + - Reusing the multicast socket to allow multiple running Yggdrasil instances without having to disable multicast - Allowing supported Macs to peer with other nearby Macs that aren't even on the same Wi-Fi network using AWDL - Flexible logging support, which allows for logging at different levels of verbosity @@ -392,7 +392,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.3.0] - 2018-12-12 ### Added -- Crypto-key routing support for tunnelling both IPv4 and IPv6 over Mesh +- Crypto-key routing support for tunnelling both IPv4 and IPv6 over Yggdrasil - Add advanced `SwitchOptions` in configuration file for tuning the switch - Add `dhtPing` to the admin socket to aid in crawling the network - New macOS .pkgs built automatically by CircleCI @@ -409,7 +409,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Cleaned up some of the parameter naming in the admin socket - Latency-based parent selection for the switch instead of uptime-based (should help to avoid high latency links somewhat) - Real peering endpoints now shown in the admin socket `getPeers` call to help identify peerings -- Reuse the multicast port on supported platforms so that multiple Mesh processes can run +- Reuse the multicast port on supported platforms so that multiple Yggdrasil processes can run - `meshctl` now has more useful help text (with `-help` or when no arguments passed) ### Fixed diff --git a/README.md b/README.md index 03b7ebc7..1a238ce6 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,19 @@ -# RiV-mesh +# Yggdrasil [![CircleCI](https://circleci.com/gh/RiV-chain/RiV-mesh.svg?style=shield&circle-token=:circle-token )](https://circleci.com/gh/RiV-chain/RiV-mesh) ## Introduction -RiV-mesh is an implementation of a fully end-to-end encrypted IPv6 -network, created in the scope to produce the Transport Layer for RiV Chain Blockchain, -also to facilitate secure conectivity between a wide spectrum of endpoint devices like IoT devices, -desktop computers or even routers. -It is lightweight, self-arranging, supported on multiple -platforms and allows pretty much any IPv6-capable application -to communicate securely with other RiV-mesh nodes. -RiV-mesh does not require you to have IPv6 Internet connectivity - it also works over IPv4. +Yggdrasil is an early-stage implementation of a fully end-to-end encrypted IPv6 +network. It is lightweight, self-arranging, supported on multiple platforms and +allows pretty much any IPv6-capable application to communicate securely with +other Yggdrasil nodes. Yggdrasil does not require you to have IPv6 Internet +connectivity - it also works over IPv4. ## Supported Platforms -RiV-mesh works on a number of platforms, including Linux, macOS, Ubiquiti +Yggdrasil works on a number of platforms, including Linux, macOS, Ubiquiti EdgeRouter, VyOS, Windows, FreeBSD, OpenBSD and OpenWrt. Please see our [Installation](https://RiV-chain.github.io/installation.html) @@ -57,7 +54,7 @@ programmatically): You will need to edit the `mesh.conf` file to add or remove peers, modify other configuration such as listen addresses or multicast addresses, etc. -### Run RiV-mesh +### Run Yggdrasil To run with the generated static configuration: ``` @@ -71,23 +68,24 @@ at each startup, instead of using a static configuration file): ./mesh -autoconf ``` -You will likely need to run RiV-mesh as a privileged user or under `sudo`, +You will likely need to run Yggdrasil as a privileged user or under `sudo`, unless you have permission to create TUN/TAP adapters. On Linux this can be done -by giving the RiV-mesh binary the `CAP_NET_ADMIN` capability. +by giving the Yggdrasil binary the `CAP_NET_ADMIN` capability. ## Documentation Documentation is available [on our website](https://RiV-chain.github.io). -- [Installing RiV-mesh](https://RiV-chain.github.io/installation.html) -- [Configuring RiV-mesh](https://RiV-chain.github.io/configuration.html) +- [Installing Yggdrasil](https://RiV-chain.github.io/installation.html) +- [Configuring Yggdrasil](https://RiV-chain.github.io/configuration.html) - [Frequently asked questions](https://RiV-chain.github.io/faq.html) - [Version changelog](CHANGELOG.md) ## Community -Feel free to join us on our [Telegram -channel](https://t.me/rivchain). +Feel free to join us on our [Matrix +channel](https://matrix.to/#/#mesh:matrix.org) at `#mesh:matrix.org` +or in the `#mesh` IRC channel on [libera.chat](https://libera.chat). ## License diff --git a/build b/build index e7338800..9358fd48 100755 --- a/build +++ b/build @@ -33,7 +33,7 @@ fi if [ $IOS ]; then echo "Building framework for iOS" go get golang.org/x/mobile/bind - gomobile bind -target ios -tags mobile -o Mesh.framework -ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \ + gomobile bind -target ios -tags mobile -o Yggdrasil.framework -ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \ github.com/RiV-chain/RiV-mesh-extras/src/mobile \ github.com/RiV-chain/RiV-mesh/src/config elif [ $ANDROID ]; then diff --git a/cmd/mesh/main.go b/cmd/mesh/main.go index 082d2394..78c268be 100644 --- a/cmd/mesh/main.go +++ b/cmd/mesh/main.go @@ -224,7 +224,7 @@ func getArgs() yggArgs { } } -// The main function is responsible for configuring and starting Mesh. +// The main function is responsible for configuring and starting Yggdrasil. func run(args yggArgs, ctx context.Context, done chan struct{}) { defer close(done) // Create a new logger that logs output to stdout. @@ -325,11 +325,11 @@ func run(args yggArgs, ctx context.Context, done chan struct{}) { default: } - // Setup the Mesh node itself. The node{} type includes a Core, so we + // Setup the Yggdrasil node itself. The node{} type includes a Core, so we // don't need to create this manually. n := node{config: cfg} - // Now start Mesh - this starts the DHT, router, switch and other core - // components needed for Mesh to operate + // Now start Yggdrasil - this starts the DHT, router, switch and other core + // components needed for Yggdrasil to operate if err = n.core.Start(cfg, logger); err != nil { logger.Errorln("An error occurred during startup") panic(err) diff --git a/cmd/meshctl/main.go b/cmd/meshctl/main.go index 9be9fff0..6d4e4be4 100644 --- a/cmd/meshctl/main.go +++ b/cmd/meshctl/main.go @@ -43,7 +43,7 @@ func run() int { if cmdLineEnv.ver { fmt.Println("Build name:", version.BuildName()) fmt.Println("Build version:", version.BuildVersion()) - fmt.Println("To get the version number of the running Mesh node, run", os.Args[0], "getSelf") + fmt.Println("To get the version number of the running Yggdrasil node, run", os.Args[0], "getSelf") return 0 } diff --git a/contrib/deb/generate.sh b/contrib/deb/generate.sh index db915abc..f13fc5cd 100644 --- a/contrib/deb/generate.sh +++ b/contrib/deb/generate.sh @@ -53,11 +53,11 @@ Architecture: $PKGARCH Replaces: $PKGREPLACES Conflicts: $PKGREPLACES Maintainer: Neil Alexander -Description: Mesh Network - Mesh is an early-stage implementation of a fully end-to-end encrypted IPv6 +Description: Yggdrasil Network + Yggdrasil is an early-stage implementation of a fully end-to-end encrypted IPv6 network. It is lightweight, self-arranging, supported on multiple platforms and allows pretty much any IPv6-capable application to communicate securely with - other Mesh nodes. + other Yggdrasil nodes. EOF cat > /tmp/$PKGNAME/debian/copyright << EOF Please see https://github.com/RiV-chain/RiV-mesh/ @@ -93,7 +93,7 @@ then fi else echo "Generating initial configuration file /etc/mesh.conf" - echo "Please familiarise yourself with this file before starting Mesh" + echo "Please familiarise yourself with this file before starting Yggdrasil" sh -c 'umask 0027 && /usr/bin/mesh -genconf > /etc/mesh.conf' chgrp mesh /etc/mesh.conf fi diff --git a/contrib/macos/create-pkg.sh b/contrib/macos/create-pkg.sh index 0b4fe7af..ff4812e3 100755 --- a/contrib/macos/create-pkg.sh +++ b/contrib/macos/create-pkg.sh @@ -45,19 +45,19 @@ cat > pkgbuild/scripts/postinstall << EOF # Normalise the config if it exists, generate it if it doesn't if [ -f /etc/mesh.conf ]; then - mkdir -p /Library/Preferences/Mesh - echo "Backing up configuration file to /Library/Preferences/Mesh/mesh.conf.`date +%Y%m%d`" - cp /etc/mesh.conf /Library/Preferences/Mesh/mesh.conf.`date +%Y%m%d` + mkdir -p /Library/Preferences/Yggdrasil + echo "Backing up configuration file to /Library/Preferences/Yggdrasil/mesh.conf.`date +%Y%m%d`" + cp /etc/mesh.conf /Library/Preferences/Yggdrasil/mesh.conf.`date +%Y%m%d` echo "Normalising /etc/mesh.conf" - /usr/local/bin/mesh -useconffile /Library/Preferences/Mesh/mesh.conf.`date +%Y%m%d` -normaliseconf > /etc/mesh.conf + /usr/local/bin/mesh -useconffile /Library/Preferences/Yggdrasil/mesh.conf.`date +%Y%m%d` -normaliseconf > /etc/mesh.conf else /usr/local/bin/mesh -genconf > /etc/mesh.conf fi -# Unload existing Mesh launchd service, if possible +# Unload existing Yggdrasil launchd service, if possible test -f /Library/LaunchDaemons/mesh.plist && (launchctl unload /Library/LaunchDaemons/mesh.plist || true) -# Load Mesh launchd service and start Mesh +# Load Yggdrasil launchd service and start Yggdrasil launchctl load /Library/LaunchDaemons/mesh.plist EOF @@ -93,7 +93,7 @@ EOF cat > pkgbuild/flat/Distribution << EOF - Mesh (${PKGNAME}-${PKGVERSION}) + Yggdrasil (${PKGNAME}-${PKGVERSION}) @@ -101,7 +101,7 @@ cat > pkgbuild/flat/Distribution << EOF function pm_install_check() { if(!(system.compareVersions(system.version.ProductVersion,'10.10') >= 0)) { my.result.title = 'Failure'; - my.result.message = 'You need at least Mac OS X 10.10 to install Mesh.'; + my.result.message = 'You need at least Mac OS X 10.10 to install Yggdrasil.'; my.result.type = 'Fatal'; return false; } diff --git a/contrib/msi/build-msi.sh b/contrib/msi/build-msi.sh index 03cf9133..9d729ca0 100644 --- a/contrib/msi/build-msi.sh +++ b/contrib/msi/build-msi.sh @@ -1,6 +1,6 @@ #!/bin/sh -# This script generates an MSI file for Mesh for a given architecture. It +# This script generates an MSI file for Yggdrasil for a given architecture. It # needs to run on Windows within MSYS2 and Go 1.13 or later must be installed on # the system and within the PATH. This is ran currently by Appveyor (see # appveyor.yml in the repository root) for both x86 and x64. @@ -47,7 +47,7 @@ then ) fi -# Build Mesh! +# Build Yggdrasil! [ "${PKGARCH}" == "x64" ] && GOOS=windows GOARCH=amd64 CGO_ENABLED=0 ./build [ "${PKGARCH}" == "x86" ] && GOOS=windows GOARCH=386 CGO_ENABLED=0 ./build [ "${PKGARCH}" == "arm" ] && GOOS=windows GOARCH=arm CGO_ENABLED=0 ./build @@ -55,12 +55,12 @@ fi # Create the postinstall script cat > updateconfig.bat << EOF -if not exist %ALLUSERSPROFILE%\\Mesh ( - mkdir %ALLUSERSPROFILE%\\Mesh +if not exist %ALLUSERSPROFILE%\\Yggdrasil ( + mkdir %ALLUSERSPROFILE%\\Yggdrasil ) -if not exist %ALLUSERSPROFILE%\\Mesh\\mesh.conf ( +if not exist %ALLUSERSPROFILE%\\Yggdrasil\\mesh.conf ( if exist mesh.exe ( - mesh.exe -genconf > %ALLUSERSPROFILE%\\Mesh\\mesh.conf + mesh.exe -genconf > %ALLUSERSPROFILE%\\Yggdrasil\\mesh.conf ) ) EOF @@ -93,9 +93,9 @@ else fi if [ $PKGNAME != "master" ]; then - PKGDISPLAYNAME="Mesh Network (${PKGNAME} branch)" + PKGDISPLAYNAME="Yggdrasil Network (${PKGNAME} branch)" else - PKGDISPLAYNAME="Mesh Network" + PKGDISPLAYNAME="Yggdrasil Network" fi # Generate the wix.xml file @@ -114,8 +114,8 @@ cat > wix.xml << EOF wix.xml << EOF - + wix.xml << EOF wix.xml << EOF wix.xml << EOF - + @@ -200,7 +200,7 @@ cat > wix.xml << EOF jm - }) - - // Clear the cache as this route might change future routing - // Setting an empty slice keeps the memory whereas nil invokes GC - for k := range *routingcache { - delete(*routingcache, k) - } - - c.tun.log.Infoln("Added CKR remote subnet", cidr) - return nil - } -} - -// Looks up the most specific route for the given address (with the address -// length specified in bytes) from the crypto-key routing table. An error is -// returned if the address is not suitable or no route was found. -func (c *cryptokey) getPublicKeyForAddress(addr address.Address, addrlen int) (ed25519.PublicKey, error) { - - // Check if the address is a valid Mesh address - if so it - // is exempt from all CKR checking - if addr.IsValid() { - return ed25519.PublicKey{}, errors.New("cannot look up CKR for Mesh addresses") - } - - // Build our references to the routing table and cache - var routingtable *[]cryptokey_route - var routingcache *map[address.Address]cryptokey_route - - // Check if the prefix is IPv4 or IPv6 - if addrlen == net.IPv6len { - routingcache = &c.ipv6cache - } else if addrlen == net.IPv4len { - routingcache = &c.ipv4cache - } else { - return ed25519.PublicKey{}, errors.New("unexpected prefix size") - } - - // Check if there's a cache entry for this addr - c.mutexcaches.RLock() - if route, ok := (*routingcache)[addr]; ok { - c.mutexcaches.RUnlock() - return route.destination, nil - } - c.mutexcaches.RUnlock() - - c.mutexremotes.RLock() - defer c.mutexremotes.RUnlock() - - // Check if the prefix is IPv4 or IPv6 - if addrlen == net.IPv6len { - routingtable = &c.ipv6remotes - } else if addrlen == net.IPv4len { - routingtable = &c.ipv4remotes - } else { - return ed25519.PublicKey{}, errors.New("unexpected prefix size") - } - - // No cache was found - start by converting the address into a net.IP - ip := make(net.IP, addrlen) - copy(ip[:addrlen], addr[:]) - - // Check if we have a route. At this point c.ipv6remotes should be - // pre-sorted so that the most specific routes are first - for _, route := range *routingtable { - // Does this subnet match the given IP? - if route.subnet.Contains(ip) { - c.mutexcaches.Lock() - defer c.mutexcaches.Unlock() - - // Check if the routing cache is above a certain size, if it is evict - // a random entry so we can make room for this one. We take advantage - // of the fact that the iteration order is random here - for k := range *routingcache { - if len(*routingcache) < 1024 { - break - } - delete(*routingcache, k) - } - - // Cache the entry for future packets to get a faster lookup - (*routingcache)[addr] = route - - // Return the boxPubKey - return route.destination, nil - } - } - - // No route was found if we got to this point - return ed25519.PublicKey{}, fmt.Errorf("no route to %s", ip.String()) -} - -// Removes a source subnet, which allows traffic with these source addresses to -// be tunnelled using crypto-key routing. -func (c *cryptokey) removeLocalSubnet(cidr string) error { - c.mutexlocals.Lock() - defer c.mutexlocals.Unlock() - - // Is the CIDR we've been given valid? - _, ipnet, err := net.ParseCIDR(cidr) - if err != nil { - return err - } - - // Get the prefix length and size - _, prefixsize := ipnet.Mask.Size() - - // Build our references to the routing sources - var routingsources *[]net.IPNet - - // Check if the prefix is IPv4 or IPv6 - if prefixsize == net.IPv6len*8 { - routingsources = &c.ipv6locals - } else if prefixsize == net.IPv4len*8 { - routingsources = &c.ipv4locals - } else { - return errors.New("unexpected prefix size") - } - - // Check if we already have this CIDR - for idx, subnet := range *routingsources { - if subnet.String() == ipnet.String() { - *routingsources = append((*routingsources)[:idx], (*routingsources)[idx+1:]...) - c.tun.log.Infoln("Removed CKR local subnet", cidr) - return nil - } - } - return errors.New("local subnet not found") -} - -// Removes a destination route for the given CIDR to be tunnelled to the node -// with the given BoxPubKey. -func (c *cryptokey) removeRemoteSubnet(cidr string, dest string) error { - c.mutexremotes.Lock() - c.mutexcaches.Lock() - defer c.mutexremotes.Unlock() - defer c.mutexcaches.Unlock() - - // Is the CIDR we've been given valid? - _, ipnet, err := net.ParseCIDR(cidr) - if err != nil { - return err - } - - // Get the prefix length and size - _, prefixsize := ipnet.Mask.Size() - - // Build our references to the routing table and cache - var routingtable *[]cryptokey_route - var routingcache *map[address.Address]cryptokey_route - - // Check if the prefix is IPv4 or IPv6 - if prefixsize == net.IPv6len*8 { - routingtable = &c.ipv6remotes - routingcache = &c.ipv6cache - } else if prefixsize == net.IPv4len*8 { - routingtable = &c.ipv4remotes - routingcache = &c.ipv4cache - } else { - return errors.New("unexpected prefix size") - } - - // Decode the public key - bpk, err := hex.DecodeString(dest) - if err != nil { - return err - } else if len(bpk) != ed25519.PrivateKeySize { - return fmt.Errorf("incorrect key length for %s", dest) - } - netStr := ipnet.String() - - for idx, route := range *routingtable { - if bytes.Equal(route.destination[:], bpk) && route.subnet.String() == netStr { - *routingtable = append((*routingtable)[:idx], (*routingtable)[idx+1:]...) - for k := range *routingcache { - delete(*routingcache, k) - } - c.tun.log.Infof("Removed CKR remote subnet %s via %s\n", cidr, dest) - return nil - } - } - return fmt.Errorf("route does not exists for %s", cidr) -} diff --git a/src/tuntap/conn.go b/src/tuntap/conn.go deleted file mode 100644 index 4a9c8fcb..00000000 --- a/src/tuntap/conn.go +++ /dev/null @@ -1,227 +0,0 @@ -package tuntap - -import ( - "bytes" - "crypto/ed25519" - "errors" - "time" - - "github.com/Arceliar/phony" - "github.com/RiV-chain/RiV-mesh/src/address" - "github.com/RiV-chain/RiV-mesh/src/util" - "github.com/RiV-chain/RiV-mesh/src/mesh" - "golang.org/x/net/icmp" - "golang.org/x/net/ipv6" -) - -const tunConnTimeout = 2 * time.Minute - -type tunConn struct { - phony.Inbox - tun *TunAdapter - conn *mesh.Conn - addr address.Address - snet address.Subnet - stop chan struct{} - alive *time.Timer // From calling time.AfterFunc -} - -func (s *tunConn) close() { - s.tun.Act(s, s._close_from_tun) -} - -func (s *tunConn) _close_from_tun() { - go s.conn.Close() // Just in case it blocks on actor operations - delete(s.tun.addrToConn, s.addr) - delete(s.tun.subnetToConn, s.snet) - func() { - defer func() { recover() }() - close(s.stop) // Closes reader/writer goroutines - }() -} - -func (s *tunConn) _read(bs []byte) (err error) { - select { - case <-s.stop: - err = errors.New("session was already closed") - return - default: - } - if len(bs) == 0 { - err = errors.New("read packet with 0 size") - return - } - ipv4 := len(bs) > 20 && bs[0]&0xf0 == 0x40 - ipv6 := len(bs) > 40 && bs[0]&0xf0 == 0x60 - isCGA := true - // Check source addresses - switch { - case ipv6 && bs[8] == 0x02 && bytes.Equal(s.addr[:16], bs[8:24]): // source - case ipv6 && bs[8] == 0x03 && bytes.Equal(s.snet[:8], bs[8:16]): // source - default: - isCGA = false - } - // Check destination addresses - switch { - case ipv6 && bs[24] == 0x02 && bytes.Equal(s.tun.addr[:16], bs[24:40]): // destination - case ipv6 && bs[24] == 0x03 && bytes.Equal(s.tun.subnet[:8], bs[24:32]): // destination - default: - isCGA = false - } - // Decide how to handle the packet - var skip bool - switch { - case isCGA: // Allowed - case s.tun.ckr.isEnabled() && (ipv4 || ipv6): - var srcAddr address.Address - var dstAddr address.Address - var addrlen int - if ipv4 { - copy(srcAddr[:], bs[12:16]) - copy(dstAddr[:], bs[16:20]) - addrlen = 4 - } - if ipv6 { - copy(srcAddr[:], bs[8:24]) - copy(dstAddr[:], bs[24:40]) - addrlen = 16 - } - if !s.tun.ckr.isValidLocalAddress(dstAddr, addrlen) { - // The destination address isn't in our CKR allowed range - skip = true - } else if key, err := s.tun.ckr.getPublicKeyForAddress(srcAddr, addrlen); err == nil { - if *s.conn.RemoteAddr().(*ed25519.PublicKey) == key { - // This is the one allowed CKR case, where source and destination addresses are both good - } else { - // The CKR key associated with this address doesn't match the sender's NodeID - skip = true - } - } else { - // We have no CKR route for this source address - skip = true - } - default: - skip = true - } - if skip { - err = errors.New("address not allowed") - return - } - s.tun.writer.writeFrom(s, bs) - s.stillAlive() - return -} - -func (s *tunConn) writeFrom(from phony.Actor, bs []byte) { - s.Act(from, func() { - s._write(bs) - }) -} - -func (s *tunConn) _write(bs []byte) (err error) { - select { - case <-s.stop: - err = errors.New("session was already closed") - return - default: - } - v4 := len(bs) > 20 && bs[0]&0xf0 == 0x40 - v6 := len(bs) > 40 && bs[0]&0xf0 == 0x60 - isCGA := true - // Check source addresses - switch { - case v6 && bs[8] == 0x02 && bytes.Equal(s.tun.addr[:16], bs[8:24]): // source - case v6 && bs[8] == 0x03 && bytes.Equal(s.tun.subnet[:8], bs[8:16]): // source - default: - isCGA = false - } - // Check destiantion addresses - switch { - case v6 && bs[24] == 0x02 && bytes.Equal(s.addr[:16], bs[24:40]): // destination - case v6 && bs[24] == 0x03 && bytes.Equal(s.snet[:8], bs[24:32]): // destination - default: - isCGA = false - } - // Decide how to handle the packet - var skip bool - switch { - case isCGA: // Allowed - case s.tun.ckr.isEnabled() && (v4 || v6): - var srcAddr address.Address - var dstAddr address.Address - var addrlen int - if v4 { - copy(srcAddr[:], bs[12:16]) - copy(dstAddr[:], bs[16:20]) - addrlen = 4 - } - if v6 { - copy(srcAddr[:], bs[8:24]) - copy(dstAddr[:], bs[24:40]) - addrlen = 16 - } - if !s.tun.ckr.isValidLocalAddress(srcAddr, addrlen) { - // The source address isn't in our CKR allowed range - skip = true - } else if key, err := s.tun.ckr.getPublicKeyForAddress(dstAddr, addrlen); err == nil { - if *s.conn.RemoteAddr().(*crypto.BoxPubKey) == key { - // This is the one allowed CKR case, where source and destination addresses are both good - } else { - // The CKR key associated with this address doesn't match the sender's NodeID - skip = true - } - } else { - // We have no CKR route for this destination address... why do we have the packet in the first place? - skip = true - } - default: - skip = true - } - if skip { - err = errors.New("address not allowed") - return - } - msg := mesh.FlowKeyMessage{ - FlowKey: util.GetFlowKey(bs), - Message: bs, - } - s.conn.WriteFrom(s, msg, func(err error) { - if err == nil { - // No point in wasting resources to send back an error if there was none - return - } - s.Act(s.conn, func() { - if e, eok := err.(mesh.ConnError); !eok { - if e.Closed() { - s.tun.log.Debugln(s.conn.String(), "TUN/TAP generic write debug:", err) - } else { - s.tun.log.Errorln(s.conn.String(), "TUN/TAP generic write error:", err) - } - } else if e.PacketTooBig() { - // TODO: This currently isn't aware of IPv4 for CKR - ptb := &icmp.PacketTooBig{ - MTU: int(e.PacketMaximumSize()), - Data: bs[:900], - } - if packet, err := CreateICMPv6(bs[8:24], bs[24:40], ipv6.ICMPTypePacketTooBig, 0, ptb); err == nil { - s.tun.writer.writeFrom(s, packet) - } - } else { - if e.Closed() { - s.tun.log.Debugln(s.conn.String(), "TUN/TAP conn write debug:", err) - } else { - s.tun.log.Errorln(s.conn.String(), "TUN/TAP conn write error:", err) - } - } - }) - }) - s.stillAlive() - return -} - -func (s *tunConn) stillAlive() { - if s.alive != nil { - s.alive.Stop() - } - s.alive = time.AfterFunc(tunConnTimeout, s.close) -} diff --git a/src/tuntap/tun.go b/src/tuntap/tun.go index 43852b59..da027f7d 100644 --- a/src/tuntap/tun.go +++ b/src/tuntap/tun.go @@ -28,7 +28,7 @@ import ( type MTU uint16 // TunAdapter represents a running TUN interface and extends the -// mesh.Adapter type. In order to use the TUN adapter with Mesh, you +// mesh.Adapter type. In order to use the TUN adapter with Yggdrasil, you // should pass this object to the mesh.SetRouterAdapter() function before // calling mesh.Start(). type TunAdapter struct { @@ -37,7 +37,6 @@ type TunAdapter struct { log *log.Logger addr address.Address subnet address.Subnet - ckr cryptokey mtu uint64 iface tun.Device phony.Inbox // Currently only used for _handlePacket from the reader, TODO: all the stuff that currently needs a mutex below @@ -93,7 +92,7 @@ func MaximumMTU() uint64 { } // Init initialises the TUN module. You must have acquired a Listener from -// the Mesh core before this point and it must not be in use elsewhere. +// the Yggdrasil core before this point and it must not be in use elsewhere. func (tun *TunAdapter) Init(rwc *ipv6rwc.ReadWriteCloser, config *config.NodeConfig, log *log.Logger, options interface{}) error { tun.rwc = rwc tun.config = config @@ -141,7 +140,6 @@ func (tun *TunAdapter) _start() error { } tun.rwc.SetMTU(tun.MTU()) tun.isOpen = true - tun.ckr.init(tun) tun.isEnabled = true go tun.read() go tun.write() diff --git a/src/util/util.go b/src/util/util.go index 653f98f3..229224ef 100644 --- a/src/util/util.go +++ b/src/util/util.go @@ -8,11 +8,6 @@ import ( "time" ) -type FlowKeyMessage struct { - FlowKey uint64 - Message []byte -} - // TimerStop stops a timer and makes sure the channel is drained, returns true if the timer was stopped before firing. func TimerStop(t *time.Timer) bool { stopped := t.Stop() @@ -40,41 +35,3 @@ func FuncTimeout(timeout time.Duration, f func()) bool { return false } } - -// GetFlowKey takes an IP packet as an argument and returns some information about the traffic flow. -// For IPv4 packets, this is derived from the source and destination protocol and port numbers. -// For IPv6 packets, this is derived from the FlowLabel field of the packet if this was set, otherwise it's handled like IPv4. -// The FlowKey is then used internally by Mesh for congestion control. -func GetFlowKey(bs []byte) uint64 { - // Work out the flowkey - this is used to determine which switch queue - // traffic will be pushed to in the event of congestion - var flowkey uint64 - // Get the IP protocol version from the packet - switch bs[0] & 0xf0 { - case 0x40: // IPv4 packet - ihl := (bs[0] & 0x0f) * 4 // whole IPv4 header length (min 20) - // 8 is minimum UDP packet length - if ihl >= 20 && len(bs)-int(ihl) >= 8 { - switch bs[9] /* protocol */ { - case 0x06 /* TCP */, 0x11 /* UDP */, 0x84 /* SCTP */ : - flowkey = uint64(bs[9])<<32 /* proto */ | - uint64(bs[ihl+0])<<24 | uint64(bs[ihl+1])<<16 /* sport */ | - uint64(bs[ihl+2])<<8 | uint64(bs[ihl+3]) /* dport */ - } - } - case 0x60: // IPv6 packet - // Check if the flowlabel was specified in the packet header - flowkey = uint64(bs[1]&0x0f)<<16 | uint64(bs[2])<<8 | uint64(bs[3]) - // If the flowlabel isn't present, make protokey from proto | sport | dport - // if the packet meets minimum UDP packet length - if flowkey == 0 && len(bs) >= 48 { - switch bs[9] /* protocol */ { - case 0x06 /* TCP */, 0x11 /* UDP */, 0x84 /* SCTP */ : - flowkey = uint64(bs[6])<<32 /* proto */ | - uint64(bs[40])<<24 | uint64(bs[41])<<16 /* sport */ | - uint64(bs[42])<<8 | uint64(bs[43]) /* dport */ - } - } - } - return flowkey -}