|
|
|
@ -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) |
|
|
|
|