Skip to content
Open
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
17 changes: 17 additions & 0 deletions backend/wireguard/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,23 @@ import (

const onlineActivityThreshold = 45 * time.Second

// The tracker preserves cumulative deltas across peer changes and soft restarts.
// A new backend instance receives a new epoch when its trackers are recreated.
func (wg *WireGuard) UsageSnapshot(ctx context.Context, kind common.StatType) (string, *common.StatResponse, error) {
wg.syncMu.Lock()
defer wg.syncMu.Unlock()
if kind == common.StatType_Outbounds {
rx, tx, err := wg.getInterfaceCounters()
if err != nil {
return "", nil, err
}
rx, tx = wg.interfaceStats.Cumulative(rx, tx)
return wg.usageEpoch, &common.StatResponse{Stats: stats.BuildInterfaceStats(wg.config.InterfaceName, "interface", rx, tx)}, nil
}
stats, err := wg.GetStats(ctx, &common.StatRequest{Type: kind, Reset_: false})
return wg.usageEpoch, stats, err
}

func (wg *WireGuard) getInterfaceCounters() (int64, int64, error) {
wg.mu.RLock()
mgr := wg.manager
Expand Down
4 changes: 4 additions & 0 deletions backend/wireguard/wireguard.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"sync"
"time"

"github.com/google/uuid"

"github.com/pasarguard/node/common"
"github.com/pasarguard/node/config"
"github.com/pasarguard/node/pkg/stats"
Expand Down Expand Up @@ -65,6 +67,7 @@ type WireGuard struct {
lastStatsErrAt time.Time
newManager newManagerFunc
hostRouting func()
usageEpoch string
}

// getWireGuardVersion fetches the wireguard-tools version
Expand Down Expand Up @@ -128,6 +131,7 @@ func newWithManagerFactory(cfg *config.Config, wgConfig *Config, users []*common
version := getWireGuardVersion()

wg := &WireGuard{
usageEpoch: uuid.NewString(),
cancelFunc: wgCancel,
cfg: cfg,
statsTracker: stats.New(),
Expand Down
9 changes: 9 additions & 0 deletions backend/xray/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,12 @@ func (x *Xray) GetStats(ctx context.Context, request *common.StatRequest) (*comm
return nil, errors.New("not implemented stat type")
}
}

// UsageSnapshot holds the lifecycle lock across the read, binding cumulative
// counters to precisely one core generation, even during a health restart.
func (x *Xray) UsageSnapshot(ctx context.Context, kind common.StatType) (string, *common.StatResponse, error) {
x.mu.RLock()
defer x.mu.RUnlock()
stats, err := x.GetStats(ctx, &common.StatRequest{Type: kind, Reset_: false})
return x.usageEpoch, stats, err
}
5 changes: 5 additions & 0 deletions backend/xray/xray.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"sync"
"time"

"github.com/google/uuid"

"github.com/pasarguard/node/backend/xray/api"
"github.com/pasarguard/node/common"
"github.com/pasarguard/node/config"
Expand All @@ -21,6 +23,7 @@ type Xray struct {
cancelFunc context.CancelFunc
mu sync.RWMutex
syncMu sync.Mutex
usageEpoch string
}

func New(ctx context.Context, xrayConfig *Config, users []*common.User, apiPort, metricPort int, cfg *config.Config) (*Xray, error) {
Expand All @@ -42,6 +45,7 @@ func New(ctx context.Context, xrayConfig *Config, users []*common.User, apiPort,
xCtx, xCancel := context.WithCancel(context.Background())

xray := &Xray{
usageEpoch: uuid.NewString(),
cancelFunc: xCancel,
cfg: cfg,
metricPort: metricPort,
Expand Down Expand Up @@ -132,6 +136,7 @@ func (x *Xray) restartCoreWithConfig(config *Config) error {
if err := x.core.Restart(config, x.cfg.Debug); err != nil {
return err
}
x.usageEpoch = uuid.NewString()
return nil
}

Expand Down
Loading
Loading