From 30e312f72b9655e0403cbb3ea49d10879f9ea587 Mon Sep 17 00:00:00 2001 From: Vigilans Date: Sat, 1 Aug 2020 02:04:06 +0800 Subject: [PATCH] Apply sockopt from inbound config to dokodemo tproxy's response connection --- app/proxyman/inbound/inbound.go | 7 +++++++ common/session/context.go | 14 ++++++++++++++ common/session/session.go | 6 ++++++ proxy/dokodemo/dokodemo.go | 9 +++++++-- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/app/proxyman/inbound/inbound.go b/app/proxyman/inbound/inbound.go index 52835694..fa8ffb78 100644 --- a/app/proxyman/inbound/inbound.go +++ b/app/proxyman/inbound/inbound.go @@ -150,6 +150,13 @@ func NewHandler(ctx context.Context, config *core.InboundHandlerConfig) (inbound return nil, newError("not a ReceiverConfig").AtError() } + streamSettings := receiverSettings.StreamSettings + if streamSettings != nil && streamSettings.SocketSettings != nil { + ctx = session.ContextWithSockopt(ctx, &session.Sockopt{ + Mark: streamSettings.SocketSettings.Mark, + }) + } + allocStrategy := receiverSettings.AllocationStrategy if allocStrategy == nil || allocStrategy.Type == proxyman.AllocationStrategy_Always { return NewAlwaysOnInboundHandler(ctx, tag, receiverSettings, proxySettings) diff --git a/common/session/context.go b/common/session/context.go index a836bc6b..7f1d7df9 100644 --- a/common/session/context.go +++ b/common/session/context.go @@ -10,6 +10,7 @@ const ( outboundSessionKey contentSessionKey muxPreferedSessionKey + sockoptSessionKey ) // ContextWithID returns a new context with the given ID. @@ -70,3 +71,16 @@ func MuxPreferedFromContext(ctx context.Context) bool { } return false } + +// ContextWithSockopt returns a new context with Socket configs included +func ContextWithSockopt(ctx context.Context, s *Sockopt) context.Context { + return context.WithValue(ctx, sockoptSessionKey, s) +} + +// SockoptFromContext returns Socket configs in this context, or nil if not contained. +func SockoptFromContext(ctx context.Context) *Sockopt { + if sockopt, ok := ctx.Value(sockoptSessionKey).(*Sockopt); ok { + return sockopt + } + return nil +} diff --git a/common/session/session.go b/common/session/session.go index 52252648..86172c8a 100644 --- a/common/session/session.go +++ b/common/session/session.go @@ -72,6 +72,12 @@ type Content struct { SkipRoutePick bool } +// Sockopt is the settings for socket connection. +type Sockopt struct { + // Mark of the socket connection. + Mark int32 +} + func (c *Content) SetAttribute(name string, value interface{}) { if c.Attributes == nil { c.Attributes = make(map[string]interface{}) diff --git a/proxy/dokodemo/dokodemo.go b/proxy/dokodemo/dokodemo.go index c351b437..24ebe098 100644 --- a/proxy/dokodemo/dokodemo.go +++ b/proxy/dokodemo/dokodemo.go @@ -27,7 +27,7 @@ func init() { common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { d := new(DokodemoDoor) err := core.RequireFeatures(ctx, func(pm policy.Manager) error { - return d.Init(config.(*Config), pm) + return d.Init(config.(*Config), pm, session.SockoptFromContext(ctx)) }) return d, err })) @@ -38,10 +38,11 @@ type DokodemoDoor struct { config *Config address net.Address port net.Port + sockopt *session.Sockopt } // Init initializes the DokodemoDoor instance with necessary parameters. -func (d *DokodemoDoor) Init(config *Config, pm policy.Manager) error { +func (d *DokodemoDoor) Init(config *Config, pm policy.Manager, sockopt *session.Sockopt) error { if (config.NetworkList == nil || len(config.NetworkList.Network) == 0) && len(config.Networks) == 0 { return newError("no network specified") } @@ -49,6 +50,7 @@ func (d *DokodemoDoor) Init(config *Config, pm policy.Manager) error { d.address = config.GetPredefinedAddress() d.port = net.Port(config.Port) d.policyManager = pm + d.sockopt = sockopt return nil } @@ -165,6 +167,9 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in sockopt.BindAddress = dest.Address.IP() sockopt.BindPort = uint32(dest.Port) } + if d.sockopt != nil { + sockopt.Mark = d.sockopt.Mark + } tConn, err := internet.DialSystem(ctx, net.DestinationFromAddr(conn.RemoteAddr()), sockopt) if err != nil { return err