English | Русский
Install the latest tagged version:
curl -fsSL \
https://raw.githubusercontent.com/santaklouse/go-p2p-netcat/main/deploy/deploy.sh |
bashThe deploy script detects Linux, macOS, or Android and the processor
architecture, downloads the matching release, verifies it against
the keyless Sigstore signature on SHA256SUMS, verifies the archive checksum,
and installs p2p-nc, pnc, and p2p-netcat. Cosign v3 is required. See
installation for version
pinning, a custom destination, and uninstalling.
Install through Homebrew on macOS or Linux:
brew install santaklouse/tap/p2p-netcatDebian and Ubuntu users can add the signed APT repository and then use
sudo apt install p2p-netcat. See
package-manager installation for the
repository command and signing-key fingerprint.
The Linux amd64/arm64 container is published to
GitHub Packages:
docker pull ghcr.io/santaklouse/go-p2p-netcat:latest
docker run --rm ghcr.io/santaklouse/go-p2p-netcat:latest --versionThe container runs as a non-root user and stores its persistent identity under
/config. See Docker and GitHub Packages
for listener, UDP, networking, version-tag, and local-build examples.
Alternatively, install with Go:
GOTOOLCHAIN=auto CGO_ENABLED=0 go install -ldflags="-s -w" \
github.com/santaklouse/go-p2p-netcat/cmd/p2p-nc@latest
GOTOOLCHAIN=auto CGO_ENABLED=0 go install -ldflags="-s -w" \
github.com/santaklouse/go-p2p-netcat/cmd/pnc@latestCGO_ENABLED=0 is intentional: the project does not require CGO, and this
avoids macOS DWARF linking failures when Homebrew LLVM takes precedence over
Apple's toolchain. If CGO is explicitly required, select Apple Clang:
GOTOOLCHAIN=auto CGO_ENABLED=1 CC=/usr/bin/clang CXX=/usr/bin/clang++ \
go install github.com/santaklouse/go-p2p-netcat/cmd/p2p-nc@latestOn macOS and Linux, install it and immediately create the p2p-netcat
command as a symbolic link next to p2p-nc:
set -e
GOTOOLCHAIN=auto CGO_ENABLED=0 go install -ldflags="-s -w" \
github.com/santaklouse/go-p2p-netcat/cmd/p2p-nc@latest
GOTOOLCHAIN=auto CGO_ENABLED=0 go install -ldflags="-s -w" \
github.com/santaklouse/go-p2p-netcat/cmd/pnc@latest
P2PNC_BIN_DIR="$(go env GOBIN)"
if [ -z "$P2PNC_BIN_DIR" ]; then
P2PNC_BIN_DIR="$(go env GOPATH)/bin"
fi
ln -sf "$P2PNC_BIN_DIR/p2p-nc" "$P2PNC_BIN_DIR/p2p-netcat"
export PATH="$P2PNC_BIN_DIR:$PATH"
p2p-netcat --versionA Go implementation of p2p-netcat: a bidirectional netcat-like stream
addressed by a libp2p PeerId instead of an IP address. The existing
/p2p-netcat/1.0.0/<logical-port> stream protocol, identity files, pairing
tokens, admission handshake, and PTY frames are compatible with the original
JavaScript implementation. Go peers additionally support framed UDP forwarding
through /p2p-netcat/udp/1.0.0/<logical-port>.
Implemented:
- persistent Ed25519 identities in the compatible protobuf format;
- TCP, QUIC v1, WebSocket, and standard libp2p WebRTC Direct;
- Noise/TLS, Yamux, and Circuit Relay v2;
- mDNS, GossipSub peer discovery, and the IPFS Amino DHT, including provider records;
- private rotating DHT rendezvous identifiers derived from
pnc1_tokens; - a mutual admission handshake before application bytes are exposed;
- canonical CBOR, HKDF-SHA-256, AES-256-GCM, and signed RouteRecords;
- native WebRTC v2 with Nostr/WebTorrent signaling, channel-bound PeerId authentication over exact SDP hashes, pairing-token encryption, flow control, 120-second stream resumption, and libp2p route racing;
- raw stdin/stdout,
-e, TCP and packet-preserving UDP forwarding, SOCKS4/4a/5, and PTY sessions, including Windows ConPTY; -l,-k,-w,-d,-p,-u,-q,-S,-T,-i,-z,-e,-4,-6, relay, id, and token commands;- the
p2p-ncand shortpnccommand names; - the browser-safe core and static English/Russian PWA in
packages/coreandweb.
The migration from the JavaScript repository is complete. The Go CLI keeps the same application protocols and can interoperate with the old CLI and browser client. Browser code remains TypeScript because it runs directly in browser Web APIs; it is now versioned and deployed from this repository.
The native WebRTC stability matrix was ported from Node.js to a real-Pion Go runner. Run the smoke profile locally with:
go run ./cmd/webrtc-soak \
--profile smoke \
--report artifacts/webrtc-soak-local.jsonProfiles, scenarios, JSON output, and limitations are documented in the native WebRTC migration record.
The current stable version is v0.7.0. Release archives contain the
p2p-nc and pnc executables, the MIT license, and both README files. Verify the
downloaded archive against SHA256SUMS before installing it.
Starting with v0.7.0, verify the Sigstore bundle for SHA256SUMS before
trusting any checksum.
Linux releases also provide optional p2p-nc-linux-amd64-upx.tar.gz and
p2p-nc-linux-arm64-upx.tar.gz archives alongside the original, unpacked
archives. These variants use standard UPX packing and remain testable and
unpackable with UPX. The deploy script deliberately installs the original
archive unless an operator selects an UPX archive manually.
The following command selects amd64 or arm64, verifies the archive, and
installs the executable into /usr/local/bin:
set -euo pipefail
P2PNC_VERSION="v0.7.0"
case "$(uname -m)" in
x86_64|amd64) P2PNC_ARCH="amd64" ;;
aarch64|arm64) P2PNC_ARCH="arm64" ;;
*) echo "Unsupported Linux architecture: $(uname -m)" >&2; exit 1 ;;
esac
P2PNC_ARCHIVE="p2p-nc-linux-${P2PNC_ARCH}.tar.gz"
P2PNC_RELEASE_URL="https://github.com/santaklouse/go-p2p-netcat/releases/download/${P2PNC_VERSION}"
curl --fail --location --remote-name "${P2PNC_RELEASE_URL}/${P2PNC_ARCHIVE}"
curl --fail --location --remote-name "${P2PNC_RELEASE_URL}/SHA256SUMS"
curl --fail --location --remote-name "${P2PNC_RELEASE_URL}/SHA256SUMS.sigstore.json"
cosign verify-blob SHA256SUMS \
--bundle SHA256SUMS.sigstore.json \
--certificate-identity "https://github.com/santaklouse/go-p2p-netcat/.github/workflows/release-main.yml@refs/tags/${P2PNC_VERSION}" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
grep " ${P2PNC_ARCHIVE}$" SHA256SUMS | sha256sum --check -
tar -xzf "$P2PNC_ARCHIVE"
sudo install -m 0755 "p2p-nc-linux-${P2PNC_ARCH}/p2p-nc" /usr/local/bin/p2p-nc
p2p-nc --versionThe macOS archives support Intel and Apple Silicon. This command detects the processor architecture automatically:
set -euo pipefail
P2PNC_VERSION="v0.7.0"
case "$(uname -m)" in
x86_64|amd64) P2PNC_ARCH="amd64" ;;
arm64|aarch64) P2PNC_ARCH="arm64" ;;
*) echo "Unsupported macOS architecture: $(uname -m)" >&2; exit 1 ;;
esac
P2PNC_ARCHIVE="p2p-nc-darwin-${P2PNC_ARCH}.tar.gz"
P2PNC_RELEASE_URL="https://github.com/santaklouse/go-p2p-netcat/releases/download/${P2PNC_VERSION}"
curl --fail --location --remote-name "${P2PNC_RELEASE_URL}/${P2PNC_ARCHIVE}"
curl --fail --location --remote-name "${P2PNC_RELEASE_URL}/SHA256SUMS"
curl --fail --location --remote-name "${P2PNC_RELEASE_URL}/SHA256SUMS.sigstore.json"
cosign verify-blob SHA256SUMS \
--bundle SHA256SUMS.sigstore.json \
--certificate-identity "https://github.com/santaklouse/go-p2p-netcat/.github/workflows/release-main.yml@refs/tags/${P2PNC_VERSION}" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
grep " ${P2PNC_ARCHIVE}$" SHA256SUMS | shasum -a 256 --check
tar -xzf "$P2PNC_ARCHIVE"
sudo mkdir -p /usr/local/bin
sudo install -m 0755 "p2p-nc-darwin-${P2PNC_ARCH}/p2p-nc" /usr/local/bin/p2p-nc
p2p-nc --versionThe release binary is not Apple-notarized. If Gatekeeper quarantines it after a browser download, inspect the file first and then remove only its quarantine attribute:
sudo xattr -d com.apple.quarantine /usr/local/bin/p2p-ncOpen PowerShell and run:
$ErrorActionPreference = 'Stop'
$Version = 'v0.7.0'
$Architecture = switch ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString()) {
'X64' { 'amd64' }
'Arm64' { 'arm64' }
default { throw "Unsupported Windows architecture: $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)" }
}
$Archive = "p2p-nc-windows-$Architecture.zip"
$ReleaseUrl = "https://github.com/santaklouse/go-p2p-netcat/releases/download/$Version"
Invoke-WebRequest "$ReleaseUrl/$Archive" -OutFile $Archive
Invoke-WebRequest "$ReleaseUrl/SHA256SUMS" -OutFile 'SHA256SUMS'
Invoke-WebRequest "$ReleaseUrl/SHA256SUMS.sigstore.json" -OutFile 'SHA256SUMS.sigstore.json'
cosign verify-blob SHA256SUMS `
--bundle SHA256SUMS.sigstore.json `
--certificate-identity "https://github.com/santaklouse/go-p2p-netcat/.github/workflows/release-main.yml@refs/tags/$Version" `
--certificate-oidc-issuer https://token.actions.githubusercontent.com
if ($LASTEXITCODE -ne 0) { throw 'Sigstore verification failed for SHA256SUMS' }
$ChecksumLine = Get-Content 'SHA256SUMS' | Where-Object { $_ -match ([regex]::Escape($Archive) + '$') }
if (-not $ChecksumLine) { throw "Checksum for $Archive was not found" }
$ExpectedHash = ($ChecksumLine -split '\s+')[0].ToLowerInvariant()
$ActualHash = (Get-FileHash $Archive -Algorithm SHA256).Hash.ToLowerInvariant()
if ($ActualHash -ne $ExpectedHash) { throw "SHA-256 verification failed for $Archive" }
Expand-Archive $Archive -DestinationPath . -Force
$InstallDir = Join-Path $env:LOCALAPPDATA 'Programs\p2p-netcat'
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
Copy-Item "p2p-nc-windows-$Architecture\p2p-nc.exe" "$InstallDir\p2p-nc.exe" -Force
$CurrentPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (($CurrentPath -split ';') -notcontains $InstallDir) {
$NewPath = if ([string]::IsNullOrWhiteSpace($CurrentPath)) { $InstallDir } else { "$CurrentPath;$InstallDir" }
[Environment]::SetEnvironmentVariable('Path', $NewPath, 'User')
}
& "$InstallDir\p2p-nc.exe" --versionThe updated user PATH is available in newly opened terminals. Windows
SmartScreen can warn because the release executable is not code-signed.
Android builds are standalone shell executables, not APK files. They require
Android 7.0 or newer and do not require root when launched through adb shell.
Enable USB debugging, connect the phone, install Android Platform Tools, and
run:
set -euo pipefail
P2PNC_VERSION="v0.7.0"
P2PNC_ANDROID_ABI="$(adb shell getprop ro.product.cpu.abi | tr -d '\r')"
case "$P2PNC_ANDROID_ABI" in
arm64-v8a) P2PNC_ANDROID_ARCH="arm64" ;;
armeabi-v7a|armeabi) P2PNC_ANDROID_ARCH="armv7" ;;
*) echo "Unsupported Android ABI: $P2PNC_ANDROID_ABI" >&2; exit 1 ;;
esac
P2PNC_ARCHIVE="p2p-nc-android-${P2PNC_ANDROID_ARCH}.tar.gz"
P2PNC_RELEASE_URL="https://github.com/santaklouse/go-p2p-netcat/releases/download/${P2PNC_VERSION}"
curl --fail --location --remote-name "${P2PNC_RELEASE_URL}/${P2PNC_ARCHIVE}"
curl --fail --location --remote-name "${P2PNC_RELEASE_URL}/SHA256SUMS"
curl --fail --location --remote-name "${P2PNC_RELEASE_URL}/SHA256SUMS.sigstore.json"
cosign verify-blob SHA256SUMS \
--bundle SHA256SUMS.sigstore.json \
--certificate-identity "https://github.com/santaklouse/go-p2p-netcat/.github/workflows/release-main.yml@refs/tags/${P2PNC_VERSION}" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
if command -v sha256sum >/dev/null 2>&1; then
grep " ${P2PNC_ARCHIVE}$" SHA256SUMS | sha256sum --check -
else
grep " ${P2PNC_ARCHIVE}$" SHA256SUMS | shasum -a 256 --check
fi
tar -xzf "$P2PNC_ARCHIVE"
adb push "p2p-nc-android-${P2PNC_ANDROID_ARCH}/p2p-nc" /data/local/tmp/p2p-nc
adb shell chmod 755 /data/local/tmp/p2p-nc
adb shell /data/local/tmp/p2p-nc --versionRun the command with an explicit writable identity path when persistent identity is required:
adb shell /data/local/tmp/p2p-nc id --identity /data/local/tmp/p2p-nc-identity.keyAndroid releases use /data/local/tmp/p2p-netcat/listeners for listener lock
files. The explicit environment override below also makes releases that predate
the Android default work correctly:
adb shell 'P2P_NETCAT_LISTENER_LOCK_DIR=/data/local/tmp/p2p-netcat/listeners /data/local/tmp/p2p-nc -lik --allow-unauthenticated-listener --identity /data/local/tmp/p2p-nc-identity.key 31337'This Android command intentionally demonstrates the explicit public-access override. Use a pairing token for any real PTY listener.
With a recent Go installation and automatic toolchain downloads enabled:
GOTOOLCHAIN=auto CGO_ENABLED=0 go install -ldflags="-s -w" \
github.com/santaklouse/go-p2p-netcat/cmd/p2p-nc@v0.7.0
GOTOOLCHAIN=auto CGO_ENABLED=0 go install -ldflags="-s -w" \
github.com/santaklouse/go-p2p-netcat/cmd/pnc@v0.7.0
"$(go env GOPATH)/bin/p2p-nc" --versionThe module pins Go 1.25.7 in go.mod. A recent Go installation with
GOTOOLCHAIN=auto downloads the required toolchain automatically.
cd /Users/alexnevpryaga/projects/santaklouse/go-p2p-netcat
GOTOOLCHAIN=auto /opt/homebrew/bin/go build -o p2p-nc ./cmd/p2p-nc
GOTOOLCHAIN=auto /opt/homebrew/bin/go build -o pnc ./cmd/pnc
./p2p-nc --versionInstall the command into GOBIN:
GOTOOLCHAIN=auto /opt/homebrew/bin/go install ./cmd/p2p-nc
GOTOOLCHAIN=auto /opt/homebrew/bin/go install ./cmd/pncOn this development machine, /usr/local/bin/go is an obsolete Intel build of
Go 1.13. Use /opt/homebrew/bin/go or correct PATH:
export PATH="/opt/homebrew/bin:$PATH"
go versionStart a listener:
./p2p-nc -l 8080Only one local listener can own a logical port at a time. This applies across
raw, PTY, exec, SOCKS, TCP-forwarding, and UDP-forwarding modes. A second
listener exits with status 1 and reports:
[p2p-nc] error: logical port 8080 already has an active listener
The command prints its PeerId and available multiaddrs to stderr. Connect
from the client:
./p2p-nc 12D3KooWJ7satLo5LXjhSZBMVTWRG1AZ77sQYtX81qHHf2VtscdL 8080Use the actual PeerId printed by the listener. The following complete example performs a local check without DHT discovery:
DEMO_DIR="$(mktemp -d)"
DEMO_KEY="$DEMO_DIR/listener.key"
DEMO_ID="$(./p2p-nc id --identity "$DEMO_KEY")"
./p2p-nc -l 8080 \
--transport-port 43127 \
--no-dht \
--no-mdns \
--no-quic \
--no-webrtc \
--identity "$DEMO_KEY" \
>"$DEMO_DIR/received.txt" &
DEMO_PID=$!
sleep 2
printf 'hello over go-libp2p\n' | ./p2p-nc \
--no-dht \
--no-mdns \
--no-quic \
--no-webrtc \
"/ip4/127.0.0.1/tcp/43127/p2p/$DEMO_ID" \
8080
wait "$DEMO_PID"
cat "$DEMO_DIR/received.txt"Raw stream listeners remain public for netcat-style use. Listener -i, -e,
-S, TCP forwarding, and UDP forwarding require a pairing token. The explicit
--allow-unauthenticated-listener override is intended only for a deliberately
public service and prints a warning. Custom Nostr/WebTorrent Native WebRTC is
enabled only with a pairing token; the separate
--allow-unauthenticated-native-webrtc escape hatch is unsafe. Standard
libp2p WebRTC Direct remains available without a token because Noise binds it
to the expected PeerId.
Create a token from the listener's persistent identity:
./p2p-nc token 31337 \
--identity "$HOME/.config/p2p-netcat/identity.key" \
>"$HOME/.config/p2p-netcat/pairing.token"
chmod 600 "$HOME/.config/p2p-netcat/pairing.token"Start the listener:
./p2p-nc -l -i \
--identity "$HOME/.config/p2p-netcat/identity.key" \
--pairing-token-file "$HOME/.config/p2p-netcat/pairing.token"After securely transferring the token file, start the client:
./p2p-nc -i \
--pairing-token-file "$HOME/.config/p2p-netcat/pairing.token"The token contains the PeerId and logical port, so private mode does not
require separate positional arguments. Keep the token file private and set its
permissions to 0600.
For password-protected storage or transfer, create an encrypted token file:
./p2p-nc token 31337 \
--identity "$HOME/.config/p2p-netcat/identity.key" \
--encrypt-to "$HOME/.config/p2p-netcat/pairing.token.enc"The command prompts for the password twice without echoing it. After receiving the encrypted file, unlock it once on each machine:
./p2p-nc token unlock \
"$HOME/.config/p2p-netcat/pairing.token.enc" \
--output "$HOME/.config/p2p-netcat/pairing.token"Unlocking prompts for the password once and creates a new bearer-token file
with mode 0600 on Unix or a protected DACL for the current user, LocalSystem,
and built-in Administrators on Windows.
Subsequent listener and client commands use --pairing-token-file without a
password. Neither command overwrites an existing output file. Existing Windows
secrets are read only when their DACL grants sensitive access to the owner,
current user, LocalSystem, or built-in Administrators.
Create service-scoped tokens for the examples below:
install -d -m 0700 "$HOME/.config/p2p-netcat"
./p2p-nc token --identity "$HOME/.config/p2p-netcat/identity.key" 15432 >"$HOME/.config/p2p-netcat/postgres.token"
./p2p-nc token --identity "$HOME/.config/p2p-netcat/identity.key" 35182 >"$HOME/.config/p2p-netcat/wireguard.token"
./p2p-nc token --identity "$HOME/.config/p2p-netcat/identity.key" 1080 >"$HOME/.config/p2p-netcat/socks.token"
./p2p-nc token --identity "$HOME/.config/p2p-netcat/identity.key" 2222 >"$HOME/.config/p2p-netcat/shell.token"
chmod 0600 "$HOME/.config/p2p-netcat/"*.tokenForward a local TCP port to 127.0.0.1:5432 on the remote peer:
./p2p-nc -l -p 5432 \
--identity "$HOME/.config/p2p-netcat/identity.key" \
--pairing-token-file "$HOME/.config/p2p-netcat/postgres.token"
./p2p-nc -p 15432 \
--pairing-token-file "$HOME/.config/p2p-netcat/postgres.token"Forward a local UDP endpoint to WireGuard on the remote peer:
# WireGuard host
./p2p-nc -u -l -d 127.0.0.1 -p 51820 \
--identity "$HOME/.config/p2p-netcat/identity.key" \
--pairing-token-file "$HOME/.config/p2p-netcat/wireguard.token"
# WireGuard client host
sudo ./deploy/wireguard-full-tunnel.sh -- \
/usr/local/bin/p2p-nc -u --udp-idle-timeout 0 -p 15182 \
--pairing-token-file "$HOME/.config/p2p-netcat/wireguard.token"Set the WireGuard peer endpoint on the client to 127.0.0.1:15182.
p2p-nc keeps UDP packet boundaries while carrying the packets through the
selected reliable stream. Native WebRTC uses public Nostr/WebTorrent signaling
and ICE/STUN to cross compatible NATs without a user-operated relay. Standard
libp2p TCP, QUIC, WebRTC Direct, WSS, and Circuit Relay routes remain available.
For AllowedIPs = 0.0.0.0/0, the Linux wrapper is required so signaling and
carrier sockets keep using the physical main route instead of recursively
entering WireGuard. The complete gateway, NAT, and verification configuration
is in the WireGuard cookbook.
Run a SOCKS server on the remote peer:
./p2p-nc -l -S \
--identity "$HOME/.config/p2p-netcat/identity.key" \
--pairing-token-file "$HOME/.config/p2p-netcat/socks.token"
./p2p-nc -p 1080 \
--pairing-token-file "$HOME/.config/p2p-netcat/socks.token"
curl --socks5-hostname 127.0.0.1:1080 https://example.com/Start an interactive login shell:
./p2p-nc -l -i \
--identity "$HOME/.config/p2p-netcat/identity.key" \
--pairing-token-file "$HOME/.config/p2p-netcat/shell.token"
./p2p-nc -i \
--pairing-token-file "$HOME/.config/p2p-netcat/shell.token"In the PTY client, press Ctrl-E followed by q to close the session.
Run a local Circuit Relay v2 instance:
./p2p-nc relay -4 -p 9090 --websocket-port 9091On a public VPS, add the server's actual public multiaddrs with --announce.
TCP and UDP port 9090 must be reachable from the internet. Open TCP port 9091
as well when WebSocket access is required.
GOTOOLCHAIN=auto /opt/homebrew/bin/go fmt ./...
GOTOOLCHAIN=auto /opt/homebrew/bin/go vet ./...
GOTOOLCHAIN=auto /opt/homebrew/bin/go test ./...The test suite includes the published JavaScript interoperability vectors for tokens, all four HKDF keys, rendezvous IDs, provider CIDs, AES-GCM envelopes, and both admission frames.
Every push to main, including merged pull requests, and every semantic
v*.*.* tag runs .github/workflows/release-main.yml. After tests and static
analysis pass, the workflow publishes a GitHub Release with these builds:
Before creating a release tag, run the WebRTC ci profile:
go run ./cmd/webrtc-soak --profile ci \
--report artifacts/webrtc-soak-release.jsonThe separate .github/workflows/webrtc-soak.yml workflow runs the longer
soak profile every Monday on Ubuntu and macOS and supports manual profile
selection.
- Linux:
amd64,arm64, with original and optional-upxarchives; - Debian packages:
amd64,arm64; - macOS:
amd64,arm64; - Windows:
amd64,arm64; - Android 7.0 (API 24) and newer:
arm64,armv7.
Linux and macOS builds are distributed as .tar.gz archives. Windows builds
are distributed as .zip archives, and Android builds as .tar.gz archives.
Only the Linux amd64 and arm64 release binaries receive separate,
explicitly named UPX variants; macOS binaries are never UPX-packed.
Every release also contains SHA256SUMS and keyless Sigstore bundles for every
artifact. New stable releases additionally contain p2p-netcat.rb for the
Homebrew tap. The deploy script authenticates the signed checksum manifest
before checking an archive. Semantic tags such as v0.7.0
produce stable releases. Builds from main are marked as prereleases and use a
deterministic tag that starts with main- and ends with the first 12
characters of the commit SHA. Rerunning a workflow updates the same release
instead of creating a duplicate.
The Android artifacts are command-line executables for Android's shell, not
APK files. Use android-arm64 for almost all current physical phones and
tablets. android-armv7 supports older 32-bit ARM devices. For example:
tar -xzf p2p-nc-android-arm64.tar.gz
adb push p2p-nc-android-arm64/p2p-nc /data/local/tmp/p2p-nc
adb shell chmod 755 /data/local/tmp/p2p-nc
adb shell /data/local/tmp/p2p-nc --version- Product and technical presentation: mobile PDF · 16:9 PDF · PPTX
- Practical usage cookbook: OpenSSH, OpenVPN, TCP/UDP forwarding, SOCKS, WireGuard, file transfer, relay, and systemd examples.
- Installation
- Architecture
- Datagram forwarding protocol
- gs-netcat compatibility
- Pairing protocol
- Relay API
- Native WebRTC migration
- Future ideas: relay-only and WSS gateway/agent
- GitHub Wiki
cmd/p2p-nc/ CLI entry point
internal/cli/ parsing, validation, and lifecycle
internal/identity/ compatible persistent Ed25519 keys
p2p/ host, transports, DHT, mDNS, and relay
protocol/pairing/ token, HKDF, rendezvous, and AEAD
protocol/admission/ mutual fixed-frame handshake
protocol/routerecord/ deterministic CBOR and identity signatures
protocol/pty/ binary PTY frames
session/ raw, exec, forwarding, SOCKS, and PTY
MIT.