瀏覽代碼

support stats counter in dispatcher

Darien Raymond 7 年之前
父節點
當前提交
e5a5c30b67
共有 1 個文件被更改,包括 29 次插入1 次删除
  1. 29 1
      app/dispatcher/default.go

+ 29 - 1
app/dispatcher/default.go

@@ -11,6 +11,7 @@ import (
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/net"
+	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/proxy"
 	"v2ray.com/core/transport/ray"
 )
@@ -23,6 +24,8 @@ var (
 type DefaultDispatcher struct {
 	ohm    core.OutboundHandlerManager
 	router core.Router
+	policy core.PolicyManager
+	stats  core.StatManager
 }
 
 // NewDefaultDispatcher create a new DefaultDispatcher.
@@ -31,6 +34,8 @@ func NewDefaultDispatcher(ctx context.Context, config *Config) (*DefaultDispatch
 	d := &DefaultDispatcher{
 		ohm:    v.OutboundHandlerManager(),
 		router: v.Router(),
+		policy: v.PolicyManager(),
+		stats:  v.Stats(),
 	}
 
 	if err := v.RegisterFeature((*core.Dispatcher)(nil), d); err != nil {
@@ -47,6 +52,10 @@ func (*DefaultDispatcher) Start() error {
 // Close implements app.Application.
 func (*DefaultDispatcher) Close() error { return nil }
 
+func getStatsName(u *protocol.User) string {
+	return "user>traffic>" + u.Email
+}
+
 // Dispatch implements core.Dispatcher.
 func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destination) (ray.InboundRay, error) {
 	if !destination.IsValid() {
@@ -54,7 +63,26 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
 	}
 	ctx = proxy.ContextWithTarget(ctx, destination)
 
-	outbound := ray.New(ctx)
+	var rayOptions []ray.Option
+
+	user := protocol.UserFromContext(ctx)
+	if user != nil && len(user.Email) > 0 {
+		name := getStatsName(user)
+		c, err := d.stats.RegisterCounter(name)
+		if err != nil {
+			c = d.stats.GetCounter(name)
+		}
+		if c == nil {
+			newError("failed to get stats counter ", name).AtWarning().WithContext(ctx).WriteToLog()
+		}
+
+		p := d.policy.ForLevel(user.Level)
+		if p.Stats.EnablePerUser {
+			rayOptions = append(rayOptions, ray.WithStatCounter(c))
+		}
+	}
+
+	outbound := ray.New(ctx, rayOptions...)
 	snifferList := proxyman.ProtocolSniffersFromContext(ctx)
 	if destination.Address.Family().IsDomain() || len(snifferList) == 0 {
 		go d.routedDispatch(ctx, outbound, destination)