diff --git a/app/proxyman/config.pb.go b/app/proxyman/config.pb.go index d644e3d1..cfa9e032 100644 --- a/app/proxyman/config.pb.go +++ b/app/proxyman/config.pb.go @@ -534,6 +534,8 @@ type MultiplexingConfig struct { XudpConcurrency int32 `protobuf:"varint,3,opt,name=xudpConcurrency,proto3" json:"xudpConcurrency,omitempty"` // "reject" (default), "allow" or "skip". XudpProxyUDP443 string `protobuf:"bytes,4,opt,name=xudpProxyUDP443,proto3" json:"xudpProxyUDP443,omitempty"` + // MaxReuseTimes for an connection + MaxReuseTimes int32 `protobuf:"varint,5,opt,name=maxReuseTimes,proto3" json:"maxReuseTimes,omitempty"` } func (x *MultiplexingConfig) Reset() { @@ -594,6 +596,13 @@ func (x *MultiplexingConfig) GetXudpProxyUDP443() string { return "" } +func (x *MultiplexingConfig) GetMaxReuseTimes() int32 { + if x != nil { + return x.MaxReuseTimes + } + return 0 +} + type AllocationStrategy_AllocationStrategyConcurrency struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -800,7 +809,7 @@ var file_app_proxyman_config_proto_rawDesc = []byte{ 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x69, 0x61, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x76, 0x69, 0x61, 0x43, 0x69, 0x64, 0x72, 0x22, 0xa4, 0x01, 0x0a, 0x12, 0x4d, 0x75, 0x6c, 0x74, + 0x76, 0x69, 0x61, 0x43, 0x69, 0x64, 0x72, 0x22, 0xca, 0x01, 0x0a, 0x12, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, @@ -810,13 +819,16 @@ var file_app_proxyman_config_proto_rawDesc = []byte{ 0x01, 0x28, 0x05, 0x52, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x44, 0x50, 0x34, 0x34, 0x33, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x78, - 0x75, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x44, 0x50, 0x34, 0x34, 0x33, 0x42, 0x55, - 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x50, 0x01, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, - 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, - 0x6e, 0xaa, 0x02, 0x11, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x75, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x44, 0x50, 0x34, 0x34, 0x33, 0x12, 0x24, + 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x75, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x75, 0x73, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x42, 0x55, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x50, 0x01, 0x5a, + 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, + 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x70, + 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0xaa, 0x02, 0x11, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, + 0x70, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/app/proxyman/config.proto b/app/proxyman/config.proto index 635ffad2..e8657d2b 100644 --- a/app/proxyman/config.proto +++ b/app/proxyman/config.proto @@ -95,4 +95,6 @@ message MultiplexingConfig { int32 xudpConcurrency = 3; // "reject" (default), "allow" or "skip". string xudpProxyUDP443 = 4; + // MaxReuseTimes for an connection + int32 maxReuseTimes = 5; } diff --git a/app/proxyman/outbound/handler.go b/app/proxyman/outbound/handler.go index df7d52a4..ef057399 100644 --- a/app/proxyman/outbound/handler.go +++ b/app/proxyman/outbound/handler.go @@ -114,6 +114,10 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou if h.senderSettings != nil && h.senderSettings.MultiplexSettings != nil { if config := h.senderSettings.MultiplexSettings; config.Enabled { + MaxReuseTimes := uint32(65535) // as many as possible + if config.MaxReuseTimes != 0 { + MaxReuseTimes = uint32(config.MaxReuseTimes) + } if config.Concurrency < 0 { h.mux = &mux.ClientManager{Enabled: false} } @@ -129,7 +133,7 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou Dialer: h, Strategy: mux.ClientStrategy{ MaxConcurrency: uint32(config.Concurrency), - MaxConnection: 128, + MaxReuseTimes: MaxReuseTimes, }, }, }, @@ -150,7 +154,7 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou Dialer: h, Strategy: mux.ClientStrategy{ MaxConcurrency: uint32(config.XudpConcurrency), - MaxConnection: 128, + MaxReuseTimes: 128, }, }, }, diff --git a/common/mux/client.go b/common/mux/client.go index df74ef17..afc4ef96 100644 --- a/common/mux/client.go +++ b/common/mux/client.go @@ -166,7 +166,7 @@ func (f *DialingWorkerFactory) Create() (*ClientWorker, error) { type ClientStrategy struct { MaxConcurrency uint32 - MaxConnection uint32 + MaxReuseTimes uint32 } type ClientWorker struct { @@ -270,7 +270,7 @@ func fetchInput(ctx context.Context, s *Session, output buf.Writer) { func (m *ClientWorker) IsClosing() bool { sm := m.sessionManager - if m.strategy.MaxConnection > 0 && sm.Count() >= int(m.strategy.MaxConnection) { + if m.strategy.MaxReuseTimes > 0 && sm.Count() >= int(m.strategy.MaxReuseTimes) { return true } return false @@ -298,6 +298,8 @@ func (m *ClientWorker) Dispatch(ctx context.Context, link *transport.Link) bool if s == nil { return false } + errors.LogInfo(ctx, "allocated mux.cool subConnection ID: ", s.ID, "/", m.strategy.MaxReuseTimes) + errors.LogInfo(ctx, "living subConnections:", sm.Size() , "/", m.strategy.MaxConcurrency) s.input = link.Reader s.output = link.Writer go fetchInput(ctx, s, m.link.Writer) diff --git a/common/mux/client_test.go b/common/mux/client_test.go index 9626e2a2..d0238e96 100644 --- a/common/mux/client_test.go +++ b/common/mux/client_test.go @@ -58,7 +58,7 @@ func TestClientWorkerClose(t *testing.T) { Writer: w1, }, mux.ClientStrategy{ MaxConcurrency: 4, - MaxConnection: 4, + MaxReuseTimes: 4, }) common.Must(err) @@ -68,7 +68,7 @@ func TestClientWorkerClose(t *testing.T) { Writer: w2, }, mux.ClientStrategy{ MaxConcurrency: 4, - MaxConnection: 4, + MaxReuseTimes: 4, }) common.Must(err) diff --git a/infra/conf/xray.go b/infra/conf/xray.go index ee9e6dfd..8700834c 100644 --- a/infra/conf/xray.go +++ b/infra/conf/xray.go @@ -97,6 +97,7 @@ func (c *SniffingConfig) Build() (*proxyman.SniffingConfig, error) { type MuxConfig struct { Enabled bool `json:"enabled"` Concurrency int16 `json:"concurrency"` + MaxReuseTimes int32 `json:"maxReuseTimes"` XudpConcurrency int16 `json:"xudpConcurrency"` XudpProxyUDP443 string `json:"xudpProxyUDP443"` } @@ -113,6 +114,7 @@ func (m *MuxConfig) Build() (*proxyman.MultiplexingConfig, error) { return &proxyman.MultiplexingConfig{ Enabled: m.Enabled, Concurrency: int32(m.Concurrency), + MaxReuseTimes: m.MaxReuseTimes, XudpConcurrency: int32(m.XudpConcurrency), XudpProxyUDP443: m.XudpProxyUDP443, }, nil