Merge commit '10025f9fa5503865918cbae2af5366afe7fd7c54' as 'components/mycelium'
This commit is contained in:
31
components/mycelium/.github/dependabot.yml
vendored
Normal file
31
components/mycelium/.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "cargo" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
mycelium:
|
||||
patterns:
|
||||
- "*"
|
||||
- package-ecosystem: "cargo" # See documentation for possible values
|
||||
directory: "/myceliumd" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
myceliumd:
|
||||
patterns:
|
||||
- "*"
|
||||
- package-ecosystem: "cargo" # See documentation for possible values
|
||||
directory: "/myceliumd-private" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
myceliumd-private:
|
||||
patterns:
|
||||
- "*"
|
||||
133
components/mycelium/.github/workflows/ci.yaml
vendored
Normal file
133
components/mycelium/.github/workflows/ci.yaml
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
check_fmt:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
with:
|
||||
components: rustfmt
|
||||
- uses: clechasseur/rs-fmt-check@v2
|
||||
|
||||
clippy:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Set windows VCPKG_ROOT env variable
|
||||
run: echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
if: runner.os == 'Windows'
|
||||
- name: Install windows openssl
|
||||
run: vcpkg install openssl:x64-windows-static-md
|
||||
if: runner.os == 'Windows'
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run Clippy
|
||||
run: cargo clippy --all-features -- -Dwarnings
|
||||
|
||||
check_library:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest,windows-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Set windows VCPKG_ROOT env variable
|
||||
run: echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
if: runner.os == 'Windows'
|
||||
- name: Install windows openssl
|
||||
run: vcpkg install openssl:x64-windows-static-md
|
||||
if: runner.os == 'Windows'
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: cargo build -p mycelium --all-features --verbose
|
||||
- name: Run tests
|
||||
run: cargo test -p mycelium --all-features --verbose
|
||||
|
||||
check_ios_library:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: install ios target
|
||||
run: rustup target add aarch64-apple-ios
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
- name: Build
|
||||
run: cargo build --target aarch64-apple-ios
|
||||
working-directory: mobile
|
||||
|
||||
check_android_library:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: install android target
|
||||
run: rustup target add aarch64-linux-android
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '17'
|
||||
- name: Set up Android NDK
|
||||
uses: android-actions/setup-android@v3
|
||||
- name: Accept Android Licenses
|
||||
run: yes | sdkmanager --licenses || true
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
- name: install cargo NDK
|
||||
run: cargo install cargo-ndk
|
||||
- name: Build
|
||||
run: cargo ndk -t arm64-v8a build
|
||||
working-directory: mobile
|
||||
|
||||
check_binaries:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
binary: [myceliumd, myceliumd-private]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Set windows VCPKG_ROOT env variable
|
||||
run: echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
if: runner.os == 'Windows'
|
||||
- name: Install windows openssl
|
||||
run: vcpkg install openssl:x64-windows-static-md
|
||||
if: runner.os == 'Windows'
|
||||
- uses: actions/checkout@v4
|
||||
- name: Change directory to binary
|
||||
run: cd ${{ matrix.binary }}
|
||||
- name: Build
|
||||
run: cargo build --verbose
|
||||
- name: Run tests
|
||||
run: cargo test --verbose
|
||||
- name: Run Clippy
|
||||
run: cargo clippy --all-features -- -Dwarnings
|
||||
|
||||
check_flake:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
id-token: "write"
|
||||
contents: "read"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- uses: DeterminateSystems/flake-checker-action@main
|
||||
- name: Run `nix build`
|
||||
run: nix build .
|
||||
121
components/mycelium/.github/workflows/release.yaml
vendored
Normal file
121
components/mycelium/.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
name: Release
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v[0-9]+.*
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: taiki-e/create-gh-release-action@v1
|
||||
with:
|
||||
changelog: CHANGELOG.md
|
||||
# (required) GitHub token for creating GitHub Releases.
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
upload-assets-mycelium:
|
||||
needs: create-release
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- target: aarch64-apple-darwin
|
||||
os: macos-latest
|
||||
- target: x86_64-unknown-linux-musl
|
||||
os: ubuntu-latest
|
||||
- target: x86_64-apple-darwin
|
||||
os: macos-latest
|
||||
- target: aarch64-unknown-linux-musl
|
||||
os: ubuntu-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: taiki-e/upload-rust-binary-action@v1
|
||||
with:
|
||||
# Name of the compiled binary, also name of the non-extension part of the produced file
|
||||
bin: mycelium
|
||||
# --target flag value, default is host
|
||||
target: ${{ matrix.target }}
|
||||
# Name of the archive when uploaded
|
||||
archive: $bin-$target
|
||||
# (required) GitHub token for uploading assets to GitHub Releases.
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Specify manifest since we are in a subdirectory
|
||||
manifest-path: myceliumd/Cargo.toml
|
||||
|
||||
# TODO: Figure out the correct matrix setup to have this in a single action
|
||||
upload-assets-myceliumd-private:
|
||||
needs: create-release
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- target: aarch64-apple-darwin
|
||||
os: macos-latest
|
||||
- target: x86_64-unknown-linux-musl
|
||||
os: ubuntu-latest
|
||||
- target: x86_64-apple-darwin
|
||||
os: macos-latest
|
||||
- target: aarch64-unknown-linux-musl
|
||||
os: ubuntu-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: taiki-e/upload-rust-binary-action@v1
|
||||
with:
|
||||
# Name of the compiled binary, also name of the non-extension part of the produced file
|
||||
bin: mycelium-private
|
||||
# Set the vendored-openssl flag for provided release builds
|
||||
features: vendored-openssl
|
||||
# --target flag value, default is host
|
||||
target: ${{ matrix.target }}
|
||||
# Name of the archive when uploaded
|
||||
archive: $bin-$target
|
||||
# (required) GitHub token for uploading assets to GitHub Releases.
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Specify manifest since we are in a subdirectory
|
||||
manifest-path: myceliumd-private/Cargo.toml
|
||||
|
||||
build-msi:
|
||||
needs: create-release
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Create .exe file
|
||||
shell: bash
|
||||
run: cd myceliumd && RUSTFLAGS="-C target-feature=+crt-static" cargo build --release && cd ..
|
||||
|
||||
- name: Setup .NET Core SDK
|
||||
uses: actions/setup-dotnet@v4.0.0
|
||||
|
||||
- name: Install WiX Toolset
|
||||
run: dotnet tool install --global wix
|
||||
|
||||
- name: Add WixToolset.UI.wixext extension
|
||||
run: wix extension add WixToolset.UI.wixext
|
||||
|
||||
- name: Download Wintun zip file
|
||||
run: curl -o wintun.zip https://www.wintun.net/builds/wintun-0.14.1.zip
|
||||
|
||||
- name: Unzip Wintun
|
||||
run: unzip wintun.zip
|
||||
|
||||
- name: Move .dll file to myceliumd directory
|
||||
run: move wintun\bin\amd64\wintun.dll myceliumd
|
||||
|
||||
- name: Build MSI package
|
||||
run: wix build -loc installers\windows\wix\mycelium.en-us.wxl installers\windows\wix\mycelium.wxs -ext WixToolset.UI.wixext -arch x64 -dcl high -out mycelium_installer.msi
|
||||
|
||||
- name: Upload MSI artifact
|
||||
uses: alexellis/upload-assets@0.4.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
asset_paths: '["mycelium_installer.msi"]'
|
||||
21
components/mycelium/.gitignore
vendored
Normal file
21
components/mycelium/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/target
|
||||
nodeconfig.toml
|
||||
keys.txt
|
||||
priv_key.bin
|
||||
|
||||
# Profile output
|
||||
*.profraw
|
||||
*.profdata
|
||||
profile.json
|
||||
|
||||
# vscode settings, keep these locally
|
||||
.vscode
|
||||
# visual studio project stuff
|
||||
.vs
|
||||
|
||||
# wintun.dll, windows tun driver in repo root for windows development
|
||||
wintun.dll
|
||||
|
||||
result/
|
||||
|
||||
.idea
|
||||
614
components/mycelium/CHANGELOG.md
Normal file
614
components/mycelium/CHANGELOG.md
Normal file
@@ -0,0 +1,614 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- New log format option `plain`, this option is the same as logfmt, but with colors
|
||||
always disabled.
|
||||
|
||||
## [0.6.1] - 2025-05-14
|
||||
|
||||
### Added
|
||||
|
||||
- When a route is used which is about to expire, we now send a route request to
|
||||
try and refresh its duration before it expires.
|
||||
- We now track when a peer was fist discovered and when we last connected to it.
|
||||
This info is displayed in the CLI when listing peers.
|
||||
- We now maintain a cache of recently sent route requests, so we can avoid spamming
|
||||
peers with duplicate requests.
|
||||
|
||||
### Changed
|
||||
|
||||
- Only keep a record of retracted routes for 6 seconds instead of 60. We'll track
|
||||
how this affects the route propagation before removing this altogether.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed an unsoundness issue in the routing table clone implementation.
|
||||
- Clear dead peer buffer once peers have been removed from the routing table.
|
||||
- Properly reply with an address unreachable ICMP when pinging an IP in the local
|
||||
subnet which does not exist.
|
||||
- Verify a packet has sufficient TTL to be routed before injecting it, and reply
|
||||
with a TTL exceeded otherwise. This fixes an issue where packets with a TTL of
|
||||
1 and 0 originating locally would not result in a proper ICMP reply. This happens
|
||||
for instance when using `traceroute`.
|
||||
- Check the local seqno request cache before sending a seqno request to a peer,
|
||||
to avoid spamming in certain occasions.
|
||||
- Don't accept packet for a destination if we only have fallback routes for said
|
||||
destination.
|
||||
|
||||
## [0.6.0] - 2025-04-25
|
||||
|
||||
This is a breaking change, check the main README file for update info.
|
||||
|
||||
### Added
|
||||
|
||||
- Json-rpc based API, see the docs for more info.
|
||||
- Message forwarding to unix sockets if configured.
|
||||
- Config file support to handle messages, if this is enabled.
|
||||
|
||||
### Changed
|
||||
|
||||
- Routing has been reworked. We no longer advertise selected subnets (which aren't
|
||||
our own). Now if a subnet is needed, we perform a route request for that subnet,
|
||||
memorizing state and responses. The current imlementation expires routes every 5
|
||||
minutes but does not yet refresh active routes before they expire.
|
||||
- Before we process a seqno request for a subnet, check the seqno cache to see if
|
||||
we recently forwarded an entry for it.
|
||||
- Discard Update TLV's if there are too many in the queue already. This binds memory
|
||||
usage but can cause nodes with a lot of load to not pick up routes immediately.
|
||||
|
||||
## [0.5.7] - 2024-11-31
|
||||
|
||||
### Fixed
|
||||
|
||||
- Properly set the interface ipv6 MTU on windows.
|
||||
|
||||
## [0.5.6] - 2024-10-03
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix a panic in the route cleanup task when a peer dies who is the last stored
|
||||
announcer of a subnet.
|
||||
|
||||
## [0.5.5] - 2024-09-27
|
||||
|
||||
### Added
|
||||
|
||||
- Mycelium-ui, a standalone GUI which exposes (part of) the mycelium API. This
|
||||
does **not** have a bundled mycelium node, so that needs to be run separately.
|
||||
|
||||
### Changed
|
||||
|
||||
- Default TUN name on Linux and Windows is now `mycelium`. On MacOS it is now `utun0`.
|
||||
- TUN interface name validation on MacOS. If the user supplies an invalid or already
|
||||
taken interface name, an available interface name will be automatically assigned.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Release flow to create the Windows installer now properly extracts wintun
|
||||
- Guard against a race condition when a route is deleted which could rarely
|
||||
trigger a panic and subsequent memory leak.
|
||||
|
||||
## [0.5.4] - 2024-08-20
|
||||
|
||||
### Added
|
||||
|
||||
- Quic protocol can now be disabled using the `--disable-quic` flag
|
||||
- Mycelium can now be started with a configuration file using `--config-file`.
|
||||
If no configuration file is supplied, Mycelium will look in a default location
|
||||
based on the OS. For more information see [README](/README.md#configuration)
|
||||
- Windows installer for Mycelium. The `.msi` file can be downloaded from the release
|
||||
assets.
|
||||
- Added flag to specify how many update workers should be started, which governs
|
||||
the amount of parallelism used for processing updates.
|
||||
- Send a seqno request if we receive an unfeasible update for a subnet with no
|
||||
routes, or if there is no selected route for the subnet.
|
||||
- New public peers in US, India, and Singapore.
|
||||
|
||||
### Changed
|
||||
|
||||
- Increased the starting metric of a peer from 50 to 1000.
|
||||
- Reworked the internals of the routing table, which should reduce memory consumption.
|
||||
Additionally, it is now possible to apply updates in parallel
|
||||
- Periodically reduce the allocated size of the seqno cache to avoid wasting some
|
||||
memory which is not currently used by the cache but still allocated.
|
||||
- Demote seqno cache warnings about duplicate seqno requests go debug lvl, as it
|
||||
is valid to send duplicate requests if sufficient time passed.
|
||||
- Skip route selection after an unfeasible update to a fallback route, as the (now
|
||||
unfeasible) route won't be selected anyway.
|
||||
- No longer refresh route timer after an unfeasbile update. This allows routes
|
||||
which have become unfeasible to gracefully be removed from the routing table
|
||||
over time.
|
||||
- Expired routes which aren't selected are now immediately removed from the routing
|
||||
table.
|
||||
- Changed how updates are sent to be more performant.
|
||||
- A triggered update is no longer sent just because a route sequence number got
|
||||
increased. We do still send the update to peer in the seqno request cache.
|
||||
- Reduced log level when a route changes next-hop to debug from info.
|
||||
|
||||
### Fixed
|
||||
|
||||
- When running `mycelium` with a command, a keyfile was loaded (or created, if not
|
||||
yet present). This was not necessary in that context.
|
||||
- Limit the amount of time allowed for inbound quic connections to be set up, and
|
||||
process multiple of them in parallel. This fixes a DOS vector against the quic
|
||||
listener.
|
||||
- We now update the source table even if we don't send an update because we are
|
||||
sure the receiver won't select us as a next-hop anyway.
|
||||
|
||||
## [0.5.3] - 2024-06-07
|
||||
|
||||
### Added
|
||||
|
||||
- On Linux and macOS, a more descriptive error is printed when setting up the tun
|
||||
device fails because a device with the same name already exists.
|
||||
- Seqno request cache, to avoid spamming peers with duplicate seqno requests and
|
||||
to make sure seqno's are forwarded to different peers.
|
||||
- Added myceliumd-private binary, which contains private network functionality.
|
||||
- Added API endpoint to retrieve the public key associated with an IP.
|
||||
- The CLI can now be used to list, remove or add peers (see `mycelium peers --help`)
|
||||
- The CLI can now be used to list selected and fallback routes (see
|
||||
`mycelium routes --help`)
|
||||
|
||||
### Changed
|
||||
|
||||
- We now send seqno requests to all peers who advertised a subnet if the selected
|
||||
route to it is lost as a result of the next-hop dying, or and update coming in
|
||||
which causes no routes to be feasible anymore.
|
||||
- Switched from the log to the tracing ecosystem.
|
||||
- Only do the periodic route announcement every 5 minutes instead of every minute.
|
||||
- Mycelium binary is no longer part of the workspace, and no longer contains private
|
||||
network functionality.
|
||||
- If a packet received from a peer can't be forwarded to the router, terminate the
|
||||
connection to the peer.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Manually implement Hash for Subnet, previously we could potentially have multiple
|
||||
distinct entries in the source table for the same source key.
|
||||
|
||||
## [0.5.2] - 2024-05-03
|
||||
|
||||
### Added
|
||||
|
||||
- New CI workflow to build and test the mycelium library separately from the full
|
||||
provided binary build.
|
||||
|
||||
### Changed
|
||||
|
||||
- Disabled the protobuf feature on prometheus, this removes protobuf related code
|
||||
and significantly reduces the release binary size.
|
||||
- Changed log level when sending a protocol message to a peer which is no longer
|
||||
alive from error to trace in most instances.
|
||||
- Improved performance of sending protocol messages to peers by queueing up multiple
|
||||
packets at once (if multiple are ready).
|
||||
- Before trying to send an update we now check if it makes sense to do so.
|
||||
- If a peer died, fallback routes using it are no longer retained with an infinite
|
||||
metric but removed immediately.
|
||||
- No longer run route selection for subnets if a peer died and the route is not
|
||||
selected.
|
||||
- If routes are removed, shrink the capacity of the route list in the route table
|
||||
if it is larger than required.
|
||||
- Check if the originator of a TLV is still available before processing said TLV.
|
||||
- The router now uses a dedicated task per TLV type to handle received TLV's from
|
||||
peers.
|
||||
- Statically linking openssl is now a feature flag when building yourself.
|
||||
|
||||
### Fixed
|
||||
|
||||
- If a peer died, unselect the selected routes which have it as next-hop if there
|
||||
is no other feasible route.
|
||||
- Properly unselect a route if a retraction update comes in and there is no other
|
||||
feasible route.
|
||||
- If the router bumps it's seqno it now properly announces the local route to it's
|
||||
peers instead of the selected routes
|
||||
- Seqno bump requests for advertised local routes now properly bump the router
|
||||
seqno.
|
||||
|
||||
## [0.5.1] - 2024-04-19
|
||||
|
||||
### Added
|
||||
|
||||
- The repo is now a workspace, and pure library code is separated out. This is mainly
|
||||
done to make it easier to develop implementations on different platforms.
|
||||
- Link local discovery will now send discovery beacons on every interface the process
|
||||
listens on for remote beacons.
|
||||
- Experimental private network support. See [the private network docs](/docs/private_network.md)
|
||||
for more info.
|
||||
- You can now optionally expose Prometheus compatible metrics about the system by
|
||||
setting the --metrics-api-address flag.
|
||||
- On Linux, you can now set an optional firewall mark by setting the --firewall-mark
|
||||
flag.
|
||||
- Added a nix flake to the repo.
|
||||
|
||||
### Changed
|
||||
|
||||
- We no longer create an outbound connection to a link local discovered IP if that
|
||||
IP is already known (usually as inbound address) with potentially a different
|
||||
port.
|
||||
|
||||
## [0.5.0] - 2024-04-04
|
||||
|
||||
### Changed
|
||||
|
||||
- Connection identifier is now included in the error log if we can't forward a
|
||||
seqno request.
|
||||
- Garbage collection time for source entries has been increased from 5 to 30 minutes
|
||||
for now.
|
||||
- The router implementation has been changed to use regular locks instead of an
|
||||
always readable concurrency primitive for all but the actual routing table. This
|
||||
should reduce the memory consumption a bit.
|
||||
- Public key and shared secret for a destination are now saved on the router, instead
|
||||
of maintaining a separate mapping for them. This slightly reduces memory consumption
|
||||
of the router, and ensures stale data is properly cleaned up when all routes to
|
||||
a subnet are removed.
|
||||
- Hello packets now set the interval in which the next Hello will be sent properly
|
||||
in centiseconds.
|
||||
- IHU packets now set the interval properly in centiseconds.
|
||||
- IHU packets now set an RX cost. For now this is the link cost, in the future
|
||||
this will be set properly.
|
||||
- Route expiration time is now calculated from the interval received in updates.
|
||||
- Ip address derivation from public keys now uses the blake3 hash algorithm.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Don't try to forward seqno requests to a peer if we know its connection is dead.
|
||||
|
||||
## [0.4.5] - 2024-03-26
|
||||
|
||||
### Changed
|
||||
|
||||
- Size of data packets is limited to 65535 bytes.
|
||||
- Update interval is now expressed as centiseconds, in accordance with the babel
|
||||
RFC.
|
||||
- Update filters now allow retractions for a route from any router-id.
|
||||
|
||||
### Fixed
|
||||
|
||||
- The feasibility distance of an existing source key is no longer incorrectly updated
|
||||
when the metric increases.
|
||||
- Source key garbage collection timers are properly reset on update even if the
|
||||
source key itself is not updated.
|
||||
- Nodes now properly reply to route requests for a static route.
|
||||
- A retraction is now sent as reply to a route request if the route is not known.
|
||||
|
||||
## [0.4.4] - 2024-03-22
|
||||
|
||||
### Changed
|
||||
|
||||
- The amount of bytes read and written to a peer are now no longer reset after
|
||||
a reconnect (for outgoing connection).
|
||||
- Renamed `connectionTxBytes` and `connectionRxBytes` on the peer stats struct
|
||||
to `txBytes` and `rxBytes` to better express that they are no longer tied to
|
||||
a single connection to the peer.
|
||||
|
||||
### Fixed
|
||||
|
||||
- When joining a link local multicast group on an interface returns a
|
||||
`Address already in use` error, the error is now ignored and the interface is
|
||||
considered to be joined.
|
||||
- When sending an update to a peer, the source table is now correctly updated before
|
||||
the update is sent, instead of doing a batched source table update afterward.
|
||||
|
||||
## [0.4.3] - 2024-03-15
|
||||
|
||||
### Added
|
||||
|
||||
- Feature flag for message subsystem. It is enabled by default, but a user can
|
||||
make a custom build with `--default-features-false` which completely leaves out
|
||||
the message related code, should he desire this and have no need for it.
|
||||
- Link local discovery now periodically checks for new IPv6 enabled interfaces
|
||||
and also joins the discovery multicast group on them.
|
||||
- Trace logs are removed from release binaries at compile time, slightly reducing
|
||||
binary size.
|
||||
- New `--silent` flag which disables all logging except error logs.
|
||||
|
||||
### Changed
|
||||
|
||||
- Update GitHub CI action to use latest version of the checkout action.
|
||||
- Update GitHub CI action to stop using deprecated actions-rs actions.
|
||||
- Failing to join the link local discovery multicast group now logs as warning
|
||||
instead of error.
|
||||
- Failing to join any IPv6 multicast group for link local peer discovery will no
|
||||
longer disable local peer discovery entirely.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Add proper validation when receiving an OOB ICMP packet.
|
||||
|
||||
## [0.4.2] - 2024-02-28
|
||||
|
||||
### Fixed
|
||||
|
||||
- Make sure the HTTP API doesn't shut down immediately after startup.
|
||||
|
||||
## [0.4.1] - 2024-02-27
|
||||
|
||||
### Added
|
||||
|
||||
- Admin API
|
||||
- Ability to see current peers and related info
|
||||
- Ability to add a new peer
|
||||
- Ability to remove an existing peer
|
||||
- List current selected routes
|
||||
- List current fallback routes
|
||||
- General node info (for now just the node subnet)
|
||||
|
||||
### Changed
|
||||
|
||||
- The tokio_unstable config flag is no longer used when building.
|
||||
- The key file is now created without read permissions for the group/world.
|
||||
|
||||
### Removed
|
||||
|
||||
- .cargo/config.toml aarch64-linux target specific entries. Cross compilation for
|
||||
these platforms can use `cross` or entries in the global .cargo/config.toml of
|
||||
the developer instead.
|
||||
- Sending SIGUSR1 to the process on unix based systems no longer dumps internal
|
||||
state, this can be accessed with the admin API instead.
|
||||
|
||||
## [0.4.0] - 2024-02-22
|
||||
|
||||
### Added
|
||||
|
||||
- Support for windows tunnels. While this works, there are no windows
|
||||
packages yet, so this is still a "developer experience".
|
||||
- Validation on source IP when sending packets over TUN interface.
|
||||
|
||||
### Changed
|
||||
|
||||
- Overlay network is now hosted in 400::/7 instead of 200::/7.
|
||||
- Key file is no longer created if it does not exist when the
|
||||
inspect command is run.
|
||||
- Packets with destination outside the global subnet now return
|
||||
a proper ICMP instead of being silently dropped.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Log the endpoint when a Quic connection can't be established.
|
||||
|
||||
## [0.3.2] - 2024-01-31
|
||||
|
||||
### Added
|
||||
|
||||
- If the router notices a Peer is dead, the connection is now forcibly terminated.
|
||||
- Example Systemd file.
|
||||
|
||||
### Changed
|
||||
|
||||
- The multicast discovery group is now joined from all available
|
||||
interfaces. This should increase the resilience of local peer
|
||||
discovery.
|
||||
- Setup of the node is now done completely in the library.
|
||||
- Route selection now accounts for the link cost of peers when
|
||||
considering if it should switch to the new route.
|
||||
- Hop count of data packets is now decremented on the first
|
||||
hop as well. As a result the sending node will show up in
|
||||
traceroute results.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Inbound peers now replace existing peers in the peer manager. This should fix
|
||||
an issue where Quic could leave zombie connections.
|
||||
|
||||
## [0.3.1] - 2024-01-23
|
||||
|
||||
### Added
|
||||
|
||||
- You can now check the version of the current binary with the --version flag.
|
||||
- Bandwidth usage is now tracked per peer.
|
||||
|
||||
### Changed
|
||||
|
||||
- Prefix decoding is now more resilient to bad prefix lengths.
|
||||
- The `-k/--key-file` flag is now global, allowing you to specify it for (inspect)
|
||||
sub commands.
|
||||
- Log the actual endpoint when we can't connect to it
|
||||
|
||||
## [0.3.0] - 2024-01-17
|
||||
|
||||
### Added
|
||||
|
||||
- Nodes can now explicitly request selected route(s) from connected peers by
|
||||
sending a Route Request Tlv.
|
||||
- The router can now inform a Peer that the connection is seemingly
|
||||
dead. This should improve the reconnect speed on connection types
|
||||
which can't tell themselves if they died.
|
||||
|
||||
### Changed
|
||||
|
||||
- Locally discovered peers are now forgotten if we fail to connect to them 3
|
||||
times.
|
||||
- Duration between periodic events has been increased, this should
|
||||
reduce bandwidth when idle to maintain the system.
|
||||
- Address encoding in update packets is now in-line with address
|
||||
encoding as described by the babel RFC.
|
||||
|
||||
### Fixed
|
||||
|
||||
- TLV bodies of unknown type are now properly skipped. Previously, the
|
||||
calculation of the body size was off by one, causing the connection to
|
||||
the peer to always die. Now, these packets should be properly ignored.
|
||||
- We are a bit more active now and no longer sleep for a second when we
|
||||
need to remove an expired route entry.
|
||||
|
||||
## [0.2.3] - 2024-01-04
|
||||
|
||||
### Added
|
||||
|
||||
- Added automatic release builds for aarch64-linux.
|
||||
|
||||
### Changed
|
||||
|
||||
- Reduce the Quic keep-alive timeout.
|
||||
|
||||
## [0.2.2] - 2024-01-03
|
||||
|
||||
### Changed
|
||||
|
||||
- Changed default multicast peer discovery port to 9650.
|
||||
|
||||
## [0.2.1] - 2024-01-03
|
||||
|
||||
### Added
|
||||
|
||||
- Experimental Quic transport. The same socket is used for sending and
|
||||
receiving. This transport is experimental and breaking changes are
|
||||
possible which won't be covered by semver guarantees for now.
|
||||
|
||||
## [0.2.0] - 2023-12-29
|
||||
|
||||
### Added
|
||||
|
||||
- Link local peer discovery over IPv6. The system will automatically detect peers on the same LAN and try to connect to them.
|
||||
This makes sure peers on the same network don't needlessly use bandwidth on external "hop" peers.
|
||||
- Data packets now carry a Hop Limit field as part of the header. Every node decrements this value, and if it is decremented
|
||||
to zero, the packet is discarded
|
||||
- Intermediate nodes can now send ICMP packets back to the source in
|
||||
reply to a dropped packet. This is useful if a hop does not have route
|
||||
to forward a packet, or the hop count for a packet reaches 0.
|
||||
- Local node now returns an ICMP Destination unreachable - no route if a
|
||||
packet is sent on the TUN interface and there is no key for the remote
|
||||
address (so the user data can't be encrypted).
|
||||
- Peers connected over IPv4 now incur a higher processing cost, causing
|
||||
IPv6 connections to be preferred for forwarding data.
|
||||
- Peer addresses now include a protocol specifier, so multiple underlay
|
||||
connections can be specified in the future.
|
||||
|
||||
### Changed
|
||||
|
||||
- The peer manager now tracks sufficient info of each connected peer to
|
||||
avoid going through the router every time to see if it needs to
|
||||
reconnect to said peers.
|
||||
- We don't send the receiver nodes IP address in IHU packets anymore, as the packet is sent over a unicast link.
|
||||
This is valid per the babel rfc.
|
||||
- Setting the peers on the CLI now requires specifying the protocol to use.
|
||||
For now only TCP is supported.
|
||||
- Change `--port` flag to `--tcp-listen-port` to more accurately reflect
|
||||
what it controls, as well as the fact that it is only for TCP.
|
||||
|
||||
### Removed
|
||||
|
||||
- Handshake when connecting to a new peer has been removed.
|
||||
|
||||
## [0.1.3] - 2023-11-22
|
||||
|
||||
### Added
|
||||
|
||||
- Add info log when next hop of a peer changes.
|
||||
- Add windows builds to CI.
|
||||
|
||||
### Changed
|
||||
|
||||
- When printing the connected peers, print the underlay IP instead of the overlay IP.
|
||||
- The link cost of a peer is now the smoothed average. This makes sure a single short latency spike doesn't disrupt routing.
|
||||
- On Linux, set the TUN ip as /7 and avoid setting a /64 route. This brings it in line with OSX.
|
||||
- When selecting the best route for a subnet, consider the currently
|
||||
installed route and only switch if it is significantly better, or
|
||||
directly connected.
|
||||
- Increase the static link cost component of a peer. This will increase
|
||||
the value of a hop in the metric of a route, in turn increasing the
|
||||
impact of multiple hops on route selection. The route selection will
|
||||
thus be more inclined to find a path with fewer hops toward a
|
||||
destination. Ultimately, if multiple paths to a destination exist with
|
||||
roughly the same latency, they one with fewer hops should be
|
||||
preferred, since this avoids putting unnecessary pressure on multiple
|
||||
nodes in the network.
|
||||
- IHU packets now include the underlay IP instead of the overlay IP.
|
||||
- When a new peer connects the underlay IP is logged instead of the
|
||||
overlay IP.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Ignore retraction updates if the route table has an existing but retracted route already. This fixes
|
||||
an issue where retracted routes would not be flushed from the routing table.
|
||||
|
||||
### Removed
|
||||
|
||||
- All uses of the exchanged overlay IP in the peer handshake are fully
|
||||
removed. Handshake is still performed to stay backwards compatible
|
||||
until the next breaking release.
|
||||
|
||||
## [0.1.2] - 2023-11-21
|
||||
|
||||
### Changed
|
||||
|
||||
- Allow routes with infinite metric for a subnet to be selected. They will only be selected if no feasible route
|
||||
with finite metric exists. They are also still ignored when looking up a route to a subnet.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Don't trigger an update when a route retraction comes in for a subnet where the route is already retracted.
|
||||
This fixes a potential storm of retraction requests in the network.
|
||||
|
||||
## [0.1.1] - 2023-11-21
|
||||
|
||||
### Added
|
||||
|
||||
- CHANGELOG.md file to keep track of notable additions, changes, fixes, deprecations, and removals.
|
||||
- A peer can now detect if it is no longer useable in most cases, allowing it to notify the router if it died. This
|
||||
allows near instant retraction of routes if a connection dies, decreasing the amount of time needed to find a
|
||||
suitable alternative route.
|
||||
- Add CHANGELOG.md entries when creating a release.
|
||||
- When sending SIGUSR1 to the process, the routing table dump will now include a list of the public key derived IP
|
||||
for every currently known subnet.
|
||||
- You can now set the name of the TUN interface on the command line with the --tun-name flag.
|
||||
- Added support for TUN devices on OSX.
|
||||
|
||||
### Changed
|
||||
|
||||
- When a peer is found to be dead, routes which use it as next-hop now have their metric set to infinity.
|
||||
If the route is selected, route selection for the subnet is run again and if needed a triggered update is sent.
|
||||
This will allow downstream peers to receive a timely update informing them of a potentially retracted route,
|
||||
instead of having to wait for route expiration.
|
||||
- Account for the link with the peer of a route when performing route selection. This was not the case previously,
|
||||
and could theoretically lead to a case where a route was selected with a non-optimal path, because the lower metric
|
||||
was offset by a high link cost of the peer.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Remove trailing 'e' character from release archive names
|
||||
|
||||
## [0.1.0] - 2023-11-15
|
||||
|
||||
### Added
|
||||
|
||||
- Initial working setup with end-to-end encryption of traffic.
|
||||
- Ability to specify peers to connect to
|
||||
- Message subsystem, including API to use it.
|
||||
- CLI options to send and receive messages with the API.
|
||||
|
||||
[0.1.1]: https://github.com/threefoldtech/mycelium/compare/v0.1.0...v0.1.1
|
||||
[0.1.2]: https://github.com/threefoldtech/mycelium/compare/v0.1.1...v0.1.2
|
||||
[0.1.3]: https://github.com/threefoldtech/mycelium/compare/v0.1.2...v0.1.3
|
||||
[0.2.0]: https://github.com/threefoldtech/mycelium/compare/v0.1.3...v0.2.0
|
||||
[0.2.1]: https://github.com/threefoldtech/mycelium/compare/v0.2.0...v0.2.1
|
||||
[0.2.2]: https://github.com/threefoldtech/mycelium/compare/v0.2.1...v0.2.2
|
||||
[0.2.3]: https://github.com/threefoldtech/mycelium/compare/v0.2.2...v0.2.3
|
||||
[0.3.0]: https://github.com/threefoldtech/mycelium/compare/v0.2.3...v0.3.0
|
||||
[0.3.1]: https://github.com/threefoldtech/mycelium/compare/v0.3.0...v0.3.1
|
||||
[0.3.2]: https://github.com/threefoldtech/mycelium/compare/v0.3.1...v0.3.2
|
||||
[0.4.0]: https://github.com/threefoldtech/mycelium/compare/v0.3.2...v0.4.0
|
||||
[0.4.1]: https://github.com/threefoldtech/mycelium/compare/v0.4.0...v0.4.1
|
||||
[0.4.2]: https://github.com/threefoldtech/mycelium/compare/v0.4.1...v0.4.2
|
||||
[0.4.3]: https://github.com/threefoldtech/mycelium/compare/v0.4.2...v0.4.3
|
||||
[0.4.4]: https://github.com/threefoldtech/mycelium/compare/v0.4.3...v0.4.4
|
||||
[0.4.5]: https://github.com/threefoldtech/mycelium/compare/v0.4.4...v0.4.5
|
||||
[0.5.0]: https://github.com/threefoldtech/mycelium/compare/v0.4.5...v0.5.0
|
||||
[0.5.1]: https://github.com/threefoldtech/mycelium/compare/v0.5.0...v0.5.1
|
||||
[0.5.2]: https://github.com/threefoldtech/mycelium/compare/v0.5.1...v0.5.2
|
||||
[0.5.3]: https://github.com/threefoldtech/mycelium/compare/v0.5.2...v0.5.3
|
||||
[0.5.4]: https://github.com/threefoldtech/mycelium/compare/v0.5.3...v0.5.4
|
||||
[0.5.5]: https://github.com/threefoldtech/mycelium/compare/v0.5.4...v0.5.5
|
||||
[0.5.6]: https://github.com/threefoldtech/mycelium/compare/v0.5.5...v0.5.6
|
||||
[0.5.7]: https://github.com/threefoldtech/mycelium/compare/v0.5.6...v0.5.7
|
||||
[0.6.0]: https://github.com/threefoldtech/mycelium/compare/v0.5.7...v0.6.0
|
||||
[0.6.1]: https://github.com/threefoldtech/mycelium/compare/v0.6.0...v0.6.1
|
||||
[unreleased]: https://github.com/threefoldtech/mycelium/compare/v0.6.1...HEAD
|
||||
2
components/mycelium/CODEOWNERS
Normal file
2
components/mycelium/CODEOWNERS
Normal file
@@ -0,0 +1,2 @@
|
||||
# global code owners
|
||||
* @leesmet
|
||||
3967
components/mycelium/Cargo.lock
generated
Normal file
3967
components/mycelium/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
9
components/mycelium/Cargo.toml
Normal file
9
components/mycelium/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[workspace]
|
||||
members = ["mycelium", "mycelium-metrics", "mycelium-api", "mycelium-cli"]
|
||||
exclude = ["myceliumd", "myceliumd-private", "mycelium-ui", "mobile"]
|
||||
resolver = "2"
|
||||
|
||||
|
||||
[profile.release]
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
||||
201
components/mycelium/LICENSE
Normal file
201
components/mycelium/LICENSE
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright TF Tech NV
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
229
components/mycelium/README.md
Normal file
229
components/mycelium/README.md
Normal file
@@ -0,0 +1,229 @@
|
||||
# Mycelium
|
||||
|
||||
Mycelium is an IPv6 overlay network written in Rust. Each node that joins the overlay
|
||||
network will receive an overlay network IP in the 400::/7 range.
|
||||
|
||||
## Features
|
||||
|
||||
- Mycelium, is locality aware, it will look for the shortest path between nodes
|
||||
- All traffic between the nodes is end-2-end encrypted
|
||||
- Traffic can be routed over nodes of friends, location aware
|
||||
- If a physical link goes down Mycelium will automatically reroute your traffic
|
||||
- The IP address is IPV6 and linked to private key
|
||||
- A simple reliable messagebus is implemented on top of Mycelium
|
||||
- Mycelium has multiple ways how to communicate quic, tcp, ... and we are working on holepunching for Quick which means P2P traffic without middlemen for NATted networks e.g. most homes
|
||||
- Scalability is very important for us, we tried many overlay networks before and got stuck on all of them, we are trying to design a network which scales to a planetary level
|
||||
- You can run mycelium without TUN and only use it as reliable message bus.
|
||||
|
||||
> We are looking for lots of testers to push the system
|
||||
|
||||
> [see here for docs](https://github.com/threefoldtech/mycelium/tree/master/docs)
|
||||
|
||||
## Running
|
||||
|
||||
> Currently, Linux, macOS and Windows are supported.
|
||||
|
||||
### Linux and macOS
|
||||
|
||||
Get an useable binary, either by downloading [an artifact from a release](https://github.com/threefoldtech/mycelium/releases),
|
||||
or by [checking out and building the code yourself](#developing).
|
||||
|
||||
### Windows
|
||||
|
||||
Download the [mycelium_installer.msi](https://github.com/threefoldtech/mycelium/releases/latest/download/mycelium_installer.msi) and run the installer.
|
||||
|
||||
### Run Mycelium
|
||||
|
||||
Once you have an useable binary, simply start it. If you want to connect to other
|
||||
nodes, you can specify their listening address as part of the command (combined
|
||||
with the protocol they are listening on, usually TCP). Check the next section if
|
||||
you want to connect to hosted public nodes.
|
||||
|
||||
```sh
|
||||
mycelium --peers tcp://188.40.132.242:9651 quic://185.69.166.8:9651
|
||||
|
||||
#other example with other tun interface if utun3 (the default) would already be used
|
||||
#also here we use sudo e.g. on OSX
|
||||
sudo mycelium --peers tcp://188.40.132.242:9651 quic://185.69.166.8:9651 --tun-name utun9
|
||||
|
||||
```
|
||||
|
||||
By default, the node will listen on port `9651`, though this can be overwritten
|
||||
with the `-p` flag.
|
||||
|
||||
To check your own info
|
||||
|
||||
```bash
|
||||
mycelium inspect --json
|
||||
{
|
||||
"publicKey": "abd16194646defe7ad2318a0f0a69eb2e3fe939c3b0b51cf0bb88bb8028ecd1d",
|
||||
"address": "5c4:c176:bf44:b2ab:5e7e:f6a:b7e2:11ca"
|
||||
}
|
||||
# test that network works, ping to anyone in the network
|
||||
ping6 54b:83ab:6cb5:7b38:44ae:cd14:53f3:a907
|
||||
```
|
||||
|
||||
The node uses a `x25519` key pair from which its identity is derived. The private key of this key pair
|
||||
is saved in a local file (32 bytes in binary format). You can specify the path to this file with the
|
||||
`-k` flag. By default, the file is saved in the current working directory as `priv_key.bin`.
|
||||
|
||||
### Running without TUN interface
|
||||
|
||||
It is possible to run the system without creating a TUN interface, by starting with the `--no-tun` flag.
|
||||
Obviously, this means that your node won't be able to send or receive L3 traffic. There is no interface
|
||||
to send packets on, and consequently no interface to send received packets out of. From the point of
|
||||
other nodes, your node will simply drop all incoming L3 traffic destined for it. The node **will still
|
||||
route traffic** as normal. It takes part in routing, exchanges route info, and forwards packets not
|
||||
intended for itself.
|
||||
|
||||
The node also still allows access to the [message subsystem](#message-system).
|
||||
|
||||
## Configuration
|
||||
|
||||
Mycelium can be started with an **optional** configuration file using the `--config-file`
|
||||
option, which offers the same capabilities as the command line arguments.
|
||||
|
||||
If no configuration file is specified with `--config-file`, Mycelium will search for one
|
||||
in a default location based on the operating system:
|
||||
|
||||
- Linux: $HOME/.config/mycelium.toml
|
||||
- Windows: %APPDATA%/ThreeFold Tech/Mycelium/mycelium.toml
|
||||
- Mac OS: $HOME/Library/Application Support/ThreeFold Tech/Mycelium/mycelium.toml
|
||||
|
||||
Command line arguments will override any settings found in the configuration file.
|
||||
|
||||
## Hosted public nodes v0.6.x
|
||||
|
||||
A couple of public nodes are provided, which can be freely connected to. This allows
|
||||
anyone to join the global network. These are hosted in multiple geographic regions,
|
||||
on both IPv4 and IPv6, and supporting both the Tcp and Quic protocols. The nodes
|
||||
are the following:
|
||||
|
||||
| Node ID | Region | IPv4 | IPv6 | Tcp port | Quic port | Mycelium IP |
|
||||
| ------- | ------- | -------------- | --------------------------------- | -------- | --------- | -------------------------------------- |
|
||||
| 01 | DE | 188.40.132.242 | 2a01:4f8:221:1e0b::2 | 9651 | 9651 | 54b:83ab:6cb5:7b38:44ae:cd14:53f3:a907 |
|
||||
| 02 | DE | 136.243.47.186 | 2a01:4f8:212:fa6::2 | 9651 | 9651 | 40a:152c:b85b:9646:5b71:d03a:eb27:2462 |
|
||||
| 03 | BE | 185.69.166.7 | 2a02:1802:5e:0:ec4:7aff:fe51:e80d | 9651 | 9651 | 597:a4ef:806:b09:6650:cbbf:1b68:cc94 |
|
||||
| 04 | BE | 185.69.166.8 | 2a02:1802:5e:0:ec4:7aff:fe51:e36b | 9651 | 9651 | 549:8bce:fa45:e001:cbf8:f2e2:2da6:a67c |
|
||||
| 05 | FI | 65.21.231.58 | 2a01:4f9:6a:1dc5::2 | 9651 | 9651 | 410:2778:53bf:6f41:af28:1b60:d7c0:707a |
|
||||
| 06 | FI | 65.109.18.113 | 2a01:4f9:5a:1042::2 | 9651 | 9651 | 488:74ac:8a31:277b:9683:c8e:e14f:79a7 |
|
||||
| 07 | US-EAST | 209.159.146.190 | 2604:a00:50:17b:9e6b:ff:fe1f:e054 | 9651 | 9651 | 4ab:a385:5a4e:ef8f:92e0:1605:7cb6:24b2 |
|
||||
| 08 | US-WEST | 5.78.122.16 | 2a01:4ff:1f0:8859::1 | 9651 | 9651 | 4de:b695:3859:8234:d04c:5de6:8097:c27c |
|
||||
| 09 | SG | 5.223.43.251 | 2a01:4ff:2f0:3621::1 | 9651 | 9651 | 5eb:c711:f9ab:eb24:ff26:e392:a115:1c0e |
|
||||
| 10 | IND | 142.93.217.194 | 2400:6180:100:d0::841:2001 | 9651 | 9651 | 445:465:fe81:1e2b:5420:a029:6b0:9f61 |
|
||||
|
||||
These nodes are all interconnected, so 2 peers who each connect to a different node
|
||||
(or set of disjoint nodes) will still be able to reach each other. For optimal performance,
|
||||
it is recommended to connect to all of the above at once however. An example connection
|
||||
string could be:
|
||||
|
||||
`--peers tcp://188.40.132.242:9651 "quic://[2a01:4f8:212:fa6::2]:9651" tcp://185.69.166.7:9651 "quic://[2a02:1802:5e:0:ec4:7aff:fe51:e36b]:9651" tcp://65.21.231.58:9651 "quic://[2a01:4f9:5a:1042::2]:9651" "tcp://[2604:a00:50:17b:9e6b:ff:fe1f:e054]:9651" quic://5.78.122.16:9651 "tcp://[2a01:4ff:2f0:3621::1]:9651" quic://142.93.217.194:9651`
|
||||
|
||||
It is up to the user to decide which peers he wants to use, over which protocol.
|
||||
Note that quotation may or may not be required, depending on which shell is being
|
||||
used. IPv6 addresses should of course only be used if your ISP provides you with
|
||||
IPv6 connectivity.
|
||||
|
||||
### Private network
|
||||
|
||||
Mycelium supports running a private network, in which you must know the network name
|
||||
and a PSK (pre shared key) to connect to nodes in the network. For more info, check
|
||||
out [the relevant docs](/docs/private_network.md).
|
||||
|
||||
## API
|
||||
|
||||
The node starts an HTTP API, which by default listens on `localhost:8989`. A different
|
||||
listening address can be specified on the CLI when starting the system through the
|
||||
`--api-addr` flag. The API allows access to [send and receive messages](#message-system),
|
||||
and will later be expanded to allow admin functionality on the system. Note that
|
||||
message are sent using the identity of the node, and a future admin API can be
|
||||
used to change the system behavior. As such, care should be taken that this API
|
||||
is not accessible to unauthorized users.
|
||||
|
||||
## Message system
|
||||
|
||||
A message system is provided which allows users to send a message, which is essentially just "some data"
|
||||
to a remote. Since the system is end-to-end encrypted, a receiver of a message is sure of the authenticity
|
||||
and confidentiality of the content. The system does not interpret the data in any way and handles it
|
||||
as an opaque block of bytes. Messages are sent with a deadline. This means the system continuously
|
||||
tries to send (part of) the message, until it either succeeds, or the deadline expires. This happens
|
||||
similar to the way TCP handles data. Messages are transmitted in chunks, which are embedded in the
|
||||
same data stream used by L3 packets. As such, intermediate nodes can't distinguish between regular L3
|
||||
and message data.
|
||||
The primary way to interact with the message system is through [the API](#api). The message API is
|
||||
documented in [an OpenAPI spec in the docs folder](docs/api.yaml). For some more info about how to
|
||||
use the message system, see [the message docs](/docs/message.md).
|
||||
|
||||
Messages can be categorized by topics, which can be configured with whitelisted subnets and socket forwarding paths.
|
||||
For detailed information on how to configure topics, see the [Topic Configuration Guide](/docs/topic_configuration.md).
|
||||
use the message system, see [the message docs](/docs/message.md).
|
||||
|
||||
## Inspecting node keys
|
||||
|
||||
Using the `inspect` subcommand, you can view the address associated with a public key. If no public key is provided, the node will show
|
||||
its own public key. In either case, the derived address is also printed. You can specify the path to the private key with the `-k` flag.
|
||||
If the file does not exist, a new private key will be generated. The optional `--json` flag can be used to print the information in json
|
||||
format.
|
||||
|
||||
```sh
|
||||
mycelium inspect a47c1d6f2a15b2c670d3a88fbe0aeb301ced12f7bcb4c8e3aa877b20f8559c02
|
||||
Public key: a47c1d6f2a15b2c670d3a88fbe0aeb301ced12f7bcb4c8e3aa877b20f8559c02
|
||||
Address: 47f:b2c5:a944:4dad:9cb1:da4:8bf7:7e65
|
||||
```
|
||||
|
||||
```sh
|
||||
mycelium inspect --json
|
||||
{
|
||||
"publicKey": "955bf6bea5e1150fd8e270c12e5b2fc08f08f7c5f3799d10550096cc137d671b",
|
||||
"address": "54f:b680:ba6e:7ced:355f:346f:d97b:eecb"
|
||||
}
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
This project is built in Rust, and you must have a rust compiler to build the code
|
||||
yourself. Please refer to [the official rust documentation](https://www.rust-lang.org/)
|
||||
for information on how to install `rustc` and `cargo`. This project is a workspace,
|
||||
however the binaries (`myceliumd` and `myceliumd-private`) are explicitly _not_
|
||||
part of this workspace. The reason for this is the way the cargo resolver unifies
|
||||
features. Making both binaries part of the workspace would make the library build
|
||||
for the regular binary include the code for the private network, and since that
|
||||
is internal code it won't be removed at link time.
|
||||
|
||||
First make sure you have cloned the repo
|
||||
|
||||
```sh
|
||||
git clone https://github.com/threefoldtech/mycelium.git
|
||||
cd mycelium
|
||||
```
|
||||
|
||||
If you only want to build the library, you can do so from the root of the repo
|
||||
|
||||
```sh
|
||||
cargo build
|
||||
```
|
||||
|
||||
If you instead want to build a binary, that must be done from the appropriate subdirectory
|
||||
|
||||
```sh
|
||||
cd myceliumd
|
||||
cargo build
|
||||
```
|
||||
|
||||
Refer to the README files in those directories for more info.
|
||||
|
||||
In case a release build is required, the `--release` flag can be added to the cargo
|
||||
command (`cargo build --release`).
|
||||
|
||||
## Cross compilation
|
||||
|
||||
For cross compilation, it is advised to use the [`cross`](https://github.com/cross-rs/cross)
|
||||
project. Alternatively, the standard way of cross compiling in rust can be used
|
||||
(by specifying the `--target` flag in the `cargo build` command). This might require
|
||||
setting some environment variables or local cargo config. On top of this, you should
|
||||
also provide the `vendored-openssl` feature flag to build and statically link a copy
|
||||
of openssl.
|
||||
|
||||
## Remarks
|
||||
|
||||
- The overlay network uses some of the core principles of the Babel routing protocol (<https://www.irif.fr/~jch/software/babel/>).
|
||||
22
components/mycelium/config_example.toml
Normal file
22
components/mycelium/config_example.toml
Normal file
@@ -0,0 +1,22 @@
|
||||
# REMOVE/ADD COMMENT TO ENABLE/DISABLE LINE
|
||||
|
||||
peers = [
|
||||
"tcp://188.40.132.242:9651",
|
||||
"quic://[2a01:4f8:212:fa6::2]:9651",
|
||||
"quic://185.69.166.7:9651",
|
||||
"tcp://[2a02:1802:5e:0:8c9e:7dff:fec9:f0d2]:9651",
|
||||
"quic://65.21.231.58:9651",
|
||||
"tcp://[2a01:4f9:5a:1042::2]:9651",
|
||||
]
|
||||
api_addr = "127.0.0.1:8989"
|
||||
tcp_listen_port = 9651
|
||||
quic_listen_port = 9651
|
||||
tun_name = "mycelium"
|
||||
disable_peer_discovery = false
|
||||
no_tun = false
|
||||
#metrics_api_address = 0.0.0.0:9999
|
||||
#firewall_mark = 30
|
||||
|
||||
## Options below only apply when myceliumd-private is used
|
||||
#network_name = "private network name"
|
||||
#network_key_file = "path_to_key_file"
|
||||
14
components/mycelium/default.nix
Normal file
14
components/mycelium/default.nix
Normal file
@@ -0,0 +1,14 @@
|
||||
(
|
||||
import
|
||||
(
|
||||
let
|
||||
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
|
||||
in
|
||||
fetchTarball {
|
||||
url = lock.nodes.flake-compat.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
|
||||
sha256 = lock.nodes.flake-compat.locked.narHash;
|
||||
}
|
||||
)
|
||||
{src = ./.;}
|
||||
)
|
||||
.defaultNix
|
||||
990
components/mycelium/docs/api.yaml
Normal file
990
components/mycelium/docs/api.yaml
Normal file
@@ -0,0 +1,990 @@
|
||||
openapi: 3.0.2
|
||||
info:
|
||||
version: "1.0.0"
|
||||
|
||||
title: Mycelium management
|
||||
contact:
|
||||
url: "https://github.com/threefoldtech/mycelium"
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: "https://github.com/threefoldtech/mycelium/blob/master/LICENSE"
|
||||
|
||||
description: |
|
||||
This is the specification of the **mycelium** management API. It is used to perform admin tasks on the system, and
|
||||
to perform administrative duties.
|
||||
|
||||
externalDocs:
|
||||
description: For full documentation, check out the mycelium github repo.
|
||||
url: "https://github.com/threefoldtech/mycelium"
|
||||
|
||||
tags:
|
||||
- name: Admin
|
||||
description: Administrative operations
|
||||
- name: Peer
|
||||
description: Operations related to peer management
|
||||
- name: Route
|
||||
description: Operations related to network routes
|
||||
- name: Message
|
||||
description: Operations on the embedded message subsystem
|
||||
- name: Topic
|
||||
description: Operations related to message topic configuration
|
||||
|
||||
servers:
|
||||
- url: "http://localhost:8989"
|
||||
|
||||
paths:
|
||||
"/api/v1/admin":
|
||||
get:
|
||||
tags:
|
||||
- Admin
|
||||
summary: Get general info about the node
|
||||
description: |
|
||||
Get general info about the node, which is not related to other more specific functionality
|
||||
operationId: getInfo
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Info"
|
||||
|
||||
"/api/v1/admin/peers":
|
||||
get:
|
||||
tags:
|
||||
- Admin
|
||||
- Peer
|
||||
summary: List known peers
|
||||
description: |
|
||||
List all peers known in the system, and info about their connection.
|
||||
This includes the endpoint, how we know about the peer, the connection state, and if the connection is alive the amount
|
||||
of bytes we've sent to and received from the peer.
|
||||
operationId: getPeers
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/PeerStats"
|
||||
post:
|
||||
tags:
|
||||
- Admin
|
||||
- Peer
|
||||
summary: Add a new peer
|
||||
description: |
|
||||
Add a new peer identified by the provided endpoint.
|
||||
The peer is added to the list of known peers. It will eventually be connected
|
||||
to by the standard connection loop of the peer manager. This means that a peer
|
||||
which can't be connected to will stay in the system, as it might be reachable
|
||||
later on.
|
||||
operationId: addPeer
|
||||
responses:
|
||||
"204":
|
||||
description: Peer added
|
||||
"400":
|
||||
description: Malformed endpoint
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Details about why the endpoint is not valid
|
||||
"409":
|
||||
description: Peer already exists
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: message saying we already know this peer
|
||||
|
||||
"/api/v1/admin/peers/{endpoint}":
|
||||
delete:
|
||||
tags:
|
||||
- Admin
|
||||
- Peer
|
||||
summary: Remove an existing peer
|
||||
description: |
|
||||
Remove an existing peer identified by the provided endpoint.
|
||||
The peer is removed from the list of known peers. If a connection to it
|
||||
is currently active, it will be closed.
|
||||
operationId: deletePeer
|
||||
responses:
|
||||
"204":
|
||||
description: Peer removed
|
||||
"400":
|
||||
description: Malformed endpoint
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Details about why the endpoint is not valid
|
||||
"404":
|
||||
description: Peer doesn't exist
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: message saying we don't know this peer
|
||||
|
||||
"/api/v1/admin/routes/selected":
|
||||
get:
|
||||
tags:
|
||||
- Admin
|
||||
- Route
|
||||
summary: List all selected routes
|
||||
description: |
|
||||
List all selected routes in the system, and their next hop identifier, metric and sequence number.
|
||||
It is possible for a route to be selected and have an infinite metric. This route will however not forward packets.
|
||||
operationId: getSelectedRoutes
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Route"
|
||||
|
||||
"/api/v1/admin/routes/fallback":
|
||||
get:
|
||||
tags:
|
||||
- Admin
|
||||
- Route
|
||||
summary: List all active fallback routes
|
||||
description: |
|
||||
List all fallback routes in the system, and their next hop identifier, metric and sequence number.
|
||||
These routes are available to be selected in case the selected route for a destination suddenly fails, or gets retracted.
|
||||
operationId: getFallbackRoutes
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Route"
|
||||
|
||||
"/api/v1/admin/routes/queried":
|
||||
get:
|
||||
tags:
|
||||
- Admin
|
||||
- Route
|
||||
summary: List all currently queried subnets
|
||||
description: |
|
||||
List all currently queried subnets in the system, and the amount of seconds until the query expires.
|
||||
These subnets are actively being probed in the network. If no route to them is discovered before the query expires,
|
||||
they will be marked as not reachable temporarily.
|
||||
operationId: getQueriedSubnets
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/QueriedSubnet"
|
||||
|
||||
"/api/v1/admin/routes/no_route":
|
||||
get:
|
||||
tags:
|
||||
- Admin
|
||||
- Route
|
||||
summary: List all subnets which are explicitly marked as no route
|
||||
description: |
|
||||
List all subnets in the system which are marked no route, and the amount of seconds until the query expires.
|
||||
These subnets have recently been probed in the network, and no route for them was discovered in time. No more
|
||||
route requests will be send for these subnets until the entry expires.
|
||||
operationId: getNoRouteEntries
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/NoRouteSubnet"
|
||||
|
||||
"/api/v1/messages":
|
||||
get:
|
||||
tags:
|
||||
- Message
|
||||
summary: Get a message from the inbound message queue
|
||||
description: |
|
||||
Get a message from the inbound message queue. By default, the message is removed from the queue and won't be shown again.
|
||||
If the peek query parameter is set to true, the message will be peeked, and the next call to this endpoint will show the same message.
|
||||
This method returns immediately by default: a message is returned if one is ready, and if there isn't nothing is returned. If the timeout
|
||||
query parameter is set, this call won't return for the given amount of seconds, unless a message is received
|
||||
operationId: popMessage
|
||||
parameters:
|
||||
- in: query
|
||||
name: peek
|
||||
required: false
|
||||
schema:
|
||||
type: boolean
|
||||
description: Whether to peek the message or not. If this is true, the message won't be removed from the inbound queue when it is read
|
||||
example: true
|
||||
- in: query
|
||||
name: timeout
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 0
|
||||
description: |
|
||||
Amount of seconds to wait for a message to arrive if one is not available. Setting this to 0 is valid and will return
|
||||
a message if present, or return immediately if there isn't
|
||||
example: 60
|
||||
- in: query
|
||||
name: topic
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: byte
|
||||
minLength: 0
|
||||
maxLength: 340
|
||||
description: |
|
||||
Optional filter for loading messages. If set, the system checks if the message has the given string at the start. This way
|
||||
a topic can be encoded.
|
||||
example: example.topic
|
||||
responses:
|
||||
"200":
|
||||
description: Message retrieved
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/InboundMessage"
|
||||
"204":
|
||||
description: No message ready
|
||||
post:
|
||||
tags:
|
||||
- Message
|
||||
summary: Submit a new message to the system.
|
||||
description: |
|
||||
Push a new message to the systems outbound message queue. The system will continuously attempt to send the message until
|
||||
it is either fully transmitted, or the send deadline is expired.
|
||||
operationId: pushMessage
|
||||
parameters:
|
||||
- in: query
|
||||
name: reply_timeout
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 0
|
||||
description: |
|
||||
Amount of seconds to wait for a reply to this message to come in. If not set, the system won't wait for a reply and return
|
||||
the ID of the message, which can be used later. If set, the system will wait for at most the given amount of seconds for a reply
|
||||
to come in. If a reply arrives, it is returned to the client. If not, the message ID is returned for later use.
|
||||
example: 120
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PushMessageBody"
|
||||
responses:
|
||||
"200":
|
||||
description: We received a reply within the specified timeout
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/InboundMessage"
|
||||
|
||||
"201":
|
||||
description: Message pushed successfully, and not waiting for a reply
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PushMessageResponseId"
|
||||
"408":
|
||||
description: The system timed out waiting for a reply to the message
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PushMessageResponseId"
|
||||
|
||||
"/api/v1/messages/reply/{id}":
|
||||
post:
|
||||
tags:
|
||||
- Message
|
||||
summary: Reply to a message with the given ID
|
||||
description: |
|
||||
Submits a reply message to the system, where ID is an id of a previously received message. If the sender is waiting
|
||||
for a reply, it will bypass the queue of open messages.
|
||||
operationId: pushMessageReply
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: hex
|
||||
minLength: 16
|
||||
maxLength: 16
|
||||
example: abcdef0123456789
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PushMessageBody"
|
||||
responses:
|
||||
"204":
|
||||
description: successfully submitted the reply
|
||||
|
||||
"/api/v1/messages/status/{id}":
|
||||
get:
|
||||
tags:
|
||||
- Message
|
||||
summary: Get the status of an outbound message
|
||||
description: |
|
||||
Get information about the current state of an outbound message. This can be used to check the transmission
|
||||
state, size and destination of the message.
|
||||
operationId: getMessageInfo
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: hex
|
||||
minLength: 16
|
||||
maxLength: 16
|
||||
example: abcdef0123456789
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/MessageStatusResponse"
|
||||
"404":
|
||||
description: Message not found
|
||||
|
||||
"/api/v1/messages/topics/default":
|
||||
get:
|
||||
tags:
|
||||
- Message
|
||||
- Topic
|
||||
summary: Get the default topic action
|
||||
description: |
|
||||
Get the default action for topics that are not explicitly configured (accept or reject).
|
||||
operationId: getDefaultTopicAction
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DefaultTopicActionResponse"
|
||||
put:
|
||||
tags:
|
||||
- Message
|
||||
- Topic
|
||||
summary: Set the default topic action
|
||||
description: |
|
||||
Set the default action for topics that are not explicitly configured (accept or reject).
|
||||
operationId: setDefaultTopicAction
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DefaultTopicActionRequest"
|
||||
responses:
|
||||
"204":
|
||||
description: Default topic action set successfully
|
||||
|
||||
"/api/v1/messages/topics":
|
||||
get:
|
||||
tags:
|
||||
- Message
|
||||
- Topic
|
||||
summary: Get all configured topics
|
||||
description: |
|
||||
Get all topics that are explicitly configured in the system.
|
||||
operationId: getTopics
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: byte
|
||||
description: Base64 encoded topic identifier
|
||||
post:
|
||||
tags:
|
||||
- Message
|
||||
- Topic
|
||||
summary: Add a new topic
|
||||
description: |
|
||||
Add a new topic to the system's whitelist.
|
||||
operationId: addTopic
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
format: byte
|
||||
description: The topic to add
|
||||
responses:
|
||||
"201":
|
||||
description: Topic added successfully
|
||||
|
||||
"/api/v1/messages/topics/{topic}":
|
||||
delete:
|
||||
tags:
|
||||
- Message
|
||||
- Topic
|
||||
summary: Remove a topic
|
||||
description: |
|
||||
Remove a topic from the system's whitelist.
|
||||
operationId: removeTopic
|
||||
parameters:
|
||||
- in: path
|
||||
name: topic
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: byte
|
||||
description: The topic to remove (base64 encoded)
|
||||
responses:
|
||||
"204":
|
||||
description: Topic removed successfully
|
||||
"400":
|
||||
description: Invalid topic format
|
||||
|
||||
"/api/v1/messages/topics/{topic}/sources":
|
||||
get:
|
||||
tags:
|
||||
- Message
|
||||
- Topic
|
||||
summary: Get sources for a topic
|
||||
description: |
|
||||
Get all sources (subnets) that are allowed to send messages for a specific topic.
|
||||
operationId: getTopicSources
|
||||
parameters:
|
||||
- in: path
|
||||
name: topic
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: byte
|
||||
description: The topic to get sources for (base64 encoded)
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Subnet in CIDR notation
|
||||
"400":
|
||||
description: Invalid topic format
|
||||
post:
|
||||
tags:
|
||||
- Message
|
||||
- Topic
|
||||
summary: Add a source to a topic
|
||||
description: |
|
||||
Add a source (subnet) that is allowed to send messages for a specific topic.
|
||||
operationId: addTopicSource
|
||||
parameters:
|
||||
- in: path
|
||||
name: topic
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: byte
|
||||
description: The topic to add a source to (base64 encoded)
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/TopicSourceRequest"
|
||||
responses:
|
||||
"204":
|
||||
description: Source added successfully
|
||||
"400":
|
||||
description: Invalid topic format or subnet
|
||||
|
||||
"/api/v1/messages/topics/{topic}/sources/{subnet}":
|
||||
delete:
|
||||
tags:
|
||||
- Message
|
||||
- Topic
|
||||
summary: Remove a source from a topic
|
||||
description: |
|
||||
Remove a source (subnet) that is allowed to send messages for a specific topic.
|
||||
operationId: removeTopicSource
|
||||
parameters:
|
||||
- in: path
|
||||
name: topic
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: byte
|
||||
description: The topic to remove a source from (base64 encoded)
|
||||
- in: path
|
||||
name: subnet
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: The subnet to remove as a source
|
||||
responses:
|
||||
"204":
|
||||
description: Source removed successfully
|
||||
"400":
|
||||
description: Invalid topic format or subnet
|
||||
|
||||
"/api/v1/messages/topics/{topic}/forward":
|
||||
get:
|
||||
tags:
|
||||
- Message
|
||||
- Topic
|
||||
summary: Get the forward socket for a topic
|
||||
description: |
|
||||
Get the socket path where messages for a specific topic are forwarded to.
|
||||
operationId: getTopicForwardSocket
|
||||
parameters:
|
||||
- in: path
|
||||
name: topic
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: byte
|
||||
description: The topic to get the forward socket for (base64 encoded)
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
nullable: true
|
||||
description: The socket path where messages are forwarded to
|
||||
"400":
|
||||
description: Invalid topic format
|
||||
put:
|
||||
tags:
|
||||
- Message
|
||||
- Topic
|
||||
summary: Set the forward socket for a topic
|
||||
description: |
|
||||
Set the socket path where messages for a specific topic should be forwarded to.
|
||||
operationId: setTopicForwardSocket
|
||||
parameters:
|
||||
- in: path
|
||||
name: topic
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: byte
|
||||
description: The topic to set the forward socket for (base64 encoded)
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/TopicForwardSocketRequest"
|
||||
responses:
|
||||
"204":
|
||||
description: Forward socket set successfully
|
||||
"400":
|
||||
description: Invalid topic format
|
||||
delete:
|
||||
tags:
|
||||
- Message
|
||||
- Topic
|
||||
summary: Remove the forward socket for a topic
|
||||
description: |
|
||||
Remove the socket path where messages for a specific topic are forwarded to.
|
||||
operationId: removeTopicForwardSocket
|
||||
parameters:
|
||||
- in: path
|
||||
name: topic
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: byte
|
||||
description: The topic to remove the forward socket for (base64 encoded)
|
||||
responses:
|
||||
"204":
|
||||
description: Forward socket removed successfully
|
||||
"400":
|
||||
description: Invalid topic format
|
||||
"/api/v1/pubkey/{mycelium_ip}":
|
||||
get:
|
||||
summary: Get the pubkey from node ip
|
||||
description: |
|
||||
Get the node's public key from it's IP address.
|
||||
operationId: getPublicKeyFromIp
|
||||
parameters:
|
||||
- in: path
|
||||
name: mycelium_ip
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: ipv6
|
||||
example: 5fd:7636:b80:9ad0::1
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PublicKeyResponse"
|
||||
"404":
|
||||
description: Public key not found
|
||||
|
||||
components:
|
||||
schemas:
|
||||
Info:
|
||||
description: General information about a node
|
||||
type: object
|
||||
properties:
|
||||
nodeSubnet:
|
||||
description: The subnet owned by the node and advertised to peers
|
||||
type: string
|
||||
example: 54f:b680:ba6e:7ced::/64
|
||||
nodePubkey:
|
||||
description: The public key of the node
|
||||
type: string
|
||||
format: hex
|
||||
minLength: 64
|
||||
maxLength: 64
|
||||
example: 02468ace13579bdf02468ace13579bdf02468ace13579bdf02468ace13579bdf
|
||||
|
||||
Endpoint:
|
||||
description: Identification to connect to a peer
|
||||
type: object
|
||||
properties:
|
||||
proto:
|
||||
description: Protocol used
|
||||
type: string
|
||||
enum:
|
||||
- "tcp"
|
||||
- "quic"
|
||||
example: tcp
|
||||
socketAddr:
|
||||
description: The socket address used
|
||||
type: string
|
||||
example: 192.0.2.6:9651
|
||||
|
||||
PeerStats:
|
||||
description: Info about a peer
|
||||
type: object
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: "#/components/schemas/Endpoint"
|
||||
type:
|
||||
description: How we know about this peer
|
||||
type: string
|
||||
enum:
|
||||
- "static"
|
||||
- "inbound"
|
||||
- "linkLocalDiscovery"
|
||||
example: static
|
||||
connectionState:
|
||||
description: The current state of the connection to the peer
|
||||
type: string
|
||||
enum:
|
||||
- "alive"
|
||||
- "connecting"
|
||||
- "dead"
|
||||
example: alive
|
||||
txBytes:
|
||||
description: The amount of bytes transmitted to this peer
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 0
|
||||
example: 464531564
|
||||
rxBytes:
|
||||
description: The amount of bytes received from this peer
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 0
|
||||
example: 64645089
|
||||
|
||||
Route:
|
||||
description: Information about a route
|
||||
type: object
|
||||
properties:
|
||||
subnet:
|
||||
description: The overlay subnet for which this is the route
|
||||
type: string
|
||||
example: 469:1348:ab0c:a1d8::/64
|
||||
nextHop:
|
||||
description: A way to identify the next hop of the route, where forwarded packets will be sent
|
||||
type: string
|
||||
example: TCP 203.0.113.2:60128 <-> 198.51.100.27:9651
|
||||
metric:
|
||||
description: The metric of the route, an estimation of how long the packet will take to arrive at its final destination
|
||||
oneOf:
|
||||
- description: A finite metric value
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
maximum: 65534
|
||||
example: 13
|
||||
- description: An infinite (unreachable) metric. This is always `infinite`
|
||||
type: string
|
||||
example: infinite
|
||||
seqno:
|
||||
description: the sequence number advertised with this route by the source
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
example: 1
|
||||
|
||||
QueriedSubnet:
|
||||
description: Information about a subnet currently being queried
|
||||
type: object
|
||||
properties:
|
||||
subnet:
|
||||
description: The overlay subnet which we are currently querying
|
||||
type: string
|
||||
example: 503:5478:df06:d79a::/64
|
||||
expiration:
|
||||
description: The amount of seconds until the query expires
|
||||
type: string
|
||||
example: "37"
|
||||
|
||||
NoRouteSubnet:
|
||||
description: Information about a subnet which is marked as no route
|
||||
type: object
|
||||
properties:
|
||||
subnet:
|
||||
description: The overlay subnet which is marked
|
||||
type: string
|
||||
example: 503:5478:df06:d79a::/64
|
||||
expiration:
|
||||
description: The amount of seconds until the entry expires
|
||||
type: string
|
||||
example: "37"
|
||||
|
||||
InboundMessage:
|
||||
description: A message received by the system
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
description: Id of the message, hex encoded
|
||||
type: string
|
||||
format: hex
|
||||
minLength: 16
|
||||
maxLength: 16
|
||||
example: 0123456789abcdef
|
||||
srcIp:
|
||||
description: Sender overlay IP address
|
||||
type: string
|
||||
format: ipv6
|
||||
example: 449:abcd:0123:defa::1
|
||||
srcPk:
|
||||
description: Sender public key, hex encoded
|
||||
type: string
|
||||
format: hex
|
||||
minLength: 64
|
||||
maxLength: 64
|
||||
example: fedbca9876543210fedbca9876543210fedbca9876543210fedbca9876543210
|
||||
dstIp:
|
||||
description: Receiver overlay IP address
|
||||
type: string
|
||||
format: ipv6
|
||||
example: 34f:b680:ba6e:7ced:355f:346f:d97b:eecb
|
||||
dstPk:
|
||||
description: Receiver public key, hex encoded. This is the public key of the system
|
||||
type: string
|
||||
format: hex
|
||||
minLength: 64
|
||||
maxLength: 64
|
||||
example: 02468ace13579bdf02468ace13579bdf02468ace13579bdf02468ace13579bdf
|
||||
topic:
|
||||
description: An optional message topic
|
||||
type: string
|
||||
format: byte
|
||||
minLength: 0
|
||||
maxLength: 340
|
||||
example: hpV+
|
||||
payload:
|
||||
description: The message payload, encoded in standard alphabet base64
|
||||
type: string
|
||||
format: byte
|
||||
example: xuV+
|
||||
|
||||
PushMessageBody:
|
||||
description: A message to send to a given receiver
|
||||
type: object
|
||||
properties:
|
||||
dst:
|
||||
$ref: "#/components/schemas/MessageDestination"
|
||||
topic:
|
||||
description: An optional message topic
|
||||
type: string
|
||||
format: byte
|
||||
minLength: 0
|
||||
maxLength: 340
|
||||
example: hpV+
|
||||
payload:
|
||||
description: The message to send, base64 encoded
|
||||
type: string
|
||||
format: byte
|
||||
example: xuV+
|
||||
|
||||
MessageDestination:
|
||||
oneOf:
|
||||
- description: An IP in the subnet of the receiver node
|
||||
type: object
|
||||
properties:
|
||||
ip:
|
||||
description: The target IP of the message
|
||||
format: ipv6
|
||||
example: 449:abcd:0123:defa::1
|
||||
- description: The hex encoded public key of the receiver node
|
||||
type: object
|
||||
properties:
|
||||
pk:
|
||||
description: The hex encoded public key of the target node
|
||||
type: string
|
||||
minLength: 64
|
||||
maxLength: 64
|
||||
example: bb39b4a3a4efd70f3e05e37887677e02efbda14681d0acd3882bc0f754792c32
|
||||
|
||||
PushMessageResponseId:
|
||||
description: The ID generated for a message after pushing it to the system
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
description: Id of the message, hex encoded
|
||||
type: string
|
||||
format: hex
|
||||
minLength: 16
|
||||
maxLength: 16
|
||||
example: 0123456789abcdef
|
||||
|
||||
MessageStatusResponse:
|
||||
description: Information about an outbound message
|
||||
type: object
|
||||
properties:
|
||||
dst:
|
||||
description: IP address of the receiving node
|
||||
type: string
|
||||
format: ipv6
|
||||
example: 449:abcd:0123:defa::1
|
||||
state:
|
||||
$ref: "#/components/schemas/TransmissionState"
|
||||
created:
|
||||
description: Unix timestamp of when this message was created
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1649512789
|
||||
deadline:
|
||||
description: Unix timestamp of when this message will expire. If the message is not received before this, the system will give up
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1649513089
|
||||
msgLen:
|
||||
description: Length of the message in bytes
|
||||
type: integer
|
||||
minimum: 0
|
||||
example: 27
|
||||
|
||||
TransmissionState:
|
||||
description: The state of an outbound message in it's lifetime
|
||||
oneOf:
|
||||
- type: string
|
||||
enum: ["pending", "received", "read", "aborted"]
|
||||
example: "received"
|
||||
- type: object
|
||||
properties:
|
||||
sending:
|
||||
type: object
|
||||
properties:
|
||||
pending:
|
||||
type: integer
|
||||
minimum: 0
|
||||
example: 5
|
||||
sent:
|
||||
type: integer
|
||||
minimum: 0
|
||||
example: 17
|
||||
acked:
|
||||
type: integer
|
||||
minimum: 0
|
||||
example: 3
|
||||
example: "received"
|
||||
|
||||
PublicKeyResponse:
|
||||
description: Public key requested based on a node's IP
|
||||
type: object
|
||||
properties:
|
||||
NodePubKey:
|
||||
type: string
|
||||
format: hex
|
||||
minLength: 64
|
||||
maxLength: 64
|
||||
example: 02468ace13579bdf02468ace13579bdf02468ace13579bdf02468ace13579bdf
|
||||
|
||||
DefaultTopicActionResponse:
|
||||
description: Response for the default topic action
|
||||
type: object
|
||||
properties:
|
||||
accept:
|
||||
description: Whether unconfigured topics are accepted by default
|
||||
type: boolean
|
||||
example: true
|
||||
|
||||
DefaultTopicActionRequest:
|
||||
description: Request to set the default topic action
|
||||
type: object
|
||||
properties:
|
||||
accept:
|
||||
description: Whether to accept unconfigured topics by default
|
||||
type: boolean
|
||||
example: true
|
||||
|
||||
TopicInfo:
|
||||
description: Information about a configured topic
|
||||
type: object
|
||||
properties:
|
||||
topic:
|
||||
description: The topic identifier (base64 encoded)
|
||||
type: string
|
||||
format: byte
|
||||
example: "ZXhhbXBsZS50b3BpYw=="
|
||||
sources:
|
||||
description: List of subnets that are allowed to send messages for this topic
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example: "503:5478:df06:d79a::/64"
|
||||
forward_socket:
|
||||
description: Optional socket path where messages for this topic are forwarded to
|
||||
type: string
|
||||
nullable: true
|
||||
example: "/var/run/mycelium/topic_socket"
|
||||
|
||||
TopicSourceRequest:
|
||||
description: Request to add a source to a topic whitelist
|
||||
type: object
|
||||
properties:
|
||||
subnet:
|
||||
description: The subnet to add as a source in CIDR notation
|
||||
type: string
|
||||
example: "503:5478:df06:d79a::/64"
|
||||
|
||||
TopicForwardSocketRequest:
|
||||
description: Request to set a forward socket for a topic
|
||||
type: object
|
||||
properties:
|
||||
socket_path:
|
||||
description: The socket path where messages should be forwarded to
|
||||
type: string
|
||||
example: "/var/run/mycelium/topic_socket"
|
||||
54
components/mycelium/docs/data_packet.md
Normal file
54
components/mycelium/docs/data_packet.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Data packet
|
||||
|
||||
A `data packet` contains user specified data. This can be any data, as long as the sender and receiver
|
||||
both understand what it is, without further help. Intermediate hops, which route the data have sufficient
|
||||
information with the header to know where to forward the packet. In practice, the data will be encrypted
|
||||
to avoid eavesdropping by intermediate hops.
|
||||
|
||||
## Packet header
|
||||
|
||||
The packet header has a fixed size of 36 bytes, with the following layout:
|
||||
|
||||
```
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Reserved | Length | Hop Limit |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+ Source IP +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+ Destination IP +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
```
|
||||
|
||||
The first 8 bits are reserved and must be set to 0.
|
||||
|
||||
The next 16 bits are used to specify the length of the body. It is expected that
|
||||
the actual length of a packet does not exceed 65K right now, and overhead related
|
||||
to encryption should be handled by the client before sending the packet.
|
||||
|
||||
The next byte is the hop-limit. Every node decrements this value by 1 before sending
|
||||
the packet. If a node decrements this value to 0, the packet is discarded.
|
||||
|
||||
The next 16 bytes contain the sender IP address.
|
||||
|
||||
The final 16 bytes contain the destination IP address.
|
||||
|
||||
## Body
|
||||
|
||||
Following the header is a variable length body. The protocol does not have any requirements for the
|
||||
body, and the only requirement imposed is that the body is as long as specified in the header length
|
||||
field. It is technically legal according to the protocol to transmit a data packet without a body,
|
||||
i.e. a body length of 0. This is useless however, as there will not be any data to interpret.
|
||||
161
components/mycelium/docs/message.md
Normal file
161
components/mycelium/docs/message.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# Message subsystem
|
||||
|
||||
The message subsystem can be used to send arbitrary length messages to receivers. A receiver is any
|
||||
other node in the network. It can be identified both by its public key, or an IP address in its announced
|
||||
range. The message subsystem can be interacted with both via the HTTP API, which is
|
||||
[documented here](./api.yaml), or via the `mycelium` binary. By default, the messages do not interpret
|
||||
the data in any way. When using the binary, the message is slightly modified to include an optional
|
||||
topic at the start of the message. Note that in the HTTP API, all messages are encoded in base64. This
|
||||
might make it difficult to consume these messages without additional tooling.
|
||||
|
||||
Messages can be categorized by topics, which can be configured with whitelisted subnets and socket forwarding paths.
|
||||
For detailed information on how to configure topics, see the [Topic Configuration Guide](./topic_configuration.md).
|
||||
|
||||
## JSON-RPC API Examples
|
||||
|
||||
These examples assume you have at least 2 nodes running, and that they are both part of the same network.
|
||||
|
||||
Send a message on node1, waiting up to 2 minutes for a possible reply:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "pushMessage",
|
||||
"params": [
|
||||
{
|
||||
"dst": {"pk": "bb39b4a3a4efd70f3e05e37887677e02efbda14681d0acd3882bc0f754792c32"},
|
||||
"payload": "xuV+"
|
||||
},
|
||||
120
|
||||
],
|
||||
"id": 1
|
||||
}
|
||||
```
|
||||
|
||||
Using curl:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8990/rpc \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "pushMessage",
|
||||
"params": [
|
||||
{
|
||||
"dst": {"pk": "bb39b4a3a4efd70f3e05e37887677e02efbda14681d0acd3882bc0f754792c32"},
|
||||
"payload": "xuV+"
|
||||
},
|
||||
120
|
||||
],
|
||||
"id": 1
|
||||
}'
|
||||
```
|
||||
|
||||
Listen for a message on node2. Note that messages received while nothing is listening are added to
|
||||
a queue for later consumption. Wait for up to 1 minute.
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "popMessage",
|
||||
"params": [false, 60, null],
|
||||
"id": 1
|
||||
}
|
||||
```
|
||||
|
||||
Using curl:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8990/rpc \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "popMessage",
|
||||
"params": [false, 60, null],
|
||||
"id": 1
|
||||
}'
|
||||
```
|
||||
|
||||
The system will (immediately) receive our previously sent message:
|
||||
|
||||
```json
|
||||
{"id":"e47b25063912f4a9","srcIp":"34f:b680:ba6e:7ced:355f:346f:d97b:eecb","srcPk":"955bf6bea5e1150fd8e270c12e5b2fc08f08f7c5f3799d10550096cc137d671b","dstIp":"2e4:9ace:9252:630:beee:e405:74c0:d876","dstPk":"bb39b4a3a4efd70f3e05e37887677e02efbda14681d0acd3882bc0f754792c32","payload":"xuV+"}
|
||||
```
|
||||
|
||||
To send a reply, we can post a message on the reply path, with the received message `id` (still on
|
||||
node2):
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "pushMessageReply",
|
||||
"params": [
|
||||
"e47b25063912f4a9",
|
||||
{
|
||||
"dst": {"pk":"955bf6bea5e1150fd8e270c12e5b2fc08f08f7c5f3799d10550096cc137d671b"},
|
||||
"payload": "xuC+"
|
||||
}
|
||||
],
|
||||
"id": 1
|
||||
}
|
||||
```
|
||||
|
||||
Using curl:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8990/rpc \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "pushMessageReply",
|
||||
"params": [
|
||||
"e47b25063912f4a9",
|
||||
{
|
||||
"dst": {"pk":"955bf6bea5e1150fd8e270c12e5b2fc08f08f7c5f3799d10550096cc137d671b"},
|
||||
"payload": "xuC+"
|
||||
}
|
||||
],
|
||||
"id": 1
|
||||
}'
|
||||
```
|
||||
|
||||
If you did this fast enough, the initial sender (node1) will now receive the reply.
|
||||
|
||||
## Mycelium binary examples
|
||||
|
||||
As explained above, while using the binary the message is slightly modified to insert the optional
|
||||
topic. As such, when using the binary to send messages, it is suggested to make sure the receiver is
|
||||
also using the binary to listen for messages. The options discussed here are not covering all possibilities,
|
||||
use the `--help` flag (`mycelium message send --help` and `mycelium message receive --help`) for a
|
||||
full overview.
|
||||
|
||||
Once again, send a message. This time using a topic (example.topic). Note that there are no constraints
|
||||
on what a valid topic is, other than that it is valid UTF-8, and at most 255 bytes in size. The `--wait`
|
||||
flag can be used to indicate that we are waiting for a reply. If it is set, we can also use an additional
|
||||
`--timeout` flag to govern exactly how long (in seconds) to wait for. The default is to wait forever.
|
||||
|
||||
```bash
|
||||
mycelium message send 2e4:9ace:9252:630:beee:e405:74c0:d876 'this is a message' -t example.topic --wait
|
||||
```
|
||||
|
||||
On the second node, listen for messages with this topic. If a different topic is used, the previous
|
||||
message won't be received. If no topic is set, all messages are received. An optional timeout flag
|
||||
can be specified, which indicates how long to wait for. Absence of this flag will cause the binary
|
||||
to wait forever.
|
||||
|
||||
```bash
|
||||
mycelium message receive -t example.topic
|
||||
```
|
||||
|
||||
Again, if the previous command was executed a message will be received immediately:
|
||||
|
||||
```json
|
||||
{"id":"4a6c956e8d36381f","topic":"example.topic","srcIp":"34f:b680:ba6e:7ced:355f:346f:d97b:eecb","srcPk":"955bf6bea5e1150fd8e270c12e5b2fc08f08f7c5f3799d10550096cc137d671b","dstIp":"2e4:9ace:9252:630:beee:e405:74c0:d876","dstPk":"bb39b4a3a4efd70f3e05e37887677e02efbda14681d0acd3882bc0f754792c32","payload":"this is a message"}
|
||||
```
|
||||
|
||||
And once again, we can use the ID from this message to reply to the original sender, who might be waiting
|
||||
for this reply (notice we used the hex encoded public key to identify the receiver here, rather than an IP):
|
||||
|
||||
```bash
|
||||
mycelium message send 955bf6bea5e1150fd8e270c12e5b2fc08f08f7c5f3799d10550096cc137d671b "this is a reply" --reply-to 4a6c956e8d36381f
|
||||
```
|
||||
1190
components/mycelium/docs/openrpc.json
Normal file
1190
components/mycelium/docs/openrpc.json
Normal file
File diff suppressed because it is too large
Load Diff
22
components/mycelium/docs/packet.md
Normal file
22
components/mycelium/docs/packet.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Packet
|
||||
|
||||
A `Packet` is the largest communication object between established `peers`. All communication is done
|
||||
via these `packets`. The `packet` itself consists of a fixed size header, and a variable size body.
|
||||
The body contains a more specific type of data.
|
||||
|
||||
## Packet header
|
||||
|
||||
The packet header has a fixed size of 4 bytes, with the following layout:
|
||||
|
||||
```
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Version | Type | Reserved |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
```
|
||||
|
||||
The first byte is used to indicate the version of the protocol. Currently, only version 1 is supported
|
||||
(0x01). The next byte is used to indicate the type of the body. `0x00` indicates a data packet, while
|
||||
`0x01` indicates a control packet. The remaining 16 bits are currently reserved, and should be set to
|
||||
all 0.
|
||||
35
components/mycelium/docs/private_network.md
Normal file
35
components/mycelium/docs/private_network.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Private network
|
||||
|
||||
> Private network functionality is currently in an experimental stage
|
||||
|
||||
While traffic is end-to-end encrypted in mycelium, any node in the network learns
|
||||
every available connected subnet (and can derive the associated default address
|
||||
in that subnet). As a result, running a mycelium node adds what is effectively
|
||||
a public interface to your computer, so everyone can send traffic to it. On top
|
||||
of this, the routing table consumes memory in relation to the amount of nodes in
|
||||
the network. To remedy this, people can opt to run a "private network". By configuring
|
||||
a pre shared key (and network name), only nodes which know the key associated to
|
||||
the name can connect to your network.
|
||||
|
||||
## Implementation
|
||||
|
||||
Private networks are implemented entirely in the connection layer (no specific
|
||||
protocol logic is implemented to support this). This relies on the pre shared key
|
||||
functionality of TLS 1.3. As such, you need both a `network name` (an `identity`),
|
||||
and the `PSK` itself. Next to the limitations in the protocol, we currently further
|
||||
limit the network name and PSK as follows:
|
||||
|
||||
- Network name must be a UTF-8 encoded string of 2 to 64 bytes.
|
||||
- PSK must be exactly 32 bytes.
|
||||
|
||||
Not all cipher suites supported in TLS1.3 are supported. At present, _at least_
|
||||
`TLS_AES_128_GCM_SHA256` and `TLS_CHACHA20_POLY1305_SHA256` are supported.
|
||||
|
||||
## Enable private network
|
||||
|
||||
In order to use the private network implementation of `mycelium`, a separate `mycelium-private`
|
||||
binary is available. Private network functionality can be enabled by setting both
|
||||
the `network-name` and `network-key-file` flags on the command line. All nodes who
|
||||
wish to join the network must use the same values for both flags.
|
||||
|
||||
> ⚠️ Network name is public, do not put any confidential data here.
|
||||
211
components/mycelium/docs/topic_configuration.md
Normal file
211
components/mycelium/docs/topic_configuration.md
Normal file
@@ -0,0 +1,211 @@
|
||||
# Topic Configuration Guide
|
||||
|
||||
This document explains how to configure message topics in Mycelium, including how to add new topics, configure socket forwarding paths, and manage whitelisted subnets.
|
||||
|
||||
## Overview
|
||||
|
||||
Mycelium's messaging system uses topics to categorize and route messages. Each topic can be configured with:
|
||||
|
||||
- **Whitelisted subnets**: IP subnets that are allowed to send messages to this topic
|
||||
- **Forward socket**: A Unix domain socket path where messages for this topic will be forwarded
|
||||
|
||||
When a message is received with a topic that has a configured socket path, the content of the message is pushed to the socket, and the system waits for a reply from the socket, which is then sent back to the original sender.
|
||||
|
||||
## Configuration Using JSON-RPC API
|
||||
|
||||
The JSON-RPC API provides a comprehensive set of methods for managing topics, socket forwarding paths, and whitelisted subnets.
|
||||
|
||||
## Adding a New Topic
|
||||
|
||||
### Using the JSON-RPC API
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "addTopic",
|
||||
"params": ["dGVzdC10b3BpYw=="], // base64 encoding of "test-topic"
|
||||
"id": 1
|
||||
}
|
||||
```
|
||||
|
||||
Example using curl:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8990/rpc \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "addTopic",
|
||||
"params": ["dGVzdC10b3BpYw=="],
|
||||
"id": 1
|
||||
}'
|
||||
```
|
||||
|
||||
|
||||
## Configuring a Socket Forwarding Path
|
||||
|
||||
When a topic is configured with a socket forwarding path, messages for that topic will be forwarded to the specified Unix domain socket instead of being pushed to the message queue.
|
||||
|
||||
### Using the JSON-RPC API
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "setTopicForwardSocket",
|
||||
"params": ["dGVzdC10b3BpYw==", "/path/to/socket"],
|
||||
"id": 1
|
||||
}
|
||||
```
|
||||
|
||||
Example using curl:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8990/rpc \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "setTopicForwardSocket",
|
||||
"params": ["dGVzdC10b3BpYw==", "/path/to/socket"],
|
||||
"id": 1
|
||||
}'
|
||||
```
|
||||
```
|
||||
|
||||
## Adding a Whitelisted Subnet
|
||||
|
||||
Whitelisted subnets control which IP addresses are allowed to send messages to a specific topic. If a message is received from an IP that is not in the whitelist, it will be dropped.
|
||||
|
||||
### Using the JSON-RPC API
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "addTopicSource",
|
||||
"params": ["dGVzdC10b3BpYw==", "192.168.1.0/24"],
|
||||
"id": 1
|
||||
}
|
||||
```
|
||||
|
||||
Example using curl:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8990/rpc \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "addTopicSource",
|
||||
"params": ["dGVzdC10b3BpYw==", "192.168.1.0/24"],
|
||||
"id": 1
|
||||
}'
|
||||
```
|
||||
```
|
||||
|
||||
## Setting the Default Topic Action
|
||||
|
||||
You can configure the default action to take for topics that don't have explicit whitelist configurations:
|
||||
|
||||
### Using the JSON-RPC API
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "setDefaultTopicAction",
|
||||
"params": [true],
|
||||
"id": 1
|
||||
}
|
||||
```
|
||||
|
||||
Example using curl:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8990/rpc \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "setDefaultTopicAction",
|
||||
"params": [true],
|
||||
"id": 1
|
||||
}'
|
||||
```
|
||||
```
|
||||
|
||||
## Socket Protocol
|
||||
|
||||
When a message is forwarded to a socket, the raw message data is sent to the socket. The socket is expected to process the message and send a reply, which will be forwarded back to the original sender.
|
||||
|
||||
The socket protocol is simple:
|
||||
1. The message data is written to the socket
|
||||
2. The system waits for a reply from the socket (with a configurable timeout)
|
||||
3. The reply data is read from the socket and sent back to the original sender
|
||||
|
||||
## Example: Creating a Socket Server
|
||||
|
||||
Here's an example of a simple socket server that echoes back the received data:
|
||||
|
||||
```rust
|
||||
use std::{
|
||||
io::{Read, Write},
|
||||
os::unix::net::UnixListener,
|
||||
path::Path,
|
||||
thread,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let socket_path = "/tmp/mycelium-socket";
|
||||
|
||||
// Remove the socket file if it already exists
|
||||
if Path::new(socket_path).exists() {
|
||||
std::fs::remove_file(socket_path).unwrap();
|
||||
}
|
||||
|
||||
// Create the Unix domain socket
|
||||
let listener = UnixListener::bind(socket_path).unwrap();
|
||||
println!("Socket server listening on {}", socket_path);
|
||||
|
||||
// Accept connections in a loop
|
||||
for stream in listener.incoming() {
|
||||
match stream {
|
||||
Ok(mut stream) => {
|
||||
// Spawn a thread to handle the connection
|
||||
thread::spawn(move || {
|
||||
// Read the data
|
||||
let mut buffer = Vec::new();
|
||||
stream.read_to_end(&mut buffer).unwrap();
|
||||
println!("Received {} bytes", buffer.len());
|
||||
|
||||
// Process the data (in this case, just echo it back)
|
||||
// In a real application, you would parse and process the message here
|
||||
|
||||
// Send the reply
|
||||
stream.write_all(&buffer).unwrap();
|
||||
println!("Sent reply");
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error accepting connection: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Message Not Being Forwarded to Socket
|
||||
|
||||
1. Check that the topic is correctly configured with a socket path
|
||||
2. Verify that the socket server is running and the socket file exists
|
||||
3. Ensure that the sender's IP is in the whitelisted subnets for the topic
|
||||
4. Check the logs for any socket connection or timeout errors
|
||||
|
||||
### Socket Server Not Receiving Messages
|
||||
|
||||
1. Verify that the socket path is correct and accessible
|
||||
2. Check that the socket server has the necessary permissions to read/write to the socket
|
||||
3. Ensure that the socket server is properly handling the connection
|
||||
|
||||
### Reply Not Being Sent Back
|
||||
|
||||
1. Verify that the socket server is sending a reply
|
||||
2. Check for any timeout errors in the logs
|
||||
3. Ensure that the original sender is still connected and able to receive the reply
|
||||
107
components/mycelium/flake.lock
generated
Normal file
107
components/mycelium/flake.lock
generated
Normal file
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"nodes": {
|
||||
"crane": {
|
||||
"locked": {
|
||||
"lastModified": 1742317686,
|
||||
"narHash": "sha256-ScJYnUykEDhYeCepoAWBbZWx2fpQ8ottyvOyGry7HqE=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "66cb0013f9a99d710b167ad13cbd8cc4e64f2ddb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"locked": {
|
||||
"lastModified": 1733328505,
|
||||
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
|
||||
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
|
||||
"revCount": 69,
|
||||
"type": "tarball",
|
||||
"url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.1.0/01948eb7-9cba-704f-bbf3-3fa956735b52/source.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "flake-utils",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nix-filter": {
|
||||
"locked": {
|
||||
"lastModified": 1731533336,
|
||||
"narHash": "sha256-oRam5PS1vcrr5UPgALW0eo1m/5/pls27Z/pabHNy2Ms=",
|
||||
"owner": "numtide",
|
||||
"repo": "nix-filter",
|
||||
"rev": "f7653272fd234696ae94229839a99b73c9ab7de0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "nix-filter",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1742288794,
|
||||
"narHash": "sha256-Txwa5uO+qpQXrNG4eumPSD+hHzzYi/CdaM80M9XRLCo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b6eaf97c6960d97350c584de1b6dcff03c9daf42",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"crane": "crane",
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-utils": "flake-utils",
|
||||
"nix-filter": "nix-filter",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
156
components/mycelium/flake.nix
Normal file
156
components/mycelium/flake.nix
Normal file
@@ -0,0 +1,156 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
|
||||
crane.url = "github:ipetkov/crane";
|
||||
|
||||
flake-compat.url = "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz";
|
||||
|
||||
nix-filter.url = "github:numtide/nix-filter";
|
||||
};
|
||||
|
||||
outputs =
|
||||
{ self
|
||||
, crane
|
||||
, flake-utils
|
||||
, nix-filter
|
||||
, ...
|
||||
}@inputs:
|
||||
{
|
||||
overlays.default = final: prev:
|
||||
let
|
||||
inherit (final) lib stdenv darwin;
|
||||
craneLib = crane.mkLib final;
|
||||
in
|
||||
{
|
||||
myceliumd =
|
||||
let
|
||||
cargoToml = ./myceliumd/Cargo.toml;
|
||||
cargoLock = ./myceliumd/Cargo.lock;
|
||||
manifest = craneLib.crateNameFromCargoToml { inherit cargoToml; };
|
||||
in
|
||||
lib.makeOverridable craneLib.buildPackage {
|
||||
src = nix-filter {
|
||||
root = ./.;
|
||||
|
||||
# If no include is passed, it will include all the paths.
|
||||
include = [
|
||||
./Cargo.toml
|
||||
./Cargo.lock
|
||||
./mycelium
|
||||
./mycelium-api
|
||||
./mycelium-cli
|
||||
./mycelium-metrics
|
||||
./myceliumd
|
||||
./myceliumd-private
|
||||
./mobile
|
||||
./docs
|
||||
];
|
||||
};
|
||||
|
||||
inherit (manifest) pname version;
|
||||
inherit cargoToml cargoLock;
|
||||
sourceRoot = "source/myceliumd";
|
||||
|
||||
doCheck = false;
|
||||
|
||||
nativeBuildInputs = [
|
||||
final.pkg-config
|
||||
# openssl base library
|
||||
final.openssl
|
||||
# required by openssl-sys
|
||||
final.perl
|
||||
];
|
||||
|
||||
buildInputs = lib.optionals stdenv.isDarwin [
|
||||
darwin.apple_sdk.frameworks.Security
|
||||
darwin.apple_sdk.frameworks.SystemConfiguration
|
||||
final.libiconv
|
||||
];
|
||||
|
||||
meta = {
|
||||
mainProgram = "mycelium";
|
||||
};
|
||||
};
|
||||
myceliumd-private =
|
||||
let
|
||||
cargoToml = ./myceliumd-private/Cargo.toml;
|
||||
cargoLock = ./myceliumd-private/Cargo.lock;
|
||||
manifest = craneLib.crateNameFromCargoToml { inherit cargoToml; };
|
||||
in
|
||||
lib.makeOverridable craneLib.buildPackage {
|
||||
src = nix-filter {
|
||||
root = ./.;
|
||||
|
||||
include = [
|
||||
./Cargo.toml
|
||||
./Cargo.lock
|
||||
./mycelium
|
||||
./mycelium-api
|
||||
./mycelium-cli
|
||||
./mycelium-metrics
|
||||
./myceliumd
|
||||
./myceliumd-private
|
||||
./mobile
|
||||
./docs
|
||||
];
|
||||
};
|
||||
|
||||
inherit (manifest) pname version;
|
||||
inherit cargoToml cargoLock;
|
||||
sourceRoot = "source/myceliumd-private";
|
||||
|
||||
doCheck = false;
|
||||
|
||||
nativeBuildInputs = [
|
||||
final.pkg-config
|
||||
# openssl base library
|
||||
final.openssl
|
||||
# required by openssl-sys
|
||||
final.perl
|
||||
];
|
||||
|
||||
buildInputs = lib.optionals stdenv.isDarwin [
|
||||
darwin.apple_sdk.frameworks.Security
|
||||
darwin.apple_sdk.frameworks.SystemConfiguration
|
||||
final.libiconv
|
||||
];
|
||||
|
||||
meta = {
|
||||
mainProgram = "mycelium-private";
|
||||
};
|
||||
};
|
||||
};
|
||||
} //
|
||||
flake-utils.lib.eachSystem
|
||||
[
|
||||
flake-utils.lib.system.x86_64-linux
|
||||
flake-utils.lib.system.aarch64-linux
|
||||
flake-utils.lib.system.x86_64-darwin
|
||||
flake-utils.lib.system.aarch64-darwin
|
||||
]
|
||||
(system:
|
||||
let
|
||||
craneLib = crane.mkLib pkgs;
|
||||
|
||||
pkgs = import inputs.nixpkgs {
|
||||
inherit system;
|
||||
overlays = [ self.overlays.default ];
|
||||
};
|
||||
in
|
||||
{
|
||||
devShells.default = craneLib.devShell {
|
||||
packages = [
|
||||
pkgs.rust-analyzer
|
||||
];
|
||||
|
||||
RUST_SRC_PATH = "${pkgs.rustPlatform.rustLibSrc}";
|
||||
};
|
||||
|
||||
packages = {
|
||||
default = self.packages.${system}.myceliumd;
|
||||
|
||||
inherit (pkgs) myceliumd myceliumd-private;
|
||||
};
|
||||
});
|
||||
}
|
||||
206
components/mycelium/installers/windows/wix/LICENSE.rtf
Normal file
206
components/mycelium/installers/windows/wix/LICENSE.rtf
Normal file
@@ -0,0 +1,206 @@
|
||||
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
|
||||
{\colortbl ;\red0\green0\blue255;}
|
||||
{\*\generator Riched20 10.0.22621}\viewkind4\uc1
|
||||
\pard\sa200\sl276\slmult1\f0\fs22\lang9 Apache License\par
|
||||
Version 2.0, January 2004\par
|
||||
{{\field{\*\fldinst{HYPERLINK http://www.apache.org/licenses/ }}{\fldrslt{http://www.apache.org/licenses/\ul0\cf0}}}}\f0\fs22\par
|
||||
\par
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\par
|
||||
\par
|
||||
1. Definitions.\par
|
||||
\par
|
||||
"License" shall mean the terms and conditions for use, reproduction,\par
|
||||
and distribution as defined by Sections 1 through 9 of this document.\par
|
||||
\par
|
||||
"Licensor" shall mean the copyright owner or entity authorized by\par
|
||||
the copyright owner that is granting the License.\par
|
||||
\par
|
||||
"Legal Entity" shall mean the union of the acting entity and all\par
|
||||
other entities that control, are controlled by, or are under common\par
|
||||
control with that entity. For the purposes of this definition,\par
|
||||
"control" means (i) the power, direct or indirect, to cause the\par
|
||||
direction or management of such entity, whether by contract or\par
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the\par
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.\par
|
||||
\par
|
||||
"You" (or "Your") shall mean an individual or Legal Entity\par
|
||||
exercising permissions granted by this License.\par
|
||||
\par
|
||||
"Source" form shall mean the preferred form for making modifications,\par
|
||||
including but not limited to software source code, documentation\par
|
||||
source, and configuration files.\par
|
||||
\par
|
||||
"Object" form shall mean any form resulting from mechanical\par
|
||||
transformation or translation of a Source form, including but\par
|
||||
not limited to compiled object code, generated documentation,\par
|
||||
and conversions to other media types.\par
|
||||
\par
|
||||
"Work" shall mean the work of authorship, whether in Source or\par
|
||||
Object form, made available under the License, as indicated by a\par
|
||||
copyright notice that is included in or attached to the work\par
|
||||
(an example is provided in the Appendix below).\par
|
||||
\par
|
||||
"Derivative Works" shall mean any work, whether in Source or Object\par
|
||||
form, that is based on (or derived from) the Work and for which the\par
|
||||
editorial revisions, annotations, elaborations, or other modifications\par
|
||||
represent, as a whole, an original work of authorship. For the purposes\par
|
||||
of this License, Derivative Works shall not include works that remain\par
|
||||
separable from, or merely link (or bind by name) to the interfaces of,\par
|
||||
the Work and Derivative Works thereof.\par
|
||||
\par
|
||||
"Contribution" shall mean any work of authorship, including\par
|
||||
the original version of the Work and any modifications or additions\par
|
||||
to that Work or Derivative Works thereof, that is intentionally\par
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner\par
|
||||
or by an individual or Legal Entity authorized to submit on behalf of\par
|
||||
the copyright owner. For the purposes of this definition, "submitted"\par
|
||||
means any form of electronic, verbal, or written communication sent\par
|
||||
to the Licensor or its representatives, including but not limited to\par
|
||||
communication on electronic mailing lists, source code control systems,\par
|
||||
and issue tracking systems that are managed by, or on behalf of, the\par
|
||||
Licensor for the purpose of discussing and improving the Work, but\par
|
||||
excluding communication that is conspicuously marked or otherwise\par
|
||||
designated in writing by the copyright owner as "Not a Contribution."\par
|
||||
\par
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity\par
|
||||
on behalf of whom a Contribution has been received by Licensor and\par
|
||||
subsequently incorporated within the Work.\par
|
||||
\par
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of\par
|
||||
this License, each Contributor hereby grants to You a perpetual,\par
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable\par
|
||||
copyright license to reproduce, prepare Derivative Works of,\par
|
||||
publicly display, publicly perform, sublicense, and distribute the\par
|
||||
Work and such Derivative Works in Source or Object form.\par
|
||||
\par
|
||||
3. Grant of Patent License. Subject to the terms and conditions of\par
|
||||
this License, each Contributor hereby grants to You a perpetual,\par
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable\par
|
||||
(except as stated in this section) patent license to make, have made,\par
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,\par
|
||||
where such license applies only to those patent claims licensable\par
|
||||
by such Contributor that are necessarily infringed by their\par
|
||||
Contribution(s) alone or by combination of their Contribution(s)\par
|
||||
with the Work to which such Contribution(s) was submitted. If You\par
|
||||
institute patent litigation against any entity (including a\par
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work\par
|
||||
or a Contribution incorporated within the Work constitutes direct\par
|
||||
or contributory patent infringement, then any patent licenses\par
|
||||
granted to You under this License for that Work shall terminate\par
|
||||
as of the date such litigation is filed.\par
|
||||
\par
|
||||
4. Redistribution. You may reproduce and distribute copies of the\par
|
||||
Work or Derivative Works thereof in any medium, with or without\par
|
||||
modifications, and in Source or Object form, provided that You\par
|
||||
meet the following conditions:\par
|
||||
\par
|
||||
(a) You must give any other recipients of the Work or\par
|
||||
Derivative Works a copy of this License; and\par
|
||||
\par
|
||||
(b) You must cause any modified files to carry prominent notices\par
|
||||
stating that You changed the files; and\par
|
||||
\par
|
||||
(c) You must retain, in the Source form of any Derivative Works\par
|
||||
that You distribute, all copyright, patent, trademark, and\par
|
||||
attribution notices from the Source form of the Work,\par
|
||||
excluding those notices that do not pertain to any part of\par
|
||||
the Derivative Works; and\par
|
||||
\par
|
||||
(d) If the Work includes a "NOTICE" text file as part of its\par
|
||||
distribution, then any Derivative Works that You distribute must\par
|
||||
include a readable copy of the attribution notices contained\par
|
||||
within such NOTICE file, excluding those notices that do not\par
|
||||
pertain to any part of the Derivative Works, in at least one\par
|
||||
of the following places: within a NOTICE text file distributed\par
|
||||
as part of the Derivative Works; within the Source form or\par
|
||||
documentation, if provided along with the Derivative Works; or,\par
|
||||
within a display generated by the Derivative Works, if and\par
|
||||
wherever such third-party notices normally appear. The contents\par
|
||||
of the NOTICE file are for informational purposes only and\par
|
||||
do not modify the License. You may add Your own attribution\par
|
||||
notices within Derivative Works that You distribute, alongside\par
|
||||
or as an addendum to the NOTICE text from the Work, provided\par
|
||||
that such additional attribution notices cannot be construed\par
|
||||
as modifying the License.\par
|
||||
\par
|
||||
You may add Your own copyright statement to Your modifications and\par
|
||||
may provide additional or different license terms and conditions\par
|
||||
for use, reproduction, or distribution of Your modifications, or\par
|
||||
for any such Derivative Works as a whole, provided Your use,\par
|
||||
reproduction, and distribution of the Work otherwise complies with\par
|
||||
the conditions stated in this License.\par
|
||||
\par
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,\par
|
||||
any Contribution intentionally submitted for inclusion in the Work\par
|
||||
by You to the Licensor shall be under the terms and conditions of\par
|
||||
this License, without any additional terms or conditions.\par
|
||||
Notwithstanding the above, nothing herein shall supersede or modify\par
|
||||
the terms of any separate license agreement you may have executed\par
|
||||
with Licensor regarding such Contributions.\par
|
||||
\par
|
||||
6. Trademarks. This License does not grant permission to use the trade\par
|
||||
names, trademarks, service marks, or product names of the Licensor,\par
|
||||
except as required for reasonable and customary use in describing the\par
|
||||
origin of the Work and reproducing the content of the NOTICE file.\par
|
||||
\par
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or\par
|
||||
agreed to in writing, Licensor provides the Work (and each\par
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,\par
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\par
|
||||
implied, including, without limitation, any warranties or conditions\par
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\par
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the\par
|
||||
appropriateness of using or redistributing the Work and assume any\par
|
||||
risks associated with Your exercise of permissions under this License.\par
|
||||
\par
|
||||
8. Limitation of Liability. In no event and under no legal theory,\par
|
||||
whether in tort (including negligence), contract, or otherwise,\par
|
||||
unless required by applicable law (such as deliberate and grossly\par
|
||||
negligent acts) or agreed to in writing, shall any Contributor be\par
|
||||
liable to You for damages, including any direct, indirect, special,\par
|
||||
incidental, or consequential damages of any character arising as a\par
|
||||
result of this License or out of the use or inability to use the\par
|
||||
Work (including but not limited to damages for loss of goodwill,\par
|
||||
work stoppage, computer failure or malfunction, or any and all\par
|
||||
other commercial damages or losses), even if such Contributor\par
|
||||
has been advised of the possibility of such damages.\par
|
||||
\par
|
||||
9. Accepting Warranty or Additional Liability. While redistributing\par
|
||||
the Work or Derivative Works thereof, You may choose to offer,\par
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,\par
|
||||
or other liability obligations and/or rights consistent with this\par
|
||||
License. However, in accepting such obligations, You may act only\par
|
||||
on Your own behalf and on Your sole responsibility, not on behalf\par
|
||||
of any other Contributor, and only if You agree to indemnify,\par
|
||||
defend, and hold each Contributor harmless for any liability\par
|
||||
incurred by, or claims asserted against, such Contributor by reason\par
|
||||
of your accepting any such warranty or additional liability.\par
|
||||
\par
|
||||
END OF TERMS AND CONDITIONS\par
|
||||
\par
|
||||
APPENDIX: How to apply the Apache License to your work.\par
|
||||
\par
|
||||
To apply the Apache License to your work, attach the following\par
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"\par
|
||||
replaced with your own identifying information. (Don't include\par
|
||||
the brackets!) The text should be enclosed in the appropriate\par
|
||||
comment syntax for the file format. We also recommend that a\par
|
||||
file or class name and description of purpose be included on the\par
|
||||
same "printed page" as the copyright notice for easier\par
|
||||
identification within third-party archives.\par
|
||||
\par
|
||||
Copyright TF Tech NV\par
|
||||
\par
|
||||
Licensed under the Apache License, Version 2.0 (the "License");\par
|
||||
you may not use this file except in compliance with the License.\par
|
||||
You may obtain a copy of the License at\par
|
||||
\par
|
||||
{{\field{\*\fldinst{HYPERLINK http://www.apache.org/licenses/LICENSE-2.0 }}{\fldrslt{http://www.apache.org/licenses/LICENSE-2.0\ul0\cf0}}}}\f0\fs22\par
|
||||
\par
|
||||
Unless required by applicable law or agreed to in writing, software\par
|
||||
distributed under the License is distributed on an "AS IS" BASIS,\par
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\par
|
||||
See the License for the specific language governing permissions and\par
|
||||
limitations under the License.\par
|
||||
}
|
||||
| ||||