support early terminition in Freedom

pull/587/head v2.38.1
Darien Raymond 2017-09-27 14:09:38 +02:00
parent 38c61acf10
commit 3d0b2e4c79
3 changed files with 60 additions and 40 deletions

View File

@ -57,6 +57,7 @@ type Config struct {
DomainStrategy Config_DomainStrategy `protobuf:"varint,1,opt,name=domain_strategy,json=domainStrategy,enum=v2ray.core.proxy.freedom.Config_DomainStrategy" json:"domain_strategy,omitempty"` DomainStrategy Config_DomainStrategy `protobuf:"varint,1,opt,name=domain_strategy,json=domainStrategy,enum=v2ray.core.proxy.freedom.Config_DomainStrategy" json:"domain_strategy,omitempty"`
Timeout uint32 `protobuf:"varint,2,opt,name=timeout" json:"timeout,omitempty"` Timeout uint32 `protobuf:"varint,2,opt,name=timeout" json:"timeout,omitempty"`
DestinationOverride *DestinationOverride `protobuf:"bytes,3,opt,name=destination_override,json=destinationOverride" json:"destination_override,omitempty"` DestinationOverride *DestinationOverride `protobuf:"bytes,3,opt,name=destination_override,json=destinationOverride" json:"destination_override,omitempty"`
KeepAliveOnResponseClose bool `protobuf:"varint,4,opt,name=keep_alive_on_response_close,json=keepAliveOnResponseClose" json:"keep_alive_on_response_close,omitempty"`
} }
func (m *Config) Reset() { *m = Config{} } func (m *Config) Reset() { *m = Config{} }
@ -85,6 +86,13 @@ func (m *Config) GetDestinationOverride() *DestinationOverride {
return nil return nil
} }
func (m *Config) GetKeepAliveOnResponseClose() bool {
if m != nil {
return m.KeepAliveOnResponseClose
}
return false
}
func init() { func init() {
proto.RegisterType((*DestinationOverride)(nil), "v2ray.core.proxy.freedom.DestinationOverride") proto.RegisterType((*DestinationOverride)(nil), "v2ray.core.proxy.freedom.DestinationOverride")
proto.RegisterType((*Config)(nil), "v2ray.core.proxy.freedom.Config") proto.RegisterType((*Config)(nil), "v2ray.core.proxy.freedom.Config")
@ -94,25 +102,28 @@ func init() {
func init() { proto.RegisterFile("v2ray.com/core/proxy/freedom/config.proto", fileDescriptor0) } func init() { proto.RegisterFile("v2ray.com/core/proxy/freedom/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 318 bytes of a gzipped FileDescriptorProto // 361 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0xcf, 0x4a, 0xc3, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xcf, 0x4e, 0xe3, 0x30,
0x10, 0xc6, 0x4d, 0xc5, 0x14, 0x47, 0xac, 0x65, 0xeb, 0x21, 0x88, 0x87, 0xd2, 0x8b, 0x55, 0x70, 0x10, 0xc6, 0x37, 0xdd, 0xdd, 0x74, 0xd7, 0x88, 0x52, 0xa5, 0x1c, 0x2c, 0xd4, 0x43, 0xd5, 0x0b,
0x23, 0xf1, 0x09, 0xec, 0x1f, 0xa1, 0x27, 0x4b, 0x82, 0xa2, 0x5e, 0x62, 0xcc, 0x4e, 0xcb, 0x82, 0x05, 0x09, 0x07, 0x85, 0x3b, 0x52, 0xff, 0x21, 0xf5, 0xd4, 0x2a, 0x11, 0x08, 0xb8, 0x98, 0x90,
0xd9, 0x09, 0x9b, 0xb5, 0x98, 0x27, 0xf0, 0x5d, 0x7c, 0x4a, 0x71, 0x93, 0xa2, 0x55, 0x73, 0xdb, 0x4c, 0x2b, 0x8b, 0xc6, 0x13, 0x39, 0x26, 0x22, 0xaf, 0xc4, 0x8b, 0xf0, 0x5a, 0x28, 0x4e, 0x2a,
0x99, 0xfd, 0x7d, 0xdf, 0xcc, 0x37, 0x70, 0xba, 0x0a, 0x74, 0x52, 0xf2, 0x94, 0x32, 0x3f, 0x25, 0x28, 0x6a, 0x6f, 0x99, 0xcc, 0xef, 0xfb, 0x66, 0xbe, 0x31, 0x39, 0xcb, 0x3d, 0x15, 0x16, 0x2c,
0x8d, 0x7e, 0xae, 0xe9, 0xad, 0xf4, 0x17, 0x1a, 0x51, 0xd8, 0x96, 0x5a, 0xc8, 0x25, 0xcf, 0x35, 0xc2, 0xc4, 0x8d, 0x50, 0x81, 0x9b, 0x2a, 0x7c, 0x2b, 0xdc, 0xa5, 0x02, 0x88, 0xcd, 0x2f, 0xb9,
0x19, 0x62, 0xde, 0x1a, 0xd5, 0xc8, 0x2d, 0xc6, 0x6b, 0xec, 0xe8, 0xe2, 0x97, 0x49, 0x4a, 0x59, 0x14, 0x2b, 0x96, 0x2a, 0xd4, 0xe8, 0xd0, 0x0d, 0xaa, 0x80, 0x19, 0x8c, 0xd5, 0xd8, 0xc9, 0xe5,
0x46, 0xca, 0xb7, 0xb2, 0x94, 0x5e, 0xfc, 0x02, 0xf5, 0x0a, 0x75, 0x5c, 0xe4, 0x98, 0x56, 0x5e, 0x0f, 0x93, 0x08, 0x93, 0x04, 0xa5, 0x6b, 0x64, 0x11, 0xae, 0xdd, 0x0c, 0x54, 0x0e, 0x8a, 0x67,
0x83, 0x07, 0xe8, 0x4d, 0xb0, 0x30, 0x52, 0x25, 0x46, 0x92, 0xba, 0x59, 0xa1, 0xd6, 0x52, 0x20, 0x29, 0x44, 0x95, 0x57, 0xff, 0x81, 0x74, 0x26, 0x90, 0x69, 0x21, 0x43, 0x2d, 0x50, 0xce, 0x73,
0x1b, 0x81, 0x5b, 0xb1, 0x9e, 0xd3, 0x77, 0x86, 0x7b, 0xc1, 0x19, 0xff, 0x31, 0xb3, 0x72, 0xe5, 0x50, 0x4a, 0xc4, 0xe0, 0x8c, 0x88, 0x5d, 0xb1, 0xd4, 0xea, 0x59, 0x83, 0x03, 0xef, 0x9c, 0x7d,
0x6b, 0x57, 0x1e, 0x59, 0x72, 0xaa, 0x44, 0x4e, 0x52, 0x99, 0xb0, 0x56, 0x0e, 0xde, 0x5b, 0xe0, 0x9b, 0x59, 0xb9, 0xb2, 0x8d, 0x2b, 0x0b, 0x0c, 0x39, 0x95, 0x71, 0x8a, 0x42, 0x6a, 0xbf, 0x56,
0x8e, 0xed, 0xde, 0xec, 0x1e, 0x0e, 0x04, 0x65, 0x89, 0x54, 0x71, 0x61, 0x74, 0x62, 0x70, 0x59, 0xf6, 0x3f, 0x1a, 0xc4, 0x1e, 0x9b, 0xbd, 0x9d, 0x7b, 0x72, 0x14, 0x63, 0x12, 0x0a, 0xc9, 0x33,
0x5a, 0xdf, 0x4e, 0xe0, 0xf3, 0xa6, 0x2c, 0xbc, 0x92, 0xf2, 0x89, 0xd5, 0x45, 0xb5, 0x2c, 0xec, 0xad, 0x42, 0x0d, 0xab, 0xc2, 0xf8, 0xb6, 0x3c, 0x97, 0xed, 0xcb, 0xc2, 0x2a, 0x29, 0x9b, 0x18,
0x88, 0x8d, 0x9a, 0x79, 0xd0, 0x36, 0x32, 0x43, 0x7a, 0x35, 0x5e, 0xab, 0xef, 0x0c, 0xf7, 0xc3, 0x5d, 0x50, 0xcb, 0xfc, 0x56, 0xbc, 0x55, 0x3b, 0x94, 0x34, 0xb5, 0x48, 0x00, 0x5f, 0x35, 0x6d,
0x75, 0xc9, 0x9e, 0xe0, 0x50, 0x7c, 0x27, 0x8b, 0xa9, 0x8e, 0xe6, 0x6d, 0xdb, 0x40, 0xe7, 0xcd, 0xf4, 0xac, 0xc1, 0xa1, 0xbf, 0x29, 0x9d, 0x27, 0x72, 0x1c, 0x7f, 0x25, 0xe3, 0x58, 0x47, 0xa3,
0x83, 0xff, 0xb9, 0x47, 0xd8, 0x13, 0x7f, 0x9b, 0x83, 0x13, 0xe8, 0x6c, 0x6e, 0xc7, 0x76, 0x61, 0xbf, 0x4d, 0xa0, 0x8b, 0xfd, 0x83, 0x77, 0xdc, 0xc3, 0xef, 0xc4, 0x3b, 0x8e, 0x74, 0x4d, 0xba,
0xe7, 0x2a, 0x8a, 0x67, 0x51, 0x77, 0x8b, 0x01, 0xb8, 0xb7, 0xd1, 0x34, 0x9e, 0xcd, 0xbb, 0xce, 0x2f, 0x00, 0x29, 0x0f, 0xd7, 0x22, 0x07, 0x8e, 0x92, 0x2b, 0xc8, 0x52, 0x94, 0x19, 0xf0, 0x68,
0x68, 0x02, 0xc7, 0x29, 0x65, 0x8d, 0x13, 0xe7, 0xce, 0x63, 0xbb, 0x7e, 0x7e, 0xb4, 0xbc, 0xbb, 0x8d, 0x19, 0xd0, 0x3f, 0x3d, 0x6b, 0xf0, 0xcf, 0xa7, 0x25, 0x33, 0x2c, 0x91, 0xb9, 0xf4, 0x6b,
0x20, 0x4c, 0x4a, 0x3e, 0xfe, 0xa2, 0xe6, 0x96, 0xba, 0xae, 0xbe, 0x9e, 0x5d, 0x7b, 0xf0, 0xcb, 0x60, 0x5c, 0xf6, 0xfb, 0xa7, 0xa4, 0xb5, 0x9d, 0xce, 0xf9, 0x4f, 0xfe, 0x0e, 0x03, 0x3e, 0x0b,
0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x45, 0xb3, 0x84, 0x2e, 0x2a, 0x02, 0x00, 0x00, 0xda, 0xbf, 0x1c, 0x42, 0xec, 0xdb, 0x60, 0xca, 0x67, 0x8b, 0xb6, 0x35, 0x9a, 0x90, 0x6e, 0x84,
0xc9, 0xde, 0x8d, 0x17, 0xd6, 0x63, 0xb3, 0xfe, 0x7c, 0x6f, 0xd0, 0x3b, 0xcf, 0x0f, 0x0b, 0x36,
0x2e, 0xa9, 0x85, 0xa1, 0x6e, 0xaa, 0xd6, 0xb3, 0x6d, 0x1e, 0xec, 0xea, 0x33, 0x00, 0x00, 0xff,
0xff, 0x6b, 0x1d, 0xf6, 0x6e, 0x6a, 0x02, 0x00, 0x00,
} }

View File

@ -20,4 +20,5 @@ message Config {
DomainStrategy domain_strategy = 1; DomainStrategy domain_strategy = 1;
uint32 timeout = 2; uint32 timeout = 2;
DestinationOverride destination_override = 3; DestinationOverride destination_override = 3;
bool keep_alive_on_response_close = 4;
} }

View File

@ -26,6 +26,7 @@ type Handler struct {
timeout uint32 timeout uint32
dns dns.Server dns dns.Server
destOverride *DestinationOverride destOverride *DestinationOverride
keepAliveOnResponseClose bool
} }
func New(ctx context.Context, config *Config) (*Handler, error) { func New(ctx context.Context, config *Config) (*Handler, error) {
@ -37,6 +38,7 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
domainStrategy: config.DomainStrategy, domainStrategy: config.DomainStrategy,
timeout: config.Timeout, timeout: config.Timeout,
destOverride: config.DestinationOverride, destOverride: config.DestinationOverride,
keepAliveOnResponseClose: config.KeepAliveOnResponseClose,
} }
space.OnInitialize(func() error { space.OnInitialize(func() error {
if config.DomainStrategy == Config_USE_IP { if config.DomainStrategy == Config_USE_IP {
@ -50,12 +52,12 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
return f, nil return f, nil
} }
func (v *Handler) ResolveIP(destination net.Destination) net.Destination { func (h *Handler) ResolveIP(destination net.Destination) net.Destination {
if !destination.Address.Family().IsDomain() { if !destination.Address.Family().IsDomain() {
return destination return destination
} }
ips := v.dns.Get(destination.Address.Domain()) ips := h.dns.Get(destination.Address.Domain())
if len(ips) == 0 { if len(ips) == 0 {
log.Trace(newError("DNS returns nil answer. Keep domain as is.")) log.Trace(newError("DNS returns nil answer. Keep domain as is."))
return destination return destination
@ -71,10 +73,10 @@ func (v *Handler) ResolveIP(destination net.Destination) net.Destination {
return newDest return newDest
} }
func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dialer proxy.Dialer) error { func (h *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dialer proxy.Dialer) error {
destination, _ := proxy.TargetFromContext(ctx) destination, _ := proxy.TargetFromContext(ctx)
if v.destOverride != nil { if h.destOverride != nil {
server := v.destOverride.Server server := h.destOverride.Server
destination = net.Destination{ destination = net.Destination{
Network: destination.Network, Network: destination.Network,
Address: server.Address.AsAddress(), Address: server.Address.AsAddress(),
@ -87,8 +89,8 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
output := outboundRay.OutboundOutput() output := outboundRay.OutboundOutput()
var conn internet.Connection var conn internet.Connection
if v.domainStrategy == Config_USE_IP && destination.Address.Family().IsDomain() { if h.domainStrategy == Config_USE_IP && destination.Address.Family().IsDomain() {
destination = v.ResolveIP(destination) destination = h.ResolveIP(destination)
} }
err := retry.ExponentialBackoff(5, 100).On(func() error { err := retry.ExponentialBackoff(5, 100).On(func() error {
@ -104,7 +106,7 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
} }
defer conn.Close() defer conn.Close()
timeout := time.Second * time.Duration(v.timeout) timeout := time.Second * time.Duration(h.timeout)
if timeout == 0 { if timeout == 0 {
timeout = time.Minute * 5 timeout = time.Minute * 5
} }
@ -124,7 +126,13 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
}) })
responseDone := signal.ExecuteAsync(func() error { responseDone := signal.ExecuteAsync(func() error {
defer output.Close() defer func() {
if h.keepAliveOnResponseClose {
output.Close()
} else {
output.CloseError()
}
}()
v2reader := buf.NewReader(conn) v2reader := buf.NewReader(conn)
if err := buf.Copy(v2reader, output, buf.UpdateActivity(timer)); err != nil { if err := buf.Copy(v2reader, output, buf.UpdateActivity(timer)); err != nil {