Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 20 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ jobs:
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
Expand Down Expand Up @@ -43,20 +45,31 @@ jobs:
# logs are free on pass and present when a rare flake finally trips.
DST_LOG: '1'
# Serialize scheduling inside the synctest bubble: one P runs goroutines
# in runqueue order and async preemption stays off, so same-tick wakeups
# replay in program order instead of racing across threads.
# in runqueue order, async preemption stays off, and crypto packages
# honor the pinned crypto/rand.Reader, so same-tick wakeups replay in
# program order instead of racing across threads.
GOMAXPROCS: '1'
GODEBUG: 'asyncpreemptoff=1'
GODEBUG: 'asyncpreemptoff=1,cryptocustomrand=1'
# Keep GC marker goroutines out of the single P's run queue so
# executions replay identically (the dst overlay pins runtime
# randomness and neutralizes sysmon P retakes).
GOGC: 'off'
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- name: Generate durable-sync overlay
# Patches the current GOROOT's sync primitives so lock waits inside a
# synctest bubble park durably and the virtual clock can advance.
run: go run ./tools/dstoverlay -write "$RUNNER_TEMP/dst_overlay.json" -dir "$RUNNER_TEMP/dst_overlay_src"
- name: Run deterministic mesh and chaos tests
run: go test -count=1 -tags dst -run 'TestSim|TestDeterministic' .
run: go test -count=1 -tags dst -overlay="$RUNNER_TEMP/dst_overlay.json" -run 'TestSim|TestDeterministic' .
- name: Run simulation-tagged unit tests
run: go test -count=1 -tags dst ./internal/simnet ./internal/durable ./dataplane/internal/streaming/tunnel ./dataplane/internal/router ./controlplane/internal/router
run: go test -count=1 -tags dst -overlay="$RUNNER_TEMP/dst_overlay.json" ./internal/simnet ./dataplane/internal/streaming/tunnel ./dataplane/internal/router ./controlplane/internal/router

cross-platform:
name: ${{ matrix.os }} / ${{ matrix.arch }}
Expand All @@ -79,6 +92,8 @@ jobs:
CGO_ENABLED: '0'
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/in-memory-eepsite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
timeout-minutes: 25
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/live-i2p-roundtrip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/ssu2-interop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ jobs:
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/sumdb-register.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
GOWORK: 'off'
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
Expand Down
4 changes: 2 additions & 2 deletions client/internal/addressbook/subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"net/http"
"net/url"
"strings"
"sync"

"gosuda.org/ivnp/internal/durable"
"gosuda.org/ivnp/internal/parallelism"
)

Expand Down Expand Up @@ -83,7 +83,7 @@ func (s *Service) refresh(parent context.Context) error {
fetches[index] = fetchJob{raw: raw, haveSnapshot: haveSnapshot, etag: etags[raw], modified: modified[raw]}
}
workers := parallelism.Workers(len(fetches))
var group durable.WaitGroup
var group sync.WaitGroup
group.Add(workers)
for range workers {
go func() {
Expand Down
4 changes: 1 addition & 3 deletions client/internal/frontend/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"net"
"net/http"
"sync"

"gosuda.org/ivnp/internal/durable"
)

var (
Expand All @@ -22,7 +20,7 @@ type server struct {
context context.Context
cancel context.CancelFunc
done chan struct{}
activities durable.WaitGroup
activities sync.WaitGroup
started bool
closed bool
}
Expand Down
5 changes: 2 additions & 3 deletions client/internal/sam/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (

"gosuda.org/ivnp/foundation"
"gosuda.org/ivnp/interfaces/destination"
"gosuda.org/ivnp/internal/durable"
"gosuda.org/ivnp/internal/ingress"
"gosuda.org/ivnp/observability"
)
Expand Down Expand Up @@ -65,7 +64,7 @@ type ServerConfig struct {
// Server serves inbound SAM while Network remains the external SAM client.
type Server struct {
config ServerConfig
mu durable.RWMutex
mu sync.RWMutex
sessions map[string]*samSession
destinations map[foundation.Hash]*samSession
listener net.Listener
Expand All @@ -75,7 +74,7 @@ type Server struct {
ctx context.Context
cancel context.CancelFunc
done chan struct{}
wg durable.WaitGroup
wg sync.WaitGroup
started bool
closed bool
sem chan struct{}
Expand Down
3 changes: 1 addition & 2 deletions client/internal/sam/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"gosuda.org/ivnp/dataplane"
"gosuda.org/ivnp/foundation"
"gosuda.org/ivnp/interfaces/destination"
"gosuda.org/ivnp/internal/durable"
)

var errUnknownSubsession = errors.New("sam: unknown subsession")
Expand Down Expand Up @@ -77,7 +76,7 @@ type samSession struct {
acceptCancellations atomic.Uint64
once sync.Once
closeErr error
wg durable.WaitGroup
wg sync.WaitGroup
}

func newRootSession(server *Server, id string, style sessionStyle, endpoint destination.DestinationEndpoint, control *serverConnection, fromPort, toPort, listenPort uint16, protocol, listenProtocol uint8, rawHeader bool, udpTarget *net.UDPAddr, offline *foundation.OfflineSignature) *samSession {
Expand Down
5 changes: 2 additions & 3 deletions cmd/ivnp-reseed/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import (
"slices"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"

"gosuda.org/ivnp/internal/durable"
)

type ServerConfig struct {
Expand All @@ -30,7 +29,7 @@ type ReseedServer struct {
// pkg is swapped atomically once per epoch; readers load an immutable
// package pointer so the hot path never takes a lock.
pkg atomic.Pointer[ReseedPackage]
mu durable.RWMutex
mu sync.RWMutex
certPEM []byte
pubKeyPEM []byte
handler http.Handler
Expand Down
4 changes: 2 additions & 2 deletions cmd/ivnp-reseed/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import (
"slices"
"strconv"
"strings"
"sync"
"time"

"gosuda.org/ivnp/foundation"
"gosuda.org/ivnp/internal/durable"
)

// PeerStore provides thread-safe, memory-bounded peer indexing and snapshot persistence.
type PeerStore struct {
mu durable.RWMutex
mu sync.RWMutex
peers map[foundation.Hash]*PeerRecord
bySubnet16 map[[2]byte]map[foundation.Hash]struct{}
byFamily map[string]map[foundation.Hash]struct{}
Expand Down
5 changes: 2 additions & 3 deletions cmd/ivnpd/webui_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"sync"
"time"

"gosuda.org/ivnp/internal/durable"
"gosuda.org/ivnp/node"
"gosuda.org/ivnp/state"
)
Expand Down Expand Up @@ -81,10 +80,10 @@ type WebUIServer struct {
tokenHash [32]byte
scriptSources string

configMu durable.RWMutex
configMu sync.RWMutex
persistedConfig state.ConfigurationOperating

trafficMu durable.RWMutex
trafficMu sync.RWMutex
traffic trafficSample

subscribersMu sync.Mutex
Expand Down
3 changes: 1 addition & 2 deletions controlplane/internal/netdb/confirmation.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"sync"

"gosuda.org/ivnp/foundation"
"gosuda.org/ivnp/internal/durable"
)

const (
Expand Down Expand Up @@ -311,7 +310,7 @@ func (p *confirmedPublication) maintain(ctx context.Context, force bool) (int, e
break
}
results := make([]error, len(batch))
var group durable.WaitGroup
var group sync.WaitGroup
group.Add(len(batch))
for index := range batch {
go func() {
Expand Down
3 changes: 1 addition & 2 deletions controlplane/internal/netdb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"time"

"gosuda.org/ivnp/foundation"
"gosuda.org/ivnp/internal/durable"
"gosuda.org/ivnp/internal/pool"
"gosuda.org/ivnp/observability"
)
Expand Down Expand Up @@ -55,7 +54,7 @@ type leaseExpiry struct {
// Database stores verified RouterInfos and LeaseSets with memory bounds and TTL expiration.
type Database struct {
routers *Table
leasesMu durable.RWMutex
leasesMu sync.RWMutex
leases map[foundation.Hash]leaseEntry
leaseExpiries []leaseExpiry
leaseExpiryIndex map[foundation.Hash]int
Expand Down
4 changes: 2 additions & 2 deletions controlplane/internal/netdb/dht.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"crypto/subtle"
"errors"
"math/bits"
"sync"

"gosuda.org/ivnp/foundation"
"gosuda.org/ivnp/internal/durable"
"gosuda.org/ivnp/internal/parallelism"
)

Expand Down Expand Up @@ -35,7 +35,7 @@ type routerSelectionBuffer struct {
// Table mirrors Java I2P's split NetDB model: routers owns every verified
// RouterInfo, while routing is the bounded KBucketSet used by DHT traversal.
type Table struct {
mu durable.RWMutex
mu sync.RWMutex
local foundation.Hash
routers map[foundation.Hash]routerEntry
routing kBucketSet
Expand Down
4 changes: 2 additions & 2 deletions controlplane/internal/netdb/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ package netdb

import (
"encoding/binary"
"sync"

"gosuda.org/ivnp/foundation"
"gosuda.org/ivnp/internal/durable"
"gosuda.org/ivnp/internal/wire"
)

// LocalLeaseSet holds locally published inbound-lease metadata. It does not
// retain encryption or signing private keys; callers supply public keys and a
// signer when they serialize a publication.
type LocalLeaseSet struct {
mu durable.RWMutex
mu sync.RWMutex
identity []byte
hash foundation.Hash
leases []foundation.NetworkDatabaseLease
Expand Down
4 changes: 2 additions & 2 deletions controlplane/internal/netdb/local_encrypted_ls2.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import (
"encoding/binary"
"errors"
"io"
"sync"
"time"

"golang.org/x/crypto/hkdf"
"gosuda.org/ivnp/cryptography"
"gosuda.org/ivnp/foundation"
"gosuda.org/ivnp/internal/durable"
)

var (
Expand Down Expand Up @@ -53,7 +53,7 @@ type LocalEncryptedLeaseSet struct {
dhClients [][32]byte
pskClients [][32]byte
random io.Reader
mu durable.RWMutex
mu sync.RWMutex
released bool
}

Expand Down
4 changes: 2 additions & 2 deletions controlplane/internal/netdb/local_ls2.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package netdb
import (
"encoding/binary"
"errors"
"sync"

"gosuda.org/ivnp/foundation"
"gosuda.org/ivnp/internal/durable"
)

var ErrLocalLeaseSet2 = errors.New("netdb: invalid local LeaseSet2")
Expand All @@ -19,7 +19,7 @@ type LocalLeaseSet2 struct {
public [32]byte
types []foundation.CryptoKeyType
offline *foundation.OfflineSignature
mu durable.RWMutex
mu sync.RWMutex
leases []foundation.NetworkDatabaseLease2
}

Expand Down
4 changes: 2 additions & 2 deletions controlplane/internal/netdb/local_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"crypto/ed25519"
"encoding/binary"
"errors"
"sync"

"gosuda.org/ivnp/foundation"
"gosuda.org/ivnp/internal/durable"
)

var ErrLocalRouterIdentity = errors.New("netdb: local RouterInfo identity does not match signing key")
Expand Down Expand Up @@ -43,7 +43,7 @@ type LocalRouterInfoConfig struct {
// Snapshot always returns an independent wire copy, so callers cannot mutate
// the retained advertisement.
type LocalRouterInfo struct {
mu durable.RWMutex
mu sync.RWMutex
identity []byte
private ed25519.PrivateKey
hash foundation.Hash
Expand Down
3 changes: 1 addition & 2 deletions controlplane/internal/netdb/lookup_responder.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"time"

"gosuda.org/ivnp/foundation"
"gosuda.org/ivnp/internal/durable"
"gosuda.org/ivnp/internal/parallelism"
)

Expand Down Expand Up @@ -76,7 +75,7 @@ type LookupResponder struct {
started bool
closed bool
cancel context.CancelFunc
wg durable.WaitGroup
wg sync.WaitGroup
err error
}

Expand Down
Loading
Loading