Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2245053
Implement fully functional auto redirect for Android
nekohasekai Sep 1, 2026
2342f95
Fix lint errors
nekohasekai Sep 1, 2026
86b91d0
Add NEON checksum for arm64
nekohasekai Sep 7, 2026
330d176
Keep the forward packet network header as a byte slice
nekohasekai Sep 7, 2026
20d414d
Drop IPv6 packets carrying extension headers from the forward dispatcher
nekohasekai Sep 7, 2026
894f469
Raise the utun receive buffer and derive the pending packet limit fro…
nekohasekai Sep 7, 2026
5548f6a
Add go stack
nekohasekai Sep 7, 2026
e14503f
Fix go stack
nekohasekai Sep 14, 2026
c10b285
Mark Android bypass routes as static to keep them out of NetworkStack
nekohasekai Sep 15, 2026
632b522
Rework go conn concurrency
nekohasekai Sep 15, 2026
5c007b1
Add userspace API and improve qdisc for stack
nekohasekai Sep 15, 2026
c2894b6
Fix iptables DNS hijack skipped by input connmark
nekohasekai Sep 17, 2026
b2a23b6
Refactor go stack memory
nekohasekai Sep 17, 2026
2b08b69
Fix Android VPNService kernel bypass
nekohasekai Sep 19, 2026
ee6bd4d
Exit go stack engine on unrecoverable read errors
nekohasekai Sep 19, 2026
396e686
Add ICMP error builder and IP transport protocol helper
nekohasekai Sep 22, 2026
47a9639
Allow IPv6 neighbor discovery under strict route on Windows
nekohasekai Sep 22, 2026
7705e5b
Fix auto-redirect interfering with bridge
nekohasekai Sep 24, 2026
06141ca
Add per-destination outbound queues to memory tun
nekohasekai Sep 25, 2026
8274bf4
Fix zero UDP checksum in checksum completion
nekohasekai Sep 28, 2026
eac7e0a
Avoid allocations in checksum paths
nekohasekai Sep 28, 2026
fb6ba84
Optimize header and NAT checksums
nekohasekai Sep 28, 2026
3929bf2
Fix packet splice reads on darwin
nekohasekai Sep 29, 2026
bde4d0f
Fix protocol input validation
nekohasekai Sep 29, 2026
a8da8dd
Add Options.AutoRedirectOutputMarkOrDefault
nekohasekai Oct 2, 2026
5c2edb1
Rework forward NAT with UDP mapping and fragment support
nekohasekai Oct 6, 2026
9982e9e
tun: prepare FreeBSD platform integration
vxzman Aug 31, 2026
d12856c
tun: implement FreeBSD tun device with FIB isolation
vxzman Oct 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 30 additions & 77 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,28 @@ on:
- '**.md'
- '.github/**'
- '!.github/workflows/debug.yml'
- '!.github/workflows/test.yml'
pull_request:
branches:
- main
- dev

jobs:
build:
name: Linux
runs-on: ubuntu-latest
test:
name: ${{ matrix.os }} (Go ${{ matrix.go }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
go: ['1.25.x', '1.26.x', stable]
include:
- os: windows-latest
go: stable
- os: macos-latest
go: stable
env:
GOTOOLCHAIN: local
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -26,81 +39,21 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ^1.25.0
- name: Build
go-version: ${{ matrix.go }}
- name: Install network test tools
if: runner.os == 'Linux'
run: |
make test
go test -c -o ping_test ./ping
sudo ./ping_test -test.v
build_go124:
name: Linux (Go 1.24)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.24
continue-on-error: true
- name: Build
run: |
make test
go test -c -o ping_test ./ping
sudo ./ping_test -test.v
build_go123:
name: Linux (Go 1.23)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.23
continue-on-error: true
- name: Build
sudo apt-get update
sudo apt-get install -y iproute2
- name: Test
env:
TEST_FLAGS: ${{ runner.os != 'Windows' && '-exec sudo' || '' }}
run: make test
- name: Test unprivileged ping
if: runner.os != 'Linux'
run: go test -v ./ping
- name: Test privileged ping
if: runner.os != 'Windows'
run: |
make test
go test -c -o ping_test ./ping
sudo ./ping_test -test.v
build_windows:
name: Windows
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ^1.23
continue-on-error: true
- name: Build
run: |
make test
go test -v ./ping
build_darwin:
name: macOS
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ^1.23
continue-on-error: true
- name: Build
run: |
make test
go test -v ./ping
go test -c -o ping_test ./ping
sudo ./ping_test -test.v
10 changes: 2 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,7 @@ build:
GOOS=windows GOARCH=amd64 go build -v -tags with_gvisor .

fmt:
@gofumpt -l -w .
@gofmt -s -w .
@gci write --custom-order -s standard -s "prefix(github.com/sagernet/)" -s "default" .

fmt_install:
go install -v mvdan.cc/gofumpt@latest
go install -v github.com/daixiang0/gci@latest
@golangci-lint fmt

lint:
GOOS=linux golangci-lint --max-same-issues=0 --max-issues-per-linter=0 run ./...
Expand All @@ -29,4 +23,4 @@ lint_install:
test:
go build -v .
#go test -bench=. ./internal/checksum_test
go test -v .
go test -v $(TEST_FLAGS) .
34 changes: 32 additions & 2 deletions flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,39 @@ type Port interface {
WritePackets(packets [][]byte) error
}

type SelectorRange struct {
Start uint16
Count uint16
}

type PortWithSelectorRange interface {
Port
PortSelectorRange() (start uint16, count uint16)
PortSelectorRanges(protocol uint8) []SelectorRange
ExpandSelectorRanges(protocol uint8) bool
}

type PortWithSelectorReservation interface {
ReserveSelector(protocol uint8, address netip.AddrPort) bool
ReleaseSelector(protocol uint8, address netip.AddrPort)
}

type PortWithUpstream interface {
UpstreamPort() any
}

func portCapability[T any](port any) (T, bool) {
for port != nil {
capability, matched := port.(T)
if matched {
return capability, true
}
wrapper, isWrapper := port.(PortWithUpstream)
if !isWrapper {
break
}
port = wrapper.UpstreamPort()
}
var zero T
return zero, false
}

type Return interface {
Expand Down
Loading