This file contains essential information for AI assistants and developers working on the MASQ Node project, including coding standards, common commands, project structure, and development workflows.
- Project Overview
- Common Terminal Commands
- Project Structure
- Development Workflow
- Code Style and Standards
- Testing Guidelines
- Build and CI/CD
- Important Notes
MASQ Node is the foundation of the MASQ Network, an open-source decentralized mesh-network (dMN) written primarily in Rust. It combines the benefits of VPN and Tor technology to create next-generation privacy software.
- Language: Rust (2021 edition)
- Build System: Cargo
- Testing: Unit tests, integration tests, multinode integration tests (Docker-based)
- CI/CD: GitHub Actions
- Platforms: Linux, macOS, Windows (64-bit)
The project is organized as a Cargo workspace with multiple crates:
node/- Main MASQ Node implementationmasq/- Command-line user interfacemasq_lib/- Shared library codedns_utility/- DNS configuration utility - deprecatedautomap/- Automatic public-IP detection and configurationport_exposer/- Port exposure utilities for testing onlyip_country/- IP geolocation functionalitymultinode_integration_tests/- Docker-based integration tests employing multiple simultaneous Nodes
ci/all.shThis runs formatting, linting, unit tests, and integration tests for all components. You will be prompted for your password during zero-hop integration tests (requires sudo).
ci/multinode_integration_test.shNote: These tests only run on Linux and require Docker.
ci/format.shFormats all Rust code using rustfmt. This is required before submitting PRs.
cargo clippy -- -D warnings -Anon-snake-caseOr for a specific component:
cd node && ci/lint.sh# For the node component
cd node && ci/unit_tests.sh
# Or manually
cargo test --release --lib --no-fail-fast --features masq_lib/log_recipient_test -- --nocapture --skip _integrationcd node && ci/integration_tests.shNote: Integration tests require sudo privileges on Linux and macOS.
cargo build --releasecargo buildcd ci && ./bump_version.sh <version>Example:
cd ci && ./bump_version.sh 6.9.1This updates version numbers in all Cargo.toml files and corresponding Cargo.lock files.
sudo nohup ./MASQNode --initialization &start /b MASQNode --initialization./masq./masq setup --log-level debug --clandestine-port 1234./masq shutdownsudo ./dns_utility revertgit checkout master
git pullgit checkout -b GH-<issue-number>
git push -u origin HEADgit checkout master
git pull
git checkout - # Returns to previous branch
git merge mastermultinode_integration_tests/docker_logs.shmultinode_integration_tests/docker_dump.shmultinode_integration_tests/docker/build.shThe core MASQ Node implementation containing:
src/accountant/- Payment and accounting logicsrc/blockchain/- Blockchain interactionsrc/entry_dns/- Tiny DNS server that returns 'localhost' for any hostname - deprecatedsrc/hopper/- Message routingsrc/neighborhood/- Network topology managementsrc/proxy_client/- Exit-Node proxysrc/proxy_server/- Originating-Node proxysrc/ui_gateway/- User interface communicationsrc/sub_lib/- Code shared among accountant, blockchain, hopper, etc.src/test_utils/- Testing utilities
Each component has its own README.md with detailed documentation.
Command-line interface for controlling the MASQ Daemon and Node.
The standard way to add intercept processing to your network data flow is to configure your system network stack to
use an HTTP and/or HTTPS proxy. However, early in the history of Substratum, Justin Tabb made a promise that Node
would be "zero-configuration." This utility, and the code in Node that it supports, were intended to keep that promise.
Essentially, Node contains a tiny DNS server that always returns 'localhost' for any hostname; therefore, when your
browser or other application performs DNS resolution, it will be fooled into routing its traffic through Node, which
is running on localhost. This utility wrangles your system DNS settings to point at that tiny DNS server, if you're
going to run Node, or back at your real DNS server if you're not. Since Node is now part of MASQ and no longer part of
Substratum and Justin Tabb is a part of history, the Node now operates as an HTTPS proxy and its entry_dns server is
no longer used. However, the code is still available and active and usable, so this utility remains available as well,
although its use is deprecated.
Docker-based integration tests that simulate multi-node networks.
Each component has its own Cargo.toml defining dependencies and metadata.
Runtime configuration file (located in data directory by default).
- Can be specified via
--config-fileparameter orMASQ_CONFIG_FILEenvironment variable - Uses TOML format with scalar settings
- Example:
clandestine-port = 1234
-
Install Rust toolchain:
rustup component add rustfmt rustup component add clippy
-
Install Docker (for multinode tests on Linux)
-
Clone repository and test:
git clone <repository-url> cd Node ci/all.sh
- Select issue from the MASQ Node Card Wall
- Update master branch:
git checkout master && git pull - Create feature branch:
git checkout -b GH-<issue-number> - Complete the work (test-driven development required)
- Merge in master regularly:
git merge master - Run full test suite:
ci/all.sh - Run multinode tests (Linux only):
ci/multinode_integration_test.sh - Push changes:
git push - Open pull request on GitHub
- Watch GitHub Actions build
- Address reviewer comments
- Wait for QA approval
- Commit frequently (commits will be squashed before merging)
- Commit when tests go green
- Commit before trying risky changes
- Write descriptive commit messages for your own reference
- Use
rustfmtfor all code formatting - Run
ci/format.shbefore committing (non-auto-formatted code will fail CI) - To skip formatting on specific code:
#[cfg_attr(rustfmt, rustfmt_skip)]
- All code must pass
clippywith-D warnings - Non-snake-case warnings are allowed:
-Anon-snake-case - Run
cargo clippy -- -D warnings -Anon-snake-case
export RUSTFLAGS="-D warnings -Anon-snake-case"- Use
Resulttypes for fallible operations - Provide descriptive error messages
- Handle errors appropriately (no
unwrap()in production code; useexpect()only, and that sparingly) - Important: Nothing that comes into the system from the network must ever be allowed to cause a panic. All the
standard anti-injection rules apply, but whenever something from the outside generates an error, the error must be
logged and execution must continue. (Sometimes additional action is appropriate, such as banning an evil Node; but
logging the error is the bare minimum.)
eprintln!()is not logging.
- Test-Driven Development (TDD) is required
- All new code must have corresponding tests
- Tests must pass before code review
- Use descriptive test names
- Test both success and failure cases
- Use snake_case for functions and variables
- Use PascalCase for types and traits
- Use SCREAMING_SNAKE_CASE for constants
- All zero-hop integration tests must have names suffixed with
_integration; otherwise they'll run as unit tests rather than integration tests.
- Document public APIs with doc comments (
///) - Include examples in doc comments where helpful
- Keep README.md files updated for each component
- Located in the same file as the code being tested (in
#[cfg(test)]modules) - Test individual functions and methods in isolation
- Run with:
cargo test --lib - Should not require sudo or network access
- Test interactions between components
- Starts up a real Node, always in
--neighborhood-mode zero-hop - Will require sudo privileges, because a Node has to start with root privileges to open low ports
- Run with:
ci/integration_tests.sh
- Docker-based tests simulating multi-node networks
- Linux only (do not run on macOS or Windows)
- Require Docker installation
- Run with:
ci/multinode_integration_test.sh
ci/all.shcargo test test_name -- --nocaptureRUST_BACKTRACE=full cargo testcargo test --release- Use
--no-fail-fastto run all tests even if some fail - Use
--nocaptureto see println! output
The ci/all.sh script performs the following:
- Format check and auto-format (
ci/format.sh) - Install git hooks (
install-hooks.sh) - Start sccache server (for faster compilation)
- Build and test each component:
- masq_lib
- node
- dns_utility
- masq (CLI)
- automap
- ip_country
- Builds run automatically on pull requests
- Unit and single-Node integration tests run on Linux, macOS, and Windows
- Multinode integration tests run on Linux only
- All builds must pass before merging
After successful builds, artifacts are available in:
/target/release/and/target/debug/- Executable binariesMASQNode(orMASQNode.exe) - Node and Daemonmasq- Command-line interfacedns_utility- DNS configuration toolautomap- Firewall penetration test utility: requires special remote setup
The project uses sccache for faster compilation:
export SCCACHE_DIR="$HOME/.cargo/sccache"
SCCACHE_IDLE_TIMEOUT=0 sccache --start-server- Full support for all features
- Multinode integration tests available
- Requires sudo for integration tests
- May need to free port 53:
sudo ci/free-port-53.sh
- Full support except multinode integration tests
- Requires sudo for integration tests
- May need to adjust file descriptor limits in GitHub Actions
- Use Git Bash for running scripts
- Multinode integration tests not supported
- Some services may need to be stopped (ICS, W3SVC)
- 32-bit Windows not reliably supported (use 64-bit)
- Run as Administrator
- MASQ Node is currently in beta - not clandestine yet
- Do not use for sensitive traffic
- Traffic cannot be decrypted by attackers but MASQ traffic is identifiable
- Database encryption uses a user-provided password
- Password is never stored on disk
- Forgetting the password means losing all the encrypted content in the database and starting over
Configuration sources in order of priority (highest to lowest):
masqUI commands- Environment variables (prefixed with
MASQ_) - Configuration file (
config.toml) - Defaults
Example:
- CLI, non-interactive mode:
masq setup --clandestine-port 1234 - Environment:
MASQ_CLANDESTINE_PORT=1234 - Config file:
clandestine-port = "1234"
- Daemon: Runs with admin privileges, starts at boot, cannot access network or communicate with Node
- Node: Starts with admin privileges, drops privileges after network configuration, handles all network traffic
- UI connects to Daemon first, then is redirected to Node when it first sends the Daemon a Node command
- MASQ Node can impersonate the remote server for HTTP errors
- Errors are clearly marked as coming from MASQ Node rather than the remote server
- In-band error reporting severely limited by TLS protocol; only available for ClientHello
- Friendliest errors are written to the log
- JetBrains IntelliJ IDEA with Rust plugin (used by MASQ team)
- Other options: VS Code with rust-analyzer, etc.
- Rust toolchain (rustc, cargo, rustfmt, clippy)
- Git
- Docker (for multinode tests on Linux)
- sudo access (for integration tests)
- MASQ Node Repository
- MASQ Node Card Wall
- GitHub Actions Build Site
- Knowledge Base
- Discord Channel
- Latest Release
# Full test suite
ci/all.sh
# Format code
ci/format.sh
# Lint code
cargo clippy -- -D warnings -Anon-snake-case
# Run unit tests
cargo test --release --lib --no-fail-fast
# Build release
cargo build --release
# Start daemon (Linux/macOS)
sudo nohup ./MASQNode --initialization &
# Start CLI
./masq
# Shutdown node
./masq shutdownexport RUST_BACKTRACE=full # Full backtraces on panic
export RUSTFLAGS="-D warnings -Anon-snake-case" # Compiler flags
export SCCACHE_DIR="$HOME/.cargo/sccache" # Cache directory- Binaries:
/target/release/or/target/debug/ - Config file:
<data-directory>/config.toml - Database:
<data-directory>/ - Logs: Configured via
--log-levelparameter
Last Updated: 2026 Project: MASQ Node License: GPL-3.0-only Copyright: (c) 2026, MASQ Network