diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index bb0444e..823617e 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -21,7 +21,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: '^1.20' + go-version: '^1.21' - name: Get dependencies run: go mod download @@ -46,7 +46,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: '^1.20' + go-version: '^1.21' - name: Get dependencies run: go mod download diff --git a/crew/connect.go b/crew/connect.go index 4d214df..5a2d22c 100644 --- a/crew/connect.go +++ b/crew/connect.go @@ -82,7 +82,7 @@ func (t *Tunnel) connectWorker(ctx context.Context) (err error) { // TODO: Clean this up. t.connInfo.Lock() defer t.connInfo.Unlock() - t.connInfo.Failed(fmt.Sprintf("failed to establish route: %s", err), "") + t.connInfo.Failed(fmt.Sprintf("SPN failed to establish route: %s", err), "") t.connInfo.Save() tracer.Warningf("spn/crew: failed to establish route for %s: %s", t.connInfo, err) @@ -97,11 +97,11 @@ func (t *Tunnel) connectWorker(ctx context.Context) (err error) { t.connInfo.Lock() defer t.connInfo.Unlock() - t.connInfo.Failed(tErr.Error(), "") + t.connInfo.Failed(fmt.Sprintf("SPN failed to initialize data tunnel (connect op): %s", tErr.Error()), "") t.connInfo.Save() // TODO: try with another route? - tracer.Warningf("spn/crew: failed to initialize tunnel for %s: %s", t.connInfo, err) + tracer.Warningf("spn/crew: failed to initialize data tunnel (connect op) for %s: %s", t.connInfo, err) return tErr } diff --git a/crew/metrics.go b/crew/metrics.go index 7e3c9c3..b9549d1 100644 --- a/crew/metrics.go +++ b/crew/metrics.go @@ -10,7 +10,14 @@ import ( ) var ( - newConnectOp *metrics.Counter + connectOpCnt *metrics.Counter + connectOpCntError *metrics.Counter + connectOpCntBadRequest *metrics.Counter + connectOpCntCanceled *metrics.Counter + connectOpCntFailed *metrics.Counter + connectOpCntConnected *metrics.Counter + connectOpCntRateLimited *metrics.Counter + connectOpIncomingBytes *metrics.Counter connectOpOutgoingBytes *metrics.Counter @@ -29,9 +36,9 @@ func registerMetrics() (err error) { return nil } - // Connect Op Stats. + // Connect Op Stats on client. - newConnectOp, err = metrics.NewCounter( + connectOpCnt, err = metrics.NewCounter( "spn/op/connect/total", nil, &metrics.Options{ @@ -45,6 +52,68 @@ func registerMetrics() (err error) { return err } + // Connect Op Stats on server. + + connectOpCntOptions := &metrics.Options{ + Name: "SPN Total Connect Operations", + Permission: api.PermitUser, + Persist: true, + } + + connectOpCntError, err = metrics.NewCounter( + "spn/op/connect/total", + map[string]string{"result": "error"}, + connectOpCntOptions, + ) + if err != nil { + return err + } + + connectOpCntBadRequest, err = metrics.NewCounter( + "spn/op/connect/total", + map[string]string{"result": "bad_request"}, + connectOpCntOptions, + ) + if err != nil { + return err + } + + connectOpCntCanceled, err = metrics.NewCounter( + "spn/op/connect/total", + map[string]string{"result": "canceled"}, + connectOpCntOptions, + ) + if err != nil { + return err + } + + connectOpCntFailed, err = metrics.NewCounter( + "spn/op/connect/total", + map[string]string{"result": "failed"}, + connectOpCntOptions, + ) + if err != nil { + return err + } + + connectOpCntConnected, err = metrics.NewCounter( + "spn/op/connect/total", + map[string]string{"result": "connected"}, + connectOpCntOptions, + ) + if err != nil { + return err + } + + connectOpCntRateLimited, err = metrics.NewCounter( + "spn/op/connect/total", + map[string]string{"result": "rate_limited"}, + connectOpCntOptions, + ) + if err != nil { + return err + } + _, err = metrics.NewGauge( "spn/op/connect/active", nil, diff --git a/crew/op_connect.go b/crew/op_connect.go index 438d5bf..158c1b0 100644 --- a/crew/op_connect.go +++ b/crew/op_connect.go @@ -116,7 +116,7 @@ func init() { // NewConnectOp starts a new connect operation. func NewConnectOp(tunnel *Tunnel) (*ConnectOp, *terminal.Error) { // Submit metrics. - newConnectOp.Inc() + connectOpCnt.Inc() // Create request. request := &ConnectRequest{ @@ -168,9 +168,6 @@ func NewConnectOp(tunnel *Tunnel) (*ConnectOp, *terminal.Error) { } func startConnectOp(t terminal.Terminal, opID uint32, data *container.Container) (terminal.Operation, *terminal.Error) { - // Submit metrics. - newConnectOp.Inc() - // Check if we are running a public hub. if !conf.PublicHub() { return nil, terminal.ErrPermissionDenied.With("connecting is only allowed on public hubs") @@ -180,14 +177,17 @@ func startConnectOp(t terminal.Terminal, opID uint32, data *container.Container) request := &ConnectRequest{} _, err := dsd.Load(data.CompileData(), request) if err != nil { + connectOpCntError.Inc() // More like a protocol/system error than a bad request. return nil, terminal.ErrMalformedData.With("failed to parse connect request: %w", err) } if request.QueueSize == 0 || request.QueueSize > terminal.MaxQueueSize { + connectOpCntError.Inc() // More like a protocol/system error than a bad request. return nil, terminal.ErrInvalidOptions.With("invalid queue size of %d", request.QueueSize) } // Check if IP seems valid. if len(request.IP) != net.IPv4len && len(request.IP) != net.IPv6len { + connectOpCntError.Inc() // More like a protocol/system error than a bad request. return nil, terminal.ErrInvalidOptions.With("ip address is not valid") } @@ -213,6 +213,7 @@ func (op *ConnectOp) handleSetup(_ context.Context) error { if sessionTerm, ok := op.t.(terminal.SessionTerminal); ok { session = sessionTerm.GetSession() } else { + connectOpCntError.Inc() log.Errorf("spn/crew: %T is not a session terminal, aborting op %s#%d", op.t, op.t.FmtID(), op.ID()) op.Stop(op, terminal.ErrInternalError.With("no session available")) return nil @@ -225,6 +226,7 @@ func (op *ConnectOp) handleSetup(_ context.Context) error { // If context was canceled, stop operation. if cancelErr != nil { + connectOpCntCanceled.Inc() op.Stop(op, terminal.ErrCanceled.With(cancelErr.Error())) } @@ -235,11 +237,14 @@ func (op *ConnectOp) handleSetup(_ context.Context) error { func (op *ConnectOp) setup(session *terminal.Session) { // Rate limit before connecting. if tErr := session.RateLimit(); tErr != nil { - // Fake connection error when rate limited. + // Add rate limit info to error. if tErr.Is(terminal.ErrRateLimited) { + connectOpCntRateLimited.Inc() op.Stop(op, tErr.With(session.RateLimitInfo())) return } + + connectOpCntError.Inc() op.Stop(op, tErr) return } @@ -248,6 +253,7 @@ func (op *ConnectOp) setup(session *terminal.Session) { ipScope := netutils.GetIPScope(op.request.IP) if ipScope != netutils.Global { session.ReportSuspiciousActivity(terminal.SusFactorQuiteUnusual) + connectOpCntBadRequest.Inc() op.Stop(op, terminal.ErrPermissionDenied.With("denied request to connect to non-global IP %s", op.request.IP)) return } @@ -255,6 +261,7 @@ func (op *ConnectOp) setup(session *terminal.Session) { // Check exit policy. if tErr := checkExitPolicy(op.request); tErr != nil { session.ReportSuspiciousActivity(terminal.SusFactorQuiteUnusual) + connectOpCntBadRequest.Inc() op.Stop(op, tErr) return } @@ -262,6 +269,7 @@ func (op *ConnectOp) setup(session *terminal.Session) { // Check one last time before connecting if operation was not canceled. if op.Ctx().Err() != nil { op.Stop(op, terminal.ErrCanceled.With(op.Ctx().Err().Error())) + connectOpCntCanceled.Inc() return } @@ -269,6 +277,7 @@ func (op *ConnectOp) setup(session *terminal.Session) { dialNet := op.request.DialNetwork() if dialNet == "" { session.ReportSuspiciousActivity(terminal.SusFactorCommon) + connectOpCntBadRequest.Inc() op.Stop(op, terminal.ErrIncorrectUsage.With("protocol %s is not supported", op.request.Protocol)) return } @@ -285,10 +294,13 @@ func (op *ConnectOp) setup(session *terminal.Session) { switch { case errors.As(err, &netError) && netError.Timeout(): session.ReportSuspiciousActivity(terminal.SusFactorCommon) + connectOpCntFailed.Inc() case errors.Is(err, context.Canceled): session.ReportSuspiciousActivity(terminal.SusFactorCommon) + connectOpCntCanceled.Inc() default: session.ReportSuspiciousActivity(terminal.SusFactorWeirdButOK) + connectOpCntFailed.Inc() } op.Stop(op, terminal.ErrConnectionError.With("failed to connect to %s: %w", op.request, err)) @@ -301,6 +313,7 @@ func (op *ConnectOp) setup(session *terminal.Session) { module.StartWorker("connect op conn writer", op.connWriter) module.StartWorker("connect op flow handler", op.dfq.FlowHandler) + connectOpCntConnected.Inc() log.Infof("spn/crew: connected op %s#%d to %s", op.t.FmtID(), op.ID(), op.request) } @@ -516,18 +529,48 @@ func (op *ConnectOp) HandleStop(err *terminal.Error) (errorToSend *terminal.Erro // Cancel workers. op.cancelCtx() - // Avoid connecting to destination via this Hub if the was a connection - // error and no data was received. - if op.entry && // On clients only. - err.Is(terminal.ErrConnectionError) && - op.outgoingTraffic.Load() == 0 { - // Only if no data was received (ie. sent to local application). - op.tunnel.avoidDestinationHub() - } + // Special client-side handling. + if op.entry { + // Mark the connection as failed if there was an error and no data was sent to the app yet. + if err.IsError() && op.outgoingTraffic.Load() == 0 { + // Set connection to failed and save it to propagate the update. + c := op.tunnel.connInfo + func() { + c.Lock() + defer c.Unlock() + + if err.IsExternal() { + c.Failed(fmt.Sprintf( + "the exit node reported an error: %s", err, + ), "") + } else { + c.Failed(fmt.Sprintf( + "connection failed locally: %s", err, + ), "") + } - // If we are on the client, don't leak local errors to the server. - if op.entry && !err.IsExternal() { - return terminal.ErrStopping + c.Save() + }() + } + + // Avoid connecting to the destination via this Hub if: + // - The error is external - ie. from the server. + // - The error is a connection error. + // - No data was received. + // This indicates that there is some network level issue that we can + // possibly work around by using another exit node. + if err.IsError() && err.IsExternal() && + err.Is(terminal.ErrConnectionError) && + op.outgoingTraffic.Load() == 0 { + op.tunnel.avoidDestinationHub() + } + + // Don't leak local errors to the server. + if !err.IsExternal() { + // Change error that is reported. + return terminal.ErrStopping + } } + return err } diff --git a/go.mod b/go.mod index bc5232d..ca1256f 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/safing/spn -go 1.19 +go 1.21 require ( github.com/awalterschulze/gographviz v2.0.3+incompatible @@ -11,12 +11,12 @@ require ( github.com/rot256/pblind v0.0.0-20230622102829-4dc2c6e4b857 github.com/safing/jess v0.3.1 github.com/safing/portbase v0.18.2 - github.com/safing/portmaster v1.4.9 + github.com/safing/portmaster v1.4.10-0.20231006102818-4f0adc87e70c github.com/spf13/cobra v1.7.0 github.com/stretchr/testify v1.8.4 github.com/tevino/abool v1.2.0 - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 - golang.org/x/net v0.15.0 + golang.org/x/exp v0.0.0-20231005195138-3e424a577f31 + golang.org/x/net v0.16.0 ) require ( @@ -68,13 +68,13 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.etcd.io/bbolt v1.3.7 // indirect - golang.org/x/crypto v0.13.0 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.12.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/mod v0.13.0 // indirect + golang.org/x/sync v0.4.0 // indirect + golang.org/x/sys v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.13.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5 // indirect + gvisor.dev/gvisor v0.0.0-20231006032704-15cc3fcbbd77 // indirect ) diff --git a/go.sum b/go.sum index ea87f68..db61fe8 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,7 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -43,9 +44,11 @@ github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrV github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fxamacker/cbor v1.5.1 h1:XjQWBgdmQyqimslUh5r4tUGmoqzHmBFQOImkWGi2awg= github.com/fxamacker/cbor v1.5.1/go.mod h1:3aPGItF174ni7dDzd6JZ206H8cmr4GDNBGpPa971zsU= @@ -67,14 +70,17 @@ github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= @@ -147,6 +153,8 @@ github.com/safing/portbase v0.18.2 h1:9zechdBe9f6ucGLUV6woc1fsy+7jjDbnJcTPNzrrm6 github.com/safing/portbase v0.18.2/go.mod h1:yAZWQZysaeXp0ITUXMiXDRZp9xdgcBmnj4SPM1euRCk= github.com/safing/portmaster v1.4.9 h1:Bf4BNZO04ZtiLuI6kiRd5Pgd2u1G2AoBfsLDlXnmHog= github.com/safing/portmaster v1.4.9/go.mod h1:xXhCSflb7294/CzEoJxLO7WoYgJFNKMfYZjlNqlX6w8= +github.com/safing/portmaster v1.4.10-0.20231006102818-4f0adc87e70c h1:3wvQZ56cpaLVGYDIuxa5aIc/pM6JgvxNTlcNVZLZjuU= +github.com/safing/portmaster v1.4.10-0.20231006102818-4f0adc87e70c/go.mod h1:/TebpO1AI2NhAA303xrrjF+XFNz8H9WPVeCPVUHMN78= github.com/safing/portmaster-android/go v0.0.0-20230830120134-3226ceac3bec h1:oSJY1seobofPwpMoJRkCgXnTwfiQWNfGMCPDfqgAEfg= github.com/safing/portmaster-android/go v0.0.0-20230830120134-3226ceac3bec/go.mod h1:abwyAQrZGemWbSh/aCD9nnkp0SvFFf/mGWkAbOwPnFE= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= @@ -236,26 +244,26 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/exp v0.0.0-20231005195138-3e424a577f31 h1:9k5exFQKQglLo+RoP+4zMjOFE14P6+vyR0baDAi0Rcs= +golang.org/x/exp v0.0.0-20231005195138-3e424a577f31/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220927171203-f486391704dc/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos= +golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -281,8 +289,8 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -305,6 +313,7 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -314,5 +323,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5 h1:cv/zaNV0nr1mJzaeo4S5mHIm5va1W0/9J3/5prlsuRM= -gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5/go.mod h1:TIvkJD0sxe8pIob3p6T8IzxXunlp6yfgktvTNp+DGNM= +gvisor.dev/gvisor v0.0.0-20231006032704-15cc3fcbbd77 h1:blu01EgRxhYVOcU4t2kV818LHmqZRk866mUBaDyaTno= +gvisor.dev/gvisor v0.0.0-20231006032704-15cc3fcbbd77/go.mod h1:AVgIgHMwK63XvmAzWG9vLQ41YnVHN0du0tEC46fI7yY=