From 671e06c459317ccbb97189290ad2bdaaad51e5d5 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Tue, 3 Oct 2023 10:18:44 +0800 Subject: [PATCH 01/81] Update Protobuf --- app/browserforwarder/config.pb.go | 24 +- app/commander/config.pb.go | 33 ++- app/dns/config.pb.go | 240 +++++++++--------- app/dns/fakedns/fakedns.pb.go | 35 ++- app/instman/command/command.pb.go | 66 ++--- app/instman/command/command_grpc.pb.go | 18 +- app/instman/config.pb.go | 20 +- app/log/command/config_grpc.pb.go | 11 +- app/log/config.pb.go | 30 +-- app/observatory/burst/config.pb.go | 48 ++-- app/observatory/command/command_grpc.pb.go | 8 +- app/observatory/config.pb.go | 25 +- app/observatory/multiobservatory/config.pb.go | 29 +-- app/policy/config.pb.go | 20 +- app/proxyman/command/command.pb.go | 108 ++++---- app/proxyman/command/command_grpc.pb.go | 33 ++- app/proxyman/config.pb.go | 4 +- app/restfulapi/config.pb.go | 20 +- app/reverse/config.pb.go | 22 +- app/router/command/command.pb.go | 88 +++---- app/router/command/command_grpc.pb.go | 21 +- app/router/config.pb.go | 209 ++++++++------- app/stats/command/command.pb.go | 67 +++-- app/stats/command/command_grpc.pb.go | 18 +- app/stats/config.pb.go | 33 ++- common/net/network.pb.go | 2 +- common/protoext/testing/test.pb.go | 29 +-- config.pb.go | 8 +- infra/vprotogen/main.go | 10 +- proxy/blackhole/config.pb.go | 22 +- proxy/dns/config.pb.go | 19 +- proxy/dokodemo/config.pb.go | 30 +-- proxy/freedom/config.pb.go | 25 +- proxy/loopback/config.pb.go | 22 +- proxy/shadowsocks/config.pb.go | 4 +- proxy/shadowsocks/simplified/config.pb.go | 6 - proxy/socks/config.pb.go | 4 +- proxy/socks/simplified/config.pb.go | 40 +-- proxy/trojan/config.pb.go | 6 - proxy/trojan/simplified/config.pb.go | 50 ++-- proxy/vless/inbound/config.pb.go | 24 +- proxy/vless/outbound/config.pb.go | 24 +- proxy/vlite/inbound/config.pb.go | 24 +- proxy/vlite/outbound/config.pb.go | 24 +- proxy/vmess/inbound/config.pb.go | 23 +- proxy/vmess/outbound/config.pb.go | 23 +- transport/config.pb.go | 2 +- transport/internet/config.pb.go | 8 +- transport/internet/grpc/config.pb.go | 26 +- .../internet/grpc/encoding/stream_grpc.pb.go | 6 +- transport/internet/kcp/config.pb.go | 27 +- transport/internet/quic/config.pb.go | 26 +- transport/internet/tcp/config.pb.go | 25 +- transport/internet/tls/config.pb.go | 24 +- transport/internet/tls/utls/config.pb.go | 36 +-- transport/internet/websocket/config.pb.go | 29 +-- 56 files changed, 932 insertions(+), 926 deletions(-) diff --git a/app/browserforwarder/config.pb.go b/app/browserforwarder/config.pb.go index 912ba0f5c4..f3b3ef6594 100644 --- a/app/browserforwarder/config.pb.go +++ b/app/browserforwarder/config.pb.go @@ -80,22 +80,22 @@ var file_app_browserforwarder_config_proto_rawDesc = []byte{ 0x61, 0x70, 0x70, 0x2e, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x66, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x62, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x50, 0x6f, - 0x72, 0x74, 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x82, 0xb5, 0x18, 0x09, 0x12, 0x07, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x42, 0x7e, - 0x0a, 0x23, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x77, - 0x61, 0x72, 0x64, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, - 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0xaa, 0x02, 0x1f, 0x56, - 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x42, 0x72, - 0x6f, 0x77, 0x73, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x74, 0x3a, 0x16, 0x82, 0xb5, 0x18, 0x12, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x07, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x42, 0x7e, 0x0a, 0x23, 0x63, 0x6f, + 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, + 0x72, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, + 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x66, + 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0xaa, 0x02, 0x1f, 0x56, 0x32, 0x52, 0x61, 0x79, + 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x42, 0x72, 0x6f, 0x77, 0x73, 0x65, + 0x72, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/app/commander/config.pb.go b/app/commander/config.pb.go index 221b42621d..bac9fa6bf2 100644 --- a/app/commander/config.pb.go +++ b/app/commander/config.pb.go @@ -184,23 +184,22 @@ var file_app_commander_config_proto_rawDesc = []byte{ 0x2e, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, - 0x35, 0x0a, 0x10, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x3a, 0x21, 0x82, 0xb5, 0x18, 0x0d, 0x0a, 0x0b, 0x67, 0x72, 0x70, 0x63, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, 0x0c, 0x12, 0x0a, 0x72, 0x65, 0x66, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x56, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, - 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, - 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x3a, 0x1c, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, - 0xb5, 0x18, 0x0b, 0x12, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x42, 0x69, - 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x01, - 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, - 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, - 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0xaa, 0x02, - 0x18, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x31, 0x0a, 0x10, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x3a, 0x1d, 0x82, 0xb5, 0x18, 0x19, 0x0a, 0x0b, 0x67, 0x72, 0x70, 0x63, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x0a, 0x72, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x52, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x18, 0x82, 0xb5, + 0x18, 0x14, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x09, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x42, 0x69, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0xaa, 0x02, 0x18, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, + 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, + 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/dns/config.pb.go b/app/dns/config.pb.go index a32c3cd542..beae966616 100644 --- a/app/dns/config.pb.go +++ b/app/dns/config.pb.go @@ -1,9 +1,3 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.12 -// source: app/dns/config.proto - package dns import ( @@ -234,7 +228,7 @@ type NameServer struct { FakeDns *fakedns.FakeDnsPoolMulti `protobuf:"bytes,11,opt,name=fake_dns,json=fakeDns,proto3" json:"fake_dns,omitempty"` // Deprecated. Use fallback_strategy. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/dns/config.proto. SkipFallback bool `protobuf:"varint,6,opt,name=skipFallback,proto3" json:"skipFallback,omitempty"` QueryStrategy *QueryStrategy `protobuf:"varint,8,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy,oneof" json:"query_strategy,omitempty"` CacheStrategy *CacheStrategy `protobuf:"varint,9,opt,name=cache_strategy,json=cacheStrategy,proto3,enum=v2ray.core.app.dns.CacheStrategy,oneof" json:"cache_strategy,omitempty"` @@ -322,7 +316,7 @@ func (x *NameServer) GetFakeDns() *fakedns.FakeDnsPoolMulti { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/dns/config.proto. func (x *NameServer) GetSkipFallback() bool { if x != nil { return x.SkipFallback @@ -433,14 +427,14 @@ type Config struct { // the moment. A special value 'localhost' as a domain address can be set to // use DNS on local system. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/dns/config.proto. NameServers []*net.Endpoint `protobuf:"bytes,1,rep,name=NameServers,proto3" json:"NameServers,omitempty"` // NameServer list used by this DNS client. NameServer []*NameServer `protobuf:"bytes,5,rep,name=name_server,json=nameServer,proto3" json:"name_server,omitempty"` // Static hosts. Domain to IP. // Deprecated. Use static_hosts. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/dns/config.proto. Hosts map[string]*net.IPOrDomain `protobuf:"bytes,2,rep,name=Hosts,proto3" json:"Hosts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes // (IPv6). @@ -456,15 +450,15 @@ type Config struct { // DisableCache disables DNS cache // Deprecated. Use cache_strategy. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/dns/config.proto. DisableCache bool `protobuf:"varint,8,opt,name=disableCache,proto3" json:"disableCache,omitempty"` // Deprecated. Use fallback_strategy. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/dns/config.proto. DisableFallback bool `protobuf:"varint,10,opt,name=disableFallback,proto3" json:"disableFallback,omitempty"` // Deprecated. Use fallback_strategy. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/dns/config.proto. DisableFallbackIfMatch bool `protobuf:"varint,11,opt,name=disableFallbackIfMatch,proto3" json:"disableFallbackIfMatch,omitempty"` // Default query strategy (IPv4, IPv6, or both) for each name server. QueryStrategy QueryStrategy `protobuf:"varint,9,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy" json:"query_strategy,omitempty"` @@ -506,7 +500,7 @@ func (*Config) Descriptor() ([]byte, []int) { return file_app_dns_config_proto_rawDescGZIP(), []int{2} } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/dns/config.proto. func (x *Config) GetNameServers() []*net.Endpoint { if x != nil { return x.NameServers @@ -521,7 +515,7 @@ func (x *Config) GetNameServer() []*NameServer { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/dns/config.proto. func (x *Config) GetHosts() map[string]*net.IPOrDomain { if x != nil { return x.Hosts @@ -564,7 +558,7 @@ func (x *Config) GetDomainMatcher() string { return "" } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/dns/config.proto. func (x *Config) GetDisableCache() bool { if x != nil { return x.DisableCache @@ -572,7 +566,7 @@ func (x *Config) GetDisableCache() bool { return false } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/dns/config.proto. func (x *Config) GetDisableFallback() bool { if x != nil { return x.DisableFallback @@ -580,7 +574,7 @@ func (x *Config) GetDisableFallback() bool { return false } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/dns/config.proto. func (x *Config) GetDisableFallbackIfMatch() bool { if x != nil { return x.DisableFallbackIfMatch @@ -630,15 +624,15 @@ type SimplifiedConfig struct { // DisableCache disables DNS cache // Deprecated. Use cache_strategy. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/dns/config.proto. DisableCache bool `protobuf:"varint,8,opt,name=disableCache,proto3" json:"disableCache,omitempty"` // Deprecated. Use fallback_strategy. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/dns/config.proto. DisableFallback bool `protobuf:"varint,10,opt,name=disableFallback,proto3" json:"disableFallback,omitempty"` // Deprecated. Use fallback_strategy. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/dns/config.proto. DisableFallbackIfMatch bool `protobuf:"varint,11,opt,name=disableFallbackIfMatch,proto3" json:"disableFallbackIfMatch,omitempty"` // Default query strategy (IPv4, IPv6, or both) for each name server. QueryStrategy QueryStrategy `protobuf:"varint,9,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy" json:"query_strategy,omitempty"` @@ -722,7 +716,7 @@ func (x *SimplifiedConfig) GetDomainMatcher() string { return "" } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/dns/config.proto. func (x *SimplifiedConfig) GetDisableCache() bool { if x != nil { return x.DisableCache @@ -730,7 +724,7 @@ func (x *SimplifiedConfig) GetDisableCache() bool { return false } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/dns/config.proto. func (x *SimplifiedConfig) GetDisableFallback() bool { if x != nil { return x.DisableFallback @@ -738,7 +732,7 @@ func (x *SimplifiedConfig) GetDisableFallback() bool { return false } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/dns/config.proto. func (x *SimplifiedConfig) GetDisableFallbackIfMatch() bool { if x != nil { return x.DisableFallbackIfMatch @@ -854,7 +848,7 @@ type SimplifiedNameServer struct { FakeDns *fakedns.FakeDnsPoolMulti `protobuf:"bytes,11,opt,name=fake_dns,json=fakeDns,proto3" json:"fake_dns,omitempty"` // Deprecated. Use fallback_strategy. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/dns/config.proto. SkipFallback bool `protobuf:"varint,6,opt,name=skipFallback,proto3" json:"skipFallback,omitempty"` QueryStrategy *QueryStrategy `protobuf:"varint,8,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy,oneof" json:"query_strategy,omitempty"` CacheStrategy *CacheStrategy `protobuf:"varint,9,opt,name=cache_strategy,json=cacheStrategy,proto3,enum=v2ray.core.app.dns.CacheStrategy,oneof" json:"cache_strategy,omitempty"` @@ -942,7 +936,7 @@ func (x *SimplifiedNameServer) GetFakeDns() *fakedns.FakeDnsPoolMulti { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/dns/config.proto. func (x *SimplifiedNameServer) GetSkipFallback() bool { if x != nil { return x.SkipFallback @@ -1332,7 +1326,7 @@ var file_app_dns_config_proto_rawDesc = []byte{ 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, - 0x08, 0x07, 0x10, 0x08, 0x22, 0xed, 0x05, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, + 0x08, 0x07, 0x10, 0x08, 0x22, 0xe9, 0x05, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x49, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, @@ -1376,102 +1370,102 @@ var file_app_dns_config_proto_rawDesc = []byte{ 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x10, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, - 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x3a, 0x16, 0x82, 0xb5, 0x18, 0x09, - 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, 0x05, 0x12, 0x03, 0x64, - 0x6e, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, - 0x08, 0x07, 0x10, 0x08, 0x22, 0xa2, 0x01, 0x0a, 0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, - 0x69, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x3a, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, - 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, - 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, - 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, - 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, - 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, - 0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0xc8, 0x07, 0x0a, 0x14, 0x53, 0x69, - 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, - 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, - 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, - 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x66, 0x0a, 0x12, - 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, - 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x53, 0x69, - 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x52, 0x11, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, - 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, - 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x5c, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, - 0x6c, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, - 0x6e, 0x73, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x4e, 0x61, 0x6d, - 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, - 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x12, 0x47, 0x0a, 0x08, 0x66, 0x61, 0x6b, 0x65, 0x5f, 0x64, 0x6e, 0x73, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x66, 0x61, 0x6b, 0x65, 0x64, - 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x52, 0x07, 0x66, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0c, - 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, - 0x62, 0x61, 0x63, 0x6b, 0x12, 0x4d, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, - 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, - 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, - 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, - 0x00, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, - 0x88, 0x01, 0x01, 0x12, 0x4d, 0x0a, 0x0e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x73, 0x74, 0x72, - 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, - 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x01, - 0x52, 0x0d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, - 0x01, 0x01, 0x12, 0x56, 0x0a, 0x11, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, - 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, - 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, - 0x65, 0x67, 0x79, 0x48, 0x02, 0x52, 0x10, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, - 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 0x1a, 0x64, 0x0a, 0x0e, 0x50, 0x72, - 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, - 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, - 0x1a, 0x36, 0x0a, 0x0c, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x72, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x42, 0x11, 0x0a, 0x0f, 0x5f, - 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x42, 0x14, - 0x0a, 0x12, 0x5f, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, 0x72, 0x61, - 0x74, 0x65, 0x67, 0x79, 0x2a, 0x45, 0x0a, 0x12, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, - 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x10, 0x02, - 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, 0x03, 0x2a, 0x35, 0x0a, 0x0d, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x0a, 0x0a, 0x06, - 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, - 0x49, 0x50, 0x34, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, - 0x10, 0x02, 0x2a, 0x34, 0x0a, 0x0d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, - 0x65, 0x67, 0x79, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x45, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x44, 0x69, - 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, 0x01, 0x2a, 0x45, 0x0a, 0x10, 0x46, 0x61, 0x6c, 0x6c, - 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x0b, 0x0a, 0x07, - 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x49, 0x66, 0x41, 0x6e, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x02, 0x42, - 0x57, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, - 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01, 0x5a, 0x26, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, - 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x12, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, - 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x3a, 0x12, 0x82, 0xb5, 0x18, 0x0e, + 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x03, 0x64, 0x6e, 0x73, 0x4a, 0x04, + 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, + 0x22, 0xa2, 0x01, 0x0a, 0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x48, + 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, + 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0xc8, 0x07, 0x0a, 0x14, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, + 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x66, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, + 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, + 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, + 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x11, 0x70, + 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, + 0x70, 0x12, 0x5c, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x75, + 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x53, + 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, + 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x47, 0x0a, 0x08, 0x66, 0x61, 0x6b, 0x65, 0x5f, 0x64, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, + 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x66, 0x61, 0x6b, 0x65, 0x64, 0x6e, 0x73, 0x2e, 0x46, + 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, + 0x07, 0x66, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, + 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, + 0x18, 0x01, 0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x12, 0x4d, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, + 0x67, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 0x12, + 0x4d, 0x0a, 0x0e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, + 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, + 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x61, 0x63, + 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x01, 0x52, 0x0d, 0x63, 0x61, + 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 0x12, 0x56, + 0x0a, 0x11, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x46, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, + 0x02, 0x52, 0x10, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 0x1a, 0x64, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, + 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x1a, 0x36, 0x0a, 0x0c, + 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, + 0x73, 0x69, 0x7a, 0x65, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x63, 0x61, 0x63, 0x68, + 0x65, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x66, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, + 0x2a, 0x45, 0x0a, 0x12, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, + 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, + 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x01, 0x12, + 0x0b, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, + 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, 0x03, 0x2a, 0x35, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, + 0x49, 0x50, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, + 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x02, 0x2a, 0x34, + 0x0a, 0x0d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, + 0x10, 0x0a, 0x0c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, + 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x10, 0x01, 0x2a, 0x45, 0x0a, 0x10, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x49, + 0x66, 0x41, 0x6e, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x02, 0x42, 0x57, 0x0a, 0x16, 0x63, + 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, + 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0xaa, + 0x02, 0x12, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, + 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/dns/fakedns/fakedns.pb.go b/app/dns/fakedns/fakedns.pb.go index 870a44fbdb..759743ba16 100644 --- a/app/dns/fakedns/fakedns.pb.go +++ b/app/dns/fakedns/fakedns.pb.go @@ -125,28 +125,27 @@ var file_app_dns_fakedns_fakedns_proto_rawDesc = []byte{ 0x1a, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x66, 0x61, 0x6b, 0x65, 0x64, 0x6e, 0x73, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, - 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5c, 0x0a, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x58, 0x0a, 0x0b, 0x46, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x6f, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x6c, 0x72, 0x75, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6c, 0x72, 0x75, 0x53, 0x69, 0x7a, 0x65, 0x3a, - 0x1a, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, - 0x18, 0x09, 0x12, 0x07, 0x66, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x22, 0x72, 0x0a, 0x10, 0x46, - 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x12, - 0x3d, 0x0a, 0x05, 0x70, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, - 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, - 0x64, 0x6e, 0x73, 0x2e, 0x66, 0x61, 0x6b, 0x65, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6b, 0x65, - 0x44, 0x6e, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x70, 0x6f, 0x6f, 0x6c, 0x73, 0x3a, 0x1f, - 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, - 0x0e, 0x12, 0x0c, 0x66, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x42, - 0x6f, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, - 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x66, 0x61, 0x6b, 0x65, 0x64, 0x6e, - 0x73, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, - 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0x2f, 0x66, 0x61, 0x6b, 0x65, - 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x1a, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, - 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6b, 0x65, 0x64, 0x6e, 0x73, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x16, 0x82, 0xb5, 0x18, 0x12, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x07, + 0x66, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x22, 0x6e, 0x0a, 0x10, 0x46, 0x61, 0x6b, 0x65, 0x44, + 0x6e, 0x73, 0x50, 0x6f, 0x6f, 0x6c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x12, 0x3d, 0x0a, 0x05, 0x70, + 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x76, 0x32, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, + 0x66, 0x61, 0x6b, 0x65, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x50, + 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x70, 0x6f, 0x6f, 0x6c, 0x73, 0x3a, 0x1b, 0x82, 0xb5, 0x18, 0x17, + 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x0c, 0x66, 0x61, 0x6b, 0x65, 0x44, + 0x6e, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x42, 0x6f, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, + 0x73, 0x2e, 0x66, 0x61, 0x6b, 0x65, 0x64, 0x6e, 0x73, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, + 0x64, 0x6e, 0x73, 0x2f, 0x66, 0x61, 0x6b, 0x65, 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x1a, 0x56, 0x32, + 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, + 0x2e, 0x46, 0x61, 0x6b, 0x65, 0x64, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/instman/command/command.pb.go b/app/instman/command/command.pb.go index 6c507470c6..ecdb7dfe06 100644 --- a/app/instman/command/command.pb.go +++ b/app/instman/command/command.pb.go @@ -349,41 +349,41 @@ var file_app_instman_command_command_proto_rawDesc = []byte{ 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x13, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x72, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x22, 0x28, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x1e, 0x82, 0xb5, - 0x18, 0x0d, 0x0a, 0x0b, 0x67, 0x72, 0x70, 0x63, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, - 0xb5, 0x18, 0x09, 0x12, 0x07, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x32, 0xf4, 0x02, 0x0a, - 0x19, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x71, 0x0a, 0x0c, 0x4c, 0x69, - 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x2f, 0x2e, 0x76, 0x32, 0x72, + 0x73, 0x70, 0x22, 0x24, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x1a, 0x82, 0xb5, + 0x18, 0x16, 0x0a, 0x0b, 0x67, 0x72, 0x70, 0x63, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x07, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x32, 0xf4, 0x02, 0x0a, 0x19, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x71, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x2f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x30, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, + 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x6e, 0x0a, 0x0b, 0x41, 0x64, 0x64, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x2e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, + 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x2f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, + 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x74, 0x0a, 0x0d, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x30, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x69, 0x6e, 0x73, 0x74, - 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x30, 0x2e, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x69, 0x6e, 0x73, - 0x74, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x6e, 0x0a, - 0x0b, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x2e, 0x2e, 0x76, + 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x31, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x69, 0x6e, - 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, - 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x2f, 0x2e, 0x76, - 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x69, 0x6e, - 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, - 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x74, 0x0a, - 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x30, - 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, - 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x1a, 0x31, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x42, 0x7f, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, - 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, - 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x50, 0x01, 0x5a, - 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, - 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, - 0x61, 0x70, 0x70, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0xaa, 0x02, 0x1e, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, - 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x42, + 0x7f, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, + 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, + 0x79, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x50, 0x01, 0x5a, 0x32, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, + 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xaa, + 0x02, 0x1e, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, + 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/instman/command/command_grpc.pb.go b/app/instman/command/command_grpc.pb.go index 5d6852f5b4..9574a28261 100644 --- a/app/instman/command/command_grpc.pb.go +++ b/app/instman/command/command_grpc.pb.go @@ -12,6 +12,12 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + InstanceManagementService_ListInstance_FullMethodName = "/v2ray.core.app.instman.command.InstanceManagementService/ListInstance" + InstanceManagementService_AddInstance_FullMethodName = "/v2ray.core.app.instman.command.InstanceManagementService/AddInstance" + InstanceManagementService_StartInstance_FullMethodName = "/v2ray.core.app.instman.command.InstanceManagementService/StartInstance" +) + // InstanceManagementServiceClient is the client API for InstanceManagementService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -31,7 +37,7 @@ func NewInstanceManagementServiceClient(cc grpc.ClientConnInterface) InstanceMan func (c *instanceManagementServiceClient) ListInstance(ctx context.Context, in *ListInstanceReq, opts ...grpc.CallOption) (*ListInstanceResp, error) { out := new(ListInstanceResp) - err := c.cc.Invoke(ctx, "/v2ray.core.app.instman.command.InstanceManagementService/ListInstance", in, out, opts...) + err := c.cc.Invoke(ctx, InstanceManagementService_ListInstance_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -40,7 +46,7 @@ func (c *instanceManagementServiceClient) ListInstance(ctx context.Context, in * func (c *instanceManagementServiceClient) AddInstance(ctx context.Context, in *AddInstanceReq, opts ...grpc.CallOption) (*AddInstanceResp, error) { out := new(AddInstanceResp) - err := c.cc.Invoke(ctx, "/v2ray.core.app.instman.command.InstanceManagementService/AddInstance", in, out, opts...) + err := c.cc.Invoke(ctx, InstanceManagementService_AddInstance_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -49,7 +55,7 @@ func (c *instanceManagementServiceClient) AddInstance(ctx context.Context, in *A func (c *instanceManagementServiceClient) StartInstance(ctx context.Context, in *StartInstanceReq, opts ...grpc.CallOption) (*StartInstanceResp, error) { out := new(StartInstanceResp) - err := c.cc.Invoke(ctx, "/v2ray.core.app.instman.command.InstanceManagementService/StartInstance", in, out, opts...) + err := c.cc.Invoke(ctx, InstanceManagementService_StartInstance_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -103,7 +109,7 @@ func _InstanceManagementService_ListInstance_Handler(srv interface{}, ctx contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.instman.command.InstanceManagementService/ListInstance", + FullMethod: InstanceManagementService_ListInstance_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(InstanceManagementServiceServer).ListInstance(ctx, req.(*ListInstanceReq)) @@ -121,7 +127,7 @@ func _InstanceManagementService_AddInstance_Handler(srv interface{}, ctx context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.instman.command.InstanceManagementService/AddInstance", + FullMethod: InstanceManagementService_AddInstance_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(InstanceManagementServiceServer).AddInstance(ctx, req.(*AddInstanceReq)) @@ -139,7 +145,7 @@ func _InstanceManagementService_StartInstance_Handler(srv interface{}, ctx conte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.instman.command.InstanceManagementService/StartInstance", + FullMethod: InstanceManagementService_StartInstance_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(InstanceManagementServiceServer).StartInstance(ctx, req.(*StartInstanceReq)) diff --git a/app/instman/config.pb.go b/app/instman/config.pb.go index 10451e44be..dccbc7a0dc 100644 --- a/app/instman/config.pb.go +++ b/app/instman/config.pb.go @@ -61,16 +61,16 @@ var file_app_instman_config_proto_rawDesc = []byte{ 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x24, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x1a, - 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, - 0x09, 0x12, 0x07, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x42, 0x63, 0x0a, 0x1a, 0x63, 0x6f, - 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x50, 0x01, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x69, - 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0xaa, 0x02, 0x16, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, - 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x20, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x16, + 0x82, 0xb5, 0x18, 0x12, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x07, 0x69, + 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x42, 0x63, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x69, 0x6e, 0x73, + 0x74, 0x6d, 0x61, 0x6e, 0x50, 0x01, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, + 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x6d, + 0x61, 0x6e, 0xaa, 0x02, 0x16, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, + 0x41, 0x70, 0x70, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/app/log/command/config_grpc.pb.go b/app/log/command/config_grpc.pb.go index 24a0fe6ed7..f1830f1acd 100644 --- a/app/log/command/config_grpc.pb.go +++ b/app/log/command/config_grpc.pb.go @@ -12,6 +12,11 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + LoggerService_RestartLogger_FullMethodName = "/v2ray.core.app.log.command.LoggerService/RestartLogger" + LoggerService_FollowLog_FullMethodName = "/v2ray.core.app.log.command.LoggerService/FollowLog" +) + // LoggerServiceClient is the client API for LoggerService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -31,7 +36,7 @@ func NewLoggerServiceClient(cc grpc.ClientConnInterface) LoggerServiceClient { func (c *loggerServiceClient) RestartLogger(ctx context.Context, in *RestartLoggerRequest, opts ...grpc.CallOption) (*RestartLoggerResponse, error) { out := new(RestartLoggerResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.log.command.LoggerService/RestartLogger", in, out, opts...) + err := c.cc.Invoke(ctx, LoggerService_RestartLogger_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -39,7 +44,7 @@ func (c *loggerServiceClient) RestartLogger(ctx context.Context, in *RestartLogg } func (c *loggerServiceClient) FollowLog(ctx context.Context, in *FollowLogRequest, opts ...grpc.CallOption) (LoggerService_FollowLogClient, error) { - stream, err := c.cc.NewStream(ctx, &LoggerService_ServiceDesc.Streams[0], "/v2ray.core.app.log.command.LoggerService/FollowLog", opts...) + stream, err := c.cc.NewStream(ctx, &LoggerService_ServiceDesc.Streams[0], LoggerService_FollowLog_FullMethodName, opts...) if err != nil { return nil, err } @@ -113,7 +118,7 @@ func _LoggerService_RestartLogger_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.log.command.LoggerService/RestartLogger", + FullMethod: LoggerService_RestartLogger_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(LoggerServiceServer).RestartLogger(ctx, req.(*RestartLoggerRequest)) diff --git a/app/log/config.pb.go b/app/log/config.pb.go index aac56a4f3f..aab3a40ddf 100644 --- a/app/log/config.pb.go +++ b/app/log/config.pb.go @@ -204,7 +204,7 @@ var file_app_log_config_proto_rawDesc = []byte{ 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x22, 0xb8, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3a, + 0x61, 0x74, 0x68, 0x22, 0xb4, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3a, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x4c, 0x6f, 0x67, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, @@ -212,20 +212,20 @@ var file_app_log_config_proto_rawDesc = []byte{ 0x63, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x4c, 0x6f, 0x67, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x16, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, 0x05, 0x12, 0x03, 0x6c, 0x6f, 0x67, - 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, - 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x2a, 0x35, - 0x0a, 0x07, 0x4c, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, - 0x65, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x10, 0x01, - 0x12, 0x08, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x10, 0x03, 0x42, 0x57, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x50, - 0x01, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, - 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, - 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x6c, 0x6f, 0x67, 0xaa, 0x02, 0x12, 0x56, 0x32, 0x52, 0x61, - 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4c, 0x6f, 0x67, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x12, 0x82, 0xb5, 0x18, 0x0e, 0x0a, 0x07, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x03, 0x6c, 0x6f, 0x67, 0x4a, 0x04, 0x08, 0x01, + 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, + 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x2a, 0x35, 0x0a, 0x07, 0x4c, 0x6f, + 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, + 0x0b, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, + 0x46, 0x69, 0x6c, 0x65, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x10, + 0x03, 0x42, 0x57, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x50, 0x01, 0x5a, 0x26, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, + 0x70, 0x2f, 0x6c, 0x6f, 0x67, 0xaa, 0x02, 0x12, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, + 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4c, 0x6f, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/app/observatory/burst/config.pb.go b/app/observatory/burst/config.pb.go index e6c988cdf1..9a751fa955 100644 --- a/app/observatory/burst/config.pb.go +++ b/app/observatory/burst/config.pb.go @@ -165,7 +165,7 @@ var file_app_observatory_burst_config_proto_rawDesc = []byte{ 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x62, 0x75, 0x72, 0x73, 0x74, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xad, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, + 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa9, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x53, @@ -174,29 +174,29 @@ var file_app_observatory_burst_config_proto_rawDesc = []byte{ 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x62, 0x75, 0x72, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x3a, 0x23, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x82, 0xb5, 0x18, 0x12, 0x12, 0x10, 0x62, 0x75, 0x72, 0x73, 0x74, 0x4f, 0x62, 0x73, - 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x22, 0xb4, 0x01, 0x0a, 0x10, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, - 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, - 0x24, 0x0a, 0x0d, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, - 0x81, 0x01, 0x0a, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, - 0x72, 0x79, 0x2e, 0x62, 0x75, 0x72, 0x73, 0x74, 0x50, 0x01, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x6f, - 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x62, 0x75, 0x72, 0x73, 0x74, - 0xaa, 0x02, 0x20, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, - 0x70, 0x2e, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x42, 0x75, - 0x72, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x66, 0x69, 0x67, 0x3a, 0x1f, 0x82, 0xb5, 0x18, 0x1b, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x10, 0x62, 0x75, 0x72, 0x73, 0x74, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, + 0x74, 0x6f, 0x72, 0x79, 0x22, 0xb4, 0x01, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, + 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, + 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x24, 0x0a, 0x0d, 0x73, + 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x0d, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x81, 0x01, 0x0a, 0x24, + 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, + 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x62, + 0x75, 0x72, 0x73, 0x74, 0x50, 0x01, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, + 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x62, 0x75, 0x72, 0x73, 0x74, 0xaa, 0x02, 0x20, 0x56, + 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4f, 0x62, + 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x42, 0x75, 0x72, 0x73, 0x74, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/observatory/command/command_grpc.pb.go b/app/observatory/command/command_grpc.pb.go index 58bd2b5dfc..d1262641cb 100644 --- a/app/observatory/command/command_grpc.pb.go +++ b/app/observatory/command/command_grpc.pb.go @@ -12,6 +12,10 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + ObservatoryService_GetOutboundStatus_FullMethodName = "/v2ray.core.app.observatory.command.ObservatoryService/GetOutboundStatus" +) + // ObservatoryServiceClient is the client API for ObservatoryService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -29,7 +33,7 @@ func NewObservatoryServiceClient(cc grpc.ClientConnInterface) ObservatoryService func (c *observatoryServiceClient) GetOutboundStatus(ctx context.Context, in *GetOutboundStatusRequest, opts ...grpc.CallOption) (*GetOutboundStatusResponse, error) { out := new(GetOutboundStatusResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.observatory.command.ObservatoryService/GetOutboundStatus", in, out, opts...) + err := c.cc.Invoke(ctx, ObservatoryService_GetOutboundStatus_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -74,7 +78,7 @@ func _ObservatoryService_GetOutboundStatus_Handler(srv interface{}, ctx context. } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.observatory.command.ObservatoryService/GetOutboundStatus", + FullMethod: ObservatoryService_GetOutboundStatus_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ObservatoryServiceServer).GetOutboundStatus(ctx, req.(*GetOutboundStatusRequest)) diff --git a/app/observatory/config.pb.go b/app/observatory/config.pb.go index f6b77557f1..97683b55c8 100644 --- a/app/observatory/config.pb.go +++ b/app/observatory/config.pb.go @@ -493,25 +493,24 @@ var file_app_observatory_config_proto_rawDesc = []byte{ 0x22, 0x32, 0x0a, 0x09, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x76, 0x61, 0x6c, 0x22, 0xa1, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x72, 0x76, 0x61, 0x6c, 0x22, 0x9d, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0d, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x3a, 0x28, - 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, - 0x17, 0x12, 0x15, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x4f, 0x62, 0x73, - 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x6f, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, - 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, - 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, - 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0xaa, 0x02, 0x1a, 0x56, - 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4f, 0x62, - 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x0d, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x3a, 0x24, + 0x82, 0xb5, 0x18, 0x20, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x15, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, + 0x74, 0x6f, 0x72, 0x79, 0x42, 0x6f, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x6f, 0x62, 0x73, + 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0xaa, 0x02, 0x1a, 0x56, 0x32, 0x52, 0x61, 0x79, + 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x61, 0x74, 0x6f, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/observatory/multiobservatory/config.pb.go b/app/observatory/multiobservatory/config.pb.go index 24ea731807..ded513f77b 100644 --- a/app/observatory/multiobservatory/config.pb.go +++ b/app/observatory/multiobservatory/config.pb.go @@ -76,25 +76,24 @@ var file_app_observatory_multiobservatory_config_proto_rawDesc = []byte{ 0x72, 0x65, 0x73, 0x2f, 0x73, 0x6b, 0x65, 0x6c, 0x65, 0x74, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x71, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6d, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x07, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x74, 0x61, 0x67, 0x67, 0x65, 0x64, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x68, 0x6f, 0x6c, 0x64, 0x65, - 0x72, 0x73, 0x3a, 0x23, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x82, 0xb5, 0x18, 0x12, 0x12, 0x10, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x6f, 0x62, 0x73, 0x65, - 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x42, 0xa2, 0x01, 0x0a, 0x2f, 0x63, 0x6f, 0x6d, 0x2e, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, - 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, - 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x01, 0x5a, 0x3f, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, - 0x70, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x6d, 0x75, - 0x6c, 0x74, 0x69, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0xaa, 0x02, - 0x2b, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, - 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x73, 0x3a, 0x1f, 0x82, 0xb5, 0x18, 0x1b, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x10, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x6f, 0x72, 0x79, 0x42, 0xa2, 0x01, 0x0a, 0x2f, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x4f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x01, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x6f, 0x62, + 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x6f, + 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0xaa, 0x02, 0x2b, 0x56, 0x32, 0x52, + 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x4f, 0x62, 0x73, + 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/policy/config.pb.go b/app/policy/config.pb.go index a9908fac81..f78c6779bb 100644 --- a/app/policy/config.pb.go +++ b/app/policy/config.pb.go @@ -548,7 +548,7 @@ var file_app_policy_config_proto_rawDesc = []byte{ 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, - 0x6e, 0x6b, 0x22, 0xf9, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3e, 0x0a, + 0x6e, 0x6b, 0x22, 0xf5, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3e, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4c, 0x65, 0x76, 0x65, @@ -562,15 +562,15 @@ var file_app_policy_config_proto_rawDesc = []byte{ 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x82, 0xb5, 0x18, 0x08, 0x12, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x60, - 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x01, 0x5a, 0x29, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, - 0x70, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xaa, 0x02, 0x15, 0x56, 0x32, 0x52, 0x61, 0x79, - 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x02, 0x38, 0x01, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x60, 0x0a, 0x19, 0x63, 0x6f, + 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0xaa, 0x02, 0x15, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, + 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/proxyman/command/command.pb.go b/app/proxyman/command/command.pb.go index a6b14681c1..4c7297ade4 100644 --- a/app/proxyman/command/command.pb.go +++ b/app/proxyman/command/command.pb.go @@ -733,67 +733,67 @@ var file_app_proxyman_command_command_proto_rawDesc = []byte{ 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x17, 0x0a, 0x15, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x0a, 0x06, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x1f, 0x82, 0xb5, 0x18, 0x0d, 0x0a, 0x0b, 0x67, 0x72, 0x70, 0x63, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, 0x0a, 0x12, 0x08, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x32, 0x90, 0x06, 0x0a, 0x0e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, - 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x49, - 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x32, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x0a, 0x06, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x1b, 0x82, 0xb5, 0x18, 0x17, 0x0a, 0x0b, 0x67, 0x72, 0x70, 0x63, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x08, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, + 0x6e, 0x32, 0x90, 0x06, 0x0a, 0x0e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x62, 0x6f, 0x75, + 0x6e, 0x64, 0x12, 0x32, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, + 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x62, 0x6f, - 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, - 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x80, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6e, 0x62, 0x6f, + 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x80, 0x01, + 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, + 0x35, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, + 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x7d, 0x0a, 0x0c, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, + 0x12, 0x34, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x6e, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x7a, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x33, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x2e, 0x41, 0x64, 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x83, 0x01, 0x0a, 0x0e, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x36, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4f, + 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x80, 0x01, 0x0a, 0x0d, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x35, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x6e, 0x62, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x7d, 0x0a, 0x0c, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x62, - 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x34, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, - 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x62, 0x6f, - 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, - 0x65, 0x72, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x12, 0x33, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, - 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x4f, 0x75, 0x74, - 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x83, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x12, 0x36, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4f, 0x75, 0x74, 0x62, 0x6f, - 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x80, 0x01, 0x0a, 0x0d, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x4f, - 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x35, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, - 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x4f, - 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, - 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x2e, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x7e, 0x0a, 0x23, 0x63, 0x6f, 0x6d, 0x2e, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, - 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, - 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, - 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2f, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xaa, 0x02, 0x1f, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, - 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, - 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x72, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x42, 0x7e, 0x0a, 0x23, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x6d, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x33, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, + 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0xaa, 0x02, 0x1f, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, + 0x41, 0x70, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/proxyman/command/command_grpc.pb.go b/app/proxyman/command/command_grpc.pb.go index 29b8146b9d..60cab05754 100644 --- a/app/proxyman/command/command_grpc.pb.go +++ b/app/proxyman/command/command_grpc.pb.go @@ -12,6 +12,15 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + HandlerService_AddInbound_FullMethodName = "/v2ray.core.app.proxyman.command.HandlerService/AddInbound" + HandlerService_RemoveInbound_FullMethodName = "/v2ray.core.app.proxyman.command.HandlerService/RemoveInbound" + HandlerService_AlterInbound_FullMethodName = "/v2ray.core.app.proxyman.command.HandlerService/AlterInbound" + HandlerService_AddOutbound_FullMethodName = "/v2ray.core.app.proxyman.command.HandlerService/AddOutbound" + HandlerService_RemoveOutbound_FullMethodName = "/v2ray.core.app.proxyman.command.HandlerService/RemoveOutbound" + HandlerService_AlterOutbound_FullMethodName = "/v2ray.core.app.proxyman.command.HandlerService/AlterOutbound" +) + // HandlerServiceClient is the client API for HandlerService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -34,7 +43,7 @@ func NewHandlerServiceClient(cc grpc.ClientConnInterface) HandlerServiceClient { func (c *handlerServiceClient) AddInbound(ctx context.Context, in *AddInboundRequest, opts ...grpc.CallOption) (*AddInboundResponse, error) { out := new(AddInboundResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.proxyman.command.HandlerService/AddInbound", in, out, opts...) + err := c.cc.Invoke(ctx, HandlerService_AddInbound_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -43,7 +52,7 @@ func (c *handlerServiceClient) AddInbound(ctx context.Context, in *AddInboundReq func (c *handlerServiceClient) RemoveInbound(ctx context.Context, in *RemoveInboundRequest, opts ...grpc.CallOption) (*RemoveInboundResponse, error) { out := new(RemoveInboundResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.proxyman.command.HandlerService/RemoveInbound", in, out, opts...) + err := c.cc.Invoke(ctx, HandlerService_RemoveInbound_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -52,7 +61,7 @@ func (c *handlerServiceClient) RemoveInbound(ctx context.Context, in *RemoveInbo func (c *handlerServiceClient) AlterInbound(ctx context.Context, in *AlterInboundRequest, opts ...grpc.CallOption) (*AlterInboundResponse, error) { out := new(AlterInboundResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.proxyman.command.HandlerService/AlterInbound", in, out, opts...) + err := c.cc.Invoke(ctx, HandlerService_AlterInbound_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -61,7 +70,7 @@ func (c *handlerServiceClient) AlterInbound(ctx context.Context, in *AlterInboun func (c *handlerServiceClient) AddOutbound(ctx context.Context, in *AddOutboundRequest, opts ...grpc.CallOption) (*AddOutboundResponse, error) { out := new(AddOutboundResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.proxyman.command.HandlerService/AddOutbound", in, out, opts...) + err := c.cc.Invoke(ctx, HandlerService_AddOutbound_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -70,7 +79,7 @@ func (c *handlerServiceClient) AddOutbound(ctx context.Context, in *AddOutboundR func (c *handlerServiceClient) RemoveOutbound(ctx context.Context, in *RemoveOutboundRequest, opts ...grpc.CallOption) (*RemoveOutboundResponse, error) { out := new(RemoveOutboundResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.proxyman.command.HandlerService/RemoveOutbound", in, out, opts...) + err := c.cc.Invoke(ctx, HandlerService_RemoveOutbound_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -79,7 +88,7 @@ func (c *handlerServiceClient) RemoveOutbound(ctx context.Context, in *RemoveOut func (c *handlerServiceClient) AlterOutbound(ctx context.Context, in *AlterOutboundRequest, opts ...grpc.CallOption) (*AlterOutboundResponse, error) { out := new(AlterOutboundResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.proxyman.command.HandlerService/AlterOutbound", in, out, opts...) + err := c.cc.Invoke(ctx, HandlerService_AlterOutbound_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -144,7 +153,7 @@ func _HandlerService_AddInbound_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.proxyman.command.HandlerService/AddInbound", + FullMethod: HandlerService_AddInbound_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(HandlerServiceServer).AddInbound(ctx, req.(*AddInboundRequest)) @@ -162,7 +171,7 @@ func _HandlerService_RemoveInbound_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.proxyman.command.HandlerService/RemoveInbound", + FullMethod: HandlerService_RemoveInbound_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(HandlerServiceServer).RemoveInbound(ctx, req.(*RemoveInboundRequest)) @@ -180,7 +189,7 @@ func _HandlerService_AlterInbound_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.proxyman.command.HandlerService/AlterInbound", + FullMethod: HandlerService_AlterInbound_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(HandlerServiceServer).AlterInbound(ctx, req.(*AlterInboundRequest)) @@ -198,7 +207,7 @@ func _HandlerService_AddOutbound_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.proxyman.command.HandlerService/AddOutbound", + FullMethod: HandlerService_AddOutbound_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(HandlerServiceServer).AddOutbound(ctx, req.(*AddOutboundRequest)) @@ -216,7 +225,7 @@ func _HandlerService_RemoveOutbound_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.proxyman.command.HandlerService/RemoveOutbound", + FullMethod: HandlerService_RemoveOutbound_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(HandlerServiceServer).RemoveOutbound(ctx, req.(*RemoveOutboundRequest)) @@ -234,7 +243,7 @@ func _HandlerService_AlterOutbound_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.proxyman.command.HandlerService/AlterOutbound", + FullMethod: HandlerService_AlterOutbound_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(HandlerServiceServer).AlterOutbound(ctx, req.(*AlterOutboundRequest)) diff --git a/app/proxyman/config.pb.go b/app/proxyman/config.pb.go index 0002af4198..e3da02c595 100644 --- a/app/proxyman/config.pb.go +++ b/app/proxyman/config.pb.go @@ -355,7 +355,7 @@ type ReceiverConfig struct { // Override domains for the given protocol. // Deprecated. Use sniffing_settings. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/proxyman/config.proto. DomainOverride []KnownProtocols `protobuf:"varint,7,rep,packed,name=domain_override,json=domainOverride,proto3,enum=v2ray.core.app.proxyman.KnownProtocols" json:"domain_override,omitempty"` SniffingSettings *SniffingConfig `protobuf:"bytes,8,opt,name=sniffing_settings,json=sniffingSettings,proto3" json:"sniffing_settings,omitempty"` } @@ -427,7 +427,7 @@ func (x *ReceiverConfig) GetReceiveOriginalDestination() bool { return false } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/proxyman/config.proto. func (x *ReceiverConfig) GetDomainOverride() []KnownProtocols { if x != nil { return x.DomainOverride diff --git a/app/restfulapi/config.pb.go b/app/restfulapi/config.pb.go index 63ea2eeff4..e7a29987c4 100644 --- a/app/restfulapi/config.pb.go +++ b/app/restfulapi/config.pb.go @@ -86,22 +86,22 @@ var file_app_restfulapi_config_proto_rawDesc = []byte{ 0x32, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x66, 0x75, 0x6c, 0x61, 0x70, 0x69, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x84, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x3a, 0x1d, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x82, 0xb5, 0x18, 0x0c, 0x12, 0x0a, 0x72, 0x65, 0x73, 0x74, 0x66, 0x75, 0x6c, 0x61, 0x70, 0x69, - 0x42, 0x61, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x70, 0x69, 0x50, 0x01, - 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, - 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, - 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x66, 0x75, 0x6c, 0x61, 0x70, 0x69, 0xaa, - 0x02, 0x11, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x65, 0x73, 0x74, - 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x15, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x0a, 0x72, 0x65, 0x73, 0x74, 0x66, 0x75, 0x6c, 0x61, 0x70, 0x69, 0x42, 0x61, 0x0a, 0x1a, + 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, + 0x70, 0x70, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x70, 0x69, 0x50, 0x01, 0x5a, 0x2d, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, + 0x2f, 0x72, 0x65, 0x73, 0x74, 0x66, 0x75, 0x6c, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x11, 0x56, 0x32, + 0x52, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x70, 0x69, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/reverse/config.pb.go b/app/reverse/config.pb.go index 386aee5607..7631762255 100644 --- a/app/reverse/config.pb.go +++ b/app/reverse/config.pb.go @@ -304,7 +304,7 @@ var file_app_reverse_config_proto_rawDesc = []byte{ 0x0a, 0x0c, 0x50, 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0xba, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, + 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0xb6, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x49, 0x0a, 0x0d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x65, 0x76, 0x65, @@ -314,16 +314,16 @@ var file_app_reverse_config_proto_rawDesc = []byte{ 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x70, 0x6f, 0x72, - 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x09, 0x0a, - 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, 0x09, 0x12, 0x07, 0x72, 0x65, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x42, 0x67, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x72, 0x65, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x50, 0x01, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, - 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x65, 0x76, 0x65, - 0x72, 0x73, 0x65, 0xaa, 0x02, 0x18, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, - 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x16, 0x82, 0xb5, 0x18, 0x12, 0x0a, + 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x07, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x42, 0x67, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x50, 0x01, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, + 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0xaa, + 0x02, 0x18, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, + 0x78, 0x79, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/app/router/command/command.pb.go b/app/router/command/command.pb.go index 88d671a879..b0db9c2d28 100644 --- a/app/router/command/command.pb.go +++ b/app/router/command/command.pb.go @@ -758,52 +758,52 @@ var file_app_router_command_command_proto_rawDesc = []byte{ 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x20, 0x0a, 0x1e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x27, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x1d, 0x82, 0xb5, 0x18, 0x0d, 0x0a, - 0x0b, 0x67, 0x72, 0x70, 0x63, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, 0x08, - 0x12, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x32, 0xa8, 0x04, 0x0a, 0x0e, 0x52, 0x6f, 0x75, - 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x15, - 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x3b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x6d, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, - 0x74, 0x65, 0x12, 0x2f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x22, 0x00, 0x12, 0x82, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x35, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, - 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x36, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, + 0x23, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x15, 0x0a, + 0x0b, 0x67, 0x72, 0x70, 0x63, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x06, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x32, 0xa8, 0x04, 0x0a, 0x0e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, + 0x73, 0x12, 0x3b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, + 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x00, 0x30, + 0x01, 0x12, 0x6d, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x2f, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x54, + 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, - 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x97, 0x01, 0x0a, 0x16, 0x4f, 0x76, - 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x12, 0x3c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, + 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x00, + 0x12, 0x82, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x35, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, + 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x97, 0x01, 0x0a, 0x16, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x64, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x12, 0x3c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, + 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4f, + 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, + 0x78, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x42, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x42, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x42, 0x78, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, - 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xaa, 0x02, 0x1d, - 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, + 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xaa, 0x02, 0x1d, 0x56, 0x32, 0x52, 0x61, + 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( diff --git a/app/router/command/command_grpc.pb.go b/app/router/command/command_grpc.pb.go index bd359fbed4..cae34f05f4 100644 --- a/app/router/command/command_grpc.pb.go +++ b/app/router/command/command_grpc.pb.go @@ -12,6 +12,13 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + RoutingService_SubscribeRoutingStats_FullMethodName = "/v2ray.core.app.router.command.RoutingService/SubscribeRoutingStats" + RoutingService_TestRoute_FullMethodName = "/v2ray.core.app.router.command.RoutingService/TestRoute" + RoutingService_GetBalancerInfo_FullMethodName = "/v2ray.core.app.router.command.RoutingService/GetBalancerInfo" + RoutingService_OverrideBalancerTarget_FullMethodName = "/v2ray.core.app.router.command.RoutingService/OverrideBalancerTarget" +) + // RoutingServiceClient is the client API for RoutingService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -31,7 +38,7 @@ func NewRoutingServiceClient(cc grpc.ClientConnInterface) RoutingServiceClient { } func (c *routingServiceClient) SubscribeRoutingStats(ctx context.Context, in *SubscribeRoutingStatsRequest, opts ...grpc.CallOption) (RoutingService_SubscribeRoutingStatsClient, error) { - stream, err := c.cc.NewStream(ctx, &RoutingService_ServiceDesc.Streams[0], "/v2ray.core.app.router.command.RoutingService/SubscribeRoutingStats", opts...) + stream, err := c.cc.NewStream(ctx, &RoutingService_ServiceDesc.Streams[0], RoutingService_SubscribeRoutingStats_FullMethodName, opts...) if err != nil { return nil, err } @@ -64,7 +71,7 @@ func (x *routingServiceSubscribeRoutingStatsClient) Recv() (*RoutingContext, err func (c *routingServiceClient) TestRoute(ctx context.Context, in *TestRouteRequest, opts ...grpc.CallOption) (*RoutingContext, error) { out := new(RoutingContext) - err := c.cc.Invoke(ctx, "/v2ray.core.app.router.command.RoutingService/TestRoute", in, out, opts...) + err := c.cc.Invoke(ctx, RoutingService_TestRoute_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -73,7 +80,7 @@ func (c *routingServiceClient) TestRoute(ctx context.Context, in *TestRouteReque func (c *routingServiceClient) GetBalancerInfo(ctx context.Context, in *GetBalancerInfoRequest, opts ...grpc.CallOption) (*GetBalancerInfoResponse, error) { out := new(GetBalancerInfoResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.router.command.RoutingService/GetBalancerInfo", in, out, opts...) + err := c.cc.Invoke(ctx, RoutingService_GetBalancerInfo_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -82,7 +89,7 @@ func (c *routingServiceClient) GetBalancerInfo(ctx context.Context, in *GetBalan func (c *routingServiceClient) OverrideBalancerTarget(ctx context.Context, in *OverrideBalancerTargetRequest, opts ...grpc.CallOption) (*OverrideBalancerTargetResponse, error) { out := new(OverrideBalancerTargetResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.router.command.RoutingService/OverrideBalancerTarget", in, out, opts...) + err := c.cc.Invoke(ctx, RoutingService_OverrideBalancerTarget_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -160,7 +167,7 @@ func _RoutingService_TestRoute_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.router.command.RoutingService/TestRoute", + FullMethod: RoutingService_TestRoute_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(RoutingServiceServer).TestRoute(ctx, req.(*TestRouteRequest)) @@ -178,7 +185,7 @@ func _RoutingService_GetBalancerInfo_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.router.command.RoutingService/GetBalancerInfo", + FullMethod: RoutingService_GetBalancerInfo_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(RoutingServiceServer).GetBalancerInfo(ctx, req.(*GetBalancerInfoRequest)) @@ -196,7 +203,7 @@ func _RoutingService_OverrideBalancerTarget_Handler(srv interface{}, ctx context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.router.command.RoutingService/OverrideBalancerTarget", + FullMethod: RoutingService_OverrideBalancerTarget_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(RoutingServiceServer).OverrideBalancerTarget(ctx, req.(*OverrideBalancerTargetRequest)) diff --git a/app/router/config.pb.go b/app/router/config.pb.go index c1b383bfef..7d077d468c 100644 --- a/app/router/config.pb.go +++ b/app/router/config.pb.go @@ -89,7 +89,7 @@ type RoutingRule struct { // List of CIDRs for target IP address matching. // Deprecated. Use geoip below. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/router/config.proto. Cidr []*routercommon.CIDR `protobuf:"bytes,3,rep,name=cidr,proto3" json:"cidr,omitempty"` // List of GeoIPs for target IP address matching. If this entry exists, the // cidr above will have no effect. GeoIP fields with the same country code are @@ -99,19 +99,19 @@ type RoutingRule struct { // A range of port [from, to]. If the destination port is in this range, this // rule takes effect. Deprecated. Use port_list. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/router/config.proto. PortRange *net.PortRange `protobuf:"bytes,4,opt,name=port_range,json=portRange,proto3" json:"port_range,omitempty"` // List of ports. PortList *net.PortList `protobuf:"bytes,14,opt,name=port_list,json=portList,proto3" json:"port_list,omitempty"` // List of networks. Deprecated. Use networks. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/router/config.proto. NetworkList *net.NetworkList `protobuf:"bytes,5,opt,name=network_list,json=networkList,proto3" json:"network_list,omitempty"` // List of networks for matching. Networks []net.Network `protobuf:"varint,13,rep,packed,name=networks,proto3,enum=v2ray.core.common.net.Network" json:"networks,omitempty"` // List of CIDRs for source IP address matching. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/router/config.proto. SourceCidr []*routercommon.CIDR `protobuf:"bytes,6,rep,name=source_cidr,json=sourceCidr,proto3" json:"source_cidr,omitempty"` // List of GeoIPs for source IP address matching. If this entry exists, the // source_cidr above will have no effect. @@ -187,7 +187,7 @@ func (x *RoutingRule) GetDomain() []*routercommon.Domain { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/router/config.proto. func (x *RoutingRule) GetCidr() []*routercommon.CIDR { if x != nil { return x.Cidr @@ -202,7 +202,7 @@ func (x *RoutingRule) GetGeoip() []*routercommon.GeoIP { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/router/config.proto. func (x *RoutingRule) GetPortRange() *net.PortRange { if x != nil { return x.PortRange @@ -217,7 +217,7 @@ func (x *RoutingRule) GetPortList() *net.PortList { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/router/config.proto. func (x *RoutingRule) GetNetworkList() *net.NetworkList { if x != nil { return x.NetworkList @@ -232,7 +232,7 @@ func (x *RoutingRule) GetNetworks() []net.Network { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/router/config.proto. func (x *RoutingRule) GetSourceCidr() []*routercommon.CIDR { if x != nil { return x.SourceCidr @@ -1047,106 +1047,105 @@ var file_app_router_config_proto_rawDesc = []byte{ 0x67, 0x65, 0x78, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0x32, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x61, 0x6e, 0x64, - 0x6f, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x82, 0xb5, 0x18, 0x08, 0x12, 0x06, 0x72, 0x61, - 0x6e, 0x64, 0x6f, 0x6d, 0x22, 0x5b, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, - 0x4c, 0x65, 0x61, 0x73, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x21, 0x0a, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, - 0x61, 0x67, 0x3a, 0x1d, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x65, 0x72, 0x82, 0xb5, 0x18, 0x0b, 0x12, 0x09, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x70, 0x69, 0x6e, - 0x67, 0x22, 0x88, 0x02, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x4c, 0x65, - 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, - 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, - 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x57, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x52, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x61, - 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x09, 0x62, - 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x70, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, 0x70, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x12, 0x1c, 0x0a, 0x09, - 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, - 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x62, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x61, 0x67, 0x3a, 0x1d, 0x82, - 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x82, 0xb5, 0x18, - 0x0b, 0x12, 0x09, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xdd, 0x01, 0x0a, - 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, - 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, - 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x36, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, - 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, - 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, - 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, - 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22, 0xab, 0x05, 0x0a, - 0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, - 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x25, 0x0a, 0x0d, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x54, 0x61, - 0x67, 0x12, 0x42, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, - 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x64, - 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0a, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, - 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, - 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, - 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x72, 0x74, 0x4c, - 0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x18, - 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x12, 0x4c, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x67, 0x65, - 0x6f, 0x69, 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x22, 0x2e, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x61, 0x6e, 0x64, + 0x6f, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x16, 0x82, 0xb5, 0x18, 0x12, 0x0a, 0x08, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, + 0x22, 0x57, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x4c, 0x65, 0x61, 0x73, + 0x74, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x6f, + 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x61, 0x67, 0x3a, 0x19, + 0x82, 0xb5, 0x18, 0x15, 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x09, + 0x6c, 0x65, 0x61, 0x73, 0x74, 0x70, 0x69, 0x6e, 0x67, 0x22, 0x84, 0x02, 0x0a, 0x17, 0x53, 0x74, + 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, + 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, + 0x61, 0x74, 0x65, 0x67, 0x79, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x05, 0x63, 0x6f, 0x73, + 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, + 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, + 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x61, + 0x78, 0x52, 0x54, 0x54, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, + 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, + 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x54, 0x61, 0x67, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x15, 0x0a, 0x08, 0x62, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x09, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x6c, 0x6f, 0x61, 0x64, + 0x22, 0xdd, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, 0x0f, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, + 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x36, 0x0a, 0x04, 0x72, + 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, - 0x65, 0x6f, 0x49, 0x50, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x65, 0x6f, 0x69, - 0x70, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, - 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, - 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0a, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x4c, - 0x0a, 0x0a, 0x67, 0x65, 0x6f, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0xa1, 0x93, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, - 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, - 0x65, 0x52, 0x09, 0x67, 0x65, 0x6f, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x8c, 0x02, 0x0a, 0x10, 0x53, - 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, - 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, + 0x75, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, + 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x22, 0xab, 0x05, 0x0a, 0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x74, 0x61, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x25, + 0x0a, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, + 0x6e, 0x67, 0x54, 0x61, 0x67, 0x12, 0x42, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, + 0x69, 0x70, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, - 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, - 0x40, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, + 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, + 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, + 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, + 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, + 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x08, 0x6e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x4c, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, - 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, - 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, - 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, - 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x3a, 0x19, - 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, - 0x08, 0x12, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2a, 0x47, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x47, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, + 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1f, + 0x0a, 0x0b, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, + 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x11, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x72, 0x12, 0x4c, 0x0a, 0x0a, 0x67, 0x65, 0x6f, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x18, 0xa1, 0x93, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, + 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, + 0x6f, 0x53, 0x69, 0x74, 0x65, 0x52, 0x09, 0x67, 0x65, 0x6f, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x88, + 0x02, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, + 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x12, 0x40, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, + 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, + 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2a, 0x47, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x49, 0x70, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66, 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, diff --git a/app/stats/command/command.pb.go b/app/stats/command/command.pb.go index 7deb254ca0..73903d35b9 100644 --- a/app/stats/command/command.pb.go +++ b/app/stats/command/command.pb.go @@ -540,40 +540,39 @@ var file_app_stats_command_command_proto_rawDesc = []byte{ 0x22, 0x0a, 0x0c, 0x50, 0x61, 0x75, 0x73, 0x65, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x4e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x50, 0x61, 0x75, 0x73, 0x65, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x4e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x06, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x26, 0x0a, 0x06, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x1c, 0x82, 0xb5, 0x18, 0x0d, 0x0a, 0x0b, 0x67, 0x72, 0x70, - 0x63, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, 0x07, 0x12, 0x05, 0x73, 0x74, - 0x61, 0x74, 0x73, 0x32, 0xde, 0x02, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x6b, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x12, 0x2d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, - 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, - 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x71, 0x0a, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, - 0x2f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x30, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x6e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x12, 0x2d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x2e, 0x53, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x2e, 0x53, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x42, 0x75, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, - 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x73, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x73, - 0x74, 0x61, 0x74, 0x73, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xaa, 0x02, 0x1c, 0x56, - 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x01, 0x28, 0x0d, 0x52, 0x06, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x22, 0x0a, 0x06, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x18, 0x82, 0xb5, 0x18, 0x14, 0x0a, 0x0b, 0x67, 0x72, 0x70, + 0x63, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x32, + 0xde, 0x02, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x6b, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2d, 0x2e, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x71, 0x0a, + 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2f, 0x2e, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x6e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, + 0x2d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, + 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x79, + 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x42, 0x75, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, + 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xaa, 0x02, 0x1c, 0x56, 0x32, 0x52, 0x61, 0x79, + 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/stats/command/command_grpc.pb.go b/app/stats/command/command_grpc.pb.go index a0fb52a275..3a301c2ae4 100644 --- a/app/stats/command/command_grpc.pb.go +++ b/app/stats/command/command_grpc.pb.go @@ -12,6 +12,12 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + StatsService_GetStats_FullMethodName = "/v2ray.core.app.stats.command.StatsService/GetStats" + StatsService_QueryStats_FullMethodName = "/v2ray.core.app.stats.command.StatsService/QueryStats" + StatsService_GetSysStats_FullMethodName = "/v2ray.core.app.stats.command.StatsService/GetSysStats" +) + // StatsServiceClient is the client API for StatsService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -31,7 +37,7 @@ func NewStatsServiceClient(cc grpc.ClientConnInterface) StatsServiceClient { func (c *statsServiceClient) GetStats(ctx context.Context, in *GetStatsRequest, opts ...grpc.CallOption) (*GetStatsResponse, error) { out := new(GetStatsResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.stats.command.StatsService/GetStats", in, out, opts...) + err := c.cc.Invoke(ctx, StatsService_GetStats_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -40,7 +46,7 @@ func (c *statsServiceClient) GetStats(ctx context.Context, in *GetStatsRequest, func (c *statsServiceClient) QueryStats(ctx context.Context, in *QueryStatsRequest, opts ...grpc.CallOption) (*QueryStatsResponse, error) { out := new(QueryStatsResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.stats.command.StatsService/QueryStats", in, out, opts...) + err := c.cc.Invoke(ctx, StatsService_QueryStats_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -49,7 +55,7 @@ func (c *statsServiceClient) QueryStats(ctx context.Context, in *QueryStatsReque func (c *statsServiceClient) GetSysStats(ctx context.Context, in *SysStatsRequest, opts ...grpc.CallOption) (*SysStatsResponse, error) { out := new(SysStatsResponse) - err := c.cc.Invoke(ctx, "/v2ray.core.app.stats.command.StatsService/GetSysStats", in, out, opts...) + err := c.cc.Invoke(ctx, StatsService_GetSysStats_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -102,7 +108,7 @@ func _StatsService_GetStats_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.stats.command.StatsService/GetStats", + FullMethod: StatsService_GetStats_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(StatsServiceServer).GetStats(ctx, req.(*GetStatsRequest)) @@ -120,7 +126,7 @@ func _StatsService_QueryStats_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.stats.command.StatsService/QueryStats", + FullMethod: StatsService_QueryStats_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(StatsServiceServer).QueryStats(ctx, req.(*QueryStatsRequest)) @@ -138,7 +144,7 @@ func _StatsService_GetSysStats_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2ray.core.app.stats.command.StatsService/GetSysStats", + FullMethod: StatsService_GetSysStats_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(StatsServiceServer).GetSysStats(ctx, req.(*SysStatsRequest)) diff --git a/app/stats/config.pb.go b/app/stats/config.pb.go index e9eb82b922..d5ce1d97b0 100644 --- a/app/stats/config.pb.go +++ b/app/stats/config.pb.go @@ -124,23 +124,22 @@ var file_app_stats_config_proto_rawDesc = []byte{ 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x22, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x18, 0x82, 0xb5, 0x18, 0x09, - 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, 0x07, 0x12, 0x05, 0x73, - 0x74, 0x61, 0x74, 0x73, 0x22, 0x75, 0x0a, 0x0d, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, - 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, - 0x67, 0x12, 0x28, 0x0a, 0x0f, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4c, - 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x53, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x42, - 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x0a, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x5d, 0x0a, 0x18, 0x63, - 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x50, 0x01, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, - 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x73, 0xaa, 0x02, 0x14, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, - 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x22, 0x1e, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x14, 0x82, 0xb5, 0x18, 0x10, + 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x22, 0x75, 0x0a, 0x0d, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, + 0x0f, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4c, 0x69, 0x6d, 0x69, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, + 0x65, 0x72, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x42, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x42, 0x75, 0x66, + 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x5d, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x50, 0x01, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, + 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0xaa, + 0x02, 0x14, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/common/net/network.pb.go b/common/net/network.pb.go index 25771cdb2c..508586333c 100644 --- a/common/net/network.pb.go +++ b/common/net/network.pb.go @@ -18,7 +18,7 @@ type Network int32 const ( Network_Unknown Network = 0 - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in common/net/network.proto. Network_RawTCP Network = 1 Network_TCP Network = 2 Network_UDP Network = 3 diff --git a/common/protoext/testing/test.pb.go b/common/protoext/testing/test.pb.go index 84f5772541..52fdc5c8a9 100644 --- a/common/protoext/testing/test.pb.go +++ b/common/protoext/testing/test.pb.go @@ -71,22 +71,21 @@ var file_common_protoext_testing_test_proto_rawDesc = []byte{ 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, 0x0a, 0x0e, 0x54, 0x65, - 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x34, 0x0a, 0x0a, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x55, 0x0a, 0x0e, 0x54, 0x65, + 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x15, 0x82, 0xb5, 0x18, 0x06, 0x12, 0x04, 0x74, 0x65, 0x73, 0x74, 0x82, 0xb5, 0x18, 0x07, - 0x12, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x52, 0x09, 0x74, 0x65, 0x73, 0x74, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x06, 0x0a, 0x04, 0x64, 0x65, 0x6d, 0x6f, 0x82, 0xb5, - 0x18, 0x07, 0x0a, 0x05, 0x64, 0x65, 0x6d, 0x6f, 0x32, 0x42, 0x84, 0x01, 0x0a, 0x26, 0x63, 0x6f, - 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2e, 0x74, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, - 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x22, 0x56, 0x32, - 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x45, 0x78, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x42, 0x11, 0x82, 0xb5, 0x18, 0x0d, 0x12, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x05, 0x74, 0x65, + 0x73, 0x74, 0x32, 0x52, 0x09, 0x74, 0x65, 0x73, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x3a, 0x11, + 0x82, 0xb5, 0x18, 0x0d, 0x0a, 0x04, 0x64, 0x65, 0x6d, 0x6f, 0x0a, 0x05, 0x64, 0x65, 0x6d, 0x6f, + 0x32, 0x42, 0x84, 0x01, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, + 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x65, 0x78, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x01, 0x5a, 0x33, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, + 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0xaa, 0x02, 0x22, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, + 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x45, 0x78, 0x74, + 0x2e, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/config.pb.go b/config.pb.go index d01562863d..1a1cfefcb3 100644 --- a/config.pb.go +++ b/config.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.17.3 +// protoc-gen-go v1.31.0 +// protoc v4.24.3 // source: config.proto package core @@ -42,7 +42,7 @@ type Config struct { // Deprecated. Each inbound and outbound should choose their own transport // config. Date to remove: 2020-01-13 // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in config.proto. Transport *transport.Config `protobuf:"bytes,5,opt,name=transport,proto3" json:"transport,omitempty"` // Configuration for extensions. The config may not work if corresponding // extension is not loaded into V2Ray. V2Ray will ignore such config during @@ -103,7 +103,7 @@ func (x *Config) GetApp() []*anypb.Any { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in config.proto. func (x *Config) GetTransport() *transport.Config { if x != nil { return x.Transport diff --git a/infra/vprotogen/main.go b/infra/vprotogen/main.go index 2551808ca6..fa5fa8170b 100644 --- a/infra/vprotogen/main.go +++ b/infra/vprotogen/main.go @@ -120,9 +120,10 @@ func getInstalledProtocVersion(protocPath string) (string, error) { if cmdErr != nil { return "", cmdErr } - versionRegexp := regexp.MustCompile(`protoc\s*(\d+\.\d+\.\d+)`) + versionRegexp := regexp.MustCompile(`protoc\s*(\d+\.\d+)`) matched := versionRegexp.FindStringSubmatch(string(output)) - return matched[1], nil + repoProtocVersion := "4." + matched[1] // in contrast to getProjectProtocVersion() + return repoProtocVersion, nil } func parseVersion(s string, width int) int64 { @@ -186,7 +187,7 @@ func main() { os.Exit(1) } - if needToUpdate(targetedVersion, installedVersion) { + if needToUpdate(targetedVersion, installedVersion) && false { fmt.Printf(` You are using an old protobuf version, please update to v%s or later. Download it from https://github.com/protocolbuffers/protobuf/releases @@ -224,6 +225,9 @@ Download it from https://github.com/protocolbuffers/protobuf/releases os.Exit(1) } + // Require: + // go install google.golang.org/protobuf/cmd/protoc-gen-go@latest + // go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest for _, files := range protoFilesMap { for _, relProtoFile := range files { args := []string{ diff --git a/proxy/blackhole/config.pb.go b/proxy/blackhole/config.pb.go index 4121e61c9c..222ef10637 100644 --- a/proxy/blackhole/config.pb.go +++ b/proxy/blackhole/config.pb.go @@ -193,17 +193,17 @@ var file_proxy_blackhole_config_proto_rawDesc = []byte{ 0x67, 0x12, 0x30, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x31, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, - 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x1d, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x6f, - 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x82, 0xb5, 0x18, 0x0b, 0x12, 0x09, 0x62, 0x6c, 0x61, - 0x63, 0x6b, 0x68, 0x6f, 0x6c, 0x65, 0x42, 0x6f, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x62, - 0x6c, 0x61, 0x63, 0x6b, 0x68, 0x6f, 0x6c, 0x65, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x2f, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x68, 0x6f, 0x6c, 0x65, 0xaa, 0x02, 0x1a, 0x56, 0x32, 0x52, - 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x42, 0x6c, - 0x61, 0x63, 0x6b, 0x68, 0x6f, 0x6c, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, + 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x15, 0x0a, 0x08, 0x6f, + 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x09, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x68, 0x6f, + 0x6c, 0x65, 0x42, 0x6f, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, + 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x62, 0x6c, 0x61, 0x63, 0x6b, + 0x68, 0x6f, 0x6c, 0x65, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, + 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x62, 0x6c, 0x61, + 0x63, 0x6b, 0x68, 0x6f, 0x6c, 0x65, 0xaa, 0x02, 0x1a, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, + 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x42, 0x6c, 0x61, 0x63, 0x6b, 0x68, + 0x6f, 0x6c, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/dns/config.pb.go b/proxy/dns/config.pb.go index de45d5d955..d3f0380e89 100644 --- a/proxy/dns/config.pb.go +++ b/proxy/dns/config.pb.go @@ -127,16 +127,15 @@ var file_proxy_dns_config_proto_rawDesc = []byte{ 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x4c, 0x65, 0x76, 0x65, 0x6c, - 0x22, 0x2b, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x17, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x62, - 0x6f, 0x75, 0x6e, 0x64, 0x82, 0xb5, 0x18, 0x05, 0x12, 0x03, 0x64, 0x6e, 0x73, 0x42, 0x5d, 0x0a, - 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01, 0x5a, 0x28, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x2f, 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x14, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, - 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x22, 0x27, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x13, 0x82, 0xb5, 0x18, 0x0f, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x03, 0x64, 0x6e, 0x73, 0x42, 0x5d, 0x0a, 0x18, 0x63, 0x6f, 0x6d, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, + 0x79, 0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, + 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x64, 0x6e, + 0x73, 0xaa, 0x02, 0x14, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, + 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/dokodemo/config.pb.go b/proxy/dokodemo/config.pb.go index fd68e7160d..e7debc4abd 100644 --- a/proxy/dokodemo/config.pb.go +++ b/proxy/dokodemo/config.pb.go @@ -26,11 +26,11 @@ type Config struct { // List of networks that the Dokodemo accepts. // Deprecated. Use networks. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in proxy/dokodemo/config.proto. NetworkList *net.NetworkList `protobuf:"bytes,3,opt,name=network_list,json=networkList,proto3" json:"network_list,omitempty"` // List of networks that the Dokodemo accepts. Networks []net.Network `protobuf:"varint,7,rep,packed,name=networks,proto3,enum=v2ray.core.common.net.Network" json:"networks,omitempty"` - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in proxy/dokodemo/config.proto. Timeout uint32 `protobuf:"varint,4,opt,name=timeout,proto3" json:"timeout,omitempty"` FollowRedirect bool `protobuf:"varint,5,opt,name=follow_redirect,json=followRedirect,proto3" json:"follow_redirect,omitempty"` UserLevel uint32 `protobuf:"varint,6,opt,name=user_level,json=userLevel,proto3" json:"user_level,omitempty"` @@ -82,7 +82,7 @@ func (x *Config) GetPort() uint32 { return 0 } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in proxy/dokodemo/config.proto. func (x *Config) GetNetworkList() *net.NetworkList { if x != nil { return x.NetworkList @@ -97,7 +97,7 @@ func (x *Config) GetNetworks() []net.Network { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in proxy/dokodemo/config.proto. func (x *Config) GetTimeout() uint32 { if x != nil { return x.Timeout @@ -222,7 +222,7 @@ var file_proxy_dokodemo_config_proto_rawDesc = []byte{ 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x75, 0x73, - 0x65, 0x72, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0xee, 0x01, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, + 0x65, 0x72, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0xea, 0x01, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, @@ -235,16 +235,16 @@ var file_proxy_dokodemo_config_proto_rawDesc = []byte{ 0x69, 0x73, 0x74, 0x52, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, - 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x69, 0x6e, - 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x82, 0xb5, 0x18, 0x0f, 0x12, 0x0d, 0x64, 0x6f, 0x6b, 0x6f, 0x64, - 0x65, 0x6d, 0x6f, 0x2d, 0x64, 0x6f, 0x6f, 0x72, 0x42, 0x6c, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x2e, 0x64, 0x6f, 0x6b, 0x6f, 0x64, 0x65, 0x6d, 0x6f, 0x50, 0x01, 0x5a, 0x2d, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x2f, 0x64, 0x6f, 0x6b, 0x6f, 0x64, 0x65, 0x6d, 0x6f, 0xaa, 0x02, 0x19, 0x56, 0x32, 0x52, - 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x44, 0x6f, - 0x6b, 0x6f, 0x64, 0x65, 0x6d, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x3a, 0x1c, 0x82, 0xb5, 0x18, 0x18, 0x0a, 0x07, 0x69, 0x6e, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x0d, 0x64, 0x6f, 0x6b, 0x6f, 0x64, 0x65, 0x6d, 0x6f, 0x2d, + 0x64, 0x6f, 0x6f, 0x72, 0x42, 0x6c, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x64, 0x6f, 0x6b, + 0x6f, 0x64, 0x65, 0x6d, 0x6f, 0x50, 0x01, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, + 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x64, 0x6f, + 0x6b, 0x6f, 0x64, 0x65, 0x6d, 0x6f, 0xaa, 0x02, 0x19, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, + 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x44, 0x6f, 0x6b, 0x6f, 0x64, 0x65, + 0x6d, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/freedom/config.pb.go b/proxy/freedom/config.pb.go index b6c6d4561d..0669c70fd0 100644 --- a/proxy/freedom/config.pb.go +++ b/proxy/freedom/config.pb.go @@ -121,7 +121,7 @@ type Config struct { unknownFields protoimpl.UnknownFields DomainStrategy Config_DomainStrategy `protobuf:"varint,1,opt,name=domain_strategy,json=domainStrategy,proto3,enum=v2ray.core.proxy.freedom.Config_DomainStrategy" json:"domain_strategy,omitempty"` - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in proxy/freedom/config.proto. Timeout uint32 `protobuf:"varint,2,opt,name=timeout,proto3" json:"timeout,omitempty"` DestinationOverride *DestinationOverride `protobuf:"bytes,3,opt,name=destination_override,json=destinationOverride,proto3" json:"destination_override,omitempty"` UserLevel uint32 `protobuf:"varint,4,opt,name=user_level,json=userLevel,proto3" json:"user_level,omitempty"` @@ -166,7 +166,7 @@ func (x *Config) GetDomainStrategy() Config_DomainStrategy { return Config_AS_IS } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in proxy/freedom/config.proto. func (x *Config) GetTimeout() uint32 { if x != nil { return x.Timeout @@ -262,18 +262,17 @@ var file_proxy_freedom_config_proto_rawDesc = []byte{ 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x53, 0x5f, 0x49, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x02, - 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x03, 0x22, 0x2f, 0x0a, + 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x03, 0x22, 0x2b, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x3a, 0x1b, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, - 0x64, 0x82, 0xb5, 0x18, 0x09, 0x12, 0x07, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x42, 0x69, - 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x50, 0x01, - 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, - 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, - 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0xaa, 0x02, - 0x18, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, - 0x79, 0x2e, 0x46, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x67, 0x3a, 0x17, 0x82, 0xb5, 0x18, 0x13, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, + 0x64, 0x12, 0x07, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x42, 0x69, 0x0a, 0x1c, 0x63, 0x6f, + 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x2f, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0xaa, 0x02, 0x18, 0x56, 0x32, 0x52, + 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x46, 0x72, + 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/loopback/config.pb.go b/proxy/loopback/config.pb.go index 53876241f5..c428b7fba9 100644 --- a/proxy/loopback/config.pb.go +++ b/proxy/loopback/config.pb.go @@ -70,19 +70,19 @@ var file_proxy_loopback_config_proto_rawDesc = []byte{ 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x47, 0x0a, 0x06, 0x43, 0x6f, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x43, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x54, 0x61, 0x67, 0x3a, 0x1c, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x6f, 0x75, 0x74, - 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x82, 0xb5, 0x18, 0x0a, 0x12, 0x08, 0x6c, 0x6f, 0x6f, 0x70, 0x62, - 0x61, 0x63, 0x6b, 0x42, 0x6c, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, - 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, - 0x62, 0x61, 0x63, 0x6b, 0x50, 0x01, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, - 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x6c, 0x6f, 0x6f, - 0x70, 0x62, 0x61, 0x63, 0x6b, 0xaa, 0x02, 0x19, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, - 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, - 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x64, 0x54, 0x61, 0x67, 0x3a, 0x18, 0x82, 0xb5, 0x18, 0x14, 0x0a, 0x08, 0x6f, 0x75, 0x74, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x08, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x42, + 0x6c, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, + 0x50, 0x01, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, + 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, + 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, + 0x6b, 0xaa, 0x02, 0x19, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, + 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/shadowsocks/config.pb.go b/proxy/shadowsocks/config.pb.go index 248520c725..e22a038c90 100644 --- a/proxy/shadowsocks/config.pb.go +++ b/proxy/shadowsocks/config.pb.go @@ -151,7 +151,7 @@ type ServerConfig struct { // UdpEnabled specified whether or not to enable UDP for Shadowsocks. // Deprecated. Use 'network' field. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in proxy/shadowsocks/config.proto. UdpEnabled bool `protobuf:"varint,1,opt,name=udp_enabled,json=udpEnabled,proto3" json:"udp_enabled,omitempty"` User *protocol.User `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` Network []net.Network `protobuf:"varint,3,rep,packed,name=network,proto3,enum=v2ray.core.common.net.Network" json:"network,omitempty"` @@ -190,7 +190,7 @@ func (*ServerConfig) Descriptor() ([]byte, []int) { return file_proxy_shadowsocks_config_proto_rawDescGZIP(), []int{1} } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in proxy/shadowsocks/config.proto. func (x *ServerConfig) GetUdpEnabled() bool { if x != nil { return x.UdpEnabled diff --git a/proxy/shadowsocks/simplified/config.pb.go b/proxy/shadowsocks/simplified/config.pb.go index ec01869b7e..1991d97f3c 100644 --- a/proxy/shadowsocks/simplified/config.pb.go +++ b/proxy/shadowsocks/simplified/config.pb.go @@ -1,9 +1,3 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 -// source: proxy/shadowsocks/simplified/config.proto - package simplified import ( diff --git a/proxy/socks/config.pb.go b/proxy/socks/config.pb.go index 376c91c208..9b7ec741dd 100644 --- a/proxy/socks/config.pb.go +++ b/proxy/socks/config.pb.go @@ -181,7 +181,7 @@ type ServerConfig struct { Accounts map[string]string `protobuf:"bytes,2,rep,name=accounts,proto3" json:"accounts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Address *net.IPOrDomain `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` UdpEnabled bool `protobuf:"varint,4,opt,name=udp_enabled,json=udpEnabled,proto3" json:"udp_enabled,omitempty"` - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in proxy/socks/config.proto. Timeout uint32 `protobuf:"varint,5,opt,name=timeout,proto3" json:"timeout,omitempty"` UserLevel uint32 `protobuf:"varint,6,opt,name=user_level,json=userLevel,proto3" json:"user_level,omitempty"` PacketEncoding packetaddr.PacketAddrType `protobuf:"varint,7,opt,name=packet_encoding,json=packetEncoding,proto3,enum=v2ray.core.net.packetaddr.PacketAddrType" json:"packet_encoding,omitempty"` @@ -247,7 +247,7 @@ func (x *ServerConfig) GetUdpEnabled() bool { return false } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in proxy/socks/config.proto. func (x *ServerConfig) GetTimeout() uint32 { if x != nil { return x.Timeout diff --git a/proxy/socks/simplified/config.pb.go b/proxy/socks/simplified/config.pb.go index cf0b169188..ccadf744ee 100644 --- a/proxy/socks/simplified/config.pb.go +++ b/proxy/socks/simplified/config.pb.go @@ -148,7 +148,7 @@ var file_proxy_socks_simplified_config_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x61, 0x64, 0x64, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xda, 0x01, 0x0a, 0x0c, 0x53, 0x65, 0x72, + 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd6, 0x01, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, @@ -160,25 +160,25 @@ var file_proxy_socks_simplified_config_proto_rawDesc = []byte{ 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x61, 0x64, 0x64, 0x72, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0e, 0x70, 0x61, 0x63, - 0x6b, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x18, 0x82, 0xb5, 0x18, - 0x09, 0x0a, 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x82, 0xb5, 0x18, 0x07, 0x12, 0x05, - 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x22, 0x7a, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, - 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x6f, 0x75, - 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x82, 0xb5, 0x18, 0x07, 0x12, 0x05, 0x73, 0x6f, 0x63, 0x6b, - 0x73, 0x42, 0x84, 0x01, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x73, 0x6f, 0x63, 0x6b, 0x73, - 0x2e, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x01, 0x5a, 0x35, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x2f, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, - 0x66, 0x69, 0x65, 0x64, 0xaa, 0x02, 0x21, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, - 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x2e, 0x53, 0x69, - 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6b, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x14, 0x82, 0xb5, 0x18, + 0x10, 0x0a, 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x05, 0x73, 0x6f, 0x63, 0x6b, + 0x73, 0x22, 0x76, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, + 0x72, 0x74, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, + 0x6e, 0x64, 0x12, 0x05, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x42, 0x84, 0x01, 0x0a, 0x25, 0x63, 0x6f, + 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x2e, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x2e, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, + 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x73, 0x6f, 0x63, 0x6b, + 0x73, 0x2f, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0xaa, 0x02, 0x21, 0x56, + 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, + 0x53, 0x6f, 0x63, 0x6b, 0x73, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/trojan/config.pb.go b/proxy/trojan/config.pb.go index e7c0916ce2..b91257687a 100644 --- a/proxy/trojan/config.pb.go +++ b/proxy/trojan/config.pb.go @@ -1,9 +1,3 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.11 -// source: proxy/trojan/config.proto - package trojan import ( diff --git a/proxy/trojan/simplified/config.pb.go b/proxy/trojan/simplified/config.pb.go index 1e3e2f8842..f066681cd5 100644 --- a/proxy/trojan/simplified/config.pb.go +++ b/proxy/trojan/simplified/config.pb.go @@ -1,9 +1,3 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.11 -// source: proxy/trojan/simplified/config.proto - package simplified import ( @@ -154,7 +148,7 @@ var file_proxy_trojan_simplified_config_proto_rawDesc = []byte{ 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x61, 0x64, 0x64, 0x72, 0x2f, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x93, 0x01, 0x0a, 0x0c, 0x53, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8f, 0x01, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0x52, 0x0a, 0x0f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x65, 0x6e, 0x63, 0x6f, @@ -162,27 +156,27 @@ var file_proxy_trojan_simplified_config_proto_rawDesc = []byte{ 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x61, 0x64, 0x64, 0x72, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0e, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x6e, 0x63, - 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x69, 0x6e, 0x62, - 0x6f, 0x75, 0x6e, 0x64, 0x82, 0xb5, 0x18, 0x08, 0x12, 0x06, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, - 0x22, 0x97, 0x01, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, - 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, - 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, - 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x3a, 0x1a, - 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x82, 0xb5, - 0x18, 0x08, 0x12, 0x06, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x42, 0x87, 0x01, 0x0a, 0x26, 0x63, - 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x2e, 0x73, 0x69, 0x6d, 0x70, 0x6c, - 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x01, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, - 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x74, 0x72, - 0x6f, 0x6a, 0x61, 0x6e, 0x2f, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0xaa, - 0x02, 0x22, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x2e, 0x54, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, - 0x66, 0x69, 0x65, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x07, 0x69, 0x6e, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x06, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x22, 0x93, 0x01, 0x0a, + 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, + 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x3a, 0x16, 0x82, 0xb5, 0x18, 0x12, + 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x06, 0x74, 0x72, 0x6f, 0x6a, + 0x61, 0x6e, 0x42, 0x87, 0x01, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x74, 0x72, 0x6f, 0x6a, + 0x61, 0x6e, 0x2e, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x01, 0x5a, + 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, + 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, + 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x2f, 0x73, 0x69, 0x6d, + 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0xaa, 0x02, 0x22, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, + 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x54, 0x72, 0x6f, 0x6a, 0x61, + 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/vless/inbound/config.pb.go b/proxy/vless/inbound/config.pb.go index 96b2913162..95dfae868c 100644 --- a/proxy/vless/inbound/config.pb.go +++ b/proxy/vless/inbound/config.pb.go @@ -236,19 +236,19 @@ var file_proxy_vless_inbound_config_proto_rawDesc = []byte{ 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x09, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x22, - 0x42, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, + 0x3e, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x3a, 0x18, 0x82, 0xb5, 0x18, 0x09, 0x0a, - 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x82, 0xb5, 0x18, 0x07, 0x12, 0x05, 0x76, 0x6c, - 0x65, 0x73, 0x73, 0x42, 0x7b, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, - 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73, - 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x32, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x2f, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, - 0x02, 0x1e, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x2e, 0x56, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x28, 0x09, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x3a, 0x14, 0x82, 0xb5, 0x18, 0x10, 0x0a, + 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x05, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x42, + 0x7b, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, + 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6c, + 0x65, 0x73, 0x73, 0x2f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, 0x1e, 0x56, 0x32, + 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, + 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/vless/outbound/config.pb.go b/proxy/vless/outbound/config.pb.go index e71df8bb61..3b52789901 100644 --- a/proxy/vless/outbound/config.pb.go +++ b/proxy/vless/outbound/config.pb.go @@ -145,24 +145,24 @@ var file_proxy_vless_outbound_config_proto_rawDesc = []byte{ 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x6e, 0x65, 0x78, 0x74, 0x22, - 0x92, 0x01, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, + 0x8e, 0x01, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x0a, 0x0a, - 0x08, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x82, 0xb5, 0x18, 0x07, 0x12, 0x05, 0x76, - 0x6c, 0x65, 0x73, 0x73, 0x42, 0x7e, 0x0a, 0x23, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, - 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, - 0x73, 0x73, 0x2e, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x33, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0xaa, 0x02, 0x1f, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, - 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x62, - 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, + 0x08, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x05, 0x76, 0x6c, 0x65, 0x73, 0x73, + 0x42, 0x7e, 0x0a, 0x23, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x6f, + 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, + 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, + 0x1f, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, + 0x79, 0x2e, 0x56, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/vlite/inbound/config.pb.go b/proxy/vlite/inbound/config.pb.go index 047a025b1b..8643949a97 100644 --- a/proxy/vlite/inbound/config.pb.go +++ b/proxy/vlite/inbound/config.pb.go @@ -111,7 +111,7 @@ var file_proxy_vlite_inbound_config_proto_rawDesc = []byte{ 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x69, 0x74, 0x65, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbd, 0x02, 0x0a, 0x11, 0x55, 0x44, 0x50, 0x50, 0x72, 0x6f, 0x74, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb9, 0x02, 0x0a, 0x11, 0x55, 0x44, 0x50, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x63, 0x72, 0x61, 0x6d, 0x62, @@ -129,17 +129,17 @@ var file_proxy_vlite_inbound_config_proto_rawDesc = []byte{ 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1b, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x69, 0x6e, 0x67, 0x50, 0x61, - 0x64, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x09, 0x0a, - 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x82, 0xb5, 0x18, 0x08, 0x12, 0x06, 0x76, 0x6c, - 0x69, 0x74, 0x65, 0x75, 0x42, 0x7b, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, - 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x69, - 0x74, 0x65, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x32, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, - 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x2f, 0x76, 0x6c, 0x69, 0x74, 0x65, 0x2f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, - 0xaa, 0x02, 0x1e, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, - 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6c, 0x69, 0x74, 0x65, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, - 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, + 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x06, 0x76, 0x6c, 0x69, 0x74, 0x65, 0x75, + 0x42, 0x7b, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x69, 0x74, 0x65, 0x2e, 0x69, + 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, + 0x6c, 0x69, 0x74, 0x65, 0x2f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, 0x1e, 0x56, + 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, + 0x56, 0x6c, 0x69, 0x74, 0x65, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/vlite/outbound/config.pb.go b/proxy/vlite/outbound/config.pb.go index b4e4e79cf1..443e4f99cf 100644 --- a/proxy/vlite/outbound/config.pb.go +++ b/proxy/vlite/outbound/config.pb.go @@ -130,7 +130,7 @@ var file_proxy_vlite_outbound_config_proto_rawDesc = []byte{ 0x2f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x8f, 0x03, 0x0a, 0x11, 0x55, 0x44, 0x50, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x22, 0x8b, 0x03, 0x0a, 0x11, 0x55, 0x44, 0x50, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, @@ -153,17 +153,17 @@ var file_proxy_vlite_outbound_config_proto_rawDesc = []byte{ 0x61, 0x73, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1b, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x64, 0x64, 0x69, - 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x6f, 0x75, - 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x82, 0xb5, 0x18, 0x08, 0x12, 0x06, 0x76, 0x6c, 0x69, 0x74, - 0x65, 0x75, 0x42, 0x7e, 0x0a, 0x23, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x69, 0x74, 0x65, - 0x2e, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x2f, 0x76, 0x6c, 0x69, 0x74, 0x65, 0x2f, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, - 0xaa, 0x02, 0x1f, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, - 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6c, 0x69, 0x74, 0x65, 0x2e, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x16, 0x82, 0xb5, 0x18, 0x12, 0x0a, 0x08, 0x6f, 0x75, + 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x06, 0x76, 0x6c, 0x69, 0x74, 0x65, 0x75, 0x42, 0x7e, + 0x0a, 0x23, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x69, 0x74, 0x65, 0x2e, 0x6f, 0x75, 0x74, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, + 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6c, + 0x69, 0x74, 0x65, 0x2f, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, 0x1f, 0x56, + 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, + 0x56, 0x6c, 0x69, 0x74, 0x65, 0x2e, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/vmess/inbound/config.pb.go b/proxy/vmess/inbound/config.pb.go index e69ea49420..ab0b3b605b 100644 --- a/proxy/vmess/inbound/config.pb.go +++ b/proxy/vmess/inbound/config.pb.go @@ -269,20 +269,19 @@ var file_proxy_vmess_inbound_config_proto_rawDesc = []byte{ 0x75, 0x72, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x42, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x3e, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x75, 0x73, 0x65, - 0x72, 0x73, 0x3a, 0x18, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, - 0x64, 0x82, 0xb5, 0x18, 0x07, 0x12, 0x05, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x42, 0x7b, 0x0a, 0x22, - 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, - 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6d, 0x65, 0x73, 0x73, - 0x2f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, 0x1e, 0x56, 0x32, 0x52, 0x61, 0x79, - 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6d, 0x65, 0x73, - 0x73, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x72, 0x73, 0x3a, 0x14, 0x82, 0xb5, 0x18, 0x10, 0x0a, 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, + 0x64, 0x12, 0x05, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x42, 0x7b, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x2e, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x2e, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, + 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, + 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, + 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x2f, 0x69, 0x6e, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, 0x1e, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, + 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6d, 0x65, 0x73, 0x73, 0x2e, 0x49, 0x6e, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/vmess/outbound/config.pb.go b/proxy/vmess/outbound/config.pb.go index 46c4d62ad7..1ac3ba66cd 100644 --- a/proxy/vmess/outbound/config.pb.go +++ b/proxy/vmess/outbound/config.pb.go @@ -145,7 +145,7 @@ var file_proxy_vmess_outbound_config_proto_rawDesc = []byte{ 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x08, 0x52, 0x65, 0x63, - 0x65, 0x69, 0x76, 0x65, 0x72, 0x22, 0x92, 0x01, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, + 0x65, 0x69, 0x76, 0x65, 0x72, 0x22, 0x8e, 0x01, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, @@ -153,17 +153,16 @@ var file_proxy_vmess_outbound_config_proto_rawDesc = []byte{ 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x3a, - 0x19, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x82, - 0xb5, 0x18, 0x07, 0x12, 0x05, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x42, 0x7e, 0x0a, 0x23, 0x63, 0x6f, - 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x2e, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x2e, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, - 0x64, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, - 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x2f, - 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, 0x1f, 0x56, 0x32, 0x52, 0x61, 0x79, - 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6d, 0x65, 0x73, - 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, + 0x05, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x42, 0x7e, 0x0a, 0x23, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, + 0x6d, 0x65, 0x73, 0x73, 0x2e, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a, + 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, + 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, + 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, 0x1f, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, + 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6d, 0x65, 0x73, 0x73, 0x2e, 0x4f, 0x75, + 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/transport/config.pb.go b/transport/config.pb.go index ed5c2eec4d..790886f427 100644 --- a/transport/config.pb.go +++ b/transport/config.pb.go @@ -18,7 +18,7 @@ const ( // Global transport settings. This affects all type of connections that go // through V2Ray. Deprecated. Use each settings in StreamConfig. // -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in transport/config.proto. type Config struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache diff --git a/transport/internet/config.pb.go b/transport/internet/config.pb.go index 729899015b..1ded5291f2 100644 --- a/transport/internet/config.pb.go +++ b/transport/internet/config.pb.go @@ -185,7 +185,7 @@ type TransportConfig struct { // Type of network that this settings supports. // Deprecated. Use the string form below. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in transport/internet/config.proto. Protocol TransportProtocol `protobuf:"varint,1,opt,name=protocol,proto3,enum=v2ray.core.transport.internet.TransportProtocol" json:"protocol,omitempty"` // Type of network that this settings supports. ProtocolName string `protobuf:"bytes,3,opt,name=protocol_name,json=protocolName,proto3" json:"protocol_name,omitempty"` @@ -225,7 +225,7 @@ func (*TransportConfig) Descriptor() ([]byte, []int) { return file_transport_internet_config_proto_rawDescGZIP(), []int{0} } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in transport/internet/config.proto. func (x *TransportConfig) GetProtocol() TransportProtocol { if x != nil { return x.Protocol @@ -254,7 +254,7 @@ type StreamConfig struct { // Effective network. Deprecated. Use the string form below. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in transport/internet/config.proto. Protocol TransportProtocol `protobuf:"varint,1,opt,name=protocol,proto3,enum=v2ray.core.transport.internet.TransportProtocol" json:"protocol,omitempty"` // Effective network. ProtocolName string `protobuf:"bytes,5,opt,name=protocol_name,json=protocolName,proto3" json:"protocol_name,omitempty"` @@ -298,7 +298,7 @@ func (*StreamConfig) Descriptor() ([]byte, []int) { return file_transport_internet_config_proto_rawDescGZIP(), []int{1} } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in transport/internet/config.proto. func (x *StreamConfig) GetProtocol() TransportProtocol { if x != nil { return x.Protocol diff --git a/transport/internet/grpc/config.pb.go b/transport/internet/grpc/config.pb.go index b424476d95..14035c9db7 100644 --- a/transport/internet/grpc/config.pb.go +++ b/transport/internet/grpc/config.pb.go @@ -80,22 +80,22 @@ var file_transport_internet_grpc_config_proto_rawDesc = []byte{ 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x65, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x24, 0x82, 0xb5, 0x18, 0x0b, 0x0a, 0x09, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x82, 0xb5, 0x18, 0x06, 0x12, 0x04, 0x67, 0x72, 0x70, - 0x63, 0x82, 0xb5, 0x18, 0x07, 0x8a, 0xff, 0x29, 0x03, 0x67, 0x75, 0x6e, 0x42, 0x85, 0x01, 0x0a, - 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, - 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, - 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x67, 0x72, 0x70, 0x63, 0xaa, - 0x02, 0x22, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, - 0x47, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x1c, 0x82, 0xb5, 0x18, 0x18, 0x0a, 0x09, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x04, 0x67, 0x72, 0x70, 0x63, 0x8a, 0xff, 0x29, + 0x03, 0x67, 0x75, 0x6e, 0x42, 0x85, 0x01, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x5a, + 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, + 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x2f, 0x67, 0x72, 0x70, 0x63, 0xaa, 0x02, 0x22, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, + 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x47, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/transport/internet/grpc/encoding/stream_grpc.pb.go b/transport/internet/grpc/encoding/stream_grpc.pb.go index c4464eb7c0..2859c424e1 100644 --- a/transport/internet/grpc/encoding/stream_grpc.pb.go +++ b/transport/internet/grpc/encoding/stream_grpc.pb.go @@ -12,6 +12,10 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + GunService_Tun_FullMethodName = "/v2ray.core.transport.internet.grpc.encoding.GunService/Tun" +) + // GunServiceClient is the client API for GunService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -28,7 +32,7 @@ func NewGunServiceClient(cc grpc.ClientConnInterface) GunServiceClient { } func (c *gunServiceClient) Tun(ctx context.Context, opts ...grpc.CallOption) (GunService_TunClient, error) { - stream, err := c.cc.NewStream(ctx, &GunService_ServiceDesc.Streams[0], "/v2ray.core.transport.internet.grpc.encoding.GunService/Tun", opts...) + stream, err := c.cc.NewStream(ctx, &GunService_ServiceDesc.Streams[0], GunService_Tun_FullMethodName, opts...) if err != nil { return nil, err } diff --git a/transport/internet/kcp/config.pb.go b/transport/internet/kcp/config.pb.go index 1f422e8f28..e9c171632b 100644 --- a/transport/internet/kcp/config.pb.go +++ b/transport/internet/kcp/config.pb.go @@ -539,7 +539,7 @@ var file_transport_internet_kcp_config_proto_rawDesc = []byte{ 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x24, 0x0a, 0x0e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x73, 0x65, 0x65, 0x64, 0x22, 0xab, 0x05, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, + 0x09, 0x52, 0x04, 0x73, 0x65, 0x65, 0x64, 0x22, 0xa3, 0x05, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, @@ -579,19 +579,18 @@ var file_transport_internet_kcp_config_proto_rawDesc = []byte{ 0x32, 0x31, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x6b, 0x63, 0x70, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x65, 0x65, 0x64, 0x52, 0x04, 0x73, 0x65, 0x65, 0x64, 0x3a, 0x24, 0x82, 0xb5, 0x18, 0x0b, 0x0a, - 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x82, 0xb5, 0x18, 0x05, 0x12, 0x03, - 0x6b, 0x63, 0x70, 0x82, 0xb5, 0x18, 0x08, 0x8a, 0xff, 0x29, 0x04, 0x6d, 0x6b, 0x63, 0x70, 0x4a, - 0x04, 0x08, 0x09, 0x10, 0x0a, 0x42, 0x84, 0x01, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x6b, 0x63, 0x70, 0x50, - 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, - 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, - 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x63, 0x70, 0xaa, 0x02, 0x21, 0x56, 0x32, 0x52, 0x61, 0x79, - 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x4b, 0x63, 0x70, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x65, 0x64, 0x52, 0x04, 0x73, 0x65, 0x65, 0x64, 0x3a, 0x1c, 0x82, 0xb5, 0x18, 0x18, 0x0a, + 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x03, 0x6b, 0x63, 0x70, 0x8a, + 0xff, 0x29, 0x04, 0x6d, 0x6b, 0x63, 0x70, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x42, 0x84, 0x01, + 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x65, 0x74, 0x2e, 0x6b, 0x63, 0x70, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x63, 0x70, + 0xaa, 0x02, 0x21, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x2e, 0x4b, 0x63, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/transport/internet/quic/config.pb.go b/transport/internet/quic/config.pb.go index 0207690354..77d44ee36f 100644 --- a/transport/internet/quic/config.pb.go +++ b/transport/internet/quic/config.pb.go @@ -93,7 +93,7 @@ var file_transport_internet_quic_config_proto_rawDesc = []byte{ 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xab, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa7, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, @@ -102,18 +102,18 @@ var file_transport_internet_quic_config_proto_rawDesc = []byte{ 0x67, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, - 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x0b, 0x0a, - 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x82, 0xb5, 0x18, 0x06, 0x12, 0x04, - 0x71, 0x75, 0x69, 0x63, 0x42, 0x87, 0x01, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x50, - 0x01, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, - 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, - 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x71, 0x75, 0x69, 0x63, 0xaa, 0x02, 0x22, 0x56, 0x32, 0x52, 0x61, - 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x51, 0x75, 0x69, 0x63, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, + 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x04, 0x71, 0x75, 0x69, 0x63, + 0x42, 0x87, 0x01, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x50, 0x01, 0x5a, 0x36, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x2f, 0x71, 0x75, 0x69, 0x63, 0xaa, 0x02, 0x22, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, + 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x51, 0x75, 0x69, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/transport/internet/tcp/config.pb.go b/transport/internet/tcp/config.pb.go index 34fbfd43c2..5d3da89947 100644 --- a/transport/internet/tcp/config.pb.go +++ b/transport/internet/tcp/config.pb.go @@ -82,7 +82,7 @@ var file_transport_internet_tcp_config_proto_rawDesc = []byte{ 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9b, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x97, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x0a, 0x0f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, @@ -90,18 +90,17 @@ var file_transport_internet_tcp_config_proto_rawDesc = []byte{ 0x32, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x3a, 0x18, 0x82, 0xb5, 0x18, 0x0b, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x70, 0x6f, 0x72, 0x74, 0x82, 0xb5, 0x18, 0x05, 0x12, 0x03, 0x74, 0x63, 0x70, 0x4a, 0x04, 0x08, - 0x01, 0x10, 0x02, 0x42, 0x84, 0x01, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, - 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x63, 0x70, 0x50, 0x01, 0x5a, - 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, - 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x2f, 0x74, 0x63, 0x70, 0xaa, 0x02, 0x21, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, - 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x63, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x63, 0x6f, 0x6c, 0x3a, 0x14, 0x82, 0xb5, 0x18, 0x10, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x70, 0x6f, 0x72, 0x74, 0x12, 0x03, 0x74, 0x63, 0x70, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x42, + 0x84, 0x01, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x63, 0x70, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, + 0x63, 0x70, 0xaa, 0x02, 0x21, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x2e, 0x54, 0x63, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/transport/internet/tls/config.pb.go b/transport/internet/tls/config.pb.go index 09ca99b630..3c399854dc 100644 --- a/transport/internet/tls/config.pb.go +++ b/transport/internet/tls/config.pb.go @@ -294,7 +294,7 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{ 0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x5f, 0x43, 0x4c, 0x49, - 0x45, 0x4e, 0x54, 0x10, 0x03, 0x22, 0xe0, 0x03, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x45, 0x4e, 0x54, 0x10, 0x03, 0x22, 0xdc, 0x03, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2d, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x42, 0x06, 0x82, 0xb5, 0x18, 0x02, 0x28, 0x01, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, @@ -323,17 +323,17 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{ 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3a, - 0x17, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x82, - 0xb5, 0x18, 0x05, 0x12, 0x03, 0x74, 0x6c, 0x73, 0x42, 0x84, 0x01, 0x0a, 0x25, 0x63, 0x6f, 0x6d, - 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, - 0x6c, 0x73, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, - 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x21, 0x56, 0x32, - 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x6c, 0x73, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x13, 0x82, 0xb5, 0x18, 0x0f, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, + 0x03, 0x74, 0x6c, 0x73, 0x42, 0x84, 0x01, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x50, 0x01, + 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, + 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, + 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x21, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, + 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/transport/internet/tls/utls/config.pb.go b/transport/internet/tls/utls/config.pb.go index 295e2eadff..057eeb7d8a 100644 --- a/transport/internet/tls/utls/config.pb.go +++ b/transport/internet/tls/utls/config.pb.go @@ -148,7 +148,7 @@ var file_transport_internet_tls_utls_config_proto_rawDesc = []byte{ 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0x2f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xef, 0x01, 0x0a, 0x06, 0x43, 0x6f, + 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xeb, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x48, 0x0a, 0x0a, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, @@ -162,23 +162,23 @@ var file_transport_internet_tls_utls_config_proto_rawDesc = []byte{ 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x2e, 0x75, 0x74, 0x6c, 0x73, 0x2e, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x64, 0x41, 0x4c, 0x50, 0x4e, 0x52, 0x09, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x41, 0x6c, 0x70, - 0x6e, 0x3a, 0x18, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x82, 0xb5, 0x18, 0x06, 0x12, 0x04, 0x75, 0x74, 0x6c, 0x73, 0x2a, 0x52, 0x0a, 0x0a, 0x46, - 0x6f, 0x72, 0x63, 0x65, 0x64, 0x41, 0x4c, 0x50, 0x4e, 0x12, 0x26, 0x0a, 0x22, 0x54, 0x52, 0x41, - 0x4e, 0x53, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, - 0x45, 0x5f, 0x54, 0x41, 0x4b, 0x45, 0x5f, 0x50, 0x52, 0x49, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x10, - 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x4e, 0x4f, 0x5f, 0x41, 0x4c, 0x50, 0x4e, 0x10, 0x01, 0x12, 0x0f, - 0x0a, 0x0b, 0x55, 0x54, 0x4c, 0x53, 0x5f, 0x50, 0x52, 0x45, 0x53, 0x45, 0x54, 0x10, 0x02, 0x42, - 0x93, 0x01, 0x0a, 0x2a, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x2e, 0x75, 0x74, 0x6c, 0x73, 0x50, 0x01, - 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, - 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, - 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0x2f, 0x75, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x26, 0x56, - 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x6c, 0x73, - 0x2e, 0x55, 0x54, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x3a, 0x14, 0x82, 0xb5, 0x18, 0x10, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x12, 0x04, 0x75, 0x74, 0x6c, 0x73, 0x2a, 0x52, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x63, 0x65, + 0x64, 0x41, 0x4c, 0x50, 0x4e, 0x12, 0x26, 0x0a, 0x22, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x50, 0x4f, + 0x52, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x5f, 0x54, 0x41, + 0x4b, 0x45, 0x5f, 0x50, 0x52, 0x49, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x10, 0x00, 0x12, 0x0b, 0x0a, + 0x07, 0x4e, 0x4f, 0x5f, 0x41, 0x4c, 0x50, 0x4e, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x54, + 0x4c, 0x53, 0x5f, 0x50, 0x52, 0x45, 0x53, 0x45, 0x54, 0x10, 0x02, 0x42, 0x93, 0x01, 0x0a, 0x2a, + 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x2e, 0x75, 0x74, 0x6c, 0x73, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, + 0x74, 0x6c, 0x73, 0x2f, 0x75, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x26, 0x56, 0x32, 0x52, 0x61, 0x79, + 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x6c, 0x73, 0x2e, 0x55, 0x54, 0x6c, + 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/transport/internet/websocket/config.pb.go b/transport/internet/websocket/config.pb.go index 5b03acb7e9..ff62bc2fa2 100644 --- a/transport/internet/websocket/config.pb.go +++ b/transport/internet/websocket/config.pb.go @@ -171,7 +171,7 @@ var file_transport_internet_websocket_config_proto_rawDesc = []byte{ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x30, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xda, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xd2, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x47, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, @@ -190,20 +190,19 @@ var file_transport_internet_websocket_config_proto_rawDesc = []byte{ 0x12, 0x33, 0x0a, 0x16, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x44, 0x61, 0x74, 0x61, 0x48, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x28, 0x82, 0xb5, 0x18, 0x0b, 0x0a, 0x09, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x82, 0xb5, 0x18, 0x04, 0x12, 0x02, 0x77, 0x73, 0x82, 0xb5, - 0x18, 0x0d, 0x8a, 0xff, 0x29, 0x09, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x4a, - 0x04, 0x08, 0x01, 0x10, 0x02, 0x42, 0x96, 0x01, 0x0a, 0x2b, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, - 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, - 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, - 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x77, 0x65, 0x62, 0x73, 0x6f, - 0x63, 0x6b, 0x65, 0x74, 0xaa, 0x02, 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, - 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x82, 0xb5, 0x18, 0x1c, 0x0a, 0x09, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x02, 0x77, 0x73, 0x8a, 0xff, 0x29, 0x09, 0x77, 0x65, + 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x42, 0x96, 0x01, + 0x0a, 0x2b, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x65, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x01, 0x5a, + 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, + 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x2f, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0xaa, 0x02, 0x27, 0x56, + 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x57, 0x65, 0x62, + 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From 257cb9f21bd78f78d1f4165d9972c1afa70f559d Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Tue, 3 Oct 2023 10:21:18 +0800 Subject: [PATCH 02/81] fix vprotogen check version --- infra/vprotogen/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/vprotogen/main.go b/infra/vprotogen/main.go index fa5fa8170b..5352ba9412 100644 --- a/infra/vprotogen/main.go +++ b/infra/vprotogen/main.go @@ -187,7 +187,7 @@ func main() { os.Exit(1) } - if needToUpdate(targetedVersion, installedVersion) && false { + if needToUpdate(targetedVersion, installedVersion) { fmt.Printf(` You are using an old protobuf version, please update to v%s or later. Download it from https://github.com/protocolbuffers/protobuf/releases From 11f6704211611618ef3d6cd8520ff531b79912f5 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Tue, 3 Oct 2023 10:26:30 +0800 Subject: [PATCH 03/81] update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ecbbd9e940..714f030129 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ This repo relies on the following third-party projects: - In production: - [gorilla/websocket](https://github.com/gorilla/websocket) - - [lucas-clemente/quic-go](https://github.com/lucas-clemente/quic-go) + - [quic-go/quic-go](https://github.com/quic-go/quic-go) - [pires/go-proxyproto](https://github.com/pires/go-proxyproto) - [seiflotfy/cuckoofilter](https://github.com/seiflotfy/cuckoofilter) - [google/starlark-go](https://github.com/google/starlark-go) From 5d89c287b5a53d76da8ef11bae32a90cc5e49cf1 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Tue, 3 Oct 2023 10:28:23 +0800 Subject: [PATCH 04/81] triger test --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 827263a929..455a0b0cfe 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,7 +5,7 @@ on: branches: - master - v* - - dev-* + - dev* paths: - "**/*.go" - "go.mod" From b6a0f009656dd32d79c2f4b0a646f54dcff0128f Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Tue, 3 Oct 2023 11:22:54 +0800 Subject: [PATCH 05/81] fix deprecated ReadFile() --- common/buf/multi_buffer_test.go | 3 +-- common/cmdarg/arg.go | 4 ++-- infra/conf/geodata/memconservative/cache.go | 6 +++--- infra/vprotogen/main.go | 3 +-- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/common/buf/multi_buffer_test.go b/common/buf/multi_buffer_test.go index 6d835c8289..c4c85c38ee 100644 --- a/common/buf/multi_buffer_test.go +++ b/common/buf/multi_buffer_test.go @@ -4,7 +4,6 @@ import ( "bytes" "crypto/rand" "io" - "io/ioutil" "os" "testing" @@ -120,7 +119,7 @@ func TestMultiBufferReadAllToByte(t *testing.T) { common.Must(err) f.Close() - cnt, err := ioutil.ReadFile(dat) + cnt, err := os.ReadFile(dat) common.Must(err) if d := cmp.Diff(buf2, cnt); d != "" { diff --git a/common/cmdarg/arg.go b/common/cmdarg/arg.go index 8a0958d420..52ccb7d6f0 100644 --- a/common/cmdarg/arg.go +++ b/common/cmdarg/arg.go @@ -3,7 +3,7 @@ package cmdarg import ( "bytes" "io" - "io/ioutil" + "os" ) // LoadArg loads one arg, maybe an remote url, or local file path @@ -18,7 +18,7 @@ func LoadArg(arg string) (out io.Reader, err error) { // LoadArgToBytes loads one arg to []byte, maybe an remote url, or local file path func LoadArgToBytes(arg string) (out []byte, err error) { - out, err = ioutil.ReadFile(arg) + out, err = os.ReadFile(arg) if err != nil { return } diff --git a/infra/conf/geodata/memconservative/cache.go b/infra/conf/geodata/memconservative/cache.go index 386086cb7f..307db9d689 100644 --- a/infra/conf/geodata/memconservative/cache.go +++ b/infra/conf/geodata/memconservative/cache.go @@ -1,7 +1,7 @@ package memconservative import ( - "io/ioutil" + "os" "strings" "google.golang.org/protobuf/proto" @@ -53,7 +53,7 @@ func (g GeoIPCache) Unmarshal(filename, code string) (*routercommon.GeoIP, error case errFailedToReadBytes, errFailedToReadExpectedLenBytes, errInvalidGeodataFile, errInvalidGeodataVarintLength: newError("failed to decode geoip file: ", filename, ", fallback to the original ReadFile method") - geoipBytes, err = ioutil.ReadFile(asset) + geoipBytes, err = os.ReadFile(asset) if err != nil { return nil, err } @@ -118,7 +118,7 @@ func (g GeoSiteCache) Unmarshal(filename, code string) (*routercommon.GeoSite, e case errFailedToReadBytes, errFailedToReadExpectedLenBytes, errInvalidGeodataFile, errInvalidGeodataVarintLength: newError("failed to decode geoip file: ", filename, ", fallback to the original ReadFile method") - geositeBytes, err = ioutil.ReadFile(asset) + geositeBytes, err = os.ReadFile(asset) if err != nil { return nil, err } diff --git a/infra/vprotogen/main.go b/infra/vprotogen/main.go index 5352ba9412..f00cdea7ac 100644 --- a/infra/vprotogen/main.go +++ b/infra/vprotogen/main.go @@ -6,7 +6,6 @@ import ( "fmt" "go/build" "io" - "io/ioutil" "net/http" "os" "os/exec" @@ -48,7 +47,7 @@ func GetRuntimeEnv(key string) (string, error) { } var data []byte var runtimeEnv string - data, readErr := ioutil.ReadFile(file) + data, readErr := os.ReadFile(file) if readErr != nil { return "", readErr } From 55cfdeb32db4f477534fc080075c6503d94373ce Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Tue, 3 Oct 2023 11:27:58 +0800 Subject: [PATCH 06/81] fix deprecated grpc.WithInsecure() --- app/router/command/command_test.go | 15 +++++++++++++-- transport/internet/grpc/dial.go | 6 ++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/app/router/command/command_test.go b/app/router/command/command_test.go index db2a645285..dac3b69b0f 100644 --- a/app/router/command/command_test.go +++ b/app/router/command/command_test.go @@ -9,6 +9,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/test/bufconn" "github.com/v2fly/v2ray-core/v5/app/router" @@ -90,7 +91,13 @@ func TestServiceSubscribeRoutingStats(t *testing.T) { // Client goroutine go func() { defer lis.Close() - conn, err := grpc.DialContext(context.Background(), "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure()) + conn, err := grpc.DialContext( + context.Background(), + "bufnet", + grpc.WithContextDialer(bufDialer), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { errCh <- err return @@ -268,7 +275,11 @@ func TestSerivceTestRoute(t *testing.T) { // Client goroutine go func() { defer lis.Close() - conn, err := grpc.DialContext(context.Background(), "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure()) + conn, err := grpc.DialContext( + context.Background(), + "bufnet", grpc.WithContextDialer(bufDialer), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) if err != nil { errCh <- err } diff --git a/transport/internet/grpc/dial.go b/transport/internet/grpc/dial.go index a07b206bc3..d4ef6c1c10 100644 --- a/transport/internet/grpc/dial.go +++ b/transport/internet/grpc/dial.go @@ -13,6 +13,7 @@ import ( "google.golang.org/grpc/backoff" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" core "github.com/v2fly/v2ray-core/v5" "github.com/v2fly/v2ray-core/v5/common" @@ -48,11 +49,12 @@ func dialgRPC(ctx context.Context, dest net.Destination, streamSettings *interne grpcSettings := streamSettings.ProtocolSettings.(*Config) config := tls.ConfigFromStreamSettings(streamSettings) - dialOption := grpc.WithInsecure() + transportCredentials := insecure.NewCredentials() if config != nil { - dialOption = grpc.WithTransportCredentials(credentials.NewTLS(config.GetTLSConfig())) + transportCredentials = credentials.NewTLS(config.GetTLSConfig()) } + dialOption := grpc.WithTransportCredentials(transportCredentials) conn, canceller, err := getGrpcClient(ctx, dest, dialOption, streamSettings) if err != nil { From 2d4f7f0fe21f80d3c466207a480c1e4b0595312b Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Wed, 4 Oct 2023 01:04:10 +0800 Subject: [PATCH 07/81] use DialEarly and rename conns --- transport/internet/quic/dialer.go | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/transport/internet/quic/dialer.go b/transport/internet/quic/dialer.go index b52dd4a5ec..329d73bcbc 100644 --- a/transport/internet/quic/dialer.go +++ b/transport/internet/quic/dialer.go @@ -41,9 +41,9 @@ func (c *connectionContext) openStream(destAddr net.Addr) (*interConn, error) { } type clientConnections struct { - access sync.Mutex - conns map[net.Destination][]*connectionContext - cleanup *task.Periodic + access sync.Mutex + runningConnections map[net.Destination][]*connectionContext + cleanup *task.Periodic } func isActive(s quic.Connection) bool { @@ -98,20 +98,20 @@ func (s *clientConnections) cleanConnections() error { s.access.Lock() defer s.access.Unlock() - if len(s.conns) == 0 { + if len(s.runningConnections) == 0 { return nil } newConnMap := make(map[net.Destination][]*connectionContext) - for dest, conns := range s.conns { + for dest, conns := range s.runningConnections { conns = removeInactiveConnections(conns) if len(conns) > 0 { newConnMap[dest] = conns } } - s.conns = newConnMap + s.runningConnections = newConnMap return nil } @@ -119,14 +119,14 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl s.access.Lock() defer s.access.Unlock() - if s.conns == nil { - s.conns = make(map[net.Destination][]*connectionContext) + if s.runningConnections == nil { + s.runningConnections = make(map[net.Destination][]*connectionContext) } dest := net.DestinationFromAddr(destAddr) var conns []*connectionContext - if s, found := s.conns[dest]; found { + if s, found := s.runningConnections[dest]; found { conns = s } @@ -162,11 +162,10 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl } tr := quic.Transport{ - Conn: sysConn, - ConnectionIDLength: 12, + Conn: sysConn, } - conn, err := tr.Dial(context.Background(), destAddr, tlsConfig.GetTLSConfig(tls.WithDestination(dest)), quicConfig) + conn, err := tr.DialEarly(context.Background(), destAddr, tlsConfig.GetTLSConfig(tls.WithDestination(dest)), quicConfig) if err != nil { sysConn.Close() return nil, err @@ -176,14 +175,14 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl conn: conn, rawConn: sysConn, } - s.conns[dest] = append(conns, context) + s.runningConnections[dest] = append(conns, context) return context.openStream(destAddr) } var client clientConnections func init() { - client.conns = make(map[net.Destination][]*connectionContext) + client.runningConnections = make(map[net.Destination][]*connectionContext) client.cleanup = &task.Periodic{ Interval: time.Minute, Execute: client.cleanConnections, From e46987d0bff1b60ff66f4a3b66d649bedfff454b Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Wed, 4 Oct 2023 01:47:31 +0800 Subject: [PATCH 08/81] replace quic-go with apernet/quic-go --- app/dns/nameserver_quic.go | 2 +- common/protocol/quic/sniff.go | 2 +- go.mod | 8 +- go.sum | 10 ++ transport/internet/quic/config.pb.go | 173 +++++++++++++++++++++------ transport/internet/quic/config.proto | 8 ++ transport/internet/quic/conn.go | 2 +- transport/internet/quic/dialer.go | 2 +- transport/internet/quic/hub.go | 2 +- 9 files changed, 162 insertions(+), 47 deletions(-) diff --git a/app/dns/nameserver_quic.go b/app/dns/nameserver_quic.go index 28e6922575..ed30afabb7 100644 --- a/app/dns/nameserver_quic.go +++ b/app/dns/nameserver_quic.go @@ -9,7 +9,7 @@ import ( "sync/atomic" "time" - "github.com/quic-go/quic-go" + "github.com/apernet/quic-go" "golang.org/x/net/dns/dnsmessage" "github.com/v2fly/v2ray-core/v5/common" diff --git a/common/protocol/quic/sniff.go b/common/protocol/quic/sniff.go index f8fcd0ba10..1957f5199f 100644 --- a/common/protocol/quic/sniff.go +++ b/common/protocol/quic/sniff.go @@ -7,7 +7,7 @@ import ( "encoding/binary" "io" - "github.com/quic-go/quic-go/quicvarint" + "github.com/apernet/quic-go/quicvarint" "golang.org/x/crypto/hkdf" "github.com/v2fly/v2ray-core/v5/common" diff --git a/go.mod b/go.mod index a2c2255999..f6c8c6a9cc 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.20 require ( github.com/adrg/xdg v0.4.0 + github.com/apernet/quic-go v0.39.1-0.20230930045547-13cecb45baa8 github.com/go-chi/chi/v5 v5.0.8 github.com/go-chi/render v1.0.2 github.com/go-playground/validator/v10 v10.14.1 @@ -16,7 +17,6 @@ require ( github.com/mustafaturan/bus v1.0.2 github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 - github.com/quic-go/quic-go v0.38.1 github.com/refraction-networking/utls v1.5.2 github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb github.com/stretchr/testify v1.8.4 @@ -66,12 +66,14 @@ require ( github.com/pion/sctp v1.8.7 // indirect github.com/pion/transport/v2 v2.2.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect + github.com/quic-go/qtls-go1-20 v0.3.4 // indirect + github.com/quic-go/quic-go v0.37.4 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 // indirect github.com/xtaci/smux v1.5.24 // indirect + go.uber.org/mock v0.3.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect - golang.org/x/mod v0.10.0 // indirect + golang.org/x/mod v0.11.0 // indirect golang.org/x/text v0.12.0 // indirect golang.org/x/tools v0.9.3 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect diff --git a/go.sum b/go.sum index 0f67ee4b39..b08d325afb 100644 --- a/go.sum +++ b/go.sum @@ -25,6 +25,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/apernet/quic-go v0.39.1-0.20230930045547-13cecb45baa8 h1:jZKdY1/SFnt6iRzSBMzaeXmgWKwSsAW2slf/o0+b3bs= +github.com/apernet/quic-go v0.39.1-0.20230930045547-13cecb45baa8/go.mod h1:UwsoszQlzTm+dBDuFEwWBYt46K56WqlFEN0RWLvQ0rE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -264,6 +266,10 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= +github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4= +github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= github.com/refraction-networking/utls v1.5.2 h1:l6diiLbEoRqdQ+/osPDO0z0lTc8O8VZV+p82N+Hi+ws= @@ -339,6 +345,8 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.starlark.net v0.0.0-20230612165344-9532f5667272 h1:2/wtqS591wZyD2OsClsVBKRPEvBsQt/Js+fsCiYhwu8= go.starlark.net v0.0.0-20230612165344-9532f5667272/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 h1:nJAwRlGWZZDOD+6wni9KVUNHMpHko/OnRwsrCYeAzPo= @@ -383,6 +391,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/transport/internet/quic/config.pb.go b/transport/internet/quic/config.pb.go index 77d44ee36f..57432e2f27 100644 --- a/transport/internet/quic/config.pb.go +++ b/transport/internet/quic/config.pb.go @@ -17,20 +17,84 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type Congestion struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + UpMbps uint32 `protobuf:"varint,2,opt,name=up_mbps,json=upMbps,proto3" json:"up_mbps,omitempty"` + DownMbps uint32 `protobuf:"varint,3,opt,name=down_mbps,json=downMbps,proto3" json:"down_mbps,omitempty"` +} + +func (x *Congestion) Reset() { + *x = Congestion{} + if protoimpl.UnsafeEnabled { + mi := &file_transport_internet_quic_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Congestion) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Congestion) ProtoMessage() {} + +func (x *Congestion) ProtoReflect() protoreflect.Message { + mi := &file_transport_internet_quic_config_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Congestion.ProtoReflect.Descriptor instead. +func (*Congestion) Descriptor() ([]byte, []int) { + return file_transport_internet_quic_config_proto_rawDescGZIP(), []int{0} +} + +func (x *Congestion) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Congestion) GetUpMbps() uint32 { + if x != nil { + return x.UpMbps + } + return 0 +} + +func (x *Congestion) GetDownMbps() uint32 { + if x != nil { + return x.DownMbps + } + return 0 +} + type Config struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Security *protocol.SecurityConfig `protobuf:"bytes,2,opt,name=security,proto3" json:"security,omitempty"` - Header *anypb.Any `protobuf:"bytes,3,opt,name=header,proto3" json:"header,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Security *protocol.SecurityConfig `protobuf:"bytes,2,opt,name=security,proto3" json:"security,omitempty"` + Header *anypb.Any `protobuf:"bytes,3,opt,name=header,proto3" json:"header,omitempty"` + Congestion *Congestion `protobuf:"bytes,4,opt,name=congestion,proto3" json:"congestion,omitempty"` } func (x *Config) Reset() { *x = Config{} if protoimpl.UnsafeEnabled { - mi := &file_transport_internet_quic_config_proto_msgTypes[0] + mi := &file_transport_internet_quic_config_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -43,7 +107,7 @@ func (x *Config) String() string { func (*Config) ProtoMessage() {} func (x *Config) ProtoReflect() protoreflect.Message { - mi := &file_transport_internet_quic_config_proto_msgTypes[0] + mi := &file_transport_internet_quic_config_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -56,7 +120,7 @@ func (x *Config) ProtoReflect() protoreflect.Message { // Deprecated: Use Config.ProtoReflect.Descriptor instead. func (*Config) Descriptor() ([]byte, []int) { - return file_transport_internet_quic_config_proto_rawDescGZIP(), []int{0} + return file_transport_internet_quic_config_proto_rawDescGZIP(), []int{1} } func (x *Config) GetKey() string { @@ -80,6 +144,13 @@ func (x *Config) GetHeader() *anypb.Any { return nil } +func (x *Config) GetCongestion() *Congestion { + if x != nil { + return x.Congestion + } + return nil +} + var File_transport_internet_quic_config_proto protoreflect.FileDescriptor var file_transport_internet_quic_config_proto_rawDesc = []byte{ @@ -93,27 +164,37 @@ var file_transport_internet_quic_config_proto_rawDesc = []byte{ 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa7, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x68, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, - 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, - 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x04, 0x71, 0x75, 0x69, 0x63, - 0x42, 0x87, 0x01, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x50, 0x01, 0x5a, 0x36, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, - 0x2f, 0x71, 0x75, 0x69, 0x63, 0xaa, 0x02, 0x22, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, - 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x51, 0x75, 0x69, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x56, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x70, 0x5f, 0x6d, + 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x4d, 0x62, 0x70, + 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xf7, + 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x12, 0x4e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x67, 0x65, + 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, + 0x72, 0x74, 0x12, 0x04, 0x71, 0x75, 0x69, 0x63, 0x42, 0x87, 0x01, 0x0a, 0x26, 0x63, 0x6f, 0x6d, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, + 0x75, 0x69, 0x63, 0x50, 0x01, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, + 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x71, 0x75, 0x69, 0x63, 0xaa, 0x02, 0x22, + 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x51, 0x75, + 0x69, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -128,20 +209,22 @@ func file_transport_internet_quic_config_proto_rawDescGZIP() []byte { return file_transport_internet_quic_config_proto_rawDescData } -var file_transport_internet_quic_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_transport_internet_quic_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_transport_internet_quic_config_proto_goTypes = []interface{}{ - (*Config)(nil), // 0: v2ray.core.transport.internet.quic.Config - (*protocol.SecurityConfig)(nil), // 1: v2ray.core.common.protocol.SecurityConfig - (*anypb.Any)(nil), // 2: google.protobuf.Any + (*Congestion)(nil), // 0: v2ray.core.transport.internet.quic.Congestion + (*Config)(nil), // 1: v2ray.core.transport.internet.quic.Config + (*protocol.SecurityConfig)(nil), // 2: v2ray.core.common.protocol.SecurityConfig + (*anypb.Any)(nil), // 3: google.protobuf.Any } var file_transport_internet_quic_config_proto_depIdxs = []int32{ - 1, // 0: v2ray.core.transport.internet.quic.Config.security:type_name -> v2ray.core.common.protocol.SecurityConfig - 2, // 1: v2ray.core.transport.internet.quic.Config.header:type_name -> google.protobuf.Any - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 2, // 0: v2ray.core.transport.internet.quic.Config.security:type_name -> v2ray.core.common.protocol.SecurityConfig + 3, // 1: v2ray.core.transport.internet.quic.Config.header:type_name -> google.protobuf.Any + 0, // 2: v2ray.core.transport.internet.quic.Config.congestion:type_name -> v2ray.core.transport.internet.quic.Congestion + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_transport_internet_quic_config_proto_init() } @@ -151,6 +234,18 @@ func file_transport_internet_quic_config_proto_init() { } if !protoimpl.UnsafeEnabled { file_transport_internet_quic_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Congestion); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_transport_internet_quic_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Config); i { case 0: return &v.state @@ -169,7 +264,7 @@ func file_transport_internet_quic_config_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_transport_internet_quic_config_proto_rawDesc, NumEnums: 0, - NumMessages: 1, + NumMessages: 2, NumExtensions: 0, NumServices: 0, }, diff --git a/transport/internet/quic/config.proto b/transport/internet/quic/config.proto index 256f8a583d..f3f52931ca 100644 --- a/transport/internet/quic/config.proto +++ b/transport/internet/quic/config.proto @@ -11,6 +11,13 @@ import "common/protocol/headers.proto"; import "common/protoext/extensions.proto"; +message Congestion{ + string type = 1; + + uint32 up_mbps = 2; + uint32 down_mbps = 3; +} + message Config { option (v2ray.core.common.protoext.message_opt).type = "transport"; option (v2ray.core.common.protoext.message_opt).short_name = "quic"; @@ -18,4 +25,5 @@ message Config { string key = 1; v2ray.core.common.protocol.SecurityConfig security = 2; google.protobuf.Any header = 3; + Congestion congestion = 4; } diff --git a/transport/internet/quic/conn.go b/transport/internet/quic/conn.go index 492c24288f..ef3f9ac5ee 100644 --- a/transport/internet/quic/conn.go +++ b/transport/internet/quic/conn.go @@ -7,7 +7,7 @@ import ( "syscall" "time" - "github.com/quic-go/quic-go" + "github.com/apernet/quic-go" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/buf" diff --git a/transport/internet/quic/dialer.go b/transport/internet/quic/dialer.go index 329d73bcbc..90295c007a 100644 --- a/transport/internet/quic/dialer.go +++ b/transport/internet/quic/dialer.go @@ -5,7 +5,7 @@ import ( "sync" "time" - "github.com/quic-go/quic-go" + "github.com/apernet/quic-go" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/net" diff --git a/transport/internet/quic/hub.go b/transport/internet/quic/hub.go index 9a89ba7db0..76ec800d16 100644 --- a/transport/internet/quic/hub.go +++ b/transport/internet/quic/hub.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/quic-go/quic-go" + "github.com/apernet/quic-go" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/net" From b8768ed2c2ecd038b5e690b2f0ea02376c8bca17 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Wed, 4 Oct 2023 01:51:44 +0800 Subject: [PATCH 09/81] go mode tidy --- go.sum | 6 ------ 1 file changed, 6 deletions(-) diff --git a/go.sum b/go.sum index b08d325afb..c3b2be4180 100644 --- a/go.sum +++ b/go.sum @@ -264,14 +264,10 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4= github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= -github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= -github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= github.com/refraction-networking/utls v1.5.2 h1:l6diiLbEoRqdQ+/osPDO0z0lTc8O8VZV+p82N+Hi+ws= github.com/refraction-networking/utls v1.5.2/go.mod h1:SPuDbBmgLGp8s+HLNc83FuavwZCFoMmExj+ltUHiHUw= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= @@ -389,8 +385,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= From 96a1e63a949cd17e26764a2285de1429b9dcbca7 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Wed, 4 Oct 2023 03:04:50 +0800 Subject: [PATCH 10/81] add quic congestion --- transport/internet/quic/config.pb.go | 12 +- transport/internet/quic/config.proto | 4 +- .../internet/quic/congestion/bbr/bandwidth.go | 27 + .../quic/congestion/bbr/bandwidth_sampler.go | 890 +++++++++++++++++ .../quic/congestion/bbr/bbr_sender.go | 935 ++++++++++++++++++ .../internet/quic/congestion/bbr/clock.go | 18 + .../bbr/packet_number_indexed_queue.go | 199 ++++ .../quic/congestion/bbr/ringbuffer.go | 118 +++ .../quic/congestion/bbr/windowed_filter.go | 162 +++ .../internet/quic/congestion/brutal/brutal.go | 148 +++ .../internet/quic/congestion/common/pacer.go | 92 ++ transport/internet/quic/congestion/utils.go | 18 + transport/internet/quic/dialer.go | 11 + 13 files changed, 2626 insertions(+), 8 deletions(-) create mode 100644 transport/internet/quic/congestion/bbr/bandwidth.go create mode 100644 transport/internet/quic/congestion/bbr/bandwidth_sampler.go create mode 100644 transport/internet/quic/congestion/bbr/bbr_sender.go create mode 100644 transport/internet/quic/congestion/bbr/clock.go create mode 100644 transport/internet/quic/congestion/bbr/packet_number_indexed_queue.go create mode 100644 transport/internet/quic/congestion/bbr/ringbuffer.go create mode 100644 transport/internet/quic/congestion/bbr/windowed_filter.go create mode 100644 transport/internet/quic/congestion/brutal/brutal.go create mode 100644 transport/internet/quic/congestion/common/pacer.go create mode 100644 transport/internet/quic/congestion/utils.go diff --git a/transport/internet/quic/config.pb.go b/transport/internet/quic/config.pb.go index 57432e2f27..9a088bb6db 100644 --- a/transport/internet/quic/config.pb.go +++ b/transport/internet/quic/config.pb.go @@ -23,8 +23,8 @@ type Congestion struct { unknownFields protoimpl.UnknownFields Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - UpMbps uint32 `protobuf:"varint,2,opt,name=up_mbps,json=upMbps,proto3" json:"up_mbps,omitempty"` - DownMbps uint32 `protobuf:"varint,3,opt,name=down_mbps,json=downMbps,proto3" json:"down_mbps,omitempty"` + UpMbps uint64 `protobuf:"varint,2,opt,name=up_mbps,json=upMbps,proto3" json:"up_mbps,omitempty"` + DownMbps uint64 `protobuf:"varint,3,opt,name=down_mbps,json=downMbps,proto3" json:"down_mbps,omitempty"` } func (x *Congestion) Reset() { @@ -66,14 +66,14 @@ func (x *Congestion) GetType() string { return "" } -func (x *Congestion) GetUpMbps() uint32 { +func (x *Congestion) GetUpMbps() uint64 { if x != nil { return x.UpMbps } return 0 } -func (x *Congestion) GetDownMbps() uint32 { +func (x *Congestion) GetDownMbps() uint64 { if x != nil { return x.DownMbps } @@ -167,9 +167,9 @@ var file_transport_internet_quic_config_proto_rawDesc = []byte{ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x56, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x70, 0x5f, 0x6d, - 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x4d, 0x62, 0x70, + 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x70, 0x4d, 0x62, 0x70, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xf7, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xf7, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, diff --git a/transport/internet/quic/config.proto b/transport/internet/quic/config.proto index f3f52931ca..8259911b32 100644 --- a/transport/internet/quic/config.proto +++ b/transport/internet/quic/config.proto @@ -14,8 +14,8 @@ import "common/protoext/extensions.proto"; message Congestion{ string type = 1; - uint32 up_mbps = 2; - uint32 down_mbps = 3; + uint64 up_mbps = 2; + uint64 down_mbps = 3; } message Config { diff --git a/transport/internet/quic/congestion/bbr/bandwidth.go b/transport/internet/quic/congestion/bbr/bandwidth.go new file mode 100644 index 0000000000..52deb24965 --- /dev/null +++ b/transport/internet/quic/congestion/bbr/bandwidth.go @@ -0,0 +1,27 @@ +package bbr + +import ( + "math" + "time" + + "github.com/apernet/quic-go/congestion" +) + +const ( + infBandwidth = Bandwidth(math.MaxUint64) +) + +// Bandwidth of a connection +type Bandwidth uint64 + +const ( + // BitsPerSecond is 1 bit per second + BitsPerSecond Bandwidth = 1 + // BytesPerSecond is 1 byte per second + BytesPerSecond = 8 * BitsPerSecond +) + +// BandwidthFromDelta calculates the bandwidth from a number of bytes and a time delta +func BandwidthFromDelta(bytes congestion.ByteCount, delta time.Duration) Bandwidth { + return Bandwidth(bytes) * Bandwidth(time.Second) / Bandwidth(delta) * BytesPerSecond +} diff --git a/transport/internet/quic/congestion/bbr/bandwidth_sampler.go b/transport/internet/quic/congestion/bbr/bandwidth_sampler.go new file mode 100644 index 0000000000..cbc922dab8 --- /dev/null +++ b/transport/internet/quic/congestion/bbr/bandwidth_sampler.go @@ -0,0 +1,890 @@ +package bbr + +import ( + "math" + "time" + + "github.com/apernet/quic-go/congestion" +) + +const ( + infRTT = time.Duration(math.MaxInt64) + defaultConnectionStateMapQueueSize = 256 + defaultCandidatesBufferSize = 256 +) + +type roundTripCount uint64 + +// SendTimeState is a subset of ConnectionStateOnSentPacket which is returned +// to the caller when the packet is acked or lost. +type sendTimeState struct { + // Whether other states in this object is valid. + isValid bool + // Whether the sender is app limited at the time the packet was sent. + // App limited bandwidth sample might be artificially low because the sender + // did not have enough data to send in order to saturate the link. + isAppLimited bool + // Total number of sent bytes at the time the packet was sent. + // Includes the packet itself. + totalBytesSent congestion.ByteCount + // Total number of acked bytes at the time the packet was sent. + totalBytesAcked congestion.ByteCount + // Total number of lost bytes at the time the packet was sent. + totalBytesLost congestion.ByteCount + // Total number of inflight bytes at the time the packet was sent. + // Includes the packet itself. + // It should be equal to |total_bytes_sent| minus the sum of + // |total_bytes_acked|, |total_bytes_lost| and total neutered bytes. + bytesInFlight congestion.ByteCount +} + +func newSendTimeState( + isAppLimited bool, + totalBytesSent congestion.ByteCount, + totalBytesAcked congestion.ByteCount, + totalBytesLost congestion.ByteCount, + bytesInFlight congestion.ByteCount, +) *sendTimeState { + return &sendTimeState{ + isValid: true, + isAppLimited: isAppLimited, + totalBytesSent: totalBytesSent, + totalBytesAcked: totalBytesAcked, + totalBytesLost: totalBytesLost, + bytesInFlight: bytesInFlight, + } +} + +type extraAckedEvent struct { + // The excess bytes acknowlwedged in the time delta for this event. + extraAcked congestion.ByteCount + + // The bytes acknowledged and time delta from the event. + bytesAcked congestion.ByteCount + timeDelta time.Duration + // The round trip of the event. + round roundTripCount +} + +func maxExtraAckedEventFunc(a, b extraAckedEvent) int { + if a.extraAcked > b.extraAcked { + return 1 + } else if a.extraAcked < b.extraAcked { + return -1 + } + return 0 +} + +func MaxBandwidth(a Bandwidth, b Bandwidth) Bandwidth { + if a > b { + return a + } + return b +} + +func MinBandwidth(a Bandwidth, b Bandwidth) Bandwidth { + if a < b { + return a + } + return b +} + +// BandwidthSample +type bandwidthSample struct { + // The bandwidth at that particular sample. Zero if no valid bandwidth sample + // is available. + bandwidth Bandwidth + // The RTT measurement at this particular sample. Zero if no RTT sample is + // available. Does not correct for delayed ack time. + rtt time.Duration + // |send_rate| is computed from the current packet being acked('P') and an + // earlier packet that is acked before P was sent. + sendRate Bandwidth + // States captured when the packet was sent. + stateAtSend sendTimeState +} + +func newBandwidthSample() *bandwidthSample { + return &bandwidthSample{ + sendRate: infBandwidth, + } +} + +// MaxAckHeightTracker is part of the BandwidthSampler. It is called after every +// ack event to keep track the degree of ack aggregation(a.k.a "ack height"). +type maxAckHeightTracker struct { + // Tracks the maximum number of bytes acked faster than the estimated + // bandwidth. + maxAckHeightFilter *WindowedFilter[extraAckedEvent, roundTripCount] + // The time this aggregation started and the number of bytes acked during it. + aggregationEpochStartTime time.Time + aggregationEpochBytes congestion.ByteCount + // The last sent packet number before the current aggregation epoch started. + lastSentPacketNumberBeforeEpoch congestion.PacketNumber + // The number of ack aggregation epochs ever started, including the ongoing + // one. Stats only. + numAckAggregationEpochs uint64 + ackAggregationBandwidthThreshold float64 + startNewAggregationEpochAfterFullRound bool + reduceExtraAckedOnBandwidthIncrease bool +} + +func newMaxAckHeightTracker(windowLength roundTripCount) *maxAckHeightTracker { + return &maxAckHeightTracker{ + maxAckHeightFilter: NewWindowedFilter(windowLength, maxExtraAckedEventFunc), + lastSentPacketNumberBeforeEpoch: invalidPacketNumber, + ackAggregationBandwidthThreshold: 1.0, + } +} + +func (m *maxAckHeightTracker) Get() congestion.ByteCount { + return m.maxAckHeightFilter.GetBest().extraAcked +} + +func (m *maxAckHeightTracker) Update( + bandwidthEstimate Bandwidth, + isNewMaxBandwidth bool, + roundTripCount roundTripCount, + lastSentPacketNumber congestion.PacketNumber, + lastAckedPacketNumber congestion.PacketNumber, + ackTime time.Time, + bytesAcked congestion.ByteCount, +) congestion.ByteCount { + forceNewEpoch := false + + if m.reduceExtraAckedOnBandwidthIncrease && isNewMaxBandwidth { + // Save and clear existing entries. + best := m.maxAckHeightFilter.GetBest() + secondBest := m.maxAckHeightFilter.GetSecondBest() + thirdBest := m.maxAckHeightFilter.GetThirdBest() + m.maxAckHeightFilter.Clear() + + // Reinsert the heights into the filter after recalculating. + expectedBytesAcked := bytesFromBandwidthAndTimeDelta(bandwidthEstimate, best.timeDelta) + if expectedBytesAcked < best.bytesAcked { + best.extraAcked = best.bytesAcked - expectedBytesAcked + m.maxAckHeightFilter.Update(best, best.round) + } + expectedBytesAcked = bytesFromBandwidthAndTimeDelta(bandwidthEstimate, secondBest.timeDelta) + if expectedBytesAcked < secondBest.bytesAcked { + secondBest.extraAcked = secondBest.bytesAcked - expectedBytesAcked + m.maxAckHeightFilter.Update(secondBest, secondBest.round) + } + expectedBytesAcked = bytesFromBandwidthAndTimeDelta(bandwidthEstimate, thirdBest.timeDelta) + if expectedBytesAcked < thirdBest.bytesAcked { + thirdBest.extraAcked = thirdBest.bytesAcked - expectedBytesAcked + m.maxAckHeightFilter.Update(thirdBest, thirdBest.round) + } + } + + // If any packet sent after the start of the epoch has been acked, start a new + // epoch. + if m.startNewAggregationEpochAfterFullRound && + m.lastSentPacketNumberBeforeEpoch != invalidPacketNumber && + lastAckedPacketNumber != invalidPacketNumber && + lastAckedPacketNumber > m.lastSentPacketNumberBeforeEpoch { + forceNewEpoch = true + } + if m.aggregationEpochStartTime.IsZero() || forceNewEpoch { + m.aggregationEpochBytes = bytesAcked + m.aggregationEpochStartTime = ackTime + m.lastSentPacketNumberBeforeEpoch = lastSentPacketNumber + m.numAckAggregationEpochs++ + return 0 + } + + // Compute how many bytes are expected to be delivered, assuming max bandwidth + // is correct. + aggregationDelta := ackTime.Sub(m.aggregationEpochStartTime) + expectedBytesAcked := bytesFromBandwidthAndTimeDelta(bandwidthEstimate, aggregationDelta) + // Reset the current aggregation epoch as soon as the ack arrival rate is less + // than or equal to the max bandwidth. + if m.aggregationEpochBytes <= congestion.ByteCount(m.ackAggregationBandwidthThreshold*float64(expectedBytesAcked)) { + // Reset to start measuring a new aggregation epoch. + m.aggregationEpochBytes = bytesAcked + m.aggregationEpochStartTime = ackTime + m.lastSentPacketNumberBeforeEpoch = lastSentPacketNumber + m.numAckAggregationEpochs++ + return 0 + } + + m.aggregationEpochBytes += bytesAcked + + // Compute how many extra bytes were delivered vs max bandwidth. + extraBytesAcked := m.aggregationEpochBytes - expectedBytesAcked + newEvent := extraAckedEvent{ + extraAcked: expectedBytesAcked, + bytesAcked: m.aggregationEpochBytes, + timeDelta: aggregationDelta, + } + m.maxAckHeightFilter.Update(newEvent, roundTripCount) + return extraBytesAcked +} + +func (m *maxAckHeightTracker) SetFilterWindowLength(length roundTripCount) { + m.maxAckHeightFilter.SetWindowLength(length) +} + +func (m *maxAckHeightTracker) Reset(newHeight congestion.ByteCount, newTime roundTripCount) { + newEvent := extraAckedEvent{ + extraAcked: newHeight, + round: newTime, + } + m.maxAckHeightFilter.Reset(newEvent, newTime) +} + +func (m *maxAckHeightTracker) SetAckAggregationBandwidthThreshold(threshold float64) { + m.ackAggregationBandwidthThreshold = threshold +} + +func (m *maxAckHeightTracker) SetStartNewAggregationEpochAfterFullRound(value bool) { + m.startNewAggregationEpochAfterFullRound = value +} + +func (m *maxAckHeightTracker) SetReduceExtraAckedOnBandwidthIncrease(value bool) { + m.reduceExtraAckedOnBandwidthIncrease = value +} + +func (m *maxAckHeightTracker) AckAggregationBandwidthThreshold() float64 { + return m.ackAggregationBandwidthThreshold +} + +func (m *maxAckHeightTracker) NumAckAggregationEpochs() uint64 { + return m.numAckAggregationEpochs +} + +// AckPoint represents a point on the ack line. +type ackPoint struct { + ackTime time.Time + totalBytesAcked congestion.ByteCount +} + +// RecentAckPoints maintains the most recent 2 ack points at distinct times. +type recentAckPoints struct { + ackPoints [2]ackPoint +} + +func (r *recentAckPoints) Update(ackTime time.Time, totalBytesAcked congestion.ByteCount) { + if ackTime.Before(r.ackPoints[1].ackTime) { + r.ackPoints[1].ackTime = ackTime + } else if ackTime.After(r.ackPoints[1].ackTime) { + r.ackPoints[0] = r.ackPoints[1] + r.ackPoints[1].ackTime = ackTime + } + + r.ackPoints[1].totalBytesAcked = totalBytesAcked +} + +func (r *recentAckPoints) Clear() { + r.ackPoints[0] = ackPoint{} + r.ackPoints[1] = ackPoint{} +} + +func (r *recentAckPoints) MostRecentPoint() *ackPoint { + return &r.ackPoints[1] +} + +func (r *recentAckPoints) LessRecentPoint() *ackPoint { + if r.ackPoints[0].totalBytesAcked != 0 { + return &r.ackPoints[0] + } + + return &r.ackPoints[1] +} + +// ConnectionStateOnSentPacket represents the information about a sent packet +// and the state of the connection at the moment the packet was sent, +// specifically the information about the most recently acknowledged packet at +// that moment. +type connectionStateOnSentPacket struct { + // Time at which the packet is sent. + sentTime time.Time + // Size of the packet. + size congestion.ByteCount + // The value of |totalBytesSentAtLastAckedPacket| at the time the + // packet was sent. + totalBytesSentAtLastAckedPacket congestion.ByteCount + // The value of |lastAckedPacketSentTime| at the time the packet was + // sent. + lastAckedPacketSentTime time.Time + // The value of |lastAckedPacketAckTime| at the time the packet was + // sent. + lastAckedPacketAckTime time.Time + // Send time states that are returned to the congestion controller when the + // packet is acked or lost. + sendTimeState sendTimeState +} + +// Snapshot constructor. Records the current state of the bandwidth +// sampler. +// |bytes_in_flight| is the bytes in flight right after the packet is sent. +func newConnectionStateOnSentPacket( + sentTime time.Time, + size congestion.ByteCount, + bytesInFlight congestion.ByteCount, + sampler *bandwidthSampler, +) *connectionStateOnSentPacket { + return &connectionStateOnSentPacket{ + sentTime: sentTime, + size: size, + totalBytesSentAtLastAckedPacket: sampler.totalBytesSentAtLastAckedPacket, + lastAckedPacketSentTime: sampler.lastAckedPacketSentTime, + lastAckedPacketAckTime: sampler.lastAckedPacketAckTime, + sendTimeState: *newSendTimeState( + sampler.isAppLimited, + sampler.totalBytesSent, + sampler.totalBytesAcked, + sampler.totalBytesLost, + bytesInFlight, + ), + } +} + +// BandwidthSampler keeps track of sent and acknowledged packets and outputs a +// bandwidth sample for every packet acknowledged. The samples are taken for +// individual packets, and are not filtered; the consumer has to filter the +// bandwidth samples itself. In certain cases, the sampler will locally severely +// underestimate the bandwidth, hence a maximum filter with a size of at least +// one RTT is recommended. +// +// This class bases its samples on the slope of two curves: the number of bytes +// sent over time, and the number of bytes acknowledged as received over time. +// It produces a sample of both slopes for every packet that gets acknowledged, +// based on a slope between two points on each of the corresponding curves. Note +// that due to the packet loss, the number of bytes on each curve might get +// further and further away from each other, meaning that it is not feasible to +// compare byte values coming from different curves with each other. +// +// The obvious points for measuring slope sample are the ones corresponding to +// the packet that was just acknowledged. Let us denote them as S_1 (point at +// which the current packet was sent) and A_1 (point at which the current packet +// was acknowledged). However, taking a slope requires two points on each line, +// so estimating bandwidth requires picking a packet in the past with respect to +// which the slope is measured. +// +// For that purpose, BandwidthSampler always keeps track of the most recently +// acknowledged packet, and records it together with every outgoing packet. +// When a packet gets acknowledged (A_1), it has not only information about when +// it itself was sent (S_1), but also the information about the latest +// acknowledged packet right before it was sent (S_0 and A_0). +// +// Based on that data, send and ack rate are estimated as: +// +// send_rate = (bytes(S_1) - bytes(S_0)) / (time(S_1) - time(S_0)) +// ack_rate = (bytes(A_1) - bytes(A_0)) / (time(A_1) - time(A_0)) +// +// Here, the ack rate is intuitively the rate we want to treat as bandwidth. +// However, in certain cases (e.g. ack compression) the ack rate at a point may +// end up higher than the rate at which the data was originally sent, which is +// not indicative of the real bandwidth. Hence, we use the send rate as an upper +// bound, and the sample value is +// +// rate_sample = min(send_rate, ack_rate) +// +// An important edge case handled by the sampler is tracking the app-limited +// samples. There are multiple meaning of "app-limited" used interchangeably, +// hence it is important to understand and to be able to distinguish between +// them. +// +// Meaning 1: connection state. The connection is said to be app-limited when +// there is no outstanding data to send. This means that certain bandwidth +// samples in the future would not be an accurate indication of the link +// capacity, and it is important to inform consumer about that. Whenever +// connection becomes app-limited, the sampler is notified via OnAppLimited() +// method. +// +// Meaning 2: a phase in the bandwidth sampler. As soon as the bandwidth +// sampler becomes notified about the connection being app-limited, it enters +// app-limited phase. In that phase, all *sent* packets are marked as +// app-limited. Note that the connection itself does not have to be +// app-limited during the app-limited phase, and in fact it will not be +// (otherwise how would it send packets?). The boolean flag below indicates +// whether the sampler is in that phase. +// +// Meaning 3: a flag on the sent packet and on the sample. If a sent packet is +// sent during the app-limited phase, the resulting sample related to the +// packet will be marked as app-limited. +// +// With the terminology issue out of the way, let us consider the question of +// what kind of situation it addresses. +// +// Consider a scenario where we first send packets 1 to 20 at a regular +// bandwidth, and then immediately run out of data. After a few seconds, we send +// packets 21 to 60, and only receive ack for 21 between sending packets 40 and +// 41. In this case, when we sample bandwidth for packets 21 to 40, the S_0/A_0 +// we use to compute the slope is going to be packet 20, a few seconds apart +// from the current packet, hence the resulting estimate would be extremely low +// and not indicative of anything. Only at packet 41 the S_0/A_0 will become 21, +// meaning that the bandwidth sample would exclude the quiescence. +// +// Based on the analysis of that scenario, we implement the following rule: once +// OnAppLimited() is called, all sent packets will produce app-limited samples +// up until an ack for a packet that was sent after OnAppLimited() was called. +// Note that while the scenario above is not the only scenario when the +// connection is app-limited, the approach works in other cases too. + +type congestionEventSample struct { + // The maximum bandwidth sample from all acked packets. + // QuicBandwidth::Zero() if no samples are available. + sampleMaxBandwidth Bandwidth + // Whether |sample_max_bandwidth| is from a app-limited sample. + sampleIsAppLimited bool + // The minimum rtt sample from all acked packets. + // QuicTime::Delta::Infinite() if no samples are available. + sampleRtt time.Duration + // For each packet p in acked packets, this is the max value of INFLIGHT(p), + // where INFLIGHT(p) is the number of bytes acked while p is inflight. + sampleMaxInflight congestion.ByteCount + // The send state of the largest packet in acked_packets, unless it is + // empty. If acked_packets is empty, it's the send state of the largest + // packet in lost_packets. + lastPacketSendState sendTimeState + // The number of extra bytes acked from this ack event, compared to what is + // expected from the flow's bandwidth. Larger value means more ack + // aggregation. + extraAcked congestion.ByteCount +} + +func newCongestionEventSample() *congestionEventSample { + return &congestionEventSample{ + sampleRtt: infRTT, + } +} + +type bandwidthSampler struct { + // The total number of congestion controlled bytes sent during the connection. + totalBytesSent congestion.ByteCount + + // The total number of congestion controlled bytes which were acknowledged. + totalBytesAcked congestion.ByteCount + + // The total number of congestion controlled bytes which were lost. + totalBytesLost congestion.ByteCount + + // The total number of congestion controlled bytes which have been neutered. + totalBytesNeutered congestion.ByteCount + + // The value of |total_bytes_sent_| at the time the last acknowledged packet + // was sent. Valid only when |last_acked_packet_sent_time_| is valid. + totalBytesSentAtLastAckedPacket congestion.ByteCount + + // The time at which the last acknowledged packet was sent. Set to + // QuicTime::Zero() if no valid timestamp is available. + lastAckedPacketSentTime time.Time + + // The time at which the most recent packet was acknowledged. + lastAckedPacketAckTime time.Time + + // The most recently sent packet. + lastSentPacket congestion.PacketNumber + + // The most recently acked packet. + lastAckedPacket congestion.PacketNumber + + // Indicates whether the bandwidth sampler is currently in an app-limited + // phase. + isAppLimited bool + + // The packet that will be acknowledged after this one will cause the sampler + // to exit the app-limited phase. + endOfAppLimitedPhase congestion.PacketNumber + + // Record of the connection state at the point where each packet in flight was + // sent, indexed by the packet number. + connectionStateMap *packetNumberIndexedQueue[connectionStateOnSentPacket] + + recentAckPoints recentAckPoints + a0Candidates RingBuffer[ackPoint] + + // Maximum number of tracked packets. + maxTrackedPackets congestion.ByteCount + + maxAckHeightTracker *maxAckHeightTracker + totalBytesAckedAfterLastAckEvent congestion.ByteCount + + // True if connection option 'BSAO' is set. + overestimateAvoidance bool + + // True if connection option 'BBRB' is set. + limitMaxAckHeightTrackerBySendRate bool +} + +func newBandwidthSampler(maxAckHeightTrackerWindowLength roundTripCount) *bandwidthSampler { + b := &bandwidthSampler{ + maxAckHeightTracker: newMaxAckHeightTracker(maxAckHeightTrackerWindowLength), + connectionStateMap: newPacketNumberIndexedQueue[connectionStateOnSentPacket](defaultConnectionStateMapQueueSize), + lastSentPacket: invalidPacketNumber, + lastAckedPacket: invalidPacketNumber, + endOfAppLimitedPhase: invalidPacketNumber, + } + + b.a0Candidates.Init(defaultCandidatesBufferSize) + + return b +} + +func (b *bandwidthSampler) MaxAckHeight() congestion.ByteCount { + return b.maxAckHeightTracker.Get() +} + +func (b *bandwidthSampler) NumAckAggregationEpochs() uint64 { + return b.maxAckHeightTracker.NumAckAggregationEpochs() +} + +func (b *bandwidthSampler) SetMaxAckHeightTrackerWindowLength(length roundTripCount) { + b.maxAckHeightTracker.SetFilterWindowLength(length) +} + +func (b *bandwidthSampler) ResetMaxAckHeightTracker(newHeight congestion.ByteCount, newTime roundTripCount) { + b.maxAckHeightTracker.Reset(newHeight, newTime) +} + +func (b *bandwidthSampler) SetStartNewAggregationEpochAfterFullRound(value bool) { + b.maxAckHeightTracker.SetStartNewAggregationEpochAfterFullRound(value) +} + +func (b *bandwidthSampler) SetLimitMaxAckHeightTrackerBySendRate(value bool) { + b.limitMaxAckHeightTrackerBySendRate = value +} + +func (b *bandwidthSampler) SetReduceExtraAckedOnBandwidthIncrease(value bool) { + b.maxAckHeightTracker.SetReduceExtraAckedOnBandwidthIncrease(value) +} + +func (b *bandwidthSampler) EnableOverestimateAvoidance() { + if b.overestimateAvoidance { + return + } + + b.overestimateAvoidance = true + b.maxAckHeightTracker.SetAckAggregationBandwidthThreshold(2.0) +} + +func (b *bandwidthSampler) IsOverestimateAvoidanceEnabled() bool { + return b.overestimateAvoidance +} + +func (b *bandwidthSampler) OnPacketSent( + sentTime time.Time, + packetNumber congestion.PacketNumber, + bytes congestion.ByteCount, + bytesInFlight congestion.ByteCount, + isRetransmittable bool, +) { + b.lastSentPacket = packetNumber + + if !isRetransmittable { + return + } + + b.totalBytesSent += bytes + + // If there are no packets in flight, the time at which the new transmission + // opens can be treated as the A_0 point for the purpose of bandwidth + // sampling. This underestimates bandwidth to some extent, and produces some + // artificially low samples for most packets in flight, but it provides with + // samples at important points where we would not have them otherwise, most + // importantly at the beginning of the connection. + if bytesInFlight == 0 { + b.lastAckedPacketAckTime = sentTime + if b.overestimateAvoidance { + b.recentAckPoints.Clear() + b.recentAckPoints.Update(sentTime, b.totalBytesAcked) + b.a0Candidates.Clear() + b.a0Candidates.PushBack(*b.recentAckPoints.MostRecentPoint()) + } + b.totalBytesSentAtLastAckedPacket = b.totalBytesSent + + // In this situation ack compression is not a concern, set send rate to + // effectively infinite. + b.lastAckedPacketSentTime = sentTime + } + + b.connectionStateMap.Emplace(packetNumber, newConnectionStateOnSentPacket( + sentTime, + bytes, + bytesInFlight+bytes, + b, + )) +} + +func (b *bandwidthSampler) OnCongestionEvent( + ackTime time.Time, + ackedPackets []congestion.AckedPacketInfo, + lostPackets []congestion.LostPacketInfo, + maxBandwidth Bandwidth, + estBandwidthUpperBound Bandwidth, + roundTripCount roundTripCount, +) congestionEventSample { + eventSample := newCongestionEventSample() + + var lastLostPacketSendState sendTimeState + + for _, p := range lostPackets { + sendState := b.OnPacketLost(p.PacketNumber, p.BytesLost) + if sendState.isValid { + lastLostPacketSendState = sendState + } + } + + if len(ackedPackets) == 0 { + // Only populate send state for a loss-only event. + eventSample.lastPacketSendState = lastLostPacketSendState + return *eventSample + } + + var lastAckedPacketSendState sendTimeState + var maxSendRate Bandwidth + + for _, p := range ackedPackets { + sample := b.onPacketAcknowledged(ackTime, p.PacketNumber) + if !sample.stateAtSend.isValid { + continue + } + + lastAckedPacketSendState = sample.stateAtSend + + if sample.rtt != 0 { + if eventSample.sampleRtt > sample.rtt { + eventSample.sampleRtt = sample.rtt + } + } + if sample.bandwidth > eventSample.sampleMaxBandwidth { + eventSample.sampleMaxBandwidth = sample.bandwidth + eventSample.sampleIsAppLimited = sample.stateAtSend.isAppLimited + } + if sample.sendRate != infBandwidth { + maxSendRate = MaxBandwidth(maxSendRate, sample.sendRate) + } + inflightSample := b.totalBytesAcked - lastAckedPacketSendState.totalBytesAcked + if inflightSample > eventSample.sampleMaxInflight { + eventSample.sampleMaxInflight = inflightSample + } + } + + if !lastLostPacketSendState.isValid { + eventSample.lastPacketSendState = lastAckedPacketSendState + } else if !lastAckedPacketSendState.isValid { + eventSample.lastPacketSendState = lastLostPacketSendState + } else { + // If two packets are inflight and an alarm is armed to lose a packet and it + // wakes up late, then the first of two in flight packets could have been + // acknowledged before the wakeup, which re-evaluates loss detection, and + // could declare the later of the two lost. + if lostPackets[len(lostPackets)-1].PacketNumber > ackedPackets[len(ackedPackets)-1].PacketNumber { + eventSample.lastPacketSendState = lastLostPacketSendState + } else { + eventSample.lastPacketSendState = lastAckedPacketSendState + } + } + + isNewMaxBandwidth := eventSample.sampleMaxBandwidth > maxBandwidth + maxBandwidth = MaxBandwidth(maxBandwidth, eventSample.sampleMaxBandwidth) + if b.limitMaxAckHeightTrackerBySendRate { + maxBandwidth = MaxBandwidth(maxBandwidth, maxSendRate) + } + + eventSample.extraAcked = b.onAckEventEnd(MinBandwidth(estBandwidthUpperBound, maxBandwidth), isNewMaxBandwidth, roundTripCount) + + return *eventSample +} + +func (b *bandwidthSampler) OnPacketLost(packetNumber congestion.PacketNumber, bytesLost congestion.ByteCount) (s sendTimeState) { + b.totalBytesLost += bytesLost + if sentPacketPointer := b.connectionStateMap.GetEntry(packetNumber); sentPacketPointer != nil { + sentPacketToSendTimeState(sentPacketPointer, &s) + } + return s +} + +func (b *bandwidthSampler) OnPacketNeutered(packetNumber congestion.PacketNumber) { + b.connectionStateMap.Remove(packetNumber, func(sentPacket connectionStateOnSentPacket) { + b.totalBytesNeutered += sentPacket.size + }) +} + +func (b *bandwidthSampler) OnAppLimited() { + b.isAppLimited = true + b.endOfAppLimitedPhase = b.lastSentPacket +} + +func (b *bandwidthSampler) RemoveObsoletePackets(leastUnacked congestion.PacketNumber) { + // A packet can become obsolete when it is removed from QuicUnackedPacketMap's + // view of inflight before it is acked or marked as lost. For example, when + // QuicSentPacketManager::RetransmitCryptoPackets retransmits a crypto packet, + // the packet is removed from QuicUnackedPacketMap's inflight, but is not + // marked as acked or lost in the BandwidthSampler. + b.connectionStateMap.RemoveUpTo(leastUnacked) +} + +func (b *bandwidthSampler) TotalBytesSent() congestion.ByteCount { + return b.totalBytesSent +} + +func (b *bandwidthSampler) TotalBytesLost() congestion.ByteCount { + return b.totalBytesLost +} + +func (b *bandwidthSampler) TotalBytesAcked() congestion.ByteCount { + return b.totalBytesAcked +} + +func (b *bandwidthSampler) TotalBytesNeutered() congestion.ByteCount { + return b.totalBytesNeutered +} + +func (b *bandwidthSampler) IsAppLimited() bool { + return b.isAppLimited +} + +func (b *bandwidthSampler) EndOfAppLimitedPhase() congestion.PacketNumber { + return b.endOfAppLimitedPhase +} + +func (b *bandwidthSampler) max_ack_height() congestion.ByteCount { + return b.maxAckHeightTracker.Get() +} + +func (b *bandwidthSampler) chooseA0Point(totalBytesAcked congestion.ByteCount, a0 *ackPoint) bool { + if b.a0Candidates.Empty() { + return false + } + + if b.a0Candidates.Len() == 1 { + *a0 = *b.a0Candidates.Front() + return true + } + + for i := 1; i < b.a0Candidates.Len(); i++ { + if b.a0Candidates.Offset(i).totalBytesAcked > totalBytesAcked { + *a0 = *b.a0Candidates.Offset(i - 1) + if i > 1 { + for j := 0; j < i-1; j++ { + b.a0Candidates.PopFront() + } + } + return true + } + } + + *a0 = *b.a0Candidates.Back() + for k := 0; k < b.a0Candidates.Len()-1; k++ { + b.a0Candidates.PopFront() + } + return true +} + +func (b *bandwidthSampler) onPacketAcknowledged(ackTime time.Time, packetNumber congestion.PacketNumber) bandwidthSample { + sample := newBandwidthSample() + b.lastAckedPacket = packetNumber + sentPacketPointer := b.connectionStateMap.GetEntry(packetNumber) + if sentPacketPointer == nil { + return *sample + } + + // OnPacketAcknowledgedInner + b.totalBytesAcked += sentPacketPointer.size + b.totalBytesSentAtLastAckedPacket = sentPacketPointer.sendTimeState.totalBytesSent + b.lastAckedPacketSentTime = sentPacketPointer.sentTime + b.lastAckedPacketAckTime = ackTime + if b.overestimateAvoidance { + b.recentAckPoints.Update(ackTime, b.totalBytesAcked) + } + + if b.isAppLimited { + // Exit app-limited phase in two cases: + // (1) end_of_app_limited_phase_ is not initialized, i.e., so far all + // packets are sent while there are buffered packets or pending data. + // (2) The current acked packet is after the sent packet marked as the end + // of the app limit phase. + if b.endOfAppLimitedPhase == invalidPacketNumber || + packetNumber > b.endOfAppLimitedPhase { + b.isAppLimited = false + } + } + + // There might have been no packets acknowledged at the moment when the + // current packet was sent. In that case, there is no bandwidth sample to + // make. + if sentPacketPointer.lastAckedPacketSentTime.IsZero() { + return *sample + } + + // Infinite rate indicates that the sampler is supposed to discard the + // current send rate sample and use only the ack rate. + sendRate := infBandwidth + if sentPacketPointer.sentTime.After(sentPacketPointer.lastAckedPacketSentTime) { + sendRate = BandwidthFromDelta( + sentPacketPointer.sendTimeState.totalBytesSent-sentPacketPointer.totalBytesSentAtLastAckedPacket, + sentPacketPointer.sentTime.Sub(sentPacketPointer.lastAckedPacketSentTime)) + } + + var a0 ackPoint + if b.overestimateAvoidance && b.chooseA0Point(sentPacketPointer.sendTimeState.totalBytesAcked, &a0) { + } else { + a0.ackTime = sentPacketPointer.lastAckedPacketAckTime + a0.totalBytesAcked = sentPacketPointer.sendTimeState.totalBytesAcked + } + + // During the slope calculation, ensure that ack time of the current packet is + // always larger than the time of the previous packet, otherwise division by + // zero or integer underflow can occur. + if ackTime.Sub(a0.ackTime) <= 0 { + return *sample + } + + ackRate := BandwidthFromDelta(b.totalBytesAcked-a0.totalBytesAcked, ackTime.Sub(a0.ackTime)) + + sample.bandwidth = MinBandwidth(sendRate, ackRate) + // Note: this sample does not account for delayed acknowledgement time. This + // means that the RTT measurements here can be artificially high, especially + // on low bandwidth connections. + sample.rtt = ackTime.Sub(sentPacketPointer.sentTime) + sample.sendRate = sendRate + sentPacketToSendTimeState(sentPacketPointer, &sample.stateAtSend) + + return *sample +} + +func (b *bandwidthSampler) onAckEventEnd( + bandwidthEstimate Bandwidth, + isNewMaxBandwidth bool, + roundTripCount roundTripCount, +) congestion.ByteCount { + newlyAckedBytes := b.totalBytesAcked - b.totalBytesAckedAfterLastAckEvent + if newlyAckedBytes == 0 { + return 0 + } + b.totalBytesAckedAfterLastAckEvent = b.totalBytesAcked + extraAcked := b.maxAckHeightTracker.Update( + bandwidthEstimate, + isNewMaxBandwidth, + roundTripCount, + b.lastSentPacket, + b.lastAckedPacket, + b.lastAckedPacketAckTime, + newlyAckedBytes) + // If |extra_acked| is zero, i.e. this ack event marks the start of a new ack + // aggregation epoch, save LessRecentPoint, which is the last ack point of the + // previous epoch, as a A0 candidate. + if b.overestimateAvoidance && extraAcked == 0 { + b.a0Candidates.PushBack(*b.recentAckPoints.LessRecentPoint()) + } + return extraAcked +} + +func sentPacketToSendTimeState(sentPacket *connectionStateOnSentPacket, sendTimeState *sendTimeState) { + *sendTimeState = sentPacket.sendTimeState + sendTimeState.isValid = true +} + +// BytesFromBandwidthAndTimeDelta calculates the bytes +// from a bandwidth(bits per second) and a time delta +func bytesFromBandwidthAndTimeDelta(bandwidth Bandwidth, delta time.Duration) congestion.ByteCount { + return (congestion.ByteCount(bandwidth) * congestion.ByteCount(delta)) / + (congestion.ByteCount(time.Second) * 8) +} + +func timeDeltaFromBytesAndBandwidth(bytes congestion.ByteCount, bandwidth Bandwidth) time.Duration { + return time.Duration(bytes*8) * time.Second / time.Duration(bandwidth) +} diff --git a/transport/internet/quic/congestion/bbr/bbr_sender.go b/transport/internet/quic/congestion/bbr/bbr_sender.go new file mode 100644 index 0000000000..be43cd600c --- /dev/null +++ b/transport/internet/quic/congestion/bbr/bbr_sender.go @@ -0,0 +1,935 @@ +package bbr + +import ( + "fmt" + "math/rand" + "net" + "time" + + "github.com/apernet/quic-go/congestion" + + "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/common" +) + +// BbrSender implements BBR congestion control algorithm. BBR aims to estimate +// the current available Bottleneck Bandwidth and RTT (hence the name), and +// regulates the pacing rate and the size of the congestion window based on +// those signals. +// +// BBR relies on pacing in order to function properly. Do not use BBR when +// pacing is disabled. +// + +const ( + invalidPacketNumber = -1 + initialCongestionWindowPackets = 32 + + // Constants based on TCP defaults. + // The minimum CWND to ensure delayed acks don't reduce bandwidth measurements. + // Does not inflate the pacing rate. + defaultMinimumCongestionWindow = 4 * congestion.ByteCount(congestion.InitialPacketSizeIPv4) + + // The gain used for the STARTUP, equal to 2/ln(2). + defaultHighGain = 2.885 + // The newly derived gain for STARTUP, equal to 4 * ln(2) + derivedHighGain = 2.773 + // The newly derived CWND gain for STARTUP, 2. + derivedHighCWNDGain = 2.0 +) + +// The cycle of gains used during the PROBE_BW stage. +var pacingGain = [...]float64{1.25, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0} + +const ( + // The length of the gain cycle. + gainCycleLength = len(pacingGain) + // The size of the bandwidth filter window, in round-trips. + bandwidthWindowSize = gainCycleLength + 2 + + // The time after which the current min_rtt value expires. + minRttExpiry = 10 * time.Second + // The minimum time the connection can spend in PROBE_RTT mode. + probeRttTime = 200 * time.Millisecond + // If the bandwidth does not increase by the factor of |kStartupGrowthTarget| + // within |kRoundTripsWithoutGrowthBeforeExitingStartup| rounds, the connection + // will exit the STARTUP mode. + startupGrowthTarget = 1.25 + roundTripsWithoutGrowthBeforeExitingStartup = int64(3) + + // Flag. + defaultStartupFullLossCount = 8 + quicBbr2DefaultLossThreshold = 0.02 + maxBbrBurstPackets = 3 +) + +type bbrMode int + +const ( + // Startup phase of the connection. + bbrModeStartup = iota + // After achieving the highest possible bandwidth during the startup, lower + // the pacing rate in order to drain the queue. + bbrModeDrain + // Cruising mode. + bbrModeProbeBw + // Temporarily slow down sending in order to empty the buffer and measure + // the real minimum RTT. + bbrModeProbeRtt +) + +// Indicates how the congestion control limits the amount of bytes in flight. +type bbrRecoveryState int + +const ( + // Do not limit. + bbrRecoveryStateNotInRecovery = iota + // Allow an extra outstanding byte for each byte acknowledged. + bbrRecoveryStateConservation + // Allow two extra outstanding bytes for each byte acknowledged (slow + // start). + bbrRecoveryStateGrowth +) + +type bbrSender struct { + rttStats congestion.RTTStatsProvider + clock Clock + pacer *common.Pacer + + mode bbrMode + + // Bandwidth sampler provides BBR with the bandwidth measurements at + // individual points. + sampler *bandwidthSampler + + // The number of the round trips that have occurred during the connection. + roundTripCount roundTripCount + + // The packet number of the most recently sent packet. + lastSentPacket congestion.PacketNumber + // Acknowledgement of any packet after |current_round_trip_end_| will cause + // the round trip counter to advance. + currentRoundTripEnd congestion.PacketNumber + + // Number of congestion events with some losses, in the current round. + numLossEventsInRound uint64 + + // Number of total bytes lost in the current round. + bytesLostInRound congestion.ByteCount + + // The filter that tracks the maximum bandwidth over the multiple recent + // round-trips. + maxBandwidth *WindowedFilter[Bandwidth, roundTripCount] + + // Minimum RTT estimate. Automatically expires within 10 seconds (and + // triggers PROBE_RTT mode) if no new value is sampled during that period. + minRtt time.Duration + // The time at which the current value of |min_rtt_| was assigned. + minRttTimestamp time.Time + + // The maximum allowed number of bytes in flight. + congestionWindow congestion.ByteCount + + // The initial value of the |congestion_window_|. + initialCongestionWindow congestion.ByteCount + + // The largest value the |congestion_window_| can achieve. + maxCongestionWindow congestion.ByteCount + + // The smallest value the |congestion_window_| can achieve. + minCongestionWindow congestion.ByteCount + + // The pacing gain applied during the STARTUP phase. + highGain float64 + + // The CWND gain applied during the STARTUP phase. + highCwndGain float64 + + // The pacing gain applied during the DRAIN phase. + drainGain float64 + + // The current pacing rate of the connection. + pacingRate Bandwidth + + // The gain currently applied to the pacing rate. + pacingGain float64 + // The gain currently applied to the congestion window. + congestionWindowGain float64 + + // The gain used for the congestion window during PROBE_BW. Latched from + // quic_bbr_cwnd_gain flag. + congestionWindowGainConstant float64 + // The number of RTTs to stay in STARTUP mode. Defaults to 3. + numStartupRtts int64 + + // Number of round-trips in PROBE_BW mode, used for determining the current + // pacing gain cycle. + cycleCurrentOffset int + // The time at which the last pacing gain cycle was started. + lastCycleStart time.Time + + // Indicates whether the connection has reached the full bandwidth mode. + isAtFullBandwidth bool + // Number of rounds during which there was no significant bandwidth increase. + roundsWithoutBandwidthGain int64 + // The bandwidth compared to which the increase is measured. + bandwidthAtLastRound Bandwidth + + // Set to true upon exiting quiescence. + exitingQuiescence bool + + // Time at which PROBE_RTT has to be exited. Setting it to zero indicates + // that the time is yet unknown as the number of packets in flight has not + // reached the required value. + exitProbeRttAt time.Time + // Indicates whether a round-trip has passed since PROBE_RTT became active. + probeRttRoundPassed bool + + // Indicates whether the most recent bandwidth sample was marked as + // app-limited. + lastSampleIsAppLimited bool + // Indicates whether any non app-limited samples have been recorded. + hasNoAppLimitedSample bool + + // Current state of recovery. + recoveryState bbrRecoveryState + // Receiving acknowledgement of a packet after |end_recovery_at_| will cause + // BBR to exit the recovery mode. A value above zero indicates at least one + // loss has been detected, so it must not be set back to zero. + endRecoveryAt congestion.PacketNumber + // A window used to limit the number of bytes in flight during loss recovery. + recoveryWindow congestion.ByteCount + // If true, consider all samples in recovery app-limited. + isAppLimitedRecovery bool // not used + + // When true, pace at 1.5x and disable packet conservation in STARTUP. + slowerStartup bool // not used + // When true, disables packet conservation in STARTUP. + rateBasedStartup bool // not used + + // When true, add the most recent ack aggregation measurement during STARTUP. + enableAckAggregationDuringStartup bool + // When true, expire the windowed ack aggregation values in STARTUP when + // bandwidth increases more than 25%. + expireAckAggregationInStartup bool + + // If true, will not exit low gain mode until bytes_in_flight drops below BDP + // or it's time for high gain mode. + drainToTarget bool + + // If true, slow down pacing rate in STARTUP when overshooting is detected. + detectOvershooting bool + // Bytes lost while detect_overshooting_ is true. + bytesLostWhileDetectingOvershooting congestion.ByteCount + // Slow down pacing rate if + // bytes_lost_while_detecting_overshooting_ * + // bytes_lost_multiplier_while_detecting_overshooting_ > IW. + bytesLostMultiplierWhileDetectingOvershooting uint8 + // When overshooting is detected, do not drop pacing_rate_ below this value / + // min_rtt. + cwndToCalculateMinPacingRate congestion.ByteCount + + // Max congestion window when adjusting network parameters. + maxCongestionWindowWithNetworkParametersAdjusted congestion.ByteCount // not used + + // Params. + maxDatagramSize congestion.ByteCount + // Recorded on packet sent. equivalent |unacked_packets_->bytes_in_flight()| + bytesInFlight congestion.ByteCount +} + +var _ congestion.CongestionControl = &bbrSender{} + +func NewBbrSender( + clock Clock, + initialMaxDatagramSize congestion.ByteCount, +) *bbrSender { + return newBbrSender( + clock, + initialMaxDatagramSize, + initialCongestionWindowPackets*initialMaxDatagramSize, + congestion.MaxCongestionWindowPackets*initialMaxDatagramSize, + ) +} + +func newBbrSender( + clock Clock, + initialMaxDatagramSize, + initialCongestionWindow, + initialMaxCongestionWindow congestion.ByteCount, +) *bbrSender { + b := &bbrSender{ + clock: clock, + mode: bbrModeStartup, + sampler: newBandwidthSampler(roundTripCount(bandwidthWindowSize)), + lastSentPacket: invalidPacketNumber, + currentRoundTripEnd: invalidPacketNumber, + maxBandwidth: NewWindowedFilter(roundTripCount(bandwidthWindowSize), MaxFilter[Bandwidth]), + congestionWindow: initialCongestionWindow, + initialCongestionWindow: initialCongestionWindow, + maxCongestionWindow: initialMaxCongestionWindow, + minCongestionWindow: defaultMinimumCongestionWindow, + highGain: defaultHighGain, + highCwndGain: defaultHighGain, + drainGain: 1.0 / defaultHighGain, + pacingGain: 1.0, + congestionWindowGain: 1.0, + congestionWindowGainConstant: 2.0, + numStartupRtts: roundTripsWithoutGrowthBeforeExitingStartup, + recoveryState: bbrRecoveryStateNotInRecovery, + endRecoveryAt: invalidPacketNumber, + recoveryWindow: initialMaxCongestionWindow, + bytesLostMultiplierWhileDetectingOvershooting: 2, + cwndToCalculateMinPacingRate: initialCongestionWindow, + maxCongestionWindowWithNetworkParametersAdjusted: initialMaxCongestionWindow, + maxDatagramSize: initialMaxDatagramSize, + } + b.pacer = common.NewPacer(func() congestion.ByteCount { + // Pacer wants bytes per second, but Bandwidth is in bits per second. + return congestion.ByteCount(float64(b.bandwidthEstimate()) * b.congestionWindowGain / float64(BytesPerSecond)) + }) + + /* + if b.tracer != nil { + b.lastState = logging.CongestionStateStartup + b.tracer.UpdatedCongestionState(logging.CongestionStateStartup) + } + */ + + b.enterStartupMode(b.clock.Now()) + b.setHighCwndGain(derivedHighCWNDGain) + + return b +} + +func (b *bbrSender) SetRTTStatsProvider(provider congestion.RTTStatsProvider) { + b.rttStats = provider +} + +// TimeUntilSend implements the SendAlgorithm interface. +func (b *bbrSender) TimeUntilSend(bytesInFlight congestion.ByteCount) time.Time { + return b.pacer.TimeUntilSend() +} + +// HasPacingBudget implements the SendAlgorithm interface. +func (b *bbrSender) HasPacingBudget(now time.Time) bool { + return b.pacer.Budget(now) >= b.maxDatagramSize +} + +// OnPacketSent implements the SendAlgorithm interface. +func (b *bbrSender) OnPacketSent( + sentTime time.Time, + bytesInFlight congestion.ByteCount, + packetNumber congestion.PacketNumber, + bytes congestion.ByteCount, + isRetransmittable bool, +) { + b.pacer.SentPacket(sentTime, bytes) + + b.lastSentPacket = packetNumber + b.bytesInFlight = bytesInFlight + + if bytesInFlight == 0 { + b.exitingQuiescence = true + } + + b.sampler.OnPacketSent(sentTime, packetNumber, bytes, bytesInFlight, isRetransmittable) +} + +// CanSend implements the SendAlgorithm interface. +func (b *bbrSender) CanSend(bytesInFlight congestion.ByteCount) bool { + return bytesInFlight < b.GetCongestionWindow() +} + +// MaybeExitSlowStart implements the SendAlgorithm interface. +func (b *bbrSender) MaybeExitSlowStart() { + // Do nothing +} + +// OnPacketAcked implements the SendAlgorithm interface. +func (b *bbrSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes, priorInFlight congestion.ByteCount, eventTime time.Time) { + // Do nothing. +} + +// OnPacketLost implements the SendAlgorithm interface. +func (b *bbrSender) OnPacketLost(number congestion.PacketNumber, lostBytes, priorInFlight congestion.ByteCount) { + // Do nothing. +} + +// OnRetransmissionTimeout implements the SendAlgorithm interface. +func (b *bbrSender) OnRetransmissionTimeout(packetsRetransmitted bool) { + // Do nothing. +} + +// SetMaxDatagramSize implements the SendAlgorithm interface. +func (b *bbrSender) SetMaxDatagramSize(s congestion.ByteCount) { + if s < b.maxDatagramSize { + panic(fmt.Sprintf("congestion BUG: decreased max datagram size from %d to %d", b.maxDatagramSize, s)) + } + cwndIsMinCwnd := b.congestionWindow == b.minCongestionWindow + b.maxDatagramSize = s + if cwndIsMinCwnd { + b.congestionWindow = b.minCongestionWindow + } + b.pacer.SetMaxDatagramSize(s) +} + +// InSlowStart implements the SendAlgorithmWithDebugInfos interface. +func (b *bbrSender) InSlowStart() bool { + return b.mode == bbrModeStartup +} + +// InRecovery implements the SendAlgorithmWithDebugInfos interface. +func (b *bbrSender) InRecovery() bool { + return b.recoveryState != bbrRecoveryStateNotInRecovery +} + +// GetCongestionWindow implements the SendAlgorithmWithDebugInfos interface. +func (b *bbrSender) GetCongestionWindow() congestion.ByteCount { + if b.mode == bbrModeProbeRtt { + return b.probeRttCongestionWindow() + } + + if b.InRecovery() { + return common.MinByteCount(b.congestionWindow, b.recoveryWindow) + } + + return b.congestionWindow +} + +func (b *bbrSender) OnCongestionEvent(number congestion.PacketNumber, lostBytes, priorInFlight congestion.ByteCount) { + // Do nothing. +} + +func (b *bbrSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, eventTime time.Time, ackedPackets []congestion.AckedPacketInfo, lostPackets []congestion.LostPacketInfo) { + totalBytesAckedBefore := b.sampler.TotalBytesAcked() + totalBytesLostBefore := b.sampler.TotalBytesLost() + + var isRoundStart, minRttExpired bool + var excessAcked, bytesLost congestion.ByteCount + + // The send state of the largest packet in acked_packets, unless it is + // empty. If acked_packets is empty, it's the send state of the largest + // packet in lost_packets. + var lastPacketSendState sendTimeState + + b.maybeApplimited(priorInFlight) + + // Update bytesInFlight + b.bytesInFlight = priorInFlight + for _, p := range ackedPackets { + b.bytesInFlight -= p.BytesAcked + } + for _, p := range lostPackets { + b.bytesInFlight -= p.BytesLost + } + + if len(ackedPackets) != 0 { + lastAckedPacket := ackedPackets[len(ackedPackets)-1].PacketNumber + isRoundStart = b.updateRoundTripCounter(lastAckedPacket) + b.updateRecoveryState(lastAckedPacket, len(lostPackets) != 0, isRoundStart) + } + + sample := b.sampler.OnCongestionEvent(eventTime, + ackedPackets, lostPackets, b.maxBandwidth.GetBest(), infBandwidth, b.roundTripCount) + if sample.lastPacketSendState.isValid { + b.lastSampleIsAppLimited = sample.lastPacketSendState.isAppLimited + b.hasNoAppLimitedSample = b.hasNoAppLimitedSample || !b.lastSampleIsAppLimited + } + // Avoid updating |max_bandwidth_| if a) this is a loss-only event, or b) all + // packets in |acked_packets| did not generate valid samples. (e.g. ack of + // ack-only packets). In both cases, sampler_.total_bytes_acked() will not + // change. + if totalBytesAckedBefore != b.sampler.TotalBytesAcked() { + if !sample.sampleIsAppLimited || sample.sampleMaxBandwidth > b.maxBandwidth.GetBest() { + b.maxBandwidth.Update(sample.sampleMaxBandwidth, b.roundTripCount) + } + } + + if sample.sampleRtt != infRTT { + minRttExpired = b.maybeUpdateMinRtt(eventTime, sample.sampleRtt) + } + bytesLost = b.sampler.TotalBytesLost() - totalBytesLostBefore + + excessAcked = sample.extraAcked + lastPacketSendState = sample.lastPacketSendState + + if len(lostPackets) != 0 { + b.numLossEventsInRound++ + b.bytesLostInRound += bytesLost + } + + // Handle logic specific to PROBE_BW mode. + if b.mode == bbrModeProbeBw { + b.updateGainCyclePhase(eventTime, priorInFlight, len(lostPackets) != 0) + } + + // Handle logic specific to STARTUP and DRAIN modes. + if isRoundStart && !b.isAtFullBandwidth { + b.checkIfFullBandwidthReached(&lastPacketSendState) + } + + b.maybeExitStartupOrDrain(eventTime) + + // Handle logic specific to PROBE_RTT. + b.maybeEnterOrExitProbeRtt(eventTime, isRoundStart, minRttExpired) + + // Calculate number of packets acked and lost. + bytesAcked := b.sampler.TotalBytesAcked() - totalBytesAckedBefore + + // After the model is updated, recalculate the pacing rate and congestion + // window. + b.calculatePacingRate(bytesLost) + b.calculateCongestionWindow(bytesAcked, excessAcked) + b.calculateRecoveryWindow(bytesAcked, bytesLost) + + // Cleanup internal state. + if len(lostPackets) != 0 { + lastLostPacket := lostPackets[len(lostPackets)-1].PacketNumber + b.sampler.RemoveObsoletePackets(lastLostPacket) + } + if isRoundStart { + b.numLossEventsInRound = 0 + b.bytesLostInRound = 0 + } +} + +func (b *bbrSender) PacingRate() Bandwidth { + if b.pacingRate == 0 { + return Bandwidth(b.highGain * float64( + BandwidthFromDelta(b.initialCongestionWindow, b.getMinRtt()))) + } + + return b.pacingRate +} + +func (b *bbrSender) hasGoodBandwidthEstimateForResumption() bool { + return b.hasNonAppLimitedSample() +} + +func (b *bbrSender) hasNonAppLimitedSample() bool { + return b.hasNoAppLimitedSample +} + +// Sets the pacing gain used in STARTUP. Must be greater than 1. +func (b *bbrSender) setHighGain(highGain float64) { + b.highGain = highGain + if b.mode == bbrModeStartup { + b.pacingGain = highGain + } +} + +// Sets the CWND gain used in STARTUP. Must be greater than 1. +func (b *bbrSender) setHighCwndGain(highCwndGain float64) { + b.highCwndGain = highCwndGain + if b.mode == bbrModeStartup { + b.congestionWindowGain = highCwndGain + } +} + +// Sets the gain used in DRAIN. Must be less than 1. +func (b *bbrSender) setDrainGain(drainGain float64) { + b.drainGain = drainGain +} + +// What's the current estimated bandwidth in bytes per second. +func (b *bbrSender) bandwidthEstimate() Bandwidth { + return b.maxBandwidth.GetBest() +} + +// Returns the current estimate of the RTT of the connection. Outside of the +// edge cases, this is minimum RTT. +func (b *bbrSender) getMinRtt() time.Duration { + if b.minRtt != 0 { + return b.minRtt + } + // min_rtt could be available if the handshake packet gets neutered then + // gets acknowledged. This could only happen for QUIC crypto where we do not + // drop keys. + minRtt := b.rttStats.MinRTT() + if minRtt == 0 { + return 100 * time.Millisecond + } else { + return minRtt + } +} + +// Computes the target congestion window using the specified gain. +func (b *bbrSender) getTargetCongestionWindow(gain float64) congestion.ByteCount { + bdp := bdpFromRttAndBandwidth(b.getMinRtt(), b.bandwidthEstimate()) + congestionWindow := congestion.ByteCount(gain * float64(bdp)) + + // BDP estimate will be zero if no bandwidth samples are available yet. + if congestionWindow == 0 { + congestionWindow = congestion.ByteCount(gain * float64(b.initialCongestionWindow)) + } + + return common.MaxByteCount(congestionWindow, b.minCongestionWindow) +} + +// The target congestion window during PROBE_RTT. +func (b *bbrSender) probeRttCongestionWindow() congestion.ByteCount { + return b.minCongestionWindow +} + +func (b *bbrSender) maybeUpdateMinRtt(now time.Time, sampleMinRtt time.Duration) bool { + // Do not expire min_rtt if none was ever available. + minRttExpired := b.minRtt != 0 && now.After(b.minRttTimestamp.Add(minRttExpiry)) + if minRttExpired || sampleMinRtt < b.minRtt || b.minRtt == 0 { + b.minRtt = sampleMinRtt + b.minRttTimestamp = now + } + + return minRttExpired +} + +// Enters the STARTUP mode. +func (b *bbrSender) enterStartupMode(now time.Time) { + b.mode = bbrModeStartup + // b.maybeTraceStateChange(logging.CongestionStateStartup) + b.pacingGain = b.highGain + b.congestionWindowGain = b.highCwndGain +} + +// Enters the PROBE_BW mode. +func (b *bbrSender) enterProbeBandwidthMode(now time.Time) { + b.mode = bbrModeProbeBw + // b.maybeTraceStateChange(logging.CongestionStateProbeBw) + b.congestionWindowGain = b.congestionWindowGainConstant + + // Pick a random offset for the gain cycle out of {0, 2..7} range. 1 is + // excluded because in that case increased gain and decreased gain would not + // follow each other. + b.cycleCurrentOffset = int(rand.Int31n(congestion.PacketsPerConnectionID)) % (gainCycleLength - 1) + if b.cycleCurrentOffset >= 1 { + b.cycleCurrentOffset += 1 + } + + b.lastCycleStart = now + b.pacingGain = pacingGain[b.cycleCurrentOffset] +} + +// Updates the round-trip counter if a round-trip has passed. Returns true if +// the counter has been advanced. +func (b *bbrSender) updateRoundTripCounter(lastAckedPacket congestion.PacketNumber) bool { + if b.currentRoundTripEnd == invalidPacketNumber || lastAckedPacket > b.currentRoundTripEnd { + b.roundTripCount++ + b.currentRoundTripEnd = b.lastSentPacket + return true + } + return false +} + +// Updates the current gain used in PROBE_BW mode. +func (b *bbrSender) updateGainCyclePhase(now time.Time, priorInFlight congestion.ByteCount, hasLosses bool) { + // In most cases, the cycle is advanced after an RTT passes. + shouldAdvanceGainCycling := now.After(b.lastCycleStart.Add(b.getMinRtt())) + // If the pacing gain is above 1.0, the connection is trying to probe the + // bandwidth by increasing the number of bytes in flight to at least + // pacing_gain * BDP. Make sure that it actually reaches the target, as long + // as there are no losses suggesting that the buffers are not able to hold + // that much. + if b.pacingGain > 1.0 && !hasLosses && priorInFlight < b.getTargetCongestionWindow(b.pacingGain) { + shouldAdvanceGainCycling = false + } + + // If pacing gain is below 1.0, the connection is trying to drain the extra + // queue which could have been incurred by probing prior to it. If the number + // of bytes in flight falls down to the estimated BDP value earlier, conclude + // that the queue has been successfully drained and exit this cycle early. + if b.pacingGain < 1.0 && b.bytesInFlight <= b.getTargetCongestionWindow(1) { + shouldAdvanceGainCycling = true + } + + if shouldAdvanceGainCycling { + b.cycleCurrentOffset = (b.cycleCurrentOffset + 1) % gainCycleLength + b.lastCycleStart = now + // Stay in low gain mode until the target BDP is hit. + // Low gain mode will be exited immediately when the target BDP is achieved. + if b.drainToTarget && b.pacingGain < 1 && + pacingGain[b.cycleCurrentOffset] == 1 && + b.bytesInFlight > b.getTargetCongestionWindow(1) { + return + } + b.pacingGain = pacingGain[b.cycleCurrentOffset] + } +} + +// Tracks for how many round-trips the bandwidth has not increased +// significantly. +func (b *bbrSender) checkIfFullBandwidthReached(lastPacketSendState *sendTimeState) { + if b.lastSampleIsAppLimited { + return + } + + target := Bandwidth(float64(b.bandwidthAtLastRound) * startupGrowthTarget) + if b.bandwidthEstimate() >= target { + b.bandwidthAtLastRound = b.bandwidthEstimate() + b.roundsWithoutBandwidthGain = 0 + if b.expireAckAggregationInStartup { + // Expire old excess delivery measurements now that bandwidth increased. + b.sampler.ResetMaxAckHeightTracker(0, b.roundTripCount) + } + return + } + + b.roundsWithoutBandwidthGain++ + if b.roundsWithoutBandwidthGain >= b.numStartupRtts || + b.shouldExitStartupDueToLoss(lastPacketSendState) { + b.isAtFullBandwidth = true + } +} + +func (b *bbrSender) maybeApplimited(bytesInFlight congestion.ByteCount) { + congestionWindow := b.GetCongestionWindow() + if bytesInFlight >= congestionWindow { + return + } + availableBytes := congestionWindow - bytesInFlight + drainLimited := b.mode == bbrModeDrain && bytesInFlight > congestionWindow/2 + if !drainLimited || availableBytes > maxBbrBurstPackets*b.maxDatagramSize { + b.sampler.OnAppLimited() + } +} + +// Transitions from STARTUP to DRAIN and from DRAIN to PROBE_BW if +// appropriate. +func (b *bbrSender) maybeExitStartupOrDrain(now time.Time) { + if b.mode == bbrModeStartup && b.isAtFullBandwidth { + b.mode = bbrModeDrain + // b.maybeTraceStateChange(logging.CongestionStateDrain) + b.pacingGain = b.drainGain + b.congestionWindowGain = b.highCwndGain + } + if b.mode == bbrModeDrain && b.bytesInFlight <= b.getTargetCongestionWindow(1) { + b.enterProbeBandwidthMode(now) + } +} + +// Decides whether to enter or exit PROBE_RTT. +func (b *bbrSender) maybeEnterOrExitProbeRtt(now time.Time, isRoundStart, minRttExpired bool) { + if minRttExpired && !b.exitingQuiescence && b.mode != bbrModeProbeRtt { + b.mode = bbrModeProbeRtt + // b.maybeTraceStateChange(logging.CongestionStateProbRtt) + b.pacingGain = 1.0 + // Do not decide on the time to exit PROBE_RTT until the |bytes_in_flight| + // is at the target small value. + b.exitProbeRttAt = time.Time{} + } + + if b.mode == bbrModeProbeRtt { + b.sampler.OnAppLimited() + // b.maybeTraceStateChange(logging.CongestionStateApplicationLimited) + + if b.exitProbeRttAt.IsZero() { + // If the window has reached the appropriate size, schedule exiting + // PROBE_RTT. The CWND during PROBE_RTT is kMinimumCongestionWindow, but + // we allow an extra packet since QUIC checks CWND before sending a + // packet. + if b.bytesInFlight < b.probeRttCongestionWindow()+congestion.MaxPacketBufferSize { + b.exitProbeRttAt = now.Add(probeRttTime) + b.probeRttRoundPassed = false + } + } else { + if isRoundStart { + b.probeRttRoundPassed = true + } + if now.Sub(b.exitProbeRttAt) >= 0 && b.probeRttRoundPassed { + b.minRttTimestamp = now + if !b.isAtFullBandwidth { + b.enterStartupMode(now) + } else { + b.enterProbeBandwidthMode(now) + } + } + } + } + + b.exitingQuiescence = false +} + +// Determines whether BBR needs to enter, exit or advance state of the +// recovery. +func (b *bbrSender) updateRecoveryState(lastAckedPacket congestion.PacketNumber, hasLosses, isRoundStart bool) { + // Disable recovery in startup, if loss-based exit is enabled. + if !b.isAtFullBandwidth { + return + } + + // Exit recovery when there are no losses for a round. + if hasLosses { + b.endRecoveryAt = b.lastSentPacket + } + + switch b.recoveryState { + case bbrRecoveryStateNotInRecovery: + if hasLosses { + b.recoveryState = bbrRecoveryStateConservation + // This will cause the |recovery_window_| to be set to the correct + // value in CalculateRecoveryWindow(). + b.recoveryWindow = 0 + // Since the conservation phase is meant to be lasting for a whole + // round, extend the current round as if it were started right now. + b.currentRoundTripEnd = b.lastSentPacket + } + case bbrRecoveryStateConservation: + if isRoundStart { + b.recoveryState = bbrRecoveryStateGrowth + } + fallthrough + case bbrRecoveryStateGrowth: + // Exit recovery if appropriate. + if !hasLosses && lastAckedPacket > b.endRecoveryAt { + b.recoveryState = bbrRecoveryStateNotInRecovery + } + } +} + +// Determines the appropriate pacing rate for the connection. +func (b *bbrSender) calculatePacingRate(bytesLost congestion.ByteCount) { + if b.bandwidthEstimate() == 0 { + return + } + + targetRate := Bandwidth(b.pacingGain * float64(b.bandwidthEstimate())) + if b.isAtFullBandwidth { + b.pacingRate = targetRate + return + } + + // Pace at the rate of initial_window / RTT as soon as RTT measurements are + // available. + if b.pacingRate == 0 && b.rttStats.MinRTT() != 0 { + b.pacingRate = BandwidthFromDelta(b.initialCongestionWindow, b.rttStats.MinRTT()) + return + } + + if b.detectOvershooting { + b.bytesLostWhileDetectingOvershooting += bytesLost + // Check for overshooting with network parameters adjusted when pacing rate + // > target_rate and loss has been detected. + if b.pacingRate > targetRate && b.bytesLostWhileDetectingOvershooting > 0 { + if b.hasNoAppLimitedSample || + b.bytesLostWhileDetectingOvershooting*congestion.ByteCount(b.bytesLostMultiplierWhileDetectingOvershooting) > b.initialCongestionWindow { + // We are fairly sure overshoot happens if 1) there is at least one + // non app-limited bw sample or 2) half of IW gets lost. Slow pacing + // rate. + remoteRate := BandwidthFromDelta(b.cwndToCalculateMinPacingRate, b.rttStats.MinRTT()) + if targetRate > remoteRate { + b.pacingRate = targetRate + } else { + b.pacingRate = remoteRate + } + b.bytesLostWhileDetectingOvershooting = 0 + b.detectOvershooting = false + } + } + } + + // Do not decrease the pacing rate during startup. + if b.pacingRate > targetRate { + b.pacingRate = b.pacingRate + } else { + b.pacingRate = targetRate + } + +} + +// Determines the appropriate congestion window for the connection. +func (b *bbrSender) calculateCongestionWindow(bytesAcked, excessAcked congestion.ByteCount) { + if b.mode == bbrModeProbeRtt { + return + } + + targetWindow := b.getTargetCongestionWindow(b.congestionWindowGain) + if b.isAtFullBandwidth { + // Add the max recently measured ack aggregation to CWND. + targetWindow += b.sampler.MaxAckHeight() + } else if b.enableAckAggregationDuringStartup { + // Add the most recent excess acked. Because CWND never decreases in + // STARTUP, this will automatically create a very localized max filter. + targetWindow += excessAcked + } + + // Instead of immediately setting the target CWND as the new one, BBR grows + // the CWND towards |target_window| by only increasing it |bytes_acked| at a + // time. + if b.isAtFullBandwidth { + b.congestionWindow = common.MinByteCount(targetWindow, b.congestionWindow+bytesAcked) + } else if b.congestionWindow < targetWindow || + b.sampler.TotalBytesAcked() < b.initialCongestionWindow { + // If the connection is not yet out of startup phase, do not decrease the + // window. + b.congestionWindow += bytesAcked + } + + // Enforce the limits on the congestion window. + b.congestionWindow = common.MaxByteCount(b.congestionWindow, b.minCongestionWindow) + b.congestionWindow = common.MinByteCount(b.congestionWindow, b.maxCongestionWindow) +} + +// Determines the appropriate window that constrains the in-flight during recovery. +func (b *bbrSender) calculateRecoveryWindow(bytesAcked, bytesLost congestion.ByteCount) { + if b.recoveryState == bbrRecoveryStateNotInRecovery { + return + } + + // Set up the initial recovery window. + if b.recoveryWindow == 0 { + b.recoveryWindow = b.bytesInFlight + bytesAcked + b.recoveryWindow = common.MaxByteCount(b.minCongestionWindow, b.recoveryWindow) + return + } + + // Remove losses from the recovery window, while accounting for a potential + // integer underflow. + if b.recoveryWindow >= bytesLost { + b.recoveryWindow = b.recoveryWindow - bytesLost + } else { + b.recoveryWindow = b.maxDatagramSize + } + + // In CONSERVATION mode, just subtracting losses is sufficient. In GROWTH, + // release additional |bytes_acked| to achieve a slow-start-like behavior. + if b.recoveryState == bbrRecoveryStateGrowth { + b.recoveryWindow += bytesAcked + } + + // Always allow sending at least |bytes_acked| in response. + b.recoveryWindow = common.MaxByteCount(b.recoveryWindow, b.bytesInFlight+bytesAcked) + b.recoveryWindow = common.MaxByteCount(b.minCongestionWindow, b.recoveryWindow) +} + +// Return whether we should exit STARTUP due to excessive loss. +func (b *bbrSender) shouldExitStartupDueToLoss(lastPacketSendState *sendTimeState) bool { + if b.numLossEventsInRound < defaultStartupFullLossCount || !lastPacketSendState.isValid { + return false + } + + inflightAtSend := lastPacketSendState.bytesInFlight + + if inflightAtSend > 0 && b.bytesLostInRound > 0 { + if b.bytesLostInRound > congestion.ByteCount(float64(inflightAtSend)*quicBbr2DefaultLossThreshold) { + return true + } + return false + } + return false +} + +func bdpFromRttAndBandwidth(rtt time.Duration, bandwidth Bandwidth) congestion.ByteCount { + return congestion.ByteCount(rtt) * congestion.ByteCount(bandwidth) / congestion.ByteCount(BytesPerSecond) / congestion.ByteCount(time.Second) +} + +func GetInitialPacketSize(addr net.Addr) congestion.ByteCount { + // If this is not a UDP address, we don't know anything about the MTU. + // Use the minimum size of an Initial packet as the max packet size. + if udpAddr, ok := addr.(*net.UDPAddr); ok { + if udpAddr.IP.To4() != nil { + return congestion.InitialPacketSizeIPv4 + } else { + return congestion.InitialPacketSizeIPv6 + } + } else { + return congestion.MinInitialPacketSize + } +} diff --git a/transport/internet/quic/congestion/bbr/clock.go b/transport/internet/quic/congestion/bbr/clock.go new file mode 100644 index 0000000000..a66344fb71 --- /dev/null +++ b/transport/internet/quic/congestion/bbr/clock.go @@ -0,0 +1,18 @@ +package bbr + +import "time" + +// A Clock returns the current time +type Clock interface { + Now() time.Time +} + +// DefaultClock implements the Clock interface using the Go stdlib clock. +type DefaultClock struct{} + +var _ Clock = DefaultClock{} + +// Now gets the current time +func (DefaultClock) Now() time.Time { + return time.Now() +} diff --git a/transport/internet/quic/congestion/bbr/packet_number_indexed_queue.go b/transport/internet/quic/congestion/bbr/packet_number_indexed_queue.go new file mode 100644 index 0000000000..86fe52d2be --- /dev/null +++ b/transport/internet/quic/congestion/bbr/packet_number_indexed_queue.go @@ -0,0 +1,199 @@ +package bbr + +import ( + "github.com/apernet/quic-go/congestion" +) + +// packetNumberIndexedQueue is a queue of mostly continuous numbered entries +// which supports the following operations: +// - adding elements to the end of the queue, or at some point past the end +// - removing elements in any order +// - retrieving elements +// If all elements are inserted in order, all of the operations above are +// amortized O(1) time. +// +// Internally, the data structure is a deque where each element is marked as +// present or not. The deque starts at the lowest present index. Whenever an +// element is removed, it's marked as not present, and the front of the deque is +// cleared of elements that are not present. +// +// The tail of the queue is not cleared due to the assumption of entries being +// inserted in order, though removing all elements of the queue will return it +// to its initial state. +// +// Note that this data structure is inherently hazardous, since an addition of +// just two entries will cause it to consume all of the memory available. +// Because of that, it is not a general-purpose container and should not be used +// as one. + +type entryWrapper[T any] struct { + present bool + entry T +} + +type packetNumberIndexedQueue[T any] struct { + entries RingBuffer[entryWrapper[T]] + numberOfPresentEntries int + firstPacket congestion.PacketNumber +} + +func newPacketNumberIndexedQueue[T any](size int) *packetNumberIndexedQueue[T] { + q := &packetNumberIndexedQueue[T]{ + firstPacket: invalidPacketNumber, + } + + q.entries.Init(size) + + return q +} + +// Emplace inserts data associated |packet_number| into (or past) the end of the +// queue, filling up the missing intermediate entries as necessary. Returns +// true if the element has been inserted successfully, false if it was already +// in the queue or inserted out of order. +func (p *packetNumberIndexedQueue[T]) Emplace(packetNumber congestion.PacketNumber, entry *T) bool { + if packetNumber == invalidPacketNumber || entry == nil { + return false + } + + if p.IsEmpty() { + p.entries.PushBack(entryWrapper[T]{ + present: true, + entry: *entry, + }) + p.numberOfPresentEntries = 1 + p.firstPacket = packetNumber + return true + } + + // Do not allow insertion out-of-order. + if packetNumber <= p.LastPacket() { + return false + } + + // Handle potentially missing elements. + offset := int(packetNumber - p.FirstPacket()) + if gap := offset - p.entries.Len(); gap > 0 { + for i := 0; i < gap; i++ { + p.entries.PushBack(entryWrapper[T]{}) + } + } + + p.entries.PushBack(entryWrapper[T]{ + present: true, + entry: *entry, + }) + p.numberOfPresentEntries++ + return true +} + +// GetEntry Retrieve the entry associated with the packet number. Returns the pointer +// to the entry in case of success, or nullptr if the entry does not exist. +func (p *packetNumberIndexedQueue[T]) GetEntry(packetNumber congestion.PacketNumber) *T { + ew := p.getEntryWraper(packetNumber) + if ew == nil { + return nil + } + + return &ew.entry +} + +// Remove, Same as above, but if an entry is present in the queue, also call f(entry) +// before removing it. +func (p *packetNumberIndexedQueue[T]) Remove(packetNumber congestion.PacketNumber, f func(T)) bool { + ew := p.getEntryWraper(packetNumber) + if ew == nil { + return false + } + if f != nil { + f(ew.entry) + } + ew.present = false + p.numberOfPresentEntries-- + + if packetNumber == p.FirstPacket() { + p.clearup() + } + + return true +} + +// RemoveUpTo, but not including |packet_number|. +// Unused slots in the front are also removed, which means when the function +// returns, |first_packet()| can be larger than |packet_number|. +func (p *packetNumberIndexedQueue[T]) RemoveUpTo(packetNumber congestion.PacketNumber) { + for !p.entries.Empty() && + p.firstPacket != invalidPacketNumber && + p.firstPacket < packetNumber { + if p.entries.Front().present { + p.numberOfPresentEntries-- + } + p.entries.PopFront() + p.firstPacket++ + } + p.clearup() + + return +} + +// IsEmpty return if queue is empty. +func (p *packetNumberIndexedQueue[T]) IsEmpty() bool { + return p.numberOfPresentEntries == 0 +} + +// NumberOfPresentEntries returns the number of entries in the queue. +func (p *packetNumberIndexedQueue[T]) NumberOfPresentEntries() int { + return p.numberOfPresentEntries +} + +// EntrySlotsUsed returns the number of entries allocated in the underlying deque. This is +// proportional to the memory usage of the queue. +func (p *packetNumberIndexedQueue[T]) EntrySlotsUsed() int { + return p.entries.Len() +} + +// LastPacket returns packet number of the first entry in the queue. +func (p *packetNumberIndexedQueue[T]) FirstPacket() (packetNumber congestion.PacketNumber) { + return p.firstPacket +} + +// LastPacket returns packet number of the last entry ever inserted in the queue. Note that the +// entry in question may have already been removed. Zero if the queue is +// empty. +func (p *packetNumberIndexedQueue[T]) LastPacket() (packetNumber congestion.PacketNumber) { + if p.IsEmpty() { + return invalidPacketNumber + } + + return p.firstPacket + congestion.PacketNumber(p.entries.Len()-1) +} + +func (p *packetNumberIndexedQueue[T]) clearup() { + for !p.entries.Empty() && !p.entries.Front().present { + p.entries.PopFront() + p.firstPacket++ + } + if p.entries.Empty() { + p.firstPacket = invalidPacketNumber + } +} + +func (p *packetNumberIndexedQueue[T]) getEntryWraper(packetNumber congestion.PacketNumber) *entryWrapper[T] { + if packetNumber == invalidPacketNumber || + p.IsEmpty() || + packetNumber < p.firstPacket { + return nil + } + + offset := int(packetNumber - p.firstPacket) + if offset >= p.entries.Len() { + return nil + } + + ew := p.entries.Offset(offset) + if ew == nil || !ew.present { + return nil + } + + return ew +} diff --git a/transport/internet/quic/congestion/bbr/ringbuffer.go b/transport/internet/quic/congestion/bbr/ringbuffer.go new file mode 100644 index 0000000000..ed92d4ce01 --- /dev/null +++ b/transport/internet/quic/congestion/bbr/ringbuffer.go @@ -0,0 +1,118 @@ +package bbr + +// A RingBuffer is a ring buffer. +// It acts as a heap that doesn't cause any allocations. +type RingBuffer[T any] struct { + ring []T + headPos, tailPos int + full bool +} + +// Init preallocs a buffer with a certain size. +func (r *RingBuffer[T]) Init(size int) { + r.ring = make([]T, size) +} + +// Len returns the number of elements in the ring buffer. +func (r *RingBuffer[T]) Len() int { + if r.full { + return len(r.ring) + } + if r.tailPos >= r.headPos { + return r.tailPos - r.headPos + } + return r.tailPos - r.headPos + len(r.ring) +} + +// Empty says if the ring buffer is empty. +func (r *RingBuffer[T]) Empty() bool { + return !r.full && r.headPos == r.tailPos +} + +// PushBack adds a new element. +// If the ring buffer is full, its capacity is increased first. +func (r *RingBuffer[T]) PushBack(t T) { + if r.full || len(r.ring) == 0 { + r.grow() + } + r.ring[r.tailPos] = t + r.tailPos++ + if r.tailPos == len(r.ring) { + r.tailPos = 0 + } + if r.tailPos == r.headPos { + r.full = true + } +} + +// PopFront returns the next element. +// It must not be called when the buffer is empty, that means that +// callers might need to check if there are elements in the buffer first. +func (r *RingBuffer[T]) PopFront() T { + if r.Empty() { + panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: pop from an empty queue") + } + r.full = false + t := r.ring[r.headPos] + r.ring[r.headPos] = *new(T) + r.headPos++ + if r.headPos == len(r.ring) { + r.headPos = 0 + } + return t +} + +// Offset returns the offset element. +// It must not be called when the buffer is empty, that means that +// callers might need to check if there are elements in the buffer first +// and check if the index larger than buffer length. +func (r *RingBuffer[T]) Offset(index int) *T { + if r.Empty() || index >= r.Len() { + panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: offset from invalid index") + } + offset := (r.headPos + index) % len(r.ring) + return &r.ring[offset] +} + +// Front returns the front element. +// It must not be called when the buffer is empty, that means that +// callers might need to check if there are elements in the buffer first. +func (r *RingBuffer[T]) Front() *T { + if r.Empty() { + panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: front from an empty queue") + } + return &r.ring[r.headPos] +} + +// Back returns the back element. +// It must not be called when the buffer is empty, that means that +// callers might need to check if there are elements in the buffer first. +func (r *RingBuffer[T]) Back() *T { + if r.Empty() { + panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: back from an empty queue") + } + return r.Offset(r.Len() - 1) +} + +// Grow the maximum size of the queue. +// This method assume the queue is full. +func (r *RingBuffer[T]) grow() { + oldRing := r.ring + newSize := len(oldRing) * 2 + if newSize == 0 { + newSize = 1 + } + r.ring = make([]T, newSize) + headLen := copy(r.ring, oldRing[r.headPos:]) + copy(r.ring[headLen:], oldRing[:r.headPos]) + r.headPos, r.tailPos, r.full = 0, len(oldRing), false +} + +// Clear removes all elements. +func (r *RingBuffer[T]) Clear() { + var zeroValue T + for i := range r.ring { + r.ring[i] = zeroValue + } + r.headPos, r.tailPos, r.full = 0, 0, false +} diff --git a/transport/internet/quic/congestion/bbr/windowed_filter.go b/transport/internet/quic/congestion/bbr/windowed_filter.go new file mode 100644 index 0000000000..4773bce597 --- /dev/null +++ b/transport/internet/quic/congestion/bbr/windowed_filter.go @@ -0,0 +1,162 @@ +package bbr + +import ( + "golang.org/x/exp/constraints" +) + +// Implements Kathleen Nichols' algorithm for tracking the minimum (or maximum) +// estimate of a stream of samples over some fixed time interval. (E.g., +// the minimum RTT over the past five minutes.) The algorithm keeps track of +// the best, second best, and third best min (or max) estimates, maintaining an +// invariant that the measurement time of the n'th best >= n-1'th best. + +// The algorithm works as follows. On a reset, all three estimates are set to +// the same sample. The second best estimate is then recorded in the second +// quarter of the window, and a third best estimate is recorded in the second +// half of the window, bounding the worst case error when the true min is +// monotonically increasing (or true max is monotonically decreasing) over the +// window. +// +// A new best sample replaces all three estimates, since the new best is lower +// (or higher) than everything else in the window and it is the most recent. +// The window thus effectively gets reset on every new min. The same property +// holds true for second best and third best estimates. Specifically, when a +// sample arrives that is better than the second best but not better than the +// best, it replaces the second and third best estimates but not the best +// estimate. Similarly, a sample that is better than the third best estimate +// but not the other estimates replaces only the third best estimate. +// +// Finally, when the best expires, it is replaced by the second best, which in +// turn is replaced by the third best. The newest sample replaces the third +// best. + +type WindowedFilterValue interface { + any +} + +type WindowedFilterTime interface { + constraints.Integer | constraints.Float +} + +type WindowedFilter[V WindowedFilterValue, T WindowedFilterTime] struct { + // Time length of window. + windowLength T + estimates []entry[V, T] + comparator func(V, V) int +} + +type entry[V WindowedFilterValue, T WindowedFilterTime] struct { + sample V + time T +} + +// Compares two values and returns true if the first is greater than or equal +// to the second. +func MaxFilter[O constraints.Ordered](a, b O) int { + if a > b { + return 1 + } else if a < b { + return -1 + } + return 0 +} + +// Compares two values and returns true if the first is less than or equal +// to the second. +func MinFilter[O constraints.Ordered](a, b O) int { + if a < b { + return 1 + } else if a > b { + return -1 + } + return 0 +} + +func NewWindowedFilter[V WindowedFilterValue, T WindowedFilterTime](windowLength T, comparator func(V, V) int) *WindowedFilter[V, T] { + return &WindowedFilter[V, T]{ + windowLength: windowLength, + estimates: make([]entry[V, T], 3, 3), + comparator: comparator, + } +} + +// Changes the window length. Does not update any current samples. +func (f *WindowedFilter[V, T]) SetWindowLength(windowLength T) { + f.windowLength = windowLength +} + +func (f *WindowedFilter[V, T]) GetBest() V { + return f.estimates[0].sample +} + +func (f *WindowedFilter[V, T]) GetSecondBest() V { + return f.estimates[1].sample +} + +func (f *WindowedFilter[V, T]) GetThirdBest() V { + return f.estimates[2].sample +} + +// Updates best estimates with |sample|, and expires and updates best +// estimates as necessary. +func (f *WindowedFilter[V, T]) Update(newSample V, newTime T) { + // Reset all estimates if they have not yet been initialized, if new sample + // is a new best, or if the newest recorded estimate is too old. + if f.comparator(f.estimates[0].sample, *new(V)) == 0 || + f.comparator(newSample, f.estimates[0].sample) >= 0 || + newTime-f.estimates[2].time > f.windowLength { + f.Reset(newSample, newTime) + return + } + + if f.comparator(newSample, f.estimates[1].sample) >= 0 { + f.estimates[1] = entry[V, T]{newSample, newTime} + f.estimates[2] = f.estimates[1] + } else if f.comparator(newSample, f.estimates[2].sample) >= 0 { + f.estimates[2] = entry[V, T]{newSample, newTime} + } + + // Expire and update estimates as necessary. + if newTime-f.estimates[0].time > f.windowLength { + // The best estimate hasn't been updated for an entire window, so promote + // second and third best estimates. + f.estimates[0] = f.estimates[1] + f.estimates[1] = f.estimates[2] + f.estimates[2] = entry[V, T]{newSample, newTime} + // Need to iterate one more time. Check if the new best estimate is + // outside the window as well, since it may also have been recorded a + // long time ago. Don't need to iterate once more since we cover that + // case at the beginning of the method. + if newTime-f.estimates[0].time > f.windowLength { + f.estimates[0] = f.estimates[1] + f.estimates[1] = f.estimates[2] + } + return + } + if f.comparator(f.estimates[1].sample, f.estimates[0].sample) == 0 && + newTime-f.estimates[1].time > f.windowLength/4 { + // A quarter of the window has passed without a better sample, so the + // second-best estimate is taken from the second quarter of the window. + f.estimates[1] = entry[V, T]{newSample, newTime} + f.estimates[2] = f.estimates[1] + return + } + + if f.comparator(f.estimates[2].sample, f.estimates[1].sample) == 0 && + newTime-f.estimates[2].time > f.windowLength/2 { + // We've passed a half of the window without a better estimate, so take + // a third-best estimate from the second half of the window. + f.estimates[2] = entry[V, T]{newSample, newTime} + } +} + +// Resets all estimates to new sample. +func (f *WindowedFilter[V, T]) Reset(newSample V, newTime T) { + f.estimates[2] = entry[V, T]{newSample, newTime} + f.estimates[1] = f.estimates[2] + f.estimates[0] = f.estimates[1] +} + +func (f *WindowedFilter[V, T]) Clear() { + f.estimates = make([]entry[V, T], 3, 3) +} diff --git a/transport/internet/quic/congestion/brutal/brutal.go b/transport/internet/quic/congestion/brutal/brutal.go new file mode 100644 index 0000000000..a225c62fd2 --- /dev/null +++ b/transport/internet/quic/congestion/brutal/brutal.go @@ -0,0 +1,148 @@ +package brutal + +import ( + "time" + + "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/common" + + "github.com/apernet/quic-go/congestion" +) + +const ( + pktInfoSlotCount = 4 + minSampleCount = 50 + minAckRate = 0.8 +) + +var _ congestion.CongestionControl = &BrutalSender{} + +type BrutalSender struct { + rttStats congestion.RTTStatsProvider + bps congestion.ByteCount + maxDatagramSize congestion.ByteCount + pacer *common.Pacer + + pktInfoSlots [pktInfoSlotCount]pktInfo + ackRate float64 +} + +type pktInfo struct { + Timestamp int64 + AckCount uint64 + LossCount uint64 +} + +func NewBrutalSender(bps uint64) *BrutalSender { + bs := &BrutalSender{ + bps: congestion.ByteCount(bps), + maxDatagramSize: congestion.InitialPacketSizeIPv4, + ackRate: 1, + } + bs.pacer = common.NewPacer(func() congestion.ByteCount { + return congestion.ByteCount(float64(bs.bps) / bs.ackRate) + }) + return bs +} + +func (b *BrutalSender) SetRTTStatsProvider(rttStats congestion.RTTStatsProvider) { + b.rttStats = rttStats +} + +func (b *BrutalSender) TimeUntilSend(bytesInFlight congestion.ByteCount) time.Time { + return b.pacer.TimeUntilSend() +} + +func (b *BrutalSender) HasPacingBudget(now time.Time) bool { + return b.pacer.Budget(now) >= b.maxDatagramSize +} + +func (b *BrutalSender) CanSend(bytesInFlight congestion.ByteCount) bool { + return bytesInFlight < b.GetCongestionWindow() +} + +func (b *BrutalSender) GetCongestionWindow() congestion.ByteCount { + rtt := b.rttStats.SmoothedRTT() + if rtt <= 0 { + return 10240 + } + return congestion.ByteCount(float64(b.bps) * rtt.Seconds() * 1.5 / b.ackRate) +} + +func (b *BrutalSender) OnPacketSent(sentTime time.Time, bytesInFlight congestion.ByteCount, + packetNumber congestion.PacketNumber, bytes congestion.ByteCount, isRetransmittable bool, +) { + b.pacer.SentPacket(sentTime, bytes) +} + +func (b *BrutalSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes congestion.ByteCount, + priorInFlight congestion.ByteCount, eventTime time.Time, +) { + currentTimestamp := eventTime.Unix() + slot := currentTimestamp % pktInfoSlotCount + if b.pktInfoSlots[slot].Timestamp == currentTimestamp { + b.pktInfoSlots[slot].AckCount++ + } else { + // uninitialized slot or too old, reset + b.pktInfoSlots[slot].Timestamp = currentTimestamp + b.pktInfoSlots[slot].AckCount = 1 + b.pktInfoSlots[slot].LossCount = 0 + } + b.updateAckRate(currentTimestamp) +} + +func (b *BrutalSender) OnCongestionEvent(number congestion.PacketNumber, lostBytes congestion.ByteCount, + priorInFlight congestion.ByteCount, +) { + currentTimestamp := time.Now().Unix() + slot := currentTimestamp % pktInfoSlotCount + if b.pktInfoSlots[slot].Timestamp == currentTimestamp { + b.pktInfoSlots[slot].LossCount++ + } else { + // uninitialized slot or too old, reset + b.pktInfoSlots[slot].Timestamp = currentTimestamp + b.pktInfoSlots[slot].AckCount = 0 + b.pktInfoSlots[slot].LossCount = 1 + } + b.updateAckRate(currentTimestamp) +} + +func (b *BrutalSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, eventTime time.Time, ackedPackets []congestion.AckedPacketInfo, lostPackets []congestion.LostPacketInfo) { + // Stub +} + +func (b *BrutalSender) SetMaxDatagramSize(size congestion.ByteCount) { + b.maxDatagramSize = size + b.pacer.SetMaxDatagramSize(size) +} + +func (b *BrutalSender) updateAckRate(currentTimestamp int64) { + minTimestamp := currentTimestamp - pktInfoSlotCount + var ackCount, lossCount uint64 + for _, info := range b.pktInfoSlots { + if info.Timestamp < minTimestamp { + continue + } + ackCount += info.AckCount + lossCount += info.LossCount + } + if ackCount+lossCount < minSampleCount { + b.ackRate = 1 + } + rate := float64(ackCount) / float64(ackCount+lossCount) + if rate < minAckRate { + b.ackRate = minAckRate + } + b.ackRate = rate +} + +func (b *BrutalSender) InSlowStart() bool { + return false +} + +func (b *BrutalSender) InRecovery() bool { + return false +} + +func (b *BrutalSender) MaybeExitSlowStart() {} + +func (b *BrutalSender) OnRetransmissionTimeout(packetsRetransmitted bool) {} diff --git a/transport/internet/quic/congestion/common/pacer.go b/transport/internet/quic/congestion/common/pacer.go new file mode 100644 index 0000000000..58a9df5119 --- /dev/null +++ b/transport/internet/quic/congestion/common/pacer.go @@ -0,0 +1,92 @@ +package common + +import ( + "math" + "time" + + "github.com/apernet/quic-go/congestion" +) + +const ( + maxBurstPackets = 10 +) + +// Pacer implements a token bucket pacing algorithm. +type Pacer struct { + budgetAtLastSent congestion.ByteCount + maxDatagramSize congestion.ByteCount + lastSentTime time.Time + getBandwidth func() congestion.ByteCount // in bytes/s +} + +func NewPacer(getBandwidth func() congestion.ByteCount) *Pacer { + p := &Pacer{ + budgetAtLastSent: maxBurstPackets * congestion.InitialPacketSizeIPv4, + maxDatagramSize: congestion.InitialPacketSizeIPv4, + getBandwidth: getBandwidth, + } + return p +} + +func (p *Pacer) SentPacket(sendTime time.Time, size congestion.ByteCount) { + budget := p.Budget(sendTime) + if size > budget { + p.budgetAtLastSent = 0 + } else { + p.budgetAtLastSent = budget - size + } + p.lastSentTime = sendTime +} + +func (p *Pacer) Budget(now time.Time) congestion.ByteCount { + if p.lastSentTime.IsZero() { + return p.maxBurstSize() + } + budget := p.budgetAtLastSent + (p.getBandwidth()*congestion.ByteCount(now.Sub(p.lastSentTime).Nanoseconds()))/1e9 + return MinByteCount(p.maxBurstSize(), budget) +} + +func (p *Pacer) maxBurstSize() congestion.ByteCount { + return MaxByteCount( + congestion.ByteCount((congestion.MinPacingDelay+time.Millisecond).Nanoseconds())*p.getBandwidth()/1e9, + maxBurstPackets*p.maxDatagramSize, + ) +} + +// TimeUntilSend returns when the next packet should be sent. +// It returns the zero value of time.Time if a packet can be sent immediately. +func (p *Pacer) TimeUntilSend() time.Time { + if p.budgetAtLastSent >= p.maxDatagramSize { + return time.Time{} + } + return p.lastSentTime.Add(MaxDuration( + congestion.MinPacingDelay, + time.Duration(math.Ceil(float64(p.maxDatagramSize-p.budgetAtLastSent)*1e9/ + float64(p.getBandwidth())))*time.Nanosecond, + )) +} + +func (p *Pacer) SetMaxDatagramSize(s congestion.ByteCount) { + p.maxDatagramSize = s +} + +func MaxByteCount(a, b congestion.ByteCount) congestion.ByteCount { + if a < b { + return b + } + return a +} + +func MinByteCount(a, b congestion.ByteCount) congestion.ByteCount { + if a < b { + return a + } + return b +} + +func MaxDuration(a, b time.Duration) time.Duration { + if a > b { + return a + } + return b +} diff --git a/transport/internet/quic/congestion/utils.go b/transport/internet/quic/congestion/utils.go new file mode 100644 index 0000000000..a9d48e975d --- /dev/null +++ b/transport/internet/quic/congestion/utils.go @@ -0,0 +1,18 @@ +package congestion + +import ( + "github.com/apernet/quic-go" + "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/bbr" + "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/brutal" +) + +func UseBBR(conn quic.Connection) { + conn.SetCongestionControl(bbr.NewBbrSender( + bbr.DefaultClock{}, + bbr.GetInitialPacketSize(conn.RemoteAddr()), + )) +} + +func UseBrutal(conn quic.Connection, tx uint64) { + conn.SetCongestionControl(brutal.NewBrutalSender(tx)) +} diff --git a/transport/internet/quic/dialer.go b/transport/internet/quic/dialer.go index 90295c007a..f7538bb134 100644 --- a/transport/internet/quic/dialer.go +++ b/transport/internet/quic/dialer.go @@ -11,6 +11,7 @@ import ( "github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/task" "github.com/v2fly/v2ray-core/v5/transport/internet" + "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion" "github.com/v2fly/v2ray-core/v5/transport/internet/tls" ) @@ -170,6 +171,7 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl sysConn.Close() return nil, err } + SetCongestion(conn, config) context := &connectionContext{ conn: conn, @@ -179,6 +181,15 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl return context.openStream(destAddr) } +func SetCongestion(conn quic.Connection, config *Config) { + if config.Congestion != nil && config.Congestion.Type == "brutal" { + byteps := config.Congestion.UpMbps * (10 ^ 6) + congestion.UseBrutal(conn, byteps) + } else { + congestion.UseBBR(conn) + } +} + var client clientConnections func init() { From b91237420d0bbf917f24c44c922633be99119c6c Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Wed, 4 Oct 2023 03:11:32 +0800 Subject: [PATCH 11/81] fix brutal congestion setting --- go.mod | 2 +- transport/internet/quic/dialer.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f6c8c6a9cc..07b3fba4e8 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,7 @@ require ( go.starlark.net v0.0.0-20230612165344-9532f5667272 go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 golang.org/x/crypto v0.12.0 + golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/net v0.14.0 golang.org/x/sync v0.2.0 golang.org/x/sys v0.11.0 @@ -72,7 +73,6 @@ require ( github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 // indirect github.com/xtaci/smux v1.5.24 // indirect go.uber.org/mock v0.3.0 // indirect - golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/mod v0.11.0 // indirect golang.org/x/text v0.12.0 // indirect golang.org/x/tools v0.9.3 // indirect diff --git a/transport/internet/quic/dialer.go b/transport/internet/quic/dialer.go index f7538bb134..def6b662ac 100644 --- a/transport/internet/quic/dialer.go +++ b/transport/internet/quic/dialer.go @@ -182,8 +182,8 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl } func SetCongestion(conn quic.Connection, config *Config) { - if config.Congestion != nil && config.Congestion.Type == "brutal" { - byteps := config.Congestion.UpMbps * (10 ^ 6) + if config.Congestion.GetType() == "brutal" && config.Congestion.GetUpMbps() != 0 { + byteps := config.Congestion.GetUpMbps() * (10 ^ 6) congestion.UseBrutal(conn, byteps) } else { congestion.UseBBR(conn) From 5daf391baceffd8f5ac66bb17566d5edebdefc4a Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Wed, 4 Oct 2023 03:58:48 +0800 Subject: [PATCH 12/81] add congestion to quic server --- transport/internet/quic/config.pb.go | 71 ++++++++++++---------------- transport/internet/quic/config.proto | 3 +- transport/internet/quic/dialer.go | 6 +-- transport/internet/quic/hub.go | 3 ++ 4 files changed, 38 insertions(+), 45 deletions(-) diff --git a/transport/internet/quic/config.pb.go b/transport/internet/quic/config.pb.go index 9a088bb6db..e4d3a62672 100644 --- a/transport/internet/quic/config.pb.go +++ b/transport/internet/quic/config.pb.go @@ -23,8 +23,7 @@ type Congestion struct { unknownFields protoimpl.UnknownFields Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - UpMbps uint64 `protobuf:"varint,2,opt,name=up_mbps,json=upMbps,proto3" json:"up_mbps,omitempty"` - DownMbps uint64 `protobuf:"varint,3,opt,name=down_mbps,json=downMbps,proto3" json:"down_mbps,omitempty"` + SendMbps uint64 `protobuf:"varint,2,opt,name=send_mbps,json=sendMbps,proto3" json:"send_mbps,omitempty"` } func (x *Congestion) Reset() { @@ -66,16 +65,9 @@ func (x *Congestion) GetType() string { return "" } -func (x *Congestion) GetUpMbps() uint64 { +func (x *Congestion) GetSendMbps() uint64 { if x != nil { - return x.UpMbps - } - return 0 -} - -func (x *Congestion) GetDownMbps() uint64 { - if x != nil { - return x.DownMbps + return x.SendMbps } return 0 } @@ -164,37 +156,36 @@ var file_transport_internet_quic_config_proto_rawDesc = []byte{ 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x56, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3d, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x70, 0x5f, 0x6d, - 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x70, 0x4d, 0x62, 0x70, - 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xf7, - 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, - 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, - 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, - 0x69, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x12, 0x4e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, + 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x6e, + 0x64, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xf7, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, + 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x67, + 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, + 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, + 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x09, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x04, 0x71, 0x75, 0x69, 0x63, 0x42, + 0x87, 0x01, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x67, 0x65, - 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, - 0x6e, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, - 0x72, 0x74, 0x12, 0x04, 0x71, 0x75, 0x69, 0x63, 0x42, 0x87, 0x01, 0x0a, 0x26, 0x63, 0x6f, 0x6d, - 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, - 0x75, 0x69, 0x63, 0x50, 0x01, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, - 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x71, 0x75, 0x69, 0x63, 0xaa, 0x02, 0x22, - 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x51, 0x75, - 0x69, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x50, 0x01, 0x5a, 0x36, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, + 0x71, 0x75, 0x69, 0x63, 0xaa, 0x02, 0x22, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, + 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x51, 0x75, 0x69, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( diff --git a/transport/internet/quic/config.proto b/transport/internet/quic/config.proto index 8259911b32..effda6fc04 100644 --- a/transport/internet/quic/config.proto +++ b/transport/internet/quic/config.proto @@ -14,8 +14,7 @@ import "common/protoext/extensions.proto"; message Congestion{ string type = 1; - uint64 up_mbps = 2; - uint64 down_mbps = 3; + uint64 send_mbps = 2; } message Config { diff --git a/transport/internet/quic/dialer.go b/transport/internet/quic/dialer.go index def6b662ac..d36aab8b95 100644 --- a/transport/internet/quic/dialer.go +++ b/transport/internet/quic/dialer.go @@ -182,9 +182,9 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl } func SetCongestion(conn quic.Connection, config *Config) { - if config.Congestion.GetType() == "brutal" && config.Congestion.GetUpMbps() != 0 { - byteps := config.Congestion.GetUpMbps() * (10 ^ 6) - congestion.UseBrutal(conn, byteps) + if config.Congestion.GetType() == "brutal" && config.Congestion.GetSendMbps() != 0 { + sendBps := config.Congestion.GetSendMbps() * (10 ^ 6) + congestion.UseBrutal(conn, sendBps) } else { congestion.UseBBR(conn) } diff --git a/transport/internet/quic/hub.go b/transport/internet/quic/hub.go index 76ec800d16..57d62f35a4 100644 --- a/transport/internet/quic/hub.go +++ b/transport/internet/quic/hub.go @@ -20,6 +20,7 @@ type Listener struct { listener *quic.Listener done *done.Instance addConn internet.ConnHandler + config *Config } func (l *Listener) acceptStreams(conn quic.Connection) { @@ -62,6 +63,7 @@ func (l *Listener) keepAccepting() { time.Sleep(time.Second) continue } + SetCongestion(conn, l.config) go l.acceptStreams(conn) } } @@ -131,6 +133,7 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti rawConn: conn, listener: qListener, addConn: handler, + config: config, } go listener.keepAccepting() From d789bfad2ef4d9cb1b78b4678d3d433eaff02614 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Wed, 4 Oct 2023 09:13:39 +0800 Subject: [PATCH 13/81] try fix quic timeout --- testing/scenarios/transport_test.go | 2 +- .../quic/congestion/bbr/bbr_sender.go | 11 ++---- transport/internet/quic/dialer.go | 35 ++++++++++++------- transport/internet/quic/hub.go | 9 +---- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/testing/scenarios/transport_test.go b/testing/scenarios/transport_test.go index 20a8dca544..5630d169f5 100644 --- a/testing/scenarios/transport_test.go +++ b/testing/scenarios/transport_test.go @@ -376,7 +376,7 @@ func TestVMessQuic(t *testing.T) { var errg errgroup.Group for i := 0; i < 10; i++ { - errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) + errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*10)) } if err := errg.Wait(); err != nil { diff --git a/transport/internet/quic/congestion/bbr/bbr_sender.go b/transport/internet/quic/congestion/bbr/bbr_sender.go index be43cd600c..1896bf6739 100644 --- a/transport/internet/quic/congestion/bbr/bbr_sender.go +++ b/transport/internet/quic/congestion/bbr/bbr_sender.go @@ -813,11 +813,9 @@ func (b *bbrSender) calculatePacingRate(bytesLost congestion.ByteCount) { // We are fairly sure overshoot happens if 1) there is at least one // non app-limited bw sample or 2) half of IW gets lost. Slow pacing // rate. - remoteRate := BandwidthFromDelta(b.cwndToCalculateMinPacingRate, b.rttStats.MinRTT()) - if targetRate > remoteRate { + b.pacingRate = BandwidthFromDelta(b.cwndToCalculateMinPacingRate, b.rttStats.MinRTT()) + if targetRate > b.pacingRate { b.pacingRate = targetRate - } else { - b.pacingRate = remoteRate } b.bytesLostWhileDetectingOvershooting = 0 b.detectOvershooting = false @@ -826,12 +824,9 @@ func (b *bbrSender) calculatePacingRate(bytesLost congestion.ByteCount) { } // Do not decrease the pacing rate during startup. - if b.pacingRate > targetRate { - b.pacingRate = b.pacingRate - } else { + if targetRate > b.pacingRate { b.pacingRate = targetRate } - } // Determines the appropriate congestion window for the connection. diff --git a/transport/internet/quic/dialer.go b/transport/internet/quic/dialer.go index d36aab8b95..1013795910 100644 --- a/transport/internet/quic/dialer.go +++ b/transport/internet/quic/dialer.go @@ -129,18 +129,14 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl var conns []*connectionContext if s, found := s.runningConnections[dest]; found { conns = s - } - - { conn := openStream(conns, destAddr) if conn != nil { + newError("dialing QUIC stream to ", dest).WriteToLog() return conn, nil } } - conns = removeInactiveConnections(conns) - - newError("dialing QUIC to ", dest).WriteToLog() + newError("dialing QUIC new connection to ", dest).WriteToLog() rawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{ IP: []byte{0, 0, 0, 0}, @@ -150,11 +146,7 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl return nil, err } - quicConfig := &quic.Config{ - HandshakeIdleTimeout: time.Second * 8, - MaxIdleTimeout: time.Second * 30, - KeepAlivePeriod: time.Second * 15, - } + quicConfig := InitQuicConfig() sysConn, err := wrapSysConn(rawConn.(*net.UDPConn), config) if err != nil { @@ -183,13 +175,32 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl func SetCongestion(conn quic.Connection, config *Config) { if config.Congestion.GetType() == "brutal" && config.Congestion.GetSendMbps() != 0 { - sendBps := config.Congestion.GetSendMbps() * (10 ^ 6) + sendBps := config.Congestion.GetSendMbps() * 1000000 congestion.UseBrutal(conn, sendBps) } else { congestion.UseBBR(conn) } } +const ( + defaultStreamReceiveWindow = 8388608 // 8MB + defaultConnReceiveWindow = defaultStreamReceiveWindow * 5 / 2 // 20MB + defaultMaxIdleTimeout = 30 * time.Second + defaultKeepAlivePeriod = 10 * time.Second + defaultHandshakeIdleTimeout = 10 * time.Second +) + +func InitQuicConfig() *quic.Config { + quicConfig := &quic.Config{ + HandshakeIdleTimeout: defaultHandshakeIdleTimeout, + MaxIdleTimeout: defaultMaxIdleTimeout, + KeepAlivePeriod: defaultKeepAlivePeriod, + InitialStreamReceiveWindow: defaultStreamReceiveWindow, + InitialConnectionReceiveWindow: defaultConnReceiveWindow, + } + return quicConfig +} + var client clientConnections func init() { diff --git a/transport/internet/quic/hub.go b/transport/internet/quic/hub.go index 57d62f35a4..9d5d3b9303 100644 --- a/transport/internet/quic/hub.go +++ b/transport/internet/quic/hub.go @@ -60,7 +60,6 @@ func (l *Listener) keepAccepting() { if l.done.Done() { break } - time.Sleep(time.Second) continue } SetCongestion(conn, l.config) @@ -103,13 +102,7 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti return nil, err } - quicConfig := &quic.Config{ - HandshakeIdleTimeout: time.Second * 8, - MaxIdleTimeout: time.Second * 45, - MaxIncomingStreams: 32, - MaxIncomingUniStreams: -1, - KeepAlivePeriod: time.Second * 15, - } + quicConfig := InitQuicConfig() conn, err := wrapSysConn(rawConn.(*net.UDPConn), config) if err != nil { From be6e364689ed532ff1af317a29b137f4956d6d52 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Fri, 6 Oct 2023 10:38:23 +0800 Subject: [PATCH 14/81] fix test --- testing/scenarios/transport_test.go | 2 +- transport/internet/quic/dialer.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/testing/scenarios/transport_test.go b/testing/scenarios/transport_test.go index 5630d169f5..20a8dca544 100644 --- a/testing/scenarios/transport_test.go +++ b/testing/scenarios/transport_test.go @@ -376,7 +376,7 @@ func TestVMessQuic(t *testing.T) { var errg errgroup.Group for i := 0; i < 10; i++ { - errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*10)) + errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) } if err := errg.Wait(); err != nil { diff --git a/transport/internet/quic/dialer.go b/transport/internet/quic/dialer.go index 1013795910..368fea6147 100644 --- a/transport/internet/quic/dialer.go +++ b/transport/internet/quic/dialer.go @@ -174,10 +174,11 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl } func SetCongestion(conn quic.Connection, config *Config) { - if config.Congestion.GetType() == "brutal" && config.Congestion.GetSendMbps() != 0 { + congestionType := config.Congestion.GetType() + if congestionType == "brutal" && config.Congestion.GetSendMbps() != 0 { sendBps := config.Congestion.GetSendMbps() * 1000000 congestion.UseBrutal(conn, sendBps) - } else { + } else if congestionType == "bbr" { congestion.UseBBR(conn) } } From ecfc7f4422cf9133f9d847e84552de70bab90b10 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Sat, 21 Oct 2023 15:28:56 +0800 Subject: [PATCH 15/81] update vprotogen --- infra/vprotogen/main.go | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/infra/vprotogen/main.go b/infra/vprotogen/main.go index f00cdea7ac..bd16ad5094 100644 --- a/infra/vprotogen/main.go +++ b/infra/vprotogen/main.go @@ -3,6 +3,7 @@ package main import ( "bufio" "bytes" + "errors" "fmt" "go/build" "io" @@ -119,10 +120,22 @@ func getInstalledProtocVersion(protocPath string) (string, error) { if cmdErr != nil { return "", cmdErr } - versionRegexp := regexp.MustCompile(`protoc\s*(\d+\.\d+)`) + versionRegexp := regexp.MustCompile(`protoc\s*(\d+\.\d+\.\d+)`) matched := versionRegexp.FindStringSubmatch(string(output)) - repoProtocVersion := "4." + matched[1] // in contrast to getProjectProtocVersion() - return repoProtocVersion, nil + installedVersion := "" + if len(matched) == 0 { + // try new version of protoc + versionRegexp = regexp.MustCompile(`protoc\s*(\d+\.\d+)`) + matched = versionRegexp.FindStringSubmatch(string(output)) + installedVersion += "4." // in contrast to getProjectProtocVersion() + } + + if len(matched) == 0 { + return "", errors.New("Can not parse protoc version.") + } + installedVersion += matched[1] + fmt.Println("Using protoc version: " + installedVersion) + return installedVersion, nil } func parseVersion(s string, width int) int64 { @@ -224,9 +237,6 @@ Download it from https://github.com/protocolbuffers/protobuf/releases os.Exit(1) } - // Require: - // go install google.golang.org/protobuf/cmd/protoc-gen-go@latest - // go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest for _, files := range protoFilesMap { for _, relProtoFile := range files { args := []string{ From ea844151421e81007c703f659dff717cc8bfc644 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Sun, 22 Oct 2023 12:07:46 +0800 Subject: [PATCH 16/81] fix BBR test --- .github/workflows/linter.yml | 2 +- .github/workflows/test.yml | 2 +- go.mod | 4 +- go.sum | 2 + testing/scenarios/transport_test.go | 272 ++++++++++++++++++ .../quic/congestion/bbr/bandwidth_sampler.go | 28 +- .../quic/congestion/bbr/bbr_sender.go | 58 ++-- .../internet/quic/congestion/brutal/brutal.go | 79 +++-- .../internet/quic/congestion/common/pacer.go | 15 +- transport/internet/quic/congestion/utils.go | 3 +- transport/internet/quic/dialer.go | 1 + 11 files changed, 388 insertions(+), 78 deletions(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 8381f19555..07174bdb1b 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v4 with: - go-version: ^1.19 + go-version: ^1.21 - name: Checkout codebase uses: actions/checkout@v3 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 455a0b0cfe..3176a95a7b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v4 with: - go-version: ^1.19 + go-version: ^1.21 - name: Checkout codebase uses: actions/checkout@v3 diff --git a/go.mod b/go.mod index 28daf57846..735b73f965 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/v2fly/v2ray-core/v5 -go 1.20 +go 1.21 require ( github.com/adrg/xdg v0.4.0 @@ -30,7 +30,7 @@ require ( golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/net v0.14.0 golang.org/x/sync v0.2.0 - golang.org/x/sys v0.11.0 + golang.org/x/sys v0.13.0 google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index 7218ad0e23..91ed5e4265 100644 --- a/go.sum +++ b/go.sum @@ -458,6 +458,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/testing/scenarios/transport_test.go b/testing/scenarios/transport_test.go index 20a8dca544..311f3eb70f 100644 --- a/testing/scenarios/transport_test.go +++ b/testing/scenarios/transport_test.go @@ -383,3 +383,275 @@ func TestVMessQuic(t *testing.T) { t.Error(err) } } + +func TestVMessQuicBBR(t *testing.T) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() + + userID := protocol.NewID(uuid.New()) + serverPort := udp.PickPort() + serverConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(serverPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ + ProtocolName: "quic", + TransportSettings: []*internet.TransportConfig{ + { + ProtocolName: "quic", + Settings: serial.ToTypedMessage(&quic.Config{ + Header: serial.ToTypedMessage(&wechat.VideoConfig{}), + Security: &protocol.SecurityConfig{ + Type: protocol.SecurityType_NONE, + }, + Congestion: &quic.Congestion{Type: "bbr"}, + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&inbound.Config{ + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + AlterId: 0, + }), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(clientPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ + StreamSettings: &internet.StreamConfig{ + ProtocolName: "quic", + TransportSettings: []*internet.TransportConfig{ + { + ProtocolName: "quic", + Settings: serial.ToTypedMessage(&quic.Config{ + Header: serial.ToTypedMessage(&wechat.VideoConfig{}), + Security: &protocol.SecurityConfig{ + Type: protocol.SecurityType_NONE, + }, + Congestion: &quic.Congestion{Type: "bbr"}, + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&outbound.Config{ + Receiver: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + AlterId: 0, + SecuritySettings: &protocol.SecurityConfig{ + Type: protocol.SecurityType_AES128_GCM, + }, + }), + }, + }, + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + if err != nil { + t.Fatal("Failed to initialize all servers: ", err.Error()) + } + defer CloseAllServers(servers) + + var errg errgroup.Group + for i := 0; i < 10; i++ { + errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) + } + + if err := errg.Wait(); err != nil { + t.Error(err) + } +} + +func TestVMessQuicBrutal(t *testing.T) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() + + userID := protocol.NewID(uuid.New()) + serverPort := udp.PickPort() + serverConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(serverPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ + ProtocolName: "quic", + TransportSettings: []*internet.TransportConfig{ + { + ProtocolName: "quic", + Settings: serial.ToTypedMessage(&quic.Config{ + Header: serial.ToTypedMessage(&wechat.VideoConfig{}), + Security: &protocol.SecurityConfig{ + Type: protocol.SecurityType_NONE, + }, + Congestion: &quic.Congestion{Type: "brutal", SendMbps: 300}, + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&inbound.Config{ + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + AlterId: 0, + }), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(clientPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ + StreamSettings: &internet.StreamConfig{ + ProtocolName: "quic", + TransportSettings: []*internet.TransportConfig{ + { + ProtocolName: "quic", + Settings: serial.ToTypedMessage(&quic.Config{ + Header: serial.ToTypedMessage(&wechat.VideoConfig{}), + Security: &protocol.SecurityConfig{ + Type: protocol.SecurityType_NONE, + }, + Congestion: &quic.Congestion{Type: "brutal", SendMbps: 300}, + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&outbound.Config{ + Receiver: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + AlterId: 0, + SecuritySettings: &protocol.SecurityConfig{ + Type: protocol.SecurityType_AES128_GCM, + }, + }), + }, + }, + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + if err != nil { + t.Fatal("Failed to initialize all servers: ", err.Error()) + } + defer CloseAllServers(servers) + + var errg errgroup.Group + for i := 0; i < 10; i++ { + errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) + } + + if err := errg.Wait(); err != nil { + t.Error(err) + } +} diff --git a/transport/internet/quic/congestion/bbr/bandwidth_sampler.go b/transport/internet/quic/congestion/bbr/bandwidth_sampler.go index cbc922dab8..0e770f1e4a 100644 --- a/transport/internet/quic/congestion/bbr/bandwidth_sampler.go +++ b/transport/internet/quic/congestion/bbr/bandwidth_sampler.go @@ -75,20 +75,6 @@ func maxExtraAckedEventFunc(a, b extraAckedEvent) int { return 0 } -func MaxBandwidth(a Bandwidth, b Bandwidth) Bandwidth { - if a > b { - return a - } - return b -} - -func MinBandwidth(a Bandwidth, b Bandwidth) Bandwidth { - if a < b { - return a - } - return b -} - // BandwidthSample type bandwidthSample struct { // The bandwidth at that particular sample. Zero if no valid bandwidth sample @@ -645,16 +631,14 @@ func (b *bandwidthSampler) OnCongestionEvent( lastAckedPacketSendState = sample.stateAtSend if sample.rtt != 0 { - if eventSample.sampleRtt > sample.rtt { - eventSample.sampleRtt = sample.rtt - } + eventSample.sampleRtt = min(eventSample.sampleRtt, sample.rtt) } if sample.bandwidth > eventSample.sampleMaxBandwidth { eventSample.sampleMaxBandwidth = sample.bandwidth eventSample.sampleIsAppLimited = sample.stateAtSend.isAppLimited } if sample.sendRate != infBandwidth { - maxSendRate = MaxBandwidth(maxSendRate, sample.sendRate) + maxSendRate = max(maxSendRate, sample.sendRate) } inflightSample := b.totalBytesAcked - lastAckedPacketSendState.totalBytesAcked if inflightSample > eventSample.sampleMaxInflight { @@ -679,12 +663,12 @@ func (b *bandwidthSampler) OnCongestionEvent( } isNewMaxBandwidth := eventSample.sampleMaxBandwidth > maxBandwidth - maxBandwidth = MaxBandwidth(maxBandwidth, eventSample.sampleMaxBandwidth) + maxBandwidth = max(maxBandwidth, eventSample.sampleMaxBandwidth) if b.limitMaxAckHeightTrackerBySendRate { - maxBandwidth = MaxBandwidth(maxBandwidth, maxSendRate) + maxBandwidth = max(maxBandwidth, maxSendRate) } - eventSample.extraAcked = b.onAckEventEnd(MinBandwidth(estBandwidthUpperBound, maxBandwidth), isNewMaxBandwidth, roundTripCount) + eventSample.extraAcked = b.onAckEventEnd(min(estBandwidthUpperBound, maxBandwidth), isNewMaxBandwidth, roundTripCount) return *eventSample } @@ -835,7 +819,7 @@ func (b *bandwidthSampler) onPacketAcknowledged(ackTime time.Time, packetNumber ackRate := BandwidthFromDelta(b.totalBytesAcked-a0.totalBytesAcked, ackTime.Sub(a0.ackTime)) - sample.bandwidth = MinBandwidth(sendRate, ackRate) + sample.bandwidth = min(sendRate, ackRate) // Note: this sample does not account for delayed acknowledgement time. This // means that the RTT measurements here can be artificially high, especially // on low bandwidth connections. diff --git a/transport/internet/quic/congestion/bbr/bbr_sender.go b/transport/internet/quic/congestion/bbr/bbr_sender.go index 1896bf6739..1745c43ed0 100644 --- a/transport/internet/quic/congestion/bbr/bbr_sender.go +++ b/transport/internet/quic/congestion/bbr/bbr_sender.go @@ -21,6 +21,8 @@ import ( // const ( + minBps = 65536 // 64 kbps + invalidPacketNumber = -1 initialCongestionWindowPackets = 32 @@ -283,10 +285,7 @@ func newBbrSender( maxCongestionWindowWithNetworkParametersAdjusted: initialMaxCongestionWindow, maxDatagramSize: initialMaxDatagramSize, } - b.pacer = common.NewPacer(func() congestion.ByteCount { - // Pacer wants bytes per second, but Bandwidth is in bits per second. - return congestion.ByteCount(float64(b.bandwidthEstimate()) * b.congestionWindowGain / float64(BytesPerSecond)) - }) + b.pacer = common.NewPacer(b.bandwidthForPacer) /* if b.tracer != nil { @@ -390,7 +389,7 @@ func (b *bbrSender) GetCongestionWindow() congestion.ByteCount { } if b.InRecovery() { - return common.MinByteCount(b.congestionWindow, b.recoveryWindow) + return min(b.congestionWindow, b.recoveryWindow) } return b.congestionWindow @@ -483,10 +482,19 @@ func (b *bbrSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, even b.calculateRecoveryWindow(bytesAcked, bytesLost) // Cleanup internal state. - if len(lostPackets) != 0 { - lastLostPacket := lostPackets[len(lostPackets)-1].PacketNumber - b.sampler.RemoveObsoletePackets(lastLostPacket) + // This is where we clean up obsolete (acked or lost) packets from the bandwidth sampler. + // The "least unacked" should actually be FirstOutstanding, but since we are not passing + // that through OnCongestionEventEx, we will only do an estimate using acked/lost packets + // for now. Because of fast retransmission, they should differ by no more than 2 packets. + // (this is controlled by packetThreshold in quic-go's sentPacketHandler) + var leastUnacked congestion.PacketNumber + if len(ackedPackets) != 0 { + leastUnacked = ackedPackets[len(ackedPackets)-1].PacketNumber - 2 + } else { + leastUnacked = lostPackets[len(lostPackets)-1].PacketNumber + 1 } + b.sampler.RemoveObsoletePackets(leastUnacked) + if isRoundStart { b.numLossEventsInRound = 0 b.bytesLostInRound = 0 @@ -536,6 +544,17 @@ func (b *bbrSender) bandwidthEstimate() Bandwidth { return b.maxBandwidth.GetBest() } +func (b *bbrSender) bandwidthForPacer() congestion.ByteCount { + bps := congestion.ByteCount(float64(b.bandwidthEstimate()) * b.congestionWindowGain / float64(BytesPerSecond)) + if bps < minBps { + // We need to make sure that the bandwidth value for pacer is never zero, + // otherwise it will go into an edge case where HasPacingBudget = false + // but TimeUntilSend is before, causing the quic-go send loop to go crazy and get stuck. + return minBps + } + return bps +} + // Returns the current estimate of the RTT of the connection. Outside of the // edge cases, this is minimum RTT. func (b *bbrSender) getMinRtt() time.Duration { @@ -563,7 +582,7 @@ func (b *bbrSender) getTargetCongestionWindow(gain float64) congestion.ByteCount congestionWindow = congestion.ByteCount(gain * float64(b.initialCongestionWindow)) } - return common.MaxByteCount(congestionWindow, b.minCongestionWindow) + return max(congestionWindow, b.minCongestionWindow) } // The target congestion window during PROBE_RTT. @@ -813,10 +832,7 @@ func (b *bbrSender) calculatePacingRate(bytesLost congestion.ByteCount) { // We are fairly sure overshoot happens if 1) there is at least one // non app-limited bw sample or 2) half of IW gets lost. Slow pacing // rate. - b.pacingRate = BandwidthFromDelta(b.cwndToCalculateMinPacingRate, b.rttStats.MinRTT()) - if targetRate > b.pacingRate { - b.pacingRate = targetRate - } + b.pacingRate = max(targetRate, BandwidthFromDelta(b.cwndToCalculateMinPacingRate, b.rttStats.MinRTT())) b.bytesLostWhileDetectingOvershooting = 0 b.detectOvershooting = false } @@ -824,9 +840,7 @@ func (b *bbrSender) calculatePacingRate(bytesLost congestion.ByteCount) { } // Do not decrease the pacing rate during startup. - if targetRate > b.pacingRate { - b.pacingRate = targetRate - } + b.pacingRate = max(b.pacingRate, targetRate) } // Determines the appropriate congestion window for the connection. @@ -849,7 +863,7 @@ func (b *bbrSender) calculateCongestionWindow(bytesAcked, excessAcked congestion // the CWND towards |target_window| by only increasing it |bytes_acked| at a // time. if b.isAtFullBandwidth { - b.congestionWindow = common.MinByteCount(targetWindow, b.congestionWindow+bytesAcked) + b.congestionWindow = min(targetWindow, b.congestionWindow+bytesAcked) } else if b.congestionWindow < targetWindow || b.sampler.TotalBytesAcked() < b.initialCongestionWindow { // If the connection is not yet out of startup phase, do not decrease the @@ -858,8 +872,8 @@ func (b *bbrSender) calculateCongestionWindow(bytesAcked, excessAcked congestion } // Enforce the limits on the congestion window. - b.congestionWindow = common.MaxByteCount(b.congestionWindow, b.minCongestionWindow) - b.congestionWindow = common.MinByteCount(b.congestionWindow, b.maxCongestionWindow) + b.congestionWindow = max(b.congestionWindow, b.minCongestionWindow) + b.congestionWindow = min(b.congestionWindow, b.maxCongestionWindow) } // Determines the appropriate window that constrains the in-flight during recovery. @@ -871,7 +885,7 @@ func (b *bbrSender) calculateRecoveryWindow(bytesAcked, bytesLost congestion.Byt // Set up the initial recovery window. if b.recoveryWindow == 0 { b.recoveryWindow = b.bytesInFlight + bytesAcked - b.recoveryWindow = common.MaxByteCount(b.minCongestionWindow, b.recoveryWindow) + b.recoveryWindow = max(b.minCongestionWindow, b.recoveryWindow) return } @@ -890,8 +904,8 @@ func (b *bbrSender) calculateRecoveryWindow(bytesAcked, bytesLost congestion.Byt } // Always allow sending at least |bytes_acked| in response. - b.recoveryWindow = common.MaxByteCount(b.recoveryWindow, b.bytesInFlight+bytesAcked) - b.recoveryWindow = common.MaxByteCount(b.minCongestionWindow, b.recoveryWindow) + b.recoveryWindow = max(b.recoveryWindow, b.bytesInFlight+bytesAcked) + b.recoveryWindow = max(b.minCongestionWindow, b.recoveryWindow) } // Return whether we should exit STARTUP due to excessive loss. diff --git a/transport/internet/quic/congestion/brutal/brutal.go b/transport/internet/quic/congestion/brutal/brutal.go index a225c62fd2..dbc31588c5 100644 --- a/transport/internet/quic/congestion/brutal/brutal.go +++ b/transport/internet/quic/congestion/brutal/brutal.go @@ -1,6 +1,9 @@ package brutal import ( + "fmt" + "os" + "strconv" "time" "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/common" @@ -9,9 +12,13 @@ import ( ) const ( - pktInfoSlotCount = 4 - minSampleCount = 50 - minAckRate = 0.8 + pktInfoSlotCount = 5 // slot index is based on seconds, so this is basically how many seconds we sample + minSampleCount = 50 + minAckRate = 0.8 + congestionWindowMultiplier = 2 + + debugEnv = "HYSTERIA_BRUTAL_DEBUG" + debugPrintInterval = 2 ) var _ congestion.CongestionControl = &BrutalSender{} @@ -24,6 +31,9 @@ type BrutalSender struct { pktInfoSlots [pktInfoSlotCount]pktInfo ackRate float64 + + debug bool + lastAckPrintTimestamp int64 } type pktInfo struct { @@ -33,10 +43,12 @@ type pktInfo struct { } func NewBrutalSender(bps uint64) *BrutalSender { + debug, _ := strconv.ParseBool(os.Getenv(debugEnv)) bs := &BrutalSender{ bps: congestion.ByteCount(bps), maxDatagramSize: congestion.InitialPacketSizeIPv4, ackRate: 1, + debug: debug, } bs.pacer = common.NewPacer(func() congestion.ByteCount { return congestion.ByteCount(float64(bs.bps) / bs.ackRate) @@ -65,7 +77,7 @@ func (b *BrutalSender) GetCongestionWindow() congestion.ByteCount { if rtt <= 0 { return 10240 } - return congestion.ByteCount(float64(b.bps) * rtt.Seconds() * 1.5 / b.ackRate) + return congestion.ByteCount(float64(b.bps) * rtt.Seconds() * congestionWindowMultiplier / b.ackRate) } func (b *BrutalSender) OnPacketSent(sentTime time.Time, bytesInFlight congestion.ByteCount, @@ -77,42 +89,36 @@ func (b *BrutalSender) OnPacketSent(sentTime time.Time, bytesInFlight congestion func (b *BrutalSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes congestion.ByteCount, priorInFlight congestion.ByteCount, eventTime time.Time, ) { - currentTimestamp := eventTime.Unix() - slot := currentTimestamp % pktInfoSlotCount - if b.pktInfoSlots[slot].Timestamp == currentTimestamp { - b.pktInfoSlots[slot].AckCount++ - } else { - // uninitialized slot or too old, reset - b.pktInfoSlots[slot].Timestamp = currentTimestamp - b.pktInfoSlots[slot].AckCount = 1 - b.pktInfoSlots[slot].LossCount = 0 - } - b.updateAckRate(currentTimestamp) + // Stub } func (b *BrutalSender) OnCongestionEvent(number congestion.PacketNumber, lostBytes congestion.ByteCount, priorInFlight congestion.ByteCount, ) { - currentTimestamp := time.Now().Unix() + // Stub +} + +func (b *BrutalSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, eventTime time.Time, ackedPackets []congestion.AckedPacketInfo, lostPackets []congestion.LostPacketInfo) { + currentTimestamp := eventTime.Unix() slot := currentTimestamp % pktInfoSlotCount if b.pktInfoSlots[slot].Timestamp == currentTimestamp { - b.pktInfoSlots[slot].LossCount++ + b.pktInfoSlots[slot].LossCount += uint64(len(lostPackets)) + b.pktInfoSlots[slot].AckCount += uint64(len(ackedPackets)) } else { // uninitialized slot or too old, reset b.pktInfoSlots[slot].Timestamp = currentTimestamp - b.pktInfoSlots[slot].AckCount = 0 - b.pktInfoSlots[slot].LossCount = 1 + b.pktInfoSlots[slot].AckCount = uint64(len(ackedPackets)) + b.pktInfoSlots[slot].LossCount = uint64(len(lostPackets)) } b.updateAckRate(currentTimestamp) } -func (b *BrutalSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, eventTime time.Time, ackedPackets []congestion.AckedPacketInfo, lostPackets []congestion.LostPacketInfo) { - // Stub -} - func (b *BrutalSender) SetMaxDatagramSize(size congestion.ByteCount) { b.maxDatagramSize = size b.pacer.SetMaxDatagramSize(size) + if b.debug { + b.debugPrint("SetMaxDatagramSize: %d", size) + } } func (b *BrutalSender) updateAckRate(currentTimestamp int64) { @@ -127,12 +133,29 @@ func (b *BrutalSender) updateAckRate(currentTimestamp int64) { } if ackCount+lossCount < minSampleCount { b.ackRate = 1 + if b.canPrintAckRate(currentTimestamp) { + b.lastAckPrintTimestamp = currentTimestamp + b.debugPrint("Not enough samples (total=%d, ack=%d, loss=%d, rtt=%d)", + ackCount+lossCount, ackCount, lossCount, b.rttStats.SmoothedRTT().Milliseconds()) + } + return } rate := float64(ackCount) / float64(ackCount+lossCount) if rate < minAckRate { b.ackRate = minAckRate + if b.canPrintAckRate(currentTimestamp) { + b.lastAckPrintTimestamp = currentTimestamp + b.debugPrint("ACK rate too low: %.2f, clamped to %.2f (total=%d, ack=%d, loss=%d, rtt=%d)", + rate, minAckRate, ackCount+lossCount, ackCount, lossCount, b.rttStats.SmoothedRTT().Milliseconds()) + } + return } b.ackRate = rate + if b.canPrintAckRate(currentTimestamp) { + b.lastAckPrintTimestamp = currentTimestamp + b.debugPrint("ACK rate: %.2f (total=%d, ack=%d, loss=%d, rtt=%d)", + rate, ackCount+lossCount, ackCount, lossCount, b.rttStats.SmoothedRTT().Milliseconds()) + } } func (b *BrutalSender) InSlowStart() bool { @@ -146,3 +169,13 @@ func (b *BrutalSender) InRecovery() bool { func (b *BrutalSender) MaybeExitSlowStart() {} func (b *BrutalSender) OnRetransmissionTimeout(packetsRetransmitted bool) {} + +func (b *BrutalSender) canPrintAckRate(currentTimestamp int64) bool { + return b.debug && currentTimestamp-b.lastAckPrintTimestamp >= debugPrintInterval +} + +func (b *BrutalSender) debugPrint(format string, a ...any) { + fmt.Printf("[BrutalSender] [%s] %s\n", + time.Now().Format("15:04:05"), + fmt.Sprintf(format, a...)) +} diff --git a/transport/internet/quic/congestion/common/pacer.go b/transport/internet/quic/congestion/common/pacer.go index 58a9df5119..4e089a3147 100644 --- a/transport/internet/quic/congestion/common/pacer.go +++ b/transport/internet/quic/congestion/common/pacer.go @@ -43,11 +43,14 @@ func (p *Pacer) Budget(now time.Time) congestion.ByteCount { return p.maxBurstSize() } budget := p.budgetAtLastSent + (p.getBandwidth()*congestion.ByteCount(now.Sub(p.lastSentTime).Nanoseconds()))/1e9 - return MinByteCount(p.maxBurstSize(), budget) + if budget < 0 { // protect against overflows + budget = congestion.ByteCount(1<<62 - 1) + } + return minByteCount(p.maxBurstSize(), budget) } func (p *Pacer) maxBurstSize() congestion.ByteCount { - return MaxByteCount( + return maxByteCount( congestion.ByteCount((congestion.MinPacingDelay+time.Millisecond).Nanoseconds())*p.getBandwidth()/1e9, maxBurstPackets*p.maxDatagramSize, ) @@ -59,7 +62,7 @@ func (p *Pacer) TimeUntilSend() time.Time { if p.budgetAtLastSent >= p.maxDatagramSize { return time.Time{} } - return p.lastSentTime.Add(MaxDuration( + return p.lastSentTime.Add(maxDuration( congestion.MinPacingDelay, time.Duration(math.Ceil(float64(p.maxDatagramSize-p.budgetAtLastSent)*1e9/ float64(p.getBandwidth())))*time.Nanosecond, @@ -70,21 +73,21 @@ func (p *Pacer) SetMaxDatagramSize(s congestion.ByteCount) { p.maxDatagramSize = s } -func MaxByteCount(a, b congestion.ByteCount) congestion.ByteCount { +func maxByteCount(a, b congestion.ByteCount) congestion.ByteCount { if a < b { return b } return a } -func MinByteCount(a, b congestion.ByteCount) congestion.ByteCount { +func minByteCount(a, b congestion.ByteCount) congestion.ByteCount { if a < b { return a } return b } -func MaxDuration(a, b time.Duration) time.Duration { +func maxDuration(a, b time.Duration) time.Duration { if a > b { return a } diff --git a/transport/internet/quic/congestion/utils.go b/transport/internet/quic/congestion/utils.go index a9d48e975d..3ff68f6fc1 100644 --- a/transport/internet/quic/congestion/utils.go +++ b/transport/internet/quic/congestion/utils.go @@ -1,9 +1,10 @@ package congestion import ( - "github.com/apernet/quic-go" "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/bbr" "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/brutal" + + "github.com/apernet/quic-go" ) func UseBBR(conn quic.Connection) { diff --git a/transport/internet/quic/dialer.go b/transport/internet/quic/dialer.go index 368fea6147..0fe900d908 100644 --- a/transport/internet/quic/dialer.go +++ b/transport/internet/quic/dialer.go @@ -181,6 +181,7 @@ func SetCongestion(conn quic.Connection, config *Config) { } else if congestionType == "bbr" { congestion.UseBBR(conn) } + newError("[QUIC] using congestion: ", congestionType).WriteToLog() } const ( From 9327ddf32a21b5ec507c3bb9730056438aaed340 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Sun, 22 Oct 2023 12:09:54 +0800 Subject: [PATCH 17/81] go mod tidy --- go.sum | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index 91ed5e4265..6dc7f120d9 100644 --- a/go.sum +++ b/go.sum @@ -82,7 +82,9 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= @@ -224,6 +226,7 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/onsi/ginkgo/v2 v2.10.0 h1:sfUl4qgLdvkChZrWCYndY2EAu9BRIw1YphNAzy1VNWs= github.com/onsi/ginkgo/v2 v2.10.0/go.mod h1:UDQOh5wbQUlMnkLfVaIUMtQ1Vus92oM+P2JX1aulgcE= github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= +github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= @@ -456,8 +459,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= From 07478e63d082a98066adce09d15f04c0c84f5b0e Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Thu, 26 Oct 2023 11:02:45 +0800 Subject: [PATCH 18/81] update vprotogen --- infra/vprotogen/main.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/infra/vprotogen/main.go b/infra/vprotogen/main.go index 863dfdc143..05ce25b7fa 100644 --- a/infra/vprotogen/main.go +++ b/infra/vprotogen/main.go @@ -124,14 +124,11 @@ func getInstalledProtocVersion(protocPath string) (string, error) { matched := versionRegexp.FindStringSubmatch(string(output)) installedVersion := "" if len(matched) == 0 { - // try new version of protoc - versionRegexp = regexp.MustCompile(`protoc\s*(\d+\.\d+)`) - matched = versionRegexp.FindStringSubmatch(string(output)) - installedVersion += "4." // in contrast to getProjectProtocVersion() + return "", errors.New("Can not parse protoc version.") } - if len(matched) == 0 { - return "", errors.New("Can not parse protoc version.") + if len(matched) == 2 { + installedVersion += "4." // in contrast to getProjectProtocVersion() } installedVersion += matched[1] fmt.Println("Using protoc version: " + installedVersion) From 150132dbf44211540ec6cc6ffd6979c74a203c77 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Thu, 26 Oct 2023 11:48:07 +0800 Subject: [PATCH 19/81] add test and fix golint --- testing/scenarios/transport_test.go | 136 ++++++++++++++++++ .../quic/congestion/bbr/bandwidth_sampler.go | 1 + .../quic/congestion/bbr/bbr_sender.go | 6 +- .../bbr/packet_number_indexed_queue.go | 1 - .../quic/congestion/bbr/windowed_filter.go | 4 +- 5 files changed, 141 insertions(+), 7 deletions(-) diff --git a/testing/scenarios/transport_test.go b/testing/scenarios/transport_test.go index 311f3eb70f..4f002cf9c3 100644 --- a/testing/scenarios/transport_test.go +++ b/testing/scenarios/transport_test.go @@ -655,3 +655,139 @@ func TestVMessQuicBrutal(t *testing.T) { t.Error(err) } } + +func TestVMessQuicBrutalBBR(t *testing.T) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() + + userID := protocol.NewID(uuid.New()) + serverPort := udp.PickPort() + serverConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(serverPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ + ProtocolName: "quic", + TransportSettings: []*internet.TransportConfig{ + { + ProtocolName: "quic", + Settings: serial.ToTypedMessage(&quic.Config{ + Header: serial.ToTypedMessage(&wechat.VideoConfig{}), + Security: &protocol.SecurityConfig{ + Type: protocol.SecurityType_NONE, + }, + Congestion: &quic.Congestion{Type: "bbr"}, + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&inbound.Config{ + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + AlterId: 0, + }), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(clientPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ + StreamSettings: &internet.StreamConfig{ + ProtocolName: "quic", + TransportSettings: []*internet.TransportConfig{ + { + ProtocolName: "quic", + Settings: serial.ToTypedMessage(&quic.Config{ + Header: serial.ToTypedMessage(&wechat.VideoConfig{}), + Security: &protocol.SecurityConfig{ + Type: protocol.SecurityType_NONE, + }, + Congestion: &quic.Congestion{Type: "brutal", SendMbps: 300}, + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&outbound.Config{ + Receiver: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + AlterId: 0, + SecuritySettings: &protocol.SecurityConfig{ + Type: protocol.SecurityType_AES128_GCM, + }, + }), + }, + }, + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + if err != nil { + t.Fatal("Failed to initialize all servers: ", err.Error()) + } + defer CloseAllServers(servers) + + var errg errgroup.Group + for i := 0; i < 10; i++ { + errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) + } + + if err := errg.Wait(); err != nil { + t.Error(err) + } +} diff --git a/transport/internet/quic/congestion/bbr/bandwidth_sampler.go b/transport/internet/quic/congestion/bbr/bandwidth_sampler.go index 0e770f1e4a..266af81f5b 100644 --- a/transport/internet/quic/congestion/bbr/bandwidth_sampler.go +++ b/transport/internet/quic/congestion/bbr/bandwidth_sampler.go @@ -1,3 +1,4 @@ +//nolint:golint,unused package bbr import ( diff --git a/transport/internet/quic/congestion/bbr/bbr_sender.go b/transport/internet/quic/congestion/bbr/bbr_sender.go index 1745c43ed0..26958a4f3d 100644 --- a/transport/internet/quic/congestion/bbr/bbr_sender.go +++ b/transport/internet/quic/congestion/bbr/bbr_sender.go @@ -1,3 +1,4 @@ +//nolint:golint,unused package bbr import ( @@ -917,10 +918,7 @@ func (b *bbrSender) shouldExitStartupDueToLoss(lastPacketSendState *sendTimeStat inflightAtSend := lastPacketSendState.bytesInFlight if inflightAtSend > 0 && b.bytesLostInRound > 0 { - if b.bytesLostInRound > congestion.ByteCount(float64(inflightAtSend)*quicBbr2DefaultLossThreshold) { - return true - } - return false + return b.bytesLostInRound > congestion.ByteCount(float64(inflightAtSend)*quicBbr2DefaultLossThreshold) } return false } diff --git a/transport/internet/quic/congestion/bbr/packet_number_indexed_queue.go b/transport/internet/quic/congestion/bbr/packet_number_indexed_queue.go index 86fe52d2be..ac4c51aafa 100644 --- a/transport/internet/quic/congestion/bbr/packet_number_indexed_queue.go +++ b/transport/internet/quic/congestion/bbr/packet_number_indexed_queue.go @@ -133,7 +133,6 @@ func (p *packetNumberIndexedQueue[T]) RemoveUpTo(packetNumber congestion.PacketN } p.clearup() - return } // IsEmpty return if queue is empty. diff --git a/transport/internet/quic/congestion/bbr/windowed_filter.go b/transport/internet/quic/congestion/bbr/windowed_filter.go index 4773bce597..bd9a5f7211 100644 --- a/transport/internet/quic/congestion/bbr/windowed_filter.go +++ b/transport/internet/quic/congestion/bbr/windowed_filter.go @@ -75,7 +75,7 @@ func MinFilter[O constraints.Ordered](a, b O) int { func NewWindowedFilter[V WindowedFilterValue, T WindowedFilterTime](windowLength T, comparator func(V, V) int) *WindowedFilter[V, T] { return &WindowedFilter[V, T]{ windowLength: windowLength, - estimates: make([]entry[V, T], 3, 3), + estimates: make([]entry[V, T], 3), comparator: comparator, } } @@ -158,5 +158,5 @@ func (f *WindowedFilter[V, T]) Reset(newSample V, newTime T) { } func (f *WindowedFilter[V, T]) Clear() { - f.estimates = make([]entry[V, T], 3, 3) + f.estimates = make([]entry[V, T], 3) } From 0b7f037645275a6b425d50dc533892f4616e8b47 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Thu, 26 Oct 2023 11:50:36 +0800 Subject: [PATCH 20/81] go mod tidy --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index ab1fd9693c..b9adfee621 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,7 @@ require ( go.starlark.net v0.0.0-20230612165344-9532f5667272 go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 golang.org/x/crypto v0.14.0 + golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 golang.org/x/net v0.17.0 golang.org/x/sync v0.4.0 golang.org/x/sys v0.13.0 @@ -75,7 +76,6 @@ require ( github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 // indirect github.com/xtaci/smux v1.5.24 // indirect go.uber.org/mock v0.3.0 // indirect - golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect golang.org/x/mod v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect From 9fa7e8705ba1f79912a0ccfbbd0531a48af1ad73 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Fri, 10 Nov 2023 16:44:12 +0800 Subject: [PATCH 21/81] add hysteria2(WIP) --- app/tun/config.pb.go | 6 - go.mod | 7 +- go.sum | 18 +- proxy/hysteria2/client.go | 198 ++++ proxy/hysteria2/config.go | 50 + proxy/hysteria2/config.pb.go | 367 +++++++ proxy/hysteria2/config.proto | 28 + proxy/hysteria2/errors.generated.go | 9 + proxy/hysteria2/protocol.go | 321 ++++++ proxy/hysteria2/server.go | 442 ++++++++ proxy/hysteria2/trojan.go | 1 + proxy/hysteria2/validator.go | 51 + transport/internet/hysteria2/config.go | 49 + transport/internet/hysteria2/config.pb.go | 256 +++++ transport/internet/hysteria2/config.proto | 26 + .../hysteria2/congestion/bbr/bandwidth.go | 27 + .../congestion/bbr/bandwidth_sampler.go | 875 ++++++++++++++++ .../hysteria2/congestion/bbr/bbr_sender.go | 942 ++++++++++++++++++ .../hysteria2/congestion/bbr/clock.go | 18 + .../bbr/packet_number_indexed_queue.go | 198 ++++ .../hysteria2/congestion/bbr/ringbuffer.go | 118 +++ .../congestion/bbr/windowed_filter.go | 162 +++ .../hysteria2/congestion/brutal/brutal.go | 181 ++++ .../hysteria2/congestion/common/pacer.go | 95 ++ .../internet/hysteria2/congestion/utils.go | 19 + transport/internet/hysteria2/conn.go | 199 ++++ transport/internet/hysteria2/dialer.go | 62 ++ .../internet/hysteria2/errors.generated.go | 9 + transport/internet/hysteria2/hub.go | 139 +++ transport/internet/hysteria2/hysteria.go | 25 + transport/internet/hysteria2/pool.go | 21 + 31 files changed, 4907 insertions(+), 12 deletions(-) create mode 100644 proxy/hysteria2/client.go create mode 100644 proxy/hysteria2/config.go create mode 100644 proxy/hysteria2/config.pb.go create mode 100644 proxy/hysteria2/config.proto create mode 100644 proxy/hysteria2/errors.generated.go create mode 100644 proxy/hysteria2/protocol.go create mode 100644 proxy/hysteria2/server.go create mode 100644 proxy/hysteria2/trojan.go create mode 100644 proxy/hysteria2/validator.go create mode 100644 transport/internet/hysteria2/config.go create mode 100644 transport/internet/hysteria2/config.pb.go create mode 100644 transport/internet/hysteria2/config.proto create mode 100644 transport/internet/hysteria2/congestion/bbr/bandwidth.go create mode 100644 transport/internet/hysteria2/congestion/bbr/bandwidth_sampler.go create mode 100644 transport/internet/hysteria2/congestion/bbr/bbr_sender.go create mode 100644 transport/internet/hysteria2/congestion/bbr/clock.go create mode 100644 transport/internet/hysteria2/congestion/bbr/packet_number_indexed_queue.go create mode 100644 transport/internet/hysteria2/congestion/bbr/ringbuffer.go create mode 100644 transport/internet/hysteria2/congestion/bbr/windowed_filter.go create mode 100644 transport/internet/hysteria2/congestion/brutal/brutal.go create mode 100644 transport/internet/hysteria2/congestion/common/pacer.go create mode 100644 transport/internet/hysteria2/congestion/utils.go create mode 100644 transport/internet/hysteria2/conn.go create mode 100644 transport/internet/hysteria2/dialer.go create mode 100644 transport/internet/hysteria2/errors.generated.go create mode 100644 transport/internet/hysteria2/hub.go create mode 100644 transport/internet/hysteria2/hysteria.go create mode 100644 transport/internet/hysteria2/pool.go diff --git a/app/tun/config.pb.go b/app/tun/config.pb.go index 47f757f38a..ddadd36293 100644 --- a/app/tun/config.pb.go +++ b/app/tun/config.pb.go @@ -1,9 +1,3 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc v4.24.4 -// source: app/tun/config.proto - package tun import ( diff --git a/go.mod b/go.mod index 00db46066c..38e3669bb3 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,8 @@ go 1.21 require ( github.com/adrg/xdg v0.4.0 - github.com/apernet/quic-go v0.39.1-0.20230930045547-13cecb45baa8 + github.com/apernet/hysteria/core v1.3.5 + github.com/apernet/quic-go v0.39.4-0.20231029220436-0faa281e4a77 github.com/go-chi/chi/v5 v5.0.10 github.com/go-chi/render v1.0.3 github.com/go-playground/validator/v10 v10.15.5 @@ -39,6 +40,8 @@ require ( h12.io/socks v1.0.3 ) +replace github.com/apernet/hysteria/core => ../../hysteria/core + require ( github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 // indirect github.com/ajg/form v1.5.1 // indirect @@ -70,10 +73,12 @@ require ( github.com/pion/sctp v1.8.7 // indirect github.com/pion/transport/v2 v2.2.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.4.1 // indirect github.com/quic-go/quic-go v0.40.0 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 // indirect + github.com/stretchr/objx v0.5.0 // indirect github.com/xtaci/smux v1.5.24 // indirect go.uber.org/mock v0.3.0 // indirect golang.org/x/mod v0.13.0 // indirect diff --git a/go.sum b/go.sum index 63d38b3267..f3aa5eb0f3 100644 --- a/go.sum +++ b/go.sum @@ -25,8 +25,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/apernet/quic-go v0.39.1-0.20230930045547-13cecb45baa8 h1:jZKdY1/SFnt6iRzSBMzaeXmgWKwSsAW2slf/o0+b3bs= -github.com/apernet/quic-go v0.39.1-0.20230930045547-13cecb45baa8/go.mod h1:UwsoszQlzTm+dBDuFEwWBYt46K56WqlFEN0RWLvQ0rE= +github.com/apernet/quic-go v0.39.4-0.20231029220436-0faa281e4a77 h1:X45zzYXs02HsYVCi6lQOs4sEvzmCXykxcVvAcQypIqM= +github.com/apernet/quic-go v0.39.4-0.20231029220436-0faa281e4a77/go.mod h1:UwsoszQlzTm+dBDuFEwWBYt46K56WqlFEN0RWLvQ0rE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -191,11 +191,11 @@ github.com/klauspost/reedsolomon v1.11.7 h1:9uaHU0slncktTEEg4+7Vl7q7XUNMBUOK4R9g github.com/klauspost/reedsolomon v1.11.7/go.mod h1:4bXRN+cVzMdml6ti7qLouuYi32KHJ5MGv0Qd8a47h6A= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lunixbochs/struc v0.0.0-20190916212049-a5c72983bc42/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg= @@ -226,6 +226,8 @@ github.com/mustafaturan/monoton v1.0.0/go.mod h1:FOnE7NV3s3EWPXb8/7+/OSdiMBbdlkV github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo/v2 v2.10.0 h1:sfUl4qgLdvkChZrWCYndY2EAu9BRIw1YphNAzy1VNWs= github.com/onsi/ginkgo/v2 v2.10.0/go.mod h1:UDQOh5wbQUlMnkLfVaIUMtQ1Vus92oM+P2JX1aulgcE= @@ -271,6 +273,8 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/quic-go v0.40.0 h1:GYd1iznlKm7dpHD7pOVpUvItgMPo/jrMgDWZhMCecqw= @@ -308,6 +312,7 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -348,6 +353,8 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.starlark.net v0.0.0-20230612165344-9532f5667272 h1:2/wtqS591wZyD2OsClsVBKRPEvBsQt/Js+fsCiYhwu8= go.starlark.net v0.0.0-20230612165344-9532f5667272/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -560,8 +567,9 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= diff --git a/proxy/hysteria2/client.go b/proxy/hysteria2/client.go new file mode 100644 index 0000000000..a2612d0ad4 --- /dev/null +++ b/proxy/hysteria2/client.go @@ -0,0 +1,198 @@ +package hysteria2 + +import ( + "context" + + core "github.com/v2fly/v2ray-core/v5" + "github.com/v2fly/v2ray-core/v5/common" + "github.com/v2fly/v2ray-core/v5/common/buf" + "github.com/v2fly/v2ray-core/v5/common/net" + "github.com/v2fly/v2ray-core/v5/common/net/packetaddr" + "github.com/v2fly/v2ray-core/v5/common/protocol" + "github.com/v2fly/v2ray-core/v5/common/retry" + "github.com/v2fly/v2ray-core/v5/common/session" + "github.com/v2fly/v2ray-core/v5/common/signal" + "github.com/v2fly/v2ray-core/v5/common/task" + "github.com/v2fly/v2ray-core/v5/features/policy" + "github.com/v2fly/v2ray-core/v5/proxy" + "github.com/v2fly/v2ray-core/v5/transport" + "github.com/v2fly/v2ray-core/v5/transport/internet" + "github.com/v2fly/v2ray-core/v5/transport/internet/udp" +) + +// Client is an inbound handler for trojan protocol +type Client struct { + serverPicker protocol.ServerPicker + policyManager policy.Manager +} + +// NewClient create a new trojan client. +func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) { + serverList := protocol.NewServerList() + for _, rec := range config.Server { + s, err := protocol.NewServerSpecFromPB(rec) + if err != nil { + return nil, newError("failed to parse server spec").Base(err) + } + serverList.AddServer(s) + } + if serverList.Size() == 0 { + return nil, newError("0 server") + } + + v := core.MustFromContext(ctx) + client := &Client{ + serverPicker: protocol.NewRoundRobinServerPicker(serverList), + policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), + } + return client, nil +} + +// Process implements OutboundHandler.Process(). +func (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error { + outbound := session.OutboundFromContext(ctx) + if outbound == nil || !outbound.Target.IsValid() { + return newError("target not specified") + } + destination := outbound.Target + network := destination.Network + + var server *protocol.ServerSpec + var conn internet.Connection + + err := retry.ExponentialBackoff(5, 100).On(func() error { + server = c.serverPicker.PickServer() + rawConn, err := dialer.Dial(ctx, server.Destination()) + if err != nil { + return err + } + + conn = rawConn + return nil + }) + if err != nil { + return newError("failed to find an available destination").AtWarning().Base(err) + } + newError("tunneling request to ", destination, " via ", server.Destination().NetAddr()).WriteToLog(session.ExportIDToError(ctx)) + + defer conn.Close() + + user := server.PickUser() + account, ok := user.Account.(*MemoryAccount) + if !ok { + return newError("user account is not valid") + } + + sessionPolicy := c.policyManager.ForLevel(user.Level) + ctx, cancel := context.WithCancel(ctx) + timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) + + if packetConn, err := packetaddr.ToPacketAddrConn(link, destination); err == nil { + postRequest := func() error { + defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) + + var buffer [2048]byte + n, addr, err := packetConn.ReadFrom(buffer[:]) + if err != nil { + return newError("failed to read a packet").Base(err) + } + dest := net.DestinationFromAddr(addr) + + bufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn)) + connWriter := &ConnWriter{Writer: bufferWriter, Target: dest, Account: account} + packetWriter := &PacketWriter{Writer: connWriter, Target: dest} + + // write some request payload to buffer + if _, err := packetWriter.WriteTo(buffer[:n], addr); err != nil { + return newError("failed to write a request payload").Base(err) + } + + // Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer + if err = bufferWriter.SetBuffered(false); err != nil { + return newError("failed to flush payload").Base(err).AtWarning() + } + + return udp.CopyPacketConn(packetWriter, packetConn, udp.UpdateActivity(timer)) + } + + getResponse := func() error { + defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) + + packetReader := &PacketReader{Reader: conn} + packetConnectionReader := &PacketConnectionReader{reader: packetReader} + + return udp.CopyPacketConn(packetConn, packetConnectionReader, udp.UpdateActivity(timer)) + } + + responseDoneAndCloseWriter := task.OnSuccess(getResponse, task.Close(link.Writer)) + if err := task.Run(ctx, postRequest, responseDoneAndCloseWriter); err != nil { + return newError("connection ends").Base(err) + } + + return nil + } + + postRequest := func() error { + defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) + + var bodyWriter buf.Writer + bufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn)) + connWriter := &ConnWriter{Writer: bufferWriter, Target: destination, Account: account} + + if destination.Network == net.Network_UDP { + bodyWriter = &PacketWriter{Writer: connWriter, Target: destination} + } else { + bodyWriter = connWriter + } + + // write some request payload to buffer + err = buf.CopyOnceTimeout(link.Reader, bodyWriter, proxy.FirstPayloadTimeout) + switch err { + case buf.ErrNotTimeoutReader, buf.ErrReadTimeout: + if err := connWriter.WriteHeader(); err != nil { + return newError("failed to write request header").Base(err).AtWarning() + } + case nil: + default: + return newError("failed to write a request payload").Base(err).AtWarning() + } + + // Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer + if err = bufferWriter.SetBuffered(false); err != nil { + return newError("failed to flush payload").Base(err).AtWarning() + } + + if err = buf.Copy(link.Reader, bodyWriter, buf.UpdateActivity(timer)); err != nil { + return newError("failed to transfer request payload").Base(err).AtInfo() + } + + return nil + } + + getResponse := func() error { + defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) + + var reader buf.Reader + if network == net.Network_UDP { + reader = &PacketReader{ + Reader: conn, + } + } else { + reader = buf.NewReader(conn) + } + return buf.Copy(reader, link.Writer, buf.UpdateActivity(timer)) + } + + responseDoneAndCloseWriter := task.OnSuccess(getResponse, task.Close(link.Writer)) + if err := task.Run(ctx, postRequest, responseDoneAndCloseWriter); err != nil { + return newError("connection ends").Base(err) + } + + return nil +} + +func init() { + common.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { + return NewClient(ctx, config.(*ClientConfig)) + })) +} diff --git a/proxy/hysteria2/config.go b/proxy/hysteria2/config.go new file mode 100644 index 0000000000..af06745ea6 --- /dev/null +++ b/proxy/hysteria2/config.go @@ -0,0 +1,50 @@ +package hysteria2 + +import ( + "crypto/sha256" + "encoding/hex" + "fmt" + + "github.com/v2fly/v2ray-core/v5/common" + "github.com/v2fly/v2ray-core/v5/common/protocol" +) + +// MemoryAccount is an account type converted from Account. +type MemoryAccount struct { + Password string + Key []byte +} + +// AsAccount implements protocol.AsAccount. +func (a *Account) AsAccount() (protocol.Account, error) { + password := a.GetPassword() + key := hexSha224(password) + return &MemoryAccount{ + Password: password, + Key: key, + }, nil +} + +// Equals implements protocol.Account.Equals(). +func (a *MemoryAccount) Equals(another protocol.Account) bool { + if account, ok := another.(*MemoryAccount); ok { + return a.Password == account.Password + } + return false +} + +func hexSha224(password string) []byte { + buf := make([]byte, 56) + hash := sha256.New224() + common.Must2(hash.Write([]byte(password))) + hex.Encode(buf, hash.Sum(nil)) + return buf +} + +func hexString(data []byte) string { + str := "" + for _, v := range data { + str += fmt.Sprintf("%02x", v) + } + return str +} diff --git a/proxy/hysteria2/config.pb.go b/proxy/hysteria2/config.pb.go new file mode 100644 index 0000000000..c28088de41 --- /dev/null +++ b/proxy/hysteria2/config.pb.go @@ -0,0 +1,367 @@ +package hysteria2 + +import ( + protocol "github.com/v2fly/v2ray-core/v5/common/protocol" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type OBFS struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` +} + +func (x *OBFS) Reset() { + *x = OBFS{} + if protoimpl.UnsafeEnabled { + mi := &file_proxy_hysteria2_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OBFS) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OBFS) ProtoMessage() {} + +func (x *OBFS) ProtoReflect() protoreflect.Message { + mi := &file_proxy_hysteria2_config_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OBFS.ProtoReflect.Descriptor instead. +func (*OBFS) Descriptor() ([]byte, []int) { + return file_proxy_hysteria2_config_proto_rawDescGZIP(), []int{0} +} + +func (x *OBFS) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *OBFS) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +type Account struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Password string `protobuf:"bytes,1,opt,name=password,proto3" json:"password,omitempty"` + Obfs *OBFS `protobuf:"bytes,2,opt,name=obfs,proto3" json:"obfs,omitempty"` +} + +func (x *Account) Reset() { + *x = Account{} + if protoimpl.UnsafeEnabled { + mi := &file_proxy_hysteria2_config_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Account) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Account) ProtoMessage() {} + +func (x *Account) ProtoReflect() protoreflect.Message { + mi := &file_proxy_hysteria2_config_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Account.ProtoReflect.Descriptor instead. +func (*Account) Descriptor() ([]byte, []int) { + return file_proxy_hysteria2_config_proto_rawDescGZIP(), []int{1} +} + +func (x *Account) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *Account) GetObfs() *OBFS { + if x != nil { + return x.Obfs + } + return nil +} + +type ClientConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Server []*protocol.ServerEndpoint `protobuf:"bytes,1,rep,name=server,proto3" json:"server,omitempty"` +} + +func (x *ClientConfig) Reset() { + *x = ClientConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_proxy_hysteria2_config_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientConfig) ProtoMessage() {} + +func (x *ClientConfig) ProtoReflect() protoreflect.Message { + mi := &file_proxy_hysteria2_config_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientConfig.ProtoReflect.Descriptor instead. +func (*ClientConfig) Descriptor() ([]byte, []int) { + return file_proxy_hysteria2_config_proto_rawDescGZIP(), []int{2} +} + +func (x *ClientConfig) GetServer() []*protocol.ServerEndpoint { + if x != nil { + return x.Server + } + return nil +} + +type ServerConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Users []*protocol.User `protobuf:"bytes,1,rep,name=users,proto3" json:"users,omitempty"` +} + +func (x *ServerConfig) Reset() { + *x = ServerConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_proxy_hysteria2_config_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServerConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerConfig) ProtoMessage() {} + +func (x *ServerConfig) ProtoReflect() protoreflect.Message { + mi := &file_proxy_hysteria2_config_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerConfig.ProtoReflect.Descriptor instead. +func (*ServerConfig) Descriptor() ([]byte, []int) { + return file_proxy_hysteria2_config_proto_rawDescGZIP(), []int{3} +} + +func (x *ServerConfig) GetUsers() []*protocol.User { + if x != nil { + return x.Users + } + return nil +} + +var File_proxy_hysteria2_config_proto protoreflect.FileDescriptor + +var file_proxy_hysteria2_config_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, + 0x32, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1a, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x1a, 0x1a, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, + 0x70, 0x65, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x36, 0x0a, 0x04, 0x4f, 0x42, 0x46, + 0x53, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x22, 0x5b, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x34, 0x0a, 0x04, 0x6f, 0x62, 0x66, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, + 0x69, 0x61, 0x32, 0x2e, 0x4f, 0x42, 0x46, 0x53, 0x52, 0x04, 0x6f, 0x62, 0x66, 0x73, 0x22, 0x52, + 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, + 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x22, 0x46, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x36, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x42, 0x6f, 0x0a, 0x1e, 0x63, 0x6f, + 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x2e, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, + 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, + 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, + 0x1a, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, + 0x79, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_proxy_hysteria2_config_proto_rawDescOnce sync.Once + file_proxy_hysteria2_config_proto_rawDescData = file_proxy_hysteria2_config_proto_rawDesc +) + +func file_proxy_hysteria2_config_proto_rawDescGZIP() []byte { + file_proxy_hysteria2_config_proto_rawDescOnce.Do(func() { + file_proxy_hysteria2_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_proxy_hysteria2_config_proto_rawDescData) + }) + return file_proxy_hysteria2_config_proto_rawDescData +} + +var file_proxy_hysteria2_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_proxy_hysteria2_config_proto_goTypes = []interface{}{ + (*OBFS)(nil), // 0: v2ray.core.proxy.hysteria2.OBFS + (*Account)(nil), // 1: v2ray.core.proxy.hysteria2.Account + (*ClientConfig)(nil), // 2: v2ray.core.proxy.hysteria2.ClientConfig + (*ServerConfig)(nil), // 3: v2ray.core.proxy.hysteria2.ServerConfig + (*protocol.ServerEndpoint)(nil), // 4: v2ray.core.common.protocol.ServerEndpoint + (*protocol.User)(nil), // 5: v2ray.core.common.protocol.User +} +var file_proxy_hysteria2_config_proto_depIdxs = []int32{ + 0, // 0: v2ray.core.proxy.hysteria2.Account.obfs:type_name -> v2ray.core.proxy.hysteria2.OBFS + 4, // 1: v2ray.core.proxy.hysteria2.ClientConfig.server:type_name -> v2ray.core.common.protocol.ServerEndpoint + 5, // 2: v2ray.core.proxy.hysteria2.ServerConfig.users:type_name -> v2ray.core.common.protocol.User + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_proxy_hysteria2_config_proto_init() } +func file_proxy_hysteria2_config_proto_init() { + if File_proxy_hysteria2_config_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proxy_hysteria2_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OBFS); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proxy_hysteria2_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Account); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proxy_hysteria2_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proxy_hysteria2_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServerConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proxy_hysteria2_config_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_proxy_hysteria2_config_proto_goTypes, + DependencyIndexes: file_proxy_hysteria2_config_proto_depIdxs, + MessageInfos: file_proxy_hysteria2_config_proto_msgTypes, + }.Build() + File_proxy_hysteria2_config_proto = out.File + file_proxy_hysteria2_config_proto_rawDesc = nil + file_proxy_hysteria2_config_proto_goTypes = nil + file_proxy_hysteria2_config_proto_depIdxs = nil +} diff --git a/proxy/hysteria2/config.proto b/proxy/hysteria2/config.proto new file mode 100644 index 0000000000..9e445f2743 --- /dev/null +++ b/proxy/hysteria2/config.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; + +package v2ray.core.proxy.hysteria2; +option csharp_namespace = "V2Ray.Core.Proxy.Hysteria2"; +option go_package = "github.com/v2fly/v2ray-core/v5/proxy/hysteria2"; +option java_package = "com.v2ray.core.proxy.hysteria2"; +option java_multiple_files = true; + +import "common/protocol/user.proto"; +import "common/protocol/server_spec.proto"; + +message OBFS { + string type = 1; + string password = 2; +} + +message Account { + string password = 1; + OBFS obfs = 2; +} + +message ClientConfig { + repeated v2ray.core.common.protocol.ServerEndpoint server = 1; +} + +message ServerConfig { + repeated v2ray.core.common.protocol.User users = 1; +} diff --git a/proxy/hysteria2/errors.generated.go b/proxy/hysteria2/errors.generated.go new file mode 100644 index 0000000000..1053170313 --- /dev/null +++ b/proxy/hysteria2/errors.generated.go @@ -0,0 +1,9 @@ +package hysteria2 + +import "github.com/v2fly/v2ray-core/v5/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go new file mode 100644 index 0000000000..8f9438ee45 --- /dev/null +++ b/proxy/hysteria2/protocol.go @@ -0,0 +1,321 @@ +package hysteria2 + +import ( + "encoding/binary" + "io" + gonet "net" + + "github.com/v2fly/v2ray-core/v5/common/buf" + "github.com/v2fly/v2ray-core/v5/common/net" + "github.com/v2fly/v2ray-core/v5/common/protocol" +) + +var ( + crlf = []byte{'\r', '\n'} + + addrParser = protocol.NewAddressParser( + protocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4), + protocol.AddressFamilyByte(0x04, net.AddressFamilyIPv6), + protocol.AddressFamilyByte(0x03, net.AddressFamilyDomain), + ) +) + +const ( + commandTCP byte = 1 + commandUDP byte = 3 +) + +// ConnWriter is TCP Connection Writer Wrapper for trojan protocol +type ConnWriter struct { + io.Writer + Target net.Destination + Account *MemoryAccount + headerSent bool +} + +// Write implements io.Writer +func (c *ConnWriter) Write(p []byte) (n int, err error) { + if !c.headerSent { + if err := c.writeHeader(); err != nil { + return 0, newError("failed to write request header").Base(err) + } + } + + return c.Writer.Write(p) +} + +// WriteMultiBuffer implements buf.Writer +func (c *ConnWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { + defer buf.ReleaseMulti(mb) + + for _, b := range mb { + if !b.IsEmpty() { + if _, err := c.Write(b.Bytes()); err != nil { + return err + } + } + } + + return nil +} + +func (c *ConnWriter) WriteHeader() error { + if !c.headerSent { + if err := c.writeHeader(); err != nil { + return err + } + } + return nil +} + +func (c *ConnWriter) writeHeader() error { + buffer := buf.StackNew() + defer buffer.Release() + + command := commandTCP + if c.Target.Network == net.Network_UDP { + command = commandUDP + } + + if _, err := buffer.Write(c.Account.Key); err != nil { + return err + } + if _, err := buffer.Write(crlf); err != nil { + return err + } + if err := buffer.WriteByte(command); err != nil { + return err + } + if err := addrParser.WriteAddressPort(&buffer, c.Target.Address, c.Target.Port); err != nil { + return err + } + if _, err := buffer.Write(crlf); err != nil { + return err + } + + _, err := c.Writer.Write(buffer.Bytes()) + if err == nil { + c.headerSent = true + } + + return err +} + +// PacketWriter UDP Connection Writer Wrapper for trojan protocol +type PacketWriter struct { + io.Writer + Target net.Destination +} + +// WriteMultiBuffer implements buf.Writer +func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { + for _, b := range mb { + if b.IsEmpty() { + continue + } + if _, err := w.writePacket(b.Bytes(), w.Target); err != nil { + buf.ReleaseMulti(mb) + return err + } + } + + return nil +} + +// WriteMultiBufferWithMetadata writes udp packet with destination specified +func (w *PacketWriter) WriteMultiBufferWithMetadata(mb buf.MultiBuffer, dest net.Destination) error { + for _, b := range mb { + if b.IsEmpty() { + continue + } + if _, err := w.writePacket(b.Bytes(), dest); err != nil { + buf.ReleaseMulti(mb) + return err + } + } + + return nil +} + +func (w *PacketWriter) WriteTo(payload []byte, addr gonet.Addr) (int, error) { + dest := net.DestinationFromAddr(addr) + + return w.writePacket(payload, dest) +} + +func (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, error) { // nolint: unparam + var addrPortLen int32 + switch dest.Address.Family() { + case net.AddressFamilyDomain: + if protocol.IsDomainTooLong(dest.Address.Domain()) { + return 0, newError("Super long domain is not supported: ", dest.Address.Domain()) + } + addrPortLen = 1 + 1 + int32(len(dest.Address.Domain())) + 2 + case net.AddressFamilyIPv4: + addrPortLen = 1 + 4 + 2 + case net.AddressFamilyIPv6: + addrPortLen = 1 + 16 + 2 + default: + panic("Unknown address type.") + } + + length := len(payload) + lengthBuf := [2]byte{} + binary.BigEndian.PutUint16(lengthBuf[:], uint16(length)) + + buffer := buf.NewWithSize(addrPortLen + 2 + 2 + int32(length)) + defer buffer.Release() + + if err := addrParser.WriteAddressPort(buffer, dest.Address, dest.Port); err != nil { + return 0, err + } + if _, err := buffer.Write(lengthBuf[:]); err != nil { + return 0, err + } + if _, err := buffer.Write(crlf); err != nil { + return 0, err + } + if _, err := buffer.Write(payload); err != nil { + return 0, err + } + _, err := w.Write(buffer.Bytes()) + if err != nil { + return 0, err + } + + return length, nil +} + +// ConnReader is TCP Connection Reader Wrapper for trojan protocol +type ConnReader struct { + io.Reader + Target net.Destination + headerParsed bool +} + +// ParseHeader parses the trojan protocol header +func (c *ConnReader) ParseHeader() error { + var crlf [2]byte + var command [1]byte + var hash [56]byte + if _, err := io.ReadFull(c.Reader, hash[:]); err != nil { + return newError("failed to read user hash").Base(err) + } + + if _, err := io.ReadFull(c.Reader, crlf[:]); err != nil { + return newError("failed to read crlf").Base(err) + } + + if _, err := io.ReadFull(c.Reader, command[:]); err != nil { + return newError("failed to read command").Base(err) + } + + network := net.Network_TCP + if command[0] == commandUDP { + network = net.Network_UDP + } + + addr, port, err := addrParser.ReadAddressPort(nil, c.Reader) + if err != nil { + return newError("failed to read address and port").Base(err) + } + c.Target = net.Destination{Network: network, Address: addr, Port: port} + + if _, err := io.ReadFull(c.Reader, crlf[:]); err != nil { + return newError("failed to read crlf").Base(err) + } + + c.headerParsed = true + return nil +} + +// Read implements io.Reader +func (c *ConnReader) Read(p []byte) (int, error) { + if !c.headerParsed { + if err := c.ParseHeader(); err != nil { + return 0, err + } + } + + return c.Reader.Read(p) +} + +// ReadMultiBuffer implements buf.Reader +func (c *ConnReader) ReadMultiBuffer() (buf.MultiBuffer, error) { + b := buf.New() + _, err := b.ReadFrom(c) + return buf.MultiBuffer{b}, err +} + +// PacketPayload combines udp payload and destination +type PacketPayload struct { + Target net.Destination + Buffer buf.MultiBuffer +} + +// PacketReader is UDP Connection Reader Wrapper for trojan protocol +type PacketReader struct { + io.Reader +} + +// ReadMultiBuffer implements buf.Reader +func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) { + p, err := r.ReadMultiBufferWithMetadata() + if p != nil { + return p.Buffer, err + } + return nil, err +} + +// ReadMultiBufferWithMetadata reads udp packet with destination +func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) { + addr, port, err := addrParser.ReadAddressPort(nil, r) + if err != nil { + return nil, newError("failed to read address and port").Base(err) + } + + var lengthBuf [2]byte + if _, err := io.ReadFull(r, lengthBuf[:]); err != nil { + return nil, newError("failed to read payload length").Base(err) + } + + length := binary.BigEndian.Uint16(lengthBuf[:]) + + var crlf [2]byte + if _, err := io.ReadFull(r, crlf[:]); err != nil { + return nil, newError("failed to read crlf").Base(err) + } + + dest := net.UDPDestination(addr, port) + + b := buf.NewWithSize(int32(length)) + _, err = b.ReadFullFrom(r, int32(length)) + if err != nil { + return nil, newError("failed to read payload").Base(err) + } + + return &PacketPayload{Target: dest, Buffer: buf.MultiBuffer{b}}, nil +} + +type PacketConnectionReader struct { + reader *PacketReader + payload *PacketPayload +} + +func (r *PacketConnectionReader) ReadFrom(p []byte) (n int, addr gonet.Addr, err error) { + if r.payload == nil || r.payload.Buffer.IsEmpty() { + r.payload, err = r.reader.ReadMultiBufferWithMetadata() + if err != nil { + return + } + } + + addr = &gonet.UDPAddr{ + IP: r.payload.Target.Address.IP(), + Port: int(r.payload.Target.Port), + } + + r.payload.Buffer, n = buf.SplitFirstBytes(r.payload.Buffer, p) + + return +} diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go new file mode 100644 index 0000000000..671a33d156 --- /dev/null +++ b/proxy/hysteria2/server.go @@ -0,0 +1,442 @@ +package hysteria2 + +import ( + "context" + "io" + "strconv" + "time" + + core "github.com/v2fly/v2ray-core/v5" + "github.com/v2fly/v2ray-core/v5/common" + "github.com/v2fly/v2ray-core/v5/common/buf" + "github.com/v2fly/v2ray-core/v5/common/errors" + "github.com/v2fly/v2ray-core/v5/common/log" + "github.com/v2fly/v2ray-core/v5/common/net" + "github.com/v2fly/v2ray-core/v5/common/net/packetaddr" + "github.com/v2fly/v2ray-core/v5/common/protocol" + udp_proto "github.com/v2fly/v2ray-core/v5/common/protocol/udp" + "github.com/v2fly/v2ray-core/v5/common/retry" + "github.com/v2fly/v2ray-core/v5/common/session" + "github.com/v2fly/v2ray-core/v5/common/signal" + "github.com/v2fly/v2ray-core/v5/common/task" + "github.com/v2fly/v2ray-core/v5/features/policy" + "github.com/v2fly/v2ray-core/v5/features/routing" + "github.com/v2fly/v2ray-core/v5/transport/internet" + "github.com/v2fly/v2ray-core/v5/transport/internet/tls" + "github.com/v2fly/v2ray-core/v5/transport/internet/udp" +) + +func init() { + common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { + return NewServer(ctx, config.(*ServerConfig)) + })) +} + +// Server is an inbound connection handler that handles messages in trojan protocol. +type Server struct { + policyManager policy.Manager + validator *Validator + fallbacks map[string]map[string]*Fallback // or nil + packetEncoding packetaddr.PacketAddrType +} + +// NewServer creates a new trojan inbound handler. +func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { + validator := new(Validator) + for _, user := range config.Users { + u, err := user.ToMemoryUser() + if err != nil { + return nil, newError("failed to get trojan user").Base(err).AtError() + } + + if err := validator.Add(u); err != nil { + return nil, newError("failed to add user").Base(err).AtError() + } + } + + v := core.MustFromContext(ctx) + server := &Server{ + policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), + validator: validator, + packetEncoding: config.PacketEncoding, + } + + if config.Fallbacks != nil { + server.fallbacks = make(map[string]map[string]*Fallback) + for _, fb := range config.Fallbacks { + if server.fallbacks[fb.Alpn] == nil { + server.fallbacks[fb.Alpn] = make(map[string]*Fallback) + } + server.fallbacks[fb.Alpn][fb.Path] = fb + } + if server.fallbacks[""] != nil { + for alpn, pfb := range server.fallbacks { + if alpn != "" { // && alpn != "h2" { + for path, fb := range server.fallbacks[""] { + if pfb[path] == nil { + pfb[path] = fb + } + } + } + } + } + } + + return server, nil +} + +// AddUser implements proxy.UserManager.AddUser(). +func (s *Server) AddUser(ctx context.Context, u *protocol.MemoryUser) error { + return s.validator.Add(u) +} + +// RemoveUser implements proxy.UserManager.RemoveUser(). +func (s *Server) RemoveUser(ctx context.Context, e string) error { + return s.validator.Del(e) +} + +// Network implements proxy.Inbound.Network(). +func (s *Server) Network() []net.Network { + return []net.Network{net.Network_TCP, net.Network_UNIX} +} + +// Process implements proxy.Inbound.Process(). +func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error { + sid := session.ExportIDToError(ctx) + + iConn := conn + if statConn, ok := iConn.(*internet.StatCouterConnection); ok { + iConn = statConn.Connection + } + + sessionPolicy := s.policyManager.ForLevel(0) + if err := conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil { + return newError("unable to set read deadline").Base(err).AtWarning() + } + + first := buf.New() + defer first.Release() + + firstLen, err := first.ReadFrom(conn) + if err != nil { + return newError("failed to read first request").Base(err) + } + newError("firstLen = ", firstLen).AtInfo().WriteToLog(sid) + + bufferedReader := &buf.BufferedReader{ + Reader: buf.NewReader(conn), + Buffer: buf.MultiBuffer{first}, + } + + var user *protocol.MemoryUser + + apfb := s.fallbacks + isfb := apfb != nil + + shouldFallback := false + if firstLen < 58 || first.Byte(56) != '\r' { + // invalid protocol + err = newError("not trojan protocol") + log.Record(&log.AccessMessage{ + From: conn.RemoteAddr(), + To: "", + Status: log.AccessRejected, + Reason: err, + }) + + shouldFallback = true + } else { + user = s.validator.Get(hexString(first.BytesTo(56))) + if user == nil { + // invalid user, let's fallback + err = newError("not a valid user") + log.Record(&log.AccessMessage{ + From: conn.RemoteAddr(), + To: "", + Status: log.AccessRejected, + Reason: err, + }) + + shouldFallback = true + } + } + + if isfb && shouldFallback { + return s.fallback(ctx, sid, err, sessionPolicy, conn, iConn, apfb, first, firstLen, bufferedReader) + } else if shouldFallback { + return newError("invalid protocol or invalid user") + } + + clientReader := &ConnReader{Reader: bufferedReader} + if err := clientReader.ParseHeader(); err != nil { + log.Record(&log.AccessMessage{ + From: conn.RemoteAddr(), + To: "", + Status: log.AccessRejected, + Reason: err, + }) + return newError("failed to create request from: ", conn.RemoteAddr()).Base(err) + } + + destination := clientReader.Target + if err := conn.SetReadDeadline(time.Time{}); err != nil { + return newError("unable to set read deadline").Base(err).AtWarning() + } + + inbound := session.InboundFromContext(ctx) + if inbound == nil { + panic("no inbound metadata") + } + inbound.User = user + sessionPolicy = s.policyManager.ForLevel(user.Level) + + if destination.Network == net.Network_UDP { // handle udp request + return s.handleUDPPayload(ctx, &PacketReader{Reader: clientReader}, &PacketWriter{Writer: conn}, dispatcher) + } + + ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ + From: conn.RemoteAddr(), + To: destination, + Status: log.AccessAccepted, + Reason: "", + Email: user.Email, + }) + + newError("received request for ", destination).WriteToLog(sid) + return s.handleConnection(ctx, sessionPolicy, destination, clientReader, buf.NewWriter(conn), dispatcher) +} + +func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReader, clientWriter *PacketWriter, dispatcher routing.Dispatcher) error { + udpDispatcherConstructor := udp.NewSplitDispatcher + switch s.packetEncoding { + case packetaddr.PacketAddrType_None: + case packetaddr.PacketAddrType_Packet: + packetAddrDispatcherFactory := udp.NewPacketAddrDispatcherCreator(ctx) + udpDispatcherConstructor = packetAddrDispatcherFactory.NewPacketAddrDispatcher + } + + udpServer := udpDispatcherConstructor(dispatcher, func(ctx context.Context, packet *udp_proto.Packet) { + if err := clientWriter.WriteMultiBufferWithMetadata(buf.MultiBuffer{packet.Payload}, packet.Source); err != nil { + newError("failed to write response").Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx)) + } + }) + + inbound := session.InboundFromContext(ctx) + user := inbound.User + + for { + select { + case <-ctx.Done(): + return nil + default: + p, err := clientReader.ReadMultiBufferWithMetadata() + if err != nil { + if errors.Cause(err) != io.EOF { + return newError("unexpected EOF").Base(err) + } + return nil + } + currentPacketCtx := ctx + currentPacketCtx = log.ContextWithAccessMessage(currentPacketCtx, &log.AccessMessage{ + From: inbound.Source, + To: p.Target, + Status: log.AccessAccepted, + Reason: "", + Email: user.Email, + }) + newError("tunnelling request to ", p.Target).WriteToLog(session.ExportIDToError(ctx)) + + for _, b := range p.Buffer { + udpServer.Dispatch(currentPacketCtx, p.Target, b) + } + } + } +} + +func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Session, + destination net.Destination, + clientReader buf.Reader, + clientWriter buf.Writer, dispatcher routing.Dispatcher, +) error { + ctx, cancel := context.WithCancel(ctx) + timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) + ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) + + link, err := dispatcher.Dispatch(ctx, destination) + if err != nil { + return newError("failed to dispatch request to ", destination).Base(err) + } + + requestDone := func() error { + defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) + + if err := buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer)); err != nil { + return newError("failed to transfer request").Base(err) + } + return nil + } + + responseDone := func() error { + defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) + + if err := buf.Copy(link.Reader, clientWriter, buf.UpdateActivity(timer)); err != nil { + return newError("failed to write response").Base(err) + } + return nil + } + + requestDonePost := task.OnSuccess(requestDone, task.Close(link.Writer)) + if err := task.Run(ctx, requestDonePost, responseDone); err != nil { + common.Must(common.Interrupt(link.Reader)) + common.Must(common.Interrupt(link.Writer)) + return newError("connection ends").Base(err) + } + + return nil +} + +func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err error, sessionPolicy policy.Session, connection internet.Connection, iConn internet.Connection, apfb map[string]map[string]*Fallback, first *buf.Buffer, firstLen int64, reader buf.Reader) error { + if err := connection.SetReadDeadline(time.Time{}); err != nil { + newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid) + } + newError("fallback starts").Base(err).AtInfo().WriteToLog(sid) + + alpn := "" + if len(apfb) > 1 || apfb[""] == nil { + if tlsConn, ok := iConn.(*tls.Conn); ok { + alpn = tlsConn.ConnectionState().NegotiatedProtocol + newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid) + } + if apfb[alpn] == nil { + alpn = "" + } + } + pfb := apfb[alpn] + if pfb == nil { + return newError(`failed to find the default "alpn" config`).AtWarning() + } + + path := "" + if len(pfb) > 1 || pfb[""] == nil { + if firstLen >= 18 && first.Byte(4) != '*' { // not h2c + firstBytes := first.Bytes() + for i := 4; i <= 8; i++ { // 5 -> 9 + if firstBytes[i] == '/' && firstBytes[i-1] == ' ' { + search := len(firstBytes) + if search > 64 { + search = 64 // up to about 60 + } + for j := i + 1; j < search; j++ { + k := firstBytes[j] + if k == '\r' || k == '\n' { // avoid logging \r or \n + break + } + if k == ' ' { + path = string(firstBytes[i:j]) + newError("realPath = " + path).AtInfo().WriteToLog(sid) + if pfb[path] == nil { + path = "" + } + break + } + } + break + } + } + } + } + fb := pfb[path] + if fb == nil { + return newError(`failed to find the default "path" config`).AtWarning() + } + + ctx, cancel := context.WithCancel(ctx) + timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) + ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) + + var conn net.Conn + if err := retry.ExponentialBackoff(5, 100).On(func() error { + var dialer net.Dialer + conn, err = dialer.DialContext(ctx, fb.Type, fb.Dest) + if err != nil { + return err + } + return nil + }); err != nil { + return newError("failed to dial to " + fb.Dest).Base(err).AtWarning() + } + defer conn.Close() + + serverReader := buf.NewReader(conn) + serverWriter := buf.NewWriter(conn) + + postRequest := func() error { + defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) + if fb.Xver != 0 { + remoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String()) + if err != nil { + return err + } + localAddr, localPort, err := net.SplitHostPort(connection.LocalAddr().String()) + if err != nil { + return err + } + ipv4 := true + for i := 0; i < len(remoteAddr); i++ { + if remoteAddr[i] == ':' { + ipv4 = false + break + } + } + pro := buf.New() + defer pro.Release() + switch fb.Xver { + case 1: + if ipv4 { + common.Must2(pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))) + } else { + common.Must2(pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))) + } + case 2: + common.Must2(pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x21"))) // signature + v2 + PROXY + if ipv4 { + common.Must2(pro.Write([]byte("\x11\x00\x0C"))) // AF_INET + STREAM + 12 bytes + common.Must2(pro.Write(net.ParseIP(remoteAddr).To4())) + common.Must2(pro.Write(net.ParseIP(localAddr).To4())) + } else { + common.Must2(pro.Write([]byte("\x21\x00\x24"))) // AF_INET6 + STREAM + 36 bytes + common.Must2(pro.Write(net.ParseIP(remoteAddr).To16())) + common.Must2(pro.Write(net.ParseIP(localAddr).To16())) + } + p1, _ := strconv.ParseUint(remotePort, 10, 16) + p2, _ := strconv.ParseUint(localPort, 10, 16) + common.Must2(pro.Write([]byte{byte(p1 >> 8), byte(p1), byte(p2 >> 8), byte(p2)})) + } + if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil { + return newError("failed to set PROXY protocol v", fb.Xver).Base(err).AtWarning() + } + } + if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil { + return newError("failed to fallback request payload").Base(err).AtInfo() + } + return nil + } + + writer := buf.NewWriter(connection) + + getResponse := func() error { + defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) + if err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil { + return newError("failed to deliver response payload").Base(err).AtInfo() + } + return nil + } + + if err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), task.OnSuccess(getResponse, task.Close(writer))); err != nil { + common.Must(common.Interrupt(serverReader)) + common.Must(common.Interrupt(serverWriter)) + return newError("fallback ends").Base(err).AtInfo() + } + + return nil +} diff --git a/proxy/hysteria2/trojan.go b/proxy/hysteria2/trojan.go new file mode 100644 index 0000000000..013f7d5ccd --- /dev/null +++ b/proxy/hysteria2/trojan.go @@ -0,0 +1 @@ +package hysteria2 diff --git a/proxy/hysteria2/validator.go b/proxy/hysteria2/validator.go new file mode 100644 index 0000000000..cd7475a26f --- /dev/null +++ b/proxy/hysteria2/validator.go @@ -0,0 +1,51 @@ +package hysteria2 + +import ( + "strings" + "sync" + + "github.com/v2fly/v2ray-core/v5/common/protocol" +) + +// Validator stores valid trojan users. +type Validator struct { + // Considering email's usage here, map + sync.Mutex/RWMutex may have better performance. + email sync.Map + users sync.Map +} + +// Add a trojan user, Email must be empty or unique. +func (v *Validator) Add(u *protocol.MemoryUser) error { + if u.Email != "" { + _, loaded := v.email.LoadOrStore(strings.ToLower(u.Email), u) + if loaded { + return newError("User ", u.Email, " already exists.") + } + } + v.users.Store(hexString(u.Account.(*MemoryAccount).Key), u) + return nil +} + +// Del a trojan user with a non-empty Email. +func (v *Validator) Del(e string) error { + if e == "" { + return newError("Email must not be empty.") + } + le := strings.ToLower(e) + u, _ := v.email.Load(le) + if u == nil { + return newError("User ", e, " not found.") + } + v.email.Delete(le) + v.users.Delete(hexString(u.(*protocol.MemoryUser).Account.(*MemoryAccount).Key)) + return nil +} + +// Get a trojan user with hashed key, nil if user doesn't exist. +func (v *Validator) Get(hash string) *protocol.MemoryUser { + u, _ := v.users.Load(hash) + if u != nil { + return u.(*protocol.MemoryUser) + } + return nil +} diff --git a/transport/internet/hysteria2/config.go b/transport/internet/hysteria2/config.go new file mode 100644 index 0000000000..60f71accd7 --- /dev/null +++ b/transport/internet/hysteria2/config.go @@ -0,0 +1,49 @@ +package hysteria2 + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/sha256" + + "golang.org/x/crypto/chacha20poly1305" + + "github.com/v2fly/v2ray-core/v5/common" + "github.com/v2fly/v2ray-core/v5/common/protocol" + "github.com/v2fly/v2ray-core/v5/common/serial" + "github.com/v2fly/v2ray-core/v5/transport/internet" +) + +func getAuth(config *Config) (cipher.AEAD, error) { + security := config.Security.GetSecurityType() + if security == protocol.SecurityType_NONE { + return nil, nil + } + + salted := []byte(config.Key + "v2ray-quic-salt") + key := sha256.Sum256(salted) + + if security == protocol.SecurityType_AES128_GCM { + block, err := aes.NewCipher(key[:16]) + common.Must(err) + return cipher.NewGCM(block) + } + + if security == protocol.SecurityType_CHACHA20_POLY1305 { + return chacha20poly1305.New(key[:]) + } + + return nil, newError("unsupported security type") +} + +func getHeader(config *Config) (internet.PacketHeader, error) { + if config.Header == nil { + return nil, nil + } + + msg, err := serial.GetInstanceOf(config.Header) + if err != nil { + return nil, err + } + + return internet.CreatePacketHeader(msg) +} diff --git a/transport/internet/hysteria2/config.pb.go b/transport/internet/hysteria2/config.pb.go new file mode 100644 index 0000000000..bd49699df3 --- /dev/null +++ b/transport/internet/hysteria2/config.pb.go @@ -0,0 +1,256 @@ +package hysteria2 + +import ( + protocol "github.com/v2fly/v2ray-core/v5/common/protocol" + _ "github.com/v2fly/v2ray-core/v5/common/protoext" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Congestion struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + SendMbps uint64 `protobuf:"varint,2,opt,name=send_mbps,json=sendMbps,proto3" json:"send_mbps,omitempty"` +} + +func (x *Congestion) Reset() { + *x = Congestion{} + if protoimpl.UnsafeEnabled { + mi := &file_transport_internet_hysteria2_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Congestion) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Congestion) ProtoMessage() {} + +func (x *Congestion) ProtoReflect() protoreflect.Message { + mi := &file_transport_internet_hysteria2_config_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Congestion.ProtoReflect.Descriptor instead. +func (*Congestion) Descriptor() ([]byte, []int) { + return file_transport_internet_hysteria2_config_proto_rawDescGZIP(), []int{0} +} + +func (x *Congestion) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Congestion) GetSendMbps() uint64 { + if x != nil { + return x.SendMbps + } + return 0 +} + +type Config struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Security *protocol.SecurityConfig `protobuf:"bytes,2,opt,name=security,proto3" json:"security,omitempty"` + Congestion *Congestion `protobuf:"bytes,4,opt,name=congestion,proto3" json:"congestion,omitempty"` +} + +func (x *Config) Reset() { + *x = Config{} + if protoimpl.UnsafeEnabled { + mi := &file_transport_internet_hysteria2_config_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Config) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Config) ProtoMessage() {} + +func (x *Config) ProtoReflect() protoreflect.Message { + mi := &file_transport_internet_hysteria2_config_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Config.ProtoReflect.Descriptor instead. +func (*Config) Descriptor() ([]byte, []int) { + return file_transport_internet_hysteria2_config_proto_rawDescGZIP(), []int{1} +} + +func (x *Config) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *Config) GetSecurity() *protocol.SecurityConfig { + if x != nil { + return x.Security + } + return nil +} + +func (x *Config) GetCongestion() *Congestion { + if x != nil { + return x.Congestion + } + return nil +} + +var File_transport_internet_hysteria2_config_proto protoreflect.FileDescriptor + +var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ + 0x0a, 0x29, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x2f, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x22, 0x76, 0x32, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x1a, + 0x1d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x3d, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x4d, 0x62, 0x70, 0x73, 0x22, + 0xce, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, + 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, + 0x72, 0x69, 0x74, 0x79, 0x12, 0x4e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x2e, 0x43, 0x6f, + 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x16, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x09, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, + 0x42, 0x96, 0x01, 0x0a, 0x2b, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, + 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, + 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, + 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, + 0x02, 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, + 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_transport_internet_hysteria2_config_proto_rawDescOnce sync.Once + file_transport_internet_hysteria2_config_proto_rawDescData = file_transport_internet_hysteria2_config_proto_rawDesc +) + +func file_transport_internet_hysteria2_config_proto_rawDescGZIP() []byte { + file_transport_internet_hysteria2_config_proto_rawDescOnce.Do(func() { + file_transport_internet_hysteria2_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_transport_internet_hysteria2_config_proto_rawDescData) + }) + return file_transport_internet_hysteria2_config_proto_rawDescData +} + +var file_transport_internet_hysteria2_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_transport_internet_hysteria2_config_proto_goTypes = []interface{}{ + (*Congestion)(nil), // 0: v2ray.core.transport.internet.quic.Congestion + (*Config)(nil), // 1: v2ray.core.transport.internet.quic.Config + (*protocol.SecurityConfig)(nil), // 2: v2ray.core.common.protocol.SecurityConfig +} +var file_transport_internet_hysteria2_config_proto_depIdxs = []int32{ + 2, // 0: v2ray.core.transport.internet.quic.Config.security:type_name -> v2ray.core.common.protocol.SecurityConfig + 0, // 1: v2ray.core.transport.internet.quic.Config.congestion:type_name -> v2ray.core.transport.internet.quic.Congestion + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_transport_internet_hysteria2_config_proto_init() } +func file_transport_internet_hysteria2_config_proto_init() { + if File_transport_internet_hysteria2_config_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_transport_internet_hysteria2_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Congestion); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_transport_internet_hysteria2_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Config); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_transport_internet_hysteria2_config_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_transport_internet_hysteria2_config_proto_goTypes, + DependencyIndexes: file_transport_internet_hysteria2_config_proto_depIdxs, + MessageInfos: file_transport_internet_hysteria2_config_proto_msgTypes, + }.Build() + File_transport_internet_hysteria2_config_proto = out.File + file_transport_internet_hysteria2_config_proto_rawDesc = nil + file_transport_internet_hysteria2_config_proto_goTypes = nil + file_transport_internet_hysteria2_config_proto_depIdxs = nil +} diff --git a/transport/internet/hysteria2/config.proto b/transport/internet/hysteria2/config.proto new file mode 100644 index 0000000000..548035caeb --- /dev/null +++ b/transport/internet/hysteria2/config.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package v2ray.core.transport.internet.quic; +option csharp_namespace = "V2Ray.Core.Transport.Internet.Hysteria2"; +option go_package = "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2"; +option java_package = "com.v2ray.core.transport.internet.hysteria2"; +option java_multiple_files = true; + +import "common/protocol/headers.proto"; + +import "common/protoext/extensions.proto"; + +message Congestion{ + string type = 1; + + uint64 send_mbps = 2; +} + +message Config { + option (v2ray.core.common.protoext.message_opt).type = "transport"; + option (v2ray.core.common.protoext.message_opt).short_name = "hysteria2"; + + string key = 1; + v2ray.core.common.protocol.SecurityConfig security = 2; + Congestion congestion = 4; +} diff --git a/transport/internet/hysteria2/congestion/bbr/bandwidth.go b/transport/internet/hysteria2/congestion/bbr/bandwidth.go new file mode 100644 index 0000000000..52deb24965 --- /dev/null +++ b/transport/internet/hysteria2/congestion/bbr/bandwidth.go @@ -0,0 +1,27 @@ +package bbr + +import ( + "math" + "time" + + "github.com/apernet/quic-go/congestion" +) + +const ( + infBandwidth = Bandwidth(math.MaxUint64) +) + +// Bandwidth of a connection +type Bandwidth uint64 + +const ( + // BitsPerSecond is 1 bit per second + BitsPerSecond Bandwidth = 1 + // BytesPerSecond is 1 byte per second + BytesPerSecond = 8 * BitsPerSecond +) + +// BandwidthFromDelta calculates the bandwidth from a number of bytes and a time delta +func BandwidthFromDelta(bytes congestion.ByteCount, delta time.Duration) Bandwidth { + return Bandwidth(bytes) * Bandwidth(time.Second) / Bandwidth(delta) * BytesPerSecond +} diff --git a/transport/internet/hysteria2/congestion/bbr/bandwidth_sampler.go b/transport/internet/hysteria2/congestion/bbr/bandwidth_sampler.go new file mode 100644 index 0000000000..266af81f5b --- /dev/null +++ b/transport/internet/hysteria2/congestion/bbr/bandwidth_sampler.go @@ -0,0 +1,875 @@ +//nolint:golint,unused +package bbr + +import ( + "math" + "time" + + "github.com/apernet/quic-go/congestion" +) + +const ( + infRTT = time.Duration(math.MaxInt64) + defaultConnectionStateMapQueueSize = 256 + defaultCandidatesBufferSize = 256 +) + +type roundTripCount uint64 + +// SendTimeState is a subset of ConnectionStateOnSentPacket which is returned +// to the caller when the packet is acked or lost. +type sendTimeState struct { + // Whether other states in this object is valid. + isValid bool + // Whether the sender is app limited at the time the packet was sent. + // App limited bandwidth sample might be artificially low because the sender + // did not have enough data to send in order to saturate the link. + isAppLimited bool + // Total number of sent bytes at the time the packet was sent. + // Includes the packet itself. + totalBytesSent congestion.ByteCount + // Total number of acked bytes at the time the packet was sent. + totalBytesAcked congestion.ByteCount + // Total number of lost bytes at the time the packet was sent. + totalBytesLost congestion.ByteCount + // Total number of inflight bytes at the time the packet was sent. + // Includes the packet itself. + // It should be equal to |total_bytes_sent| minus the sum of + // |total_bytes_acked|, |total_bytes_lost| and total neutered bytes. + bytesInFlight congestion.ByteCount +} + +func newSendTimeState( + isAppLimited bool, + totalBytesSent congestion.ByteCount, + totalBytesAcked congestion.ByteCount, + totalBytesLost congestion.ByteCount, + bytesInFlight congestion.ByteCount, +) *sendTimeState { + return &sendTimeState{ + isValid: true, + isAppLimited: isAppLimited, + totalBytesSent: totalBytesSent, + totalBytesAcked: totalBytesAcked, + totalBytesLost: totalBytesLost, + bytesInFlight: bytesInFlight, + } +} + +type extraAckedEvent struct { + // The excess bytes acknowlwedged in the time delta for this event. + extraAcked congestion.ByteCount + + // The bytes acknowledged and time delta from the event. + bytesAcked congestion.ByteCount + timeDelta time.Duration + // The round trip of the event. + round roundTripCount +} + +func maxExtraAckedEventFunc(a, b extraAckedEvent) int { + if a.extraAcked > b.extraAcked { + return 1 + } else if a.extraAcked < b.extraAcked { + return -1 + } + return 0 +} + +// BandwidthSample +type bandwidthSample struct { + // The bandwidth at that particular sample. Zero if no valid bandwidth sample + // is available. + bandwidth Bandwidth + // The RTT measurement at this particular sample. Zero if no RTT sample is + // available. Does not correct for delayed ack time. + rtt time.Duration + // |send_rate| is computed from the current packet being acked('P') and an + // earlier packet that is acked before P was sent. + sendRate Bandwidth + // States captured when the packet was sent. + stateAtSend sendTimeState +} + +func newBandwidthSample() *bandwidthSample { + return &bandwidthSample{ + sendRate: infBandwidth, + } +} + +// MaxAckHeightTracker is part of the BandwidthSampler. It is called after every +// ack event to keep track the degree of ack aggregation(a.k.a "ack height"). +type maxAckHeightTracker struct { + // Tracks the maximum number of bytes acked faster than the estimated + // bandwidth. + maxAckHeightFilter *WindowedFilter[extraAckedEvent, roundTripCount] + // The time this aggregation started and the number of bytes acked during it. + aggregationEpochStartTime time.Time + aggregationEpochBytes congestion.ByteCount + // The last sent packet number before the current aggregation epoch started. + lastSentPacketNumberBeforeEpoch congestion.PacketNumber + // The number of ack aggregation epochs ever started, including the ongoing + // one. Stats only. + numAckAggregationEpochs uint64 + ackAggregationBandwidthThreshold float64 + startNewAggregationEpochAfterFullRound bool + reduceExtraAckedOnBandwidthIncrease bool +} + +func newMaxAckHeightTracker(windowLength roundTripCount) *maxAckHeightTracker { + return &maxAckHeightTracker{ + maxAckHeightFilter: NewWindowedFilter(windowLength, maxExtraAckedEventFunc), + lastSentPacketNumberBeforeEpoch: invalidPacketNumber, + ackAggregationBandwidthThreshold: 1.0, + } +} + +func (m *maxAckHeightTracker) Get() congestion.ByteCount { + return m.maxAckHeightFilter.GetBest().extraAcked +} + +func (m *maxAckHeightTracker) Update( + bandwidthEstimate Bandwidth, + isNewMaxBandwidth bool, + roundTripCount roundTripCount, + lastSentPacketNumber congestion.PacketNumber, + lastAckedPacketNumber congestion.PacketNumber, + ackTime time.Time, + bytesAcked congestion.ByteCount, +) congestion.ByteCount { + forceNewEpoch := false + + if m.reduceExtraAckedOnBandwidthIncrease && isNewMaxBandwidth { + // Save and clear existing entries. + best := m.maxAckHeightFilter.GetBest() + secondBest := m.maxAckHeightFilter.GetSecondBest() + thirdBest := m.maxAckHeightFilter.GetThirdBest() + m.maxAckHeightFilter.Clear() + + // Reinsert the heights into the filter after recalculating. + expectedBytesAcked := bytesFromBandwidthAndTimeDelta(bandwidthEstimate, best.timeDelta) + if expectedBytesAcked < best.bytesAcked { + best.extraAcked = best.bytesAcked - expectedBytesAcked + m.maxAckHeightFilter.Update(best, best.round) + } + expectedBytesAcked = bytesFromBandwidthAndTimeDelta(bandwidthEstimate, secondBest.timeDelta) + if expectedBytesAcked < secondBest.bytesAcked { + secondBest.extraAcked = secondBest.bytesAcked - expectedBytesAcked + m.maxAckHeightFilter.Update(secondBest, secondBest.round) + } + expectedBytesAcked = bytesFromBandwidthAndTimeDelta(bandwidthEstimate, thirdBest.timeDelta) + if expectedBytesAcked < thirdBest.bytesAcked { + thirdBest.extraAcked = thirdBest.bytesAcked - expectedBytesAcked + m.maxAckHeightFilter.Update(thirdBest, thirdBest.round) + } + } + + // If any packet sent after the start of the epoch has been acked, start a new + // epoch. + if m.startNewAggregationEpochAfterFullRound && + m.lastSentPacketNumberBeforeEpoch != invalidPacketNumber && + lastAckedPacketNumber != invalidPacketNumber && + lastAckedPacketNumber > m.lastSentPacketNumberBeforeEpoch { + forceNewEpoch = true + } + if m.aggregationEpochStartTime.IsZero() || forceNewEpoch { + m.aggregationEpochBytes = bytesAcked + m.aggregationEpochStartTime = ackTime + m.lastSentPacketNumberBeforeEpoch = lastSentPacketNumber + m.numAckAggregationEpochs++ + return 0 + } + + // Compute how many bytes are expected to be delivered, assuming max bandwidth + // is correct. + aggregationDelta := ackTime.Sub(m.aggregationEpochStartTime) + expectedBytesAcked := bytesFromBandwidthAndTimeDelta(bandwidthEstimate, aggregationDelta) + // Reset the current aggregation epoch as soon as the ack arrival rate is less + // than or equal to the max bandwidth. + if m.aggregationEpochBytes <= congestion.ByteCount(m.ackAggregationBandwidthThreshold*float64(expectedBytesAcked)) { + // Reset to start measuring a new aggregation epoch. + m.aggregationEpochBytes = bytesAcked + m.aggregationEpochStartTime = ackTime + m.lastSentPacketNumberBeforeEpoch = lastSentPacketNumber + m.numAckAggregationEpochs++ + return 0 + } + + m.aggregationEpochBytes += bytesAcked + + // Compute how many extra bytes were delivered vs max bandwidth. + extraBytesAcked := m.aggregationEpochBytes - expectedBytesAcked + newEvent := extraAckedEvent{ + extraAcked: expectedBytesAcked, + bytesAcked: m.aggregationEpochBytes, + timeDelta: aggregationDelta, + } + m.maxAckHeightFilter.Update(newEvent, roundTripCount) + return extraBytesAcked +} + +func (m *maxAckHeightTracker) SetFilterWindowLength(length roundTripCount) { + m.maxAckHeightFilter.SetWindowLength(length) +} + +func (m *maxAckHeightTracker) Reset(newHeight congestion.ByteCount, newTime roundTripCount) { + newEvent := extraAckedEvent{ + extraAcked: newHeight, + round: newTime, + } + m.maxAckHeightFilter.Reset(newEvent, newTime) +} + +func (m *maxAckHeightTracker) SetAckAggregationBandwidthThreshold(threshold float64) { + m.ackAggregationBandwidthThreshold = threshold +} + +func (m *maxAckHeightTracker) SetStartNewAggregationEpochAfterFullRound(value bool) { + m.startNewAggregationEpochAfterFullRound = value +} + +func (m *maxAckHeightTracker) SetReduceExtraAckedOnBandwidthIncrease(value bool) { + m.reduceExtraAckedOnBandwidthIncrease = value +} + +func (m *maxAckHeightTracker) AckAggregationBandwidthThreshold() float64 { + return m.ackAggregationBandwidthThreshold +} + +func (m *maxAckHeightTracker) NumAckAggregationEpochs() uint64 { + return m.numAckAggregationEpochs +} + +// AckPoint represents a point on the ack line. +type ackPoint struct { + ackTime time.Time + totalBytesAcked congestion.ByteCount +} + +// RecentAckPoints maintains the most recent 2 ack points at distinct times. +type recentAckPoints struct { + ackPoints [2]ackPoint +} + +func (r *recentAckPoints) Update(ackTime time.Time, totalBytesAcked congestion.ByteCount) { + if ackTime.Before(r.ackPoints[1].ackTime) { + r.ackPoints[1].ackTime = ackTime + } else if ackTime.After(r.ackPoints[1].ackTime) { + r.ackPoints[0] = r.ackPoints[1] + r.ackPoints[1].ackTime = ackTime + } + + r.ackPoints[1].totalBytesAcked = totalBytesAcked +} + +func (r *recentAckPoints) Clear() { + r.ackPoints[0] = ackPoint{} + r.ackPoints[1] = ackPoint{} +} + +func (r *recentAckPoints) MostRecentPoint() *ackPoint { + return &r.ackPoints[1] +} + +func (r *recentAckPoints) LessRecentPoint() *ackPoint { + if r.ackPoints[0].totalBytesAcked != 0 { + return &r.ackPoints[0] + } + + return &r.ackPoints[1] +} + +// ConnectionStateOnSentPacket represents the information about a sent packet +// and the state of the connection at the moment the packet was sent, +// specifically the information about the most recently acknowledged packet at +// that moment. +type connectionStateOnSentPacket struct { + // Time at which the packet is sent. + sentTime time.Time + // Size of the packet. + size congestion.ByteCount + // The value of |totalBytesSentAtLastAckedPacket| at the time the + // packet was sent. + totalBytesSentAtLastAckedPacket congestion.ByteCount + // The value of |lastAckedPacketSentTime| at the time the packet was + // sent. + lastAckedPacketSentTime time.Time + // The value of |lastAckedPacketAckTime| at the time the packet was + // sent. + lastAckedPacketAckTime time.Time + // Send time states that are returned to the congestion controller when the + // packet is acked or lost. + sendTimeState sendTimeState +} + +// Snapshot constructor. Records the current state of the bandwidth +// sampler. +// |bytes_in_flight| is the bytes in flight right after the packet is sent. +func newConnectionStateOnSentPacket( + sentTime time.Time, + size congestion.ByteCount, + bytesInFlight congestion.ByteCount, + sampler *bandwidthSampler, +) *connectionStateOnSentPacket { + return &connectionStateOnSentPacket{ + sentTime: sentTime, + size: size, + totalBytesSentAtLastAckedPacket: sampler.totalBytesSentAtLastAckedPacket, + lastAckedPacketSentTime: sampler.lastAckedPacketSentTime, + lastAckedPacketAckTime: sampler.lastAckedPacketAckTime, + sendTimeState: *newSendTimeState( + sampler.isAppLimited, + sampler.totalBytesSent, + sampler.totalBytesAcked, + sampler.totalBytesLost, + bytesInFlight, + ), + } +} + +// BandwidthSampler keeps track of sent and acknowledged packets and outputs a +// bandwidth sample for every packet acknowledged. The samples are taken for +// individual packets, and are not filtered; the consumer has to filter the +// bandwidth samples itself. In certain cases, the sampler will locally severely +// underestimate the bandwidth, hence a maximum filter with a size of at least +// one RTT is recommended. +// +// This class bases its samples on the slope of two curves: the number of bytes +// sent over time, and the number of bytes acknowledged as received over time. +// It produces a sample of both slopes for every packet that gets acknowledged, +// based on a slope between two points on each of the corresponding curves. Note +// that due to the packet loss, the number of bytes on each curve might get +// further and further away from each other, meaning that it is not feasible to +// compare byte values coming from different curves with each other. +// +// The obvious points for measuring slope sample are the ones corresponding to +// the packet that was just acknowledged. Let us denote them as S_1 (point at +// which the current packet was sent) and A_1 (point at which the current packet +// was acknowledged). However, taking a slope requires two points on each line, +// so estimating bandwidth requires picking a packet in the past with respect to +// which the slope is measured. +// +// For that purpose, BandwidthSampler always keeps track of the most recently +// acknowledged packet, and records it together with every outgoing packet. +// When a packet gets acknowledged (A_1), it has not only information about when +// it itself was sent (S_1), but also the information about the latest +// acknowledged packet right before it was sent (S_0 and A_0). +// +// Based on that data, send and ack rate are estimated as: +// +// send_rate = (bytes(S_1) - bytes(S_0)) / (time(S_1) - time(S_0)) +// ack_rate = (bytes(A_1) - bytes(A_0)) / (time(A_1) - time(A_0)) +// +// Here, the ack rate is intuitively the rate we want to treat as bandwidth. +// However, in certain cases (e.g. ack compression) the ack rate at a point may +// end up higher than the rate at which the data was originally sent, which is +// not indicative of the real bandwidth. Hence, we use the send rate as an upper +// bound, and the sample value is +// +// rate_sample = min(send_rate, ack_rate) +// +// An important edge case handled by the sampler is tracking the app-limited +// samples. There are multiple meaning of "app-limited" used interchangeably, +// hence it is important to understand and to be able to distinguish between +// them. +// +// Meaning 1: connection state. The connection is said to be app-limited when +// there is no outstanding data to send. This means that certain bandwidth +// samples in the future would not be an accurate indication of the link +// capacity, and it is important to inform consumer about that. Whenever +// connection becomes app-limited, the sampler is notified via OnAppLimited() +// method. +// +// Meaning 2: a phase in the bandwidth sampler. As soon as the bandwidth +// sampler becomes notified about the connection being app-limited, it enters +// app-limited phase. In that phase, all *sent* packets are marked as +// app-limited. Note that the connection itself does not have to be +// app-limited during the app-limited phase, and in fact it will not be +// (otherwise how would it send packets?). The boolean flag below indicates +// whether the sampler is in that phase. +// +// Meaning 3: a flag on the sent packet and on the sample. If a sent packet is +// sent during the app-limited phase, the resulting sample related to the +// packet will be marked as app-limited. +// +// With the terminology issue out of the way, let us consider the question of +// what kind of situation it addresses. +// +// Consider a scenario where we first send packets 1 to 20 at a regular +// bandwidth, and then immediately run out of data. After a few seconds, we send +// packets 21 to 60, and only receive ack for 21 between sending packets 40 and +// 41. In this case, when we sample bandwidth for packets 21 to 40, the S_0/A_0 +// we use to compute the slope is going to be packet 20, a few seconds apart +// from the current packet, hence the resulting estimate would be extremely low +// and not indicative of anything. Only at packet 41 the S_0/A_0 will become 21, +// meaning that the bandwidth sample would exclude the quiescence. +// +// Based on the analysis of that scenario, we implement the following rule: once +// OnAppLimited() is called, all sent packets will produce app-limited samples +// up until an ack for a packet that was sent after OnAppLimited() was called. +// Note that while the scenario above is not the only scenario when the +// connection is app-limited, the approach works in other cases too. + +type congestionEventSample struct { + // The maximum bandwidth sample from all acked packets. + // QuicBandwidth::Zero() if no samples are available. + sampleMaxBandwidth Bandwidth + // Whether |sample_max_bandwidth| is from a app-limited sample. + sampleIsAppLimited bool + // The minimum rtt sample from all acked packets. + // QuicTime::Delta::Infinite() if no samples are available. + sampleRtt time.Duration + // For each packet p in acked packets, this is the max value of INFLIGHT(p), + // where INFLIGHT(p) is the number of bytes acked while p is inflight. + sampleMaxInflight congestion.ByteCount + // The send state of the largest packet in acked_packets, unless it is + // empty. If acked_packets is empty, it's the send state of the largest + // packet in lost_packets. + lastPacketSendState sendTimeState + // The number of extra bytes acked from this ack event, compared to what is + // expected from the flow's bandwidth. Larger value means more ack + // aggregation. + extraAcked congestion.ByteCount +} + +func newCongestionEventSample() *congestionEventSample { + return &congestionEventSample{ + sampleRtt: infRTT, + } +} + +type bandwidthSampler struct { + // The total number of congestion controlled bytes sent during the connection. + totalBytesSent congestion.ByteCount + + // The total number of congestion controlled bytes which were acknowledged. + totalBytesAcked congestion.ByteCount + + // The total number of congestion controlled bytes which were lost. + totalBytesLost congestion.ByteCount + + // The total number of congestion controlled bytes which have been neutered. + totalBytesNeutered congestion.ByteCount + + // The value of |total_bytes_sent_| at the time the last acknowledged packet + // was sent. Valid only when |last_acked_packet_sent_time_| is valid. + totalBytesSentAtLastAckedPacket congestion.ByteCount + + // The time at which the last acknowledged packet was sent. Set to + // QuicTime::Zero() if no valid timestamp is available. + lastAckedPacketSentTime time.Time + + // The time at which the most recent packet was acknowledged. + lastAckedPacketAckTime time.Time + + // The most recently sent packet. + lastSentPacket congestion.PacketNumber + + // The most recently acked packet. + lastAckedPacket congestion.PacketNumber + + // Indicates whether the bandwidth sampler is currently in an app-limited + // phase. + isAppLimited bool + + // The packet that will be acknowledged after this one will cause the sampler + // to exit the app-limited phase. + endOfAppLimitedPhase congestion.PacketNumber + + // Record of the connection state at the point where each packet in flight was + // sent, indexed by the packet number. + connectionStateMap *packetNumberIndexedQueue[connectionStateOnSentPacket] + + recentAckPoints recentAckPoints + a0Candidates RingBuffer[ackPoint] + + // Maximum number of tracked packets. + maxTrackedPackets congestion.ByteCount + + maxAckHeightTracker *maxAckHeightTracker + totalBytesAckedAfterLastAckEvent congestion.ByteCount + + // True if connection option 'BSAO' is set. + overestimateAvoidance bool + + // True if connection option 'BBRB' is set. + limitMaxAckHeightTrackerBySendRate bool +} + +func newBandwidthSampler(maxAckHeightTrackerWindowLength roundTripCount) *bandwidthSampler { + b := &bandwidthSampler{ + maxAckHeightTracker: newMaxAckHeightTracker(maxAckHeightTrackerWindowLength), + connectionStateMap: newPacketNumberIndexedQueue[connectionStateOnSentPacket](defaultConnectionStateMapQueueSize), + lastSentPacket: invalidPacketNumber, + lastAckedPacket: invalidPacketNumber, + endOfAppLimitedPhase: invalidPacketNumber, + } + + b.a0Candidates.Init(defaultCandidatesBufferSize) + + return b +} + +func (b *bandwidthSampler) MaxAckHeight() congestion.ByteCount { + return b.maxAckHeightTracker.Get() +} + +func (b *bandwidthSampler) NumAckAggregationEpochs() uint64 { + return b.maxAckHeightTracker.NumAckAggregationEpochs() +} + +func (b *bandwidthSampler) SetMaxAckHeightTrackerWindowLength(length roundTripCount) { + b.maxAckHeightTracker.SetFilterWindowLength(length) +} + +func (b *bandwidthSampler) ResetMaxAckHeightTracker(newHeight congestion.ByteCount, newTime roundTripCount) { + b.maxAckHeightTracker.Reset(newHeight, newTime) +} + +func (b *bandwidthSampler) SetStartNewAggregationEpochAfterFullRound(value bool) { + b.maxAckHeightTracker.SetStartNewAggregationEpochAfterFullRound(value) +} + +func (b *bandwidthSampler) SetLimitMaxAckHeightTrackerBySendRate(value bool) { + b.limitMaxAckHeightTrackerBySendRate = value +} + +func (b *bandwidthSampler) SetReduceExtraAckedOnBandwidthIncrease(value bool) { + b.maxAckHeightTracker.SetReduceExtraAckedOnBandwidthIncrease(value) +} + +func (b *bandwidthSampler) EnableOverestimateAvoidance() { + if b.overestimateAvoidance { + return + } + + b.overestimateAvoidance = true + b.maxAckHeightTracker.SetAckAggregationBandwidthThreshold(2.0) +} + +func (b *bandwidthSampler) IsOverestimateAvoidanceEnabled() bool { + return b.overestimateAvoidance +} + +func (b *bandwidthSampler) OnPacketSent( + sentTime time.Time, + packetNumber congestion.PacketNumber, + bytes congestion.ByteCount, + bytesInFlight congestion.ByteCount, + isRetransmittable bool, +) { + b.lastSentPacket = packetNumber + + if !isRetransmittable { + return + } + + b.totalBytesSent += bytes + + // If there are no packets in flight, the time at which the new transmission + // opens can be treated as the A_0 point for the purpose of bandwidth + // sampling. This underestimates bandwidth to some extent, and produces some + // artificially low samples for most packets in flight, but it provides with + // samples at important points where we would not have them otherwise, most + // importantly at the beginning of the connection. + if bytesInFlight == 0 { + b.lastAckedPacketAckTime = sentTime + if b.overestimateAvoidance { + b.recentAckPoints.Clear() + b.recentAckPoints.Update(sentTime, b.totalBytesAcked) + b.a0Candidates.Clear() + b.a0Candidates.PushBack(*b.recentAckPoints.MostRecentPoint()) + } + b.totalBytesSentAtLastAckedPacket = b.totalBytesSent + + // In this situation ack compression is not a concern, set send rate to + // effectively infinite. + b.lastAckedPacketSentTime = sentTime + } + + b.connectionStateMap.Emplace(packetNumber, newConnectionStateOnSentPacket( + sentTime, + bytes, + bytesInFlight+bytes, + b, + )) +} + +func (b *bandwidthSampler) OnCongestionEvent( + ackTime time.Time, + ackedPackets []congestion.AckedPacketInfo, + lostPackets []congestion.LostPacketInfo, + maxBandwidth Bandwidth, + estBandwidthUpperBound Bandwidth, + roundTripCount roundTripCount, +) congestionEventSample { + eventSample := newCongestionEventSample() + + var lastLostPacketSendState sendTimeState + + for _, p := range lostPackets { + sendState := b.OnPacketLost(p.PacketNumber, p.BytesLost) + if sendState.isValid { + lastLostPacketSendState = sendState + } + } + + if len(ackedPackets) == 0 { + // Only populate send state for a loss-only event. + eventSample.lastPacketSendState = lastLostPacketSendState + return *eventSample + } + + var lastAckedPacketSendState sendTimeState + var maxSendRate Bandwidth + + for _, p := range ackedPackets { + sample := b.onPacketAcknowledged(ackTime, p.PacketNumber) + if !sample.stateAtSend.isValid { + continue + } + + lastAckedPacketSendState = sample.stateAtSend + + if sample.rtt != 0 { + eventSample.sampleRtt = min(eventSample.sampleRtt, sample.rtt) + } + if sample.bandwidth > eventSample.sampleMaxBandwidth { + eventSample.sampleMaxBandwidth = sample.bandwidth + eventSample.sampleIsAppLimited = sample.stateAtSend.isAppLimited + } + if sample.sendRate != infBandwidth { + maxSendRate = max(maxSendRate, sample.sendRate) + } + inflightSample := b.totalBytesAcked - lastAckedPacketSendState.totalBytesAcked + if inflightSample > eventSample.sampleMaxInflight { + eventSample.sampleMaxInflight = inflightSample + } + } + + if !lastLostPacketSendState.isValid { + eventSample.lastPacketSendState = lastAckedPacketSendState + } else if !lastAckedPacketSendState.isValid { + eventSample.lastPacketSendState = lastLostPacketSendState + } else { + // If two packets are inflight and an alarm is armed to lose a packet and it + // wakes up late, then the first of two in flight packets could have been + // acknowledged before the wakeup, which re-evaluates loss detection, and + // could declare the later of the two lost. + if lostPackets[len(lostPackets)-1].PacketNumber > ackedPackets[len(ackedPackets)-1].PacketNumber { + eventSample.lastPacketSendState = lastLostPacketSendState + } else { + eventSample.lastPacketSendState = lastAckedPacketSendState + } + } + + isNewMaxBandwidth := eventSample.sampleMaxBandwidth > maxBandwidth + maxBandwidth = max(maxBandwidth, eventSample.sampleMaxBandwidth) + if b.limitMaxAckHeightTrackerBySendRate { + maxBandwidth = max(maxBandwidth, maxSendRate) + } + + eventSample.extraAcked = b.onAckEventEnd(min(estBandwidthUpperBound, maxBandwidth), isNewMaxBandwidth, roundTripCount) + + return *eventSample +} + +func (b *bandwidthSampler) OnPacketLost(packetNumber congestion.PacketNumber, bytesLost congestion.ByteCount) (s sendTimeState) { + b.totalBytesLost += bytesLost + if sentPacketPointer := b.connectionStateMap.GetEntry(packetNumber); sentPacketPointer != nil { + sentPacketToSendTimeState(sentPacketPointer, &s) + } + return s +} + +func (b *bandwidthSampler) OnPacketNeutered(packetNumber congestion.PacketNumber) { + b.connectionStateMap.Remove(packetNumber, func(sentPacket connectionStateOnSentPacket) { + b.totalBytesNeutered += sentPacket.size + }) +} + +func (b *bandwidthSampler) OnAppLimited() { + b.isAppLimited = true + b.endOfAppLimitedPhase = b.lastSentPacket +} + +func (b *bandwidthSampler) RemoveObsoletePackets(leastUnacked congestion.PacketNumber) { + // A packet can become obsolete when it is removed from QuicUnackedPacketMap's + // view of inflight before it is acked or marked as lost. For example, when + // QuicSentPacketManager::RetransmitCryptoPackets retransmits a crypto packet, + // the packet is removed from QuicUnackedPacketMap's inflight, but is not + // marked as acked or lost in the BandwidthSampler. + b.connectionStateMap.RemoveUpTo(leastUnacked) +} + +func (b *bandwidthSampler) TotalBytesSent() congestion.ByteCount { + return b.totalBytesSent +} + +func (b *bandwidthSampler) TotalBytesLost() congestion.ByteCount { + return b.totalBytesLost +} + +func (b *bandwidthSampler) TotalBytesAcked() congestion.ByteCount { + return b.totalBytesAcked +} + +func (b *bandwidthSampler) TotalBytesNeutered() congestion.ByteCount { + return b.totalBytesNeutered +} + +func (b *bandwidthSampler) IsAppLimited() bool { + return b.isAppLimited +} + +func (b *bandwidthSampler) EndOfAppLimitedPhase() congestion.PacketNumber { + return b.endOfAppLimitedPhase +} + +func (b *bandwidthSampler) max_ack_height() congestion.ByteCount { + return b.maxAckHeightTracker.Get() +} + +func (b *bandwidthSampler) chooseA0Point(totalBytesAcked congestion.ByteCount, a0 *ackPoint) bool { + if b.a0Candidates.Empty() { + return false + } + + if b.a0Candidates.Len() == 1 { + *a0 = *b.a0Candidates.Front() + return true + } + + for i := 1; i < b.a0Candidates.Len(); i++ { + if b.a0Candidates.Offset(i).totalBytesAcked > totalBytesAcked { + *a0 = *b.a0Candidates.Offset(i - 1) + if i > 1 { + for j := 0; j < i-1; j++ { + b.a0Candidates.PopFront() + } + } + return true + } + } + + *a0 = *b.a0Candidates.Back() + for k := 0; k < b.a0Candidates.Len()-1; k++ { + b.a0Candidates.PopFront() + } + return true +} + +func (b *bandwidthSampler) onPacketAcknowledged(ackTime time.Time, packetNumber congestion.PacketNumber) bandwidthSample { + sample := newBandwidthSample() + b.lastAckedPacket = packetNumber + sentPacketPointer := b.connectionStateMap.GetEntry(packetNumber) + if sentPacketPointer == nil { + return *sample + } + + // OnPacketAcknowledgedInner + b.totalBytesAcked += sentPacketPointer.size + b.totalBytesSentAtLastAckedPacket = sentPacketPointer.sendTimeState.totalBytesSent + b.lastAckedPacketSentTime = sentPacketPointer.sentTime + b.lastAckedPacketAckTime = ackTime + if b.overestimateAvoidance { + b.recentAckPoints.Update(ackTime, b.totalBytesAcked) + } + + if b.isAppLimited { + // Exit app-limited phase in two cases: + // (1) end_of_app_limited_phase_ is not initialized, i.e., so far all + // packets are sent while there are buffered packets or pending data. + // (2) The current acked packet is after the sent packet marked as the end + // of the app limit phase. + if b.endOfAppLimitedPhase == invalidPacketNumber || + packetNumber > b.endOfAppLimitedPhase { + b.isAppLimited = false + } + } + + // There might have been no packets acknowledged at the moment when the + // current packet was sent. In that case, there is no bandwidth sample to + // make. + if sentPacketPointer.lastAckedPacketSentTime.IsZero() { + return *sample + } + + // Infinite rate indicates that the sampler is supposed to discard the + // current send rate sample and use only the ack rate. + sendRate := infBandwidth + if sentPacketPointer.sentTime.After(sentPacketPointer.lastAckedPacketSentTime) { + sendRate = BandwidthFromDelta( + sentPacketPointer.sendTimeState.totalBytesSent-sentPacketPointer.totalBytesSentAtLastAckedPacket, + sentPacketPointer.sentTime.Sub(sentPacketPointer.lastAckedPacketSentTime)) + } + + var a0 ackPoint + if b.overestimateAvoidance && b.chooseA0Point(sentPacketPointer.sendTimeState.totalBytesAcked, &a0) { + } else { + a0.ackTime = sentPacketPointer.lastAckedPacketAckTime + a0.totalBytesAcked = sentPacketPointer.sendTimeState.totalBytesAcked + } + + // During the slope calculation, ensure that ack time of the current packet is + // always larger than the time of the previous packet, otherwise division by + // zero or integer underflow can occur. + if ackTime.Sub(a0.ackTime) <= 0 { + return *sample + } + + ackRate := BandwidthFromDelta(b.totalBytesAcked-a0.totalBytesAcked, ackTime.Sub(a0.ackTime)) + + sample.bandwidth = min(sendRate, ackRate) + // Note: this sample does not account for delayed acknowledgement time. This + // means that the RTT measurements here can be artificially high, especially + // on low bandwidth connections. + sample.rtt = ackTime.Sub(sentPacketPointer.sentTime) + sample.sendRate = sendRate + sentPacketToSendTimeState(sentPacketPointer, &sample.stateAtSend) + + return *sample +} + +func (b *bandwidthSampler) onAckEventEnd( + bandwidthEstimate Bandwidth, + isNewMaxBandwidth bool, + roundTripCount roundTripCount, +) congestion.ByteCount { + newlyAckedBytes := b.totalBytesAcked - b.totalBytesAckedAfterLastAckEvent + if newlyAckedBytes == 0 { + return 0 + } + b.totalBytesAckedAfterLastAckEvent = b.totalBytesAcked + extraAcked := b.maxAckHeightTracker.Update( + bandwidthEstimate, + isNewMaxBandwidth, + roundTripCount, + b.lastSentPacket, + b.lastAckedPacket, + b.lastAckedPacketAckTime, + newlyAckedBytes) + // If |extra_acked| is zero, i.e. this ack event marks the start of a new ack + // aggregation epoch, save LessRecentPoint, which is the last ack point of the + // previous epoch, as a A0 candidate. + if b.overestimateAvoidance && extraAcked == 0 { + b.a0Candidates.PushBack(*b.recentAckPoints.LessRecentPoint()) + } + return extraAcked +} + +func sentPacketToSendTimeState(sentPacket *connectionStateOnSentPacket, sendTimeState *sendTimeState) { + *sendTimeState = sentPacket.sendTimeState + sendTimeState.isValid = true +} + +// BytesFromBandwidthAndTimeDelta calculates the bytes +// from a bandwidth(bits per second) and a time delta +func bytesFromBandwidthAndTimeDelta(bandwidth Bandwidth, delta time.Duration) congestion.ByteCount { + return (congestion.ByteCount(bandwidth) * congestion.ByteCount(delta)) / + (congestion.ByteCount(time.Second) * 8) +} + +func timeDeltaFromBytesAndBandwidth(bytes congestion.ByteCount, bandwidth Bandwidth) time.Duration { + return time.Duration(bytes*8) * time.Second / time.Duration(bandwidth) +} diff --git a/transport/internet/hysteria2/congestion/bbr/bbr_sender.go b/transport/internet/hysteria2/congestion/bbr/bbr_sender.go new file mode 100644 index 0000000000..26958a4f3d --- /dev/null +++ b/transport/internet/hysteria2/congestion/bbr/bbr_sender.go @@ -0,0 +1,942 @@ +//nolint:golint,unused +package bbr + +import ( + "fmt" + "math/rand" + "net" + "time" + + "github.com/apernet/quic-go/congestion" + + "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/common" +) + +// BbrSender implements BBR congestion control algorithm. BBR aims to estimate +// the current available Bottleneck Bandwidth and RTT (hence the name), and +// regulates the pacing rate and the size of the congestion window based on +// those signals. +// +// BBR relies on pacing in order to function properly. Do not use BBR when +// pacing is disabled. +// + +const ( + minBps = 65536 // 64 kbps + + invalidPacketNumber = -1 + initialCongestionWindowPackets = 32 + + // Constants based on TCP defaults. + // The minimum CWND to ensure delayed acks don't reduce bandwidth measurements. + // Does not inflate the pacing rate. + defaultMinimumCongestionWindow = 4 * congestion.ByteCount(congestion.InitialPacketSizeIPv4) + + // The gain used for the STARTUP, equal to 2/ln(2). + defaultHighGain = 2.885 + // The newly derived gain for STARTUP, equal to 4 * ln(2) + derivedHighGain = 2.773 + // The newly derived CWND gain for STARTUP, 2. + derivedHighCWNDGain = 2.0 +) + +// The cycle of gains used during the PROBE_BW stage. +var pacingGain = [...]float64{1.25, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0} + +const ( + // The length of the gain cycle. + gainCycleLength = len(pacingGain) + // The size of the bandwidth filter window, in round-trips. + bandwidthWindowSize = gainCycleLength + 2 + + // The time after which the current min_rtt value expires. + minRttExpiry = 10 * time.Second + // The minimum time the connection can spend in PROBE_RTT mode. + probeRttTime = 200 * time.Millisecond + // If the bandwidth does not increase by the factor of |kStartupGrowthTarget| + // within |kRoundTripsWithoutGrowthBeforeExitingStartup| rounds, the connection + // will exit the STARTUP mode. + startupGrowthTarget = 1.25 + roundTripsWithoutGrowthBeforeExitingStartup = int64(3) + + // Flag. + defaultStartupFullLossCount = 8 + quicBbr2DefaultLossThreshold = 0.02 + maxBbrBurstPackets = 3 +) + +type bbrMode int + +const ( + // Startup phase of the connection. + bbrModeStartup = iota + // After achieving the highest possible bandwidth during the startup, lower + // the pacing rate in order to drain the queue. + bbrModeDrain + // Cruising mode. + bbrModeProbeBw + // Temporarily slow down sending in order to empty the buffer and measure + // the real minimum RTT. + bbrModeProbeRtt +) + +// Indicates how the congestion control limits the amount of bytes in flight. +type bbrRecoveryState int + +const ( + // Do not limit. + bbrRecoveryStateNotInRecovery = iota + // Allow an extra outstanding byte for each byte acknowledged. + bbrRecoveryStateConservation + // Allow two extra outstanding bytes for each byte acknowledged (slow + // start). + bbrRecoveryStateGrowth +) + +type bbrSender struct { + rttStats congestion.RTTStatsProvider + clock Clock + pacer *common.Pacer + + mode bbrMode + + // Bandwidth sampler provides BBR with the bandwidth measurements at + // individual points. + sampler *bandwidthSampler + + // The number of the round trips that have occurred during the connection. + roundTripCount roundTripCount + + // The packet number of the most recently sent packet. + lastSentPacket congestion.PacketNumber + // Acknowledgement of any packet after |current_round_trip_end_| will cause + // the round trip counter to advance. + currentRoundTripEnd congestion.PacketNumber + + // Number of congestion events with some losses, in the current round. + numLossEventsInRound uint64 + + // Number of total bytes lost in the current round. + bytesLostInRound congestion.ByteCount + + // The filter that tracks the maximum bandwidth over the multiple recent + // round-trips. + maxBandwidth *WindowedFilter[Bandwidth, roundTripCount] + + // Minimum RTT estimate. Automatically expires within 10 seconds (and + // triggers PROBE_RTT mode) if no new value is sampled during that period. + minRtt time.Duration + // The time at which the current value of |min_rtt_| was assigned. + minRttTimestamp time.Time + + // The maximum allowed number of bytes in flight. + congestionWindow congestion.ByteCount + + // The initial value of the |congestion_window_|. + initialCongestionWindow congestion.ByteCount + + // The largest value the |congestion_window_| can achieve. + maxCongestionWindow congestion.ByteCount + + // The smallest value the |congestion_window_| can achieve. + minCongestionWindow congestion.ByteCount + + // The pacing gain applied during the STARTUP phase. + highGain float64 + + // The CWND gain applied during the STARTUP phase. + highCwndGain float64 + + // The pacing gain applied during the DRAIN phase. + drainGain float64 + + // The current pacing rate of the connection. + pacingRate Bandwidth + + // The gain currently applied to the pacing rate. + pacingGain float64 + // The gain currently applied to the congestion window. + congestionWindowGain float64 + + // The gain used for the congestion window during PROBE_BW. Latched from + // quic_bbr_cwnd_gain flag. + congestionWindowGainConstant float64 + // The number of RTTs to stay in STARTUP mode. Defaults to 3. + numStartupRtts int64 + + // Number of round-trips in PROBE_BW mode, used for determining the current + // pacing gain cycle. + cycleCurrentOffset int + // The time at which the last pacing gain cycle was started. + lastCycleStart time.Time + + // Indicates whether the connection has reached the full bandwidth mode. + isAtFullBandwidth bool + // Number of rounds during which there was no significant bandwidth increase. + roundsWithoutBandwidthGain int64 + // The bandwidth compared to which the increase is measured. + bandwidthAtLastRound Bandwidth + + // Set to true upon exiting quiescence. + exitingQuiescence bool + + // Time at which PROBE_RTT has to be exited. Setting it to zero indicates + // that the time is yet unknown as the number of packets in flight has not + // reached the required value. + exitProbeRttAt time.Time + // Indicates whether a round-trip has passed since PROBE_RTT became active. + probeRttRoundPassed bool + + // Indicates whether the most recent bandwidth sample was marked as + // app-limited. + lastSampleIsAppLimited bool + // Indicates whether any non app-limited samples have been recorded. + hasNoAppLimitedSample bool + + // Current state of recovery. + recoveryState bbrRecoveryState + // Receiving acknowledgement of a packet after |end_recovery_at_| will cause + // BBR to exit the recovery mode. A value above zero indicates at least one + // loss has been detected, so it must not be set back to zero. + endRecoveryAt congestion.PacketNumber + // A window used to limit the number of bytes in flight during loss recovery. + recoveryWindow congestion.ByteCount + // If true, consider all samples in recovery app-limited. + isAppLimitedRecovery bool // not used + + // When true, pace at 1.5x and disable packet conservation in STARTUP. + slowerStartup bool // not used + // When true, disables packet conservation in STARTUP. + rateBasedStartup bool // not used + + // When true, add the most recent ack aggregation measurement during STARTUP. + enableAckAggregationDuringStartup bool + // When true, expire the windowed ack aggregation values in STARTUP when + // bandwidth increases more than 25%. + expireAckAggregationInStartup bool + + // If true, will not exit low gain mode until bytes_in_flight drops below BDP + // or it's time for high gain mode. + drainToTarget bool + + // If true, slow down pacing rate in STARTUP when overshooting is detected. + detectOvershooting bool + // Bytes lost while detect_overshooting_ is true. + bytesLostWhileDetectingOvershooting congestion.ByteCount + // Slow down pacing rate if + // bytes_lost_while_detecting_overshooting_ * + // bytes_lost_multiplier_while_detecting_overshooting_ > IW. + bytesLostMultiplierWhileDetectingOvershooting uint8 + // When overshooting is detected, do not drop pacing_rate_ below this value / + // min_rtt. + cwndToCalculateMinPacingRate congestion.ByteCount + + // Max congestion window when adjusting network parameters. + maxCongestionWindowWithNetworkParametersAdjusted congestion.ByteCount // not used + + // Params. + maxDatagramSize congestion.ByteCount + // Recorded on packet sent. equivalent |unacked_packets_->bytes_in_flight()| + bytesInFlight congestion.ByteCount +} + +var _ congestion.CongestionControl = &bbrSender{} + +func NewBbrSender( + clock Clock, + initialMaxDatagramSize congestion.ByteCount, +) *bbrSender { + return newBbrSender( + clock, + initialMaxDatagramSize, + initialCongestionWindowPackets*initialMaxDatagramSize, + congestion.MaxCongestionWindowPackets*initialMaxDatagramSize, + ) +} + +func newBbrSender( + clock Clock, + initialMaxDatagramSize, + initialCongestionWindow, + initialMaxCongestionWindow congestion.ByteCount, +) *bbrSender { + b := &bbrSender{ + clock: clock, + mode: bbrModeStartup, + sampler: newBandwidthSampler(roundTripCount(bandwidthWindowSize)), + lastSentPacket: invalidPacketNumber, + currentRoundTripEnd: invalidPacketNumber, + maxBandwidth: NewWindowedFilter(roundTripCount(bandwidthWindowSize), MaxFilter[Bandwidth]), + congestionWindow: initialCongestionWindow, + initialCongestionWindow: initialCongestionWindow, + maxCongestionWindow: initialMaxCongestionWindow, + minCongestionWindow: defaultMinimumCongestionWindow, + highGain: defaultHighGain, + highCwndGain: defaultHighGain, + drainGain: 1.0 / defaultHighGain, + pacingGain: 1.0, + congestionWindowGain: 1.0, + congestionWindowGainConstant: 2.0, + numStartupRtts: roundTripsWithoutGrowthBeforeExitingStartup, + recoveryState: bbrRecoveryStateNotInRecovery, + endRecoveryAt: invalidPacketNumber, + recoveryWindow: initialMaxCongestionWindow, + bytesLostMultiplierWhileDetectingOvershooting: 2, + cwndToCalculateMinPacingRate: initialCongestionWindow, + maxCongestionWindowWithNetworkParametersAdjusted: initialMaxCongestionWindow, + maxDatagramSize: initialMaxDatagramSize, + } + b.pacer = common.NewPacer(b.bandwidthForPacer) + + /* + if b.tracer != nil { + b.lastState = logging.CongestionStateStartup + b.tracer.UpdatedCongestionState(logging.CongestionStateStartup) + } + */ + + b.enterStartupMode(b.clock.Now()) + b.setHighCwndGain(derivedHighCWNDGain) + + return b +} + +func (b *bbrSender) SetRTTStatsProvider(provider congestion.RTTStatsProvider) { + b.rttStats = provider +} + +// TimeUntilSend implements the SendAlgorithm interface. +func (b *bbrSender) TimeUntilSend(bytesInFlight congestion.ByteCount) time.Time { + return b.pacer.TimeUntilSend() +} + +// HasPacingBudget implements the SendAlgorithm interface. +func (b *bbrSender) HasPacingBudget(now time.Time) bool { + return b.pacer.Budget(now) >= b.maxDatagramSize +} + +// OnPacketSent implements the SendAlgorithm interface. +func (b *bbrSender) OnPacketSent( + sentTime time.Time, + bytesInFlight congestion.ByteCount, + packetNumber congestion.PacketNumber, + bytes congestion.ByteCount, + isRetransmittable bool, +) { + b.pacer.SentPacket(sentTime, bytes) + + b.lastSentPacket = packetNumber + b.bytesInFlight = bytesInFlight + + if bytesInFlight == 0 { + b.exitingQuiescence = true + } + + b.sampler.OnPacketSent(sentTime, packetNumber, bytes, bytesInFlight, isRetransmittable) +} + +// CanSend implements the SendAlgorithm interface. +func (b *bbrSender) CanSend(bytesInFlight congestion.ByteCount) bool { + return bytesInFlight < b.GetCongestionWindow() +} + +// MaybeExitSlowStart implements the SendAlgorithm interface. +func (b *bbrSender) MaybeExitSlowStart() { + // Do nothing +} + +// OnPacketAcked implements the SendAlgorithm interface. +func (b *bbrSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes, priorInFlight congestion.ByteCount, eventTime time.Time) { + // Do nothing. +} + +// OnPacketLost implements the SendAlgorithm interface. +func (b *bbrSender) OnPacketLost(number congestion.PacketNumber, lostBytes, priorInFlight congestion.ByteCount) { + // Do nothing. +} + +// OnRetransmissionTimeout implements the SendAlgorithm interface. +func (b *bbrSender) OnRetransmissionTimeout(packetsRetransmitted bool) { + // Do nothing. +} + +// SetMaxDatagramSize implements the SendAlgorithm interface. +func (b *bbrSender) SetMaxDatagramSize(s congestion.ByteCount) { + if s < b.maxDatagramSize { + panic(fmt.Sprintf("congestion BUG: decreased max datagram size from %d to %d", b.maxDatagramSize, s)) + } + cwndIsMinCwnd := b.congestionWindow == b.minCongestionWindow + b.maxDatagramSize = s + if cwndIsMinCwnd { + b.congestionWindow = b.minCongestionWindow + } + b.pacer.SetMaxDatagramSize(s) +} + +// InSlowStart implements the SendAlgorithmWithDebugInfos interface. +func (b *bbrSender) InSlowStart() bool { + return b.mode == bbrModeStartup +} + +// InRecovery implements the SendAlgorithmWithDebugInfos interface. +func (b *bbrSender) InRecovery() bool { + return b.recoveryState != bbrRecoveryStateNotInRecovery +} + +// GetCongestionWindow implements the SendAlgorithmWithDebugInfos interface. +func (b *bbrSender) GetCongestionWindow() congestion.ByteCount { + if b.mode == bbrModeProbeRtt { + return b.probeRttCongestionWindow() + } + + if b.InRecovery() { + return min(b.congestionWindow, b.recoveryWindow) + } + + return b.congestionWindow +} + +func (b *bbrSender) OnCongestionEvent(number congestion.PacketNumber, lostBytes, priorInFlight congestion.ByteCount) { + // Do nothing. +} + +func (b *bbrSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, eventTime time.Time, ackedPackets []congestion.AckedPacketInfo, lostPackets []congestion.LostPacketInfo) { + totalBytesAckedBefore := b.sampler.TotalBytesAcked() + totalBytesLostBefore := b.sampler.TotalBytesLost() + + var isRoundStart, minRttExpired bool + var excessAcked, bytesLost congestion.ByteCount + + // The send state of the largest packet in acked_packets, unless it is + // empty. If acked_packets is empty, it's the send state of the largest + // packet in lost_packets. + var lastPacketSendState sendTimeState + + b.maybeApplimited(priorInFlight) + + // Update bytesInFlight + b.bytesInFlight = priorInFlight + for _, p := range ackedPackets { + b.bytesInFlight -= p.BytesAcked + } + for _, p := range lostPackets { + b.bytesInFlight -= p.BytesLost + } + + if len(ackedPackets) != 0 { + lastAckedPacket := ackedPackets[len(ackedPackets)-1].PacketNumber + isRoundStart = b.updateRoundTripCounter(lastAckedPacket) + b.updateRecoveryState(lastAckedPacket, len(lostPackets) != 0, isRoundStart) + } + + sample := b.sampler.OnCongestionEvent(eventTime, + ackedPackets, lostPackets, b.maxBandwidth.GetBest(), infBandwidth, b.roundTripCount) + if sample.lastPacketSendState.isValid { + b.lastSampleIsAppLimited = sample.lastPacketSendState.isAppLimited + b.hasNoAppLimitedSample = b.hasNoAppLimitedSample || !b.lastSampleIsAppLimited + } + // Avoid updating |max_bandwidth_| if a) this is a loss-only event, or b) all + // packets in |acked_packets| did not generate valid samples. (e.g. ack of + // ack-only packets). In both cases, sampler_.total_bytes_acked() will not + // change. + if totalBytesAckedBefore != b.sampler.TotalBytesAcked() { + if !sample.sampleIsAppLimited || sample.sampleMaxBandwidth > b.maxBandwidth.GetBest() { + b.maxBandwidth.Update(sample.sampleMaxBandwidth, b.roundTripCount) + } + } + + if sample.sampleRtt != infRTT { + minRttExpired = b.maybeUpdateMinRtt(eventTime, sample.sampleRtt) + } + bytesLost = b.sampler.TotalBytesLost() - totalBytesLostBefore + + excessAcked = sample.extraAcked + lastPacketSendState = sample.lastPacketSendState + + if len(lostPackets) != 0 { + b.numLossEventsInRound++ + b.bytesLostInRound += bytesLost + } + + // Handle logic specific to PROBE_BW mode. + if b.mode == bbrModeProbeBw { + b.updateGainCyclePhase(eventTime, priorInFlight, len(lostPackets) != 0) + } + + // Handle logic specific to STARTUP and DRAIN modes. + if isRoundStart && !b.isAtFullBandwidth { + b.checkIfFullBandwidthReached(&lastPacketSendState) + } + + b.maybeExitStartupOrDrain(eventTime) + + // Handle logic specific to PROBE_RTT. + b.maybeEnterOrExitProbeRtt(eventTime, isRoundStart, minRttExpired) + + // Calculate number of packets acked and lost. + bytesAcked := b.sampler.TotalBytesAcked() - totalBytesAckedBefore + + // After the model is updated, recalculate the pacing rate and congestion + // window. + b.calculatePacingRate(bytesLost) + b.calculateCongestionWindow(bytesAcked, excessAcked) + b.calculateRecoveryWindow(bytesAcked, bytesLost) + + // Cleanup internal state. + // This is where we clean up obsolete (acked or lost) packets from the bandwidth sampler. + // The "least unacked" should actually be FirstOutstanding, but since we are not passing + // that through OnCongestionEventEx, we will only do an estimate using acked/lost packets + // for now. Because of fast retransmission, they should differ by no more than 2 packets. + // (this is controlled by packetThreshold in quic-go's sentPacketHandler) + var leastUnacked congestion.PacketNumber + if len(ackedPackets) != 0 { + leastUnacked = ackedPackets[len(ackedPackets)-1].PacketNumber - 2 + } else { + leastUnacked = lostPackets[len(lostPackets)-1].PacketNumber + 1 + } + b.sampler.RemoveObsoletePackets(leastUnacked) + + if isRoundStart { + b.numLossEventsInRound = 0 + b.bytesLostInRound = 0 + } +} + +func (b *bbrSender) PacingRate() Bandwidth { + if b.pacingRate == 0 { + return Bandwidth(b.highGain * float64( + BandwidthFromDelta(b.initialCongestionWindow, b.getMinRtt()))) + } + + return b.pacingRate +} + +func (b *bbrSender) hasGoodBandwidthEstimateForResumption() bool { + return b.hasNonAppLimitedSample() +} + +func (b *bbrSender) hasNonAppLimitedSample() bool { + return b.hasNoAppLimitedSample +} + +// Sets the pacing gain used in STARTUP. Must be greater than 1. +func (b *bbrSender) setHighGain(highGain float64) { + b.highGain = highGain + if b.mode == bbrModeStartup { + b.pacingGain = highGain + } +} + +// Sets the CWND gain used in STARTUP. Must be greater than 1. +func (b *bbrSender) setHighCwndGain(highCwndGain float64) { + b.highCwndGain = highCwndGain + if b.mode == bbrModeStartup { + b.congestionWindowGain = highCwndGain + } +} + +// Sets the gain used in DRAIN. Must be less than 1. +func (b *bbrSender) setDrainGain(drainGain float64) { + b.drainGain = drainGain +} + +// What's the current estimated bandwidth in bytes per second. +func (b *bbrSender) bandwidthEstimate() Bandwidth { + return b.maxBandwidth.GetBest() +} + +func (b *bbrSender) bandwidthForPacer() congestion.ByteCount { + bps := congestion.ByteCount(float64(b.bandwidthEstimate()) * b.congestionWindowGain / float64(BytesPerSecond)) + if bps < minBps { + // We need to make sure that the bandwidth value for pacer is never zero, + // otherwise it will go into an edge case where HasPacingBudget = false + // but TimeUntilSend is before, causing the quic-go send loop to go crazy and get stuck. + return minBps + } + return bps +} + +// Returns the current estimate of the RTT of the connection. Outside of the +// edge cases, this is minimum RTT. +func (b *bbrSender) getMinRtt() time.Duration { + if b.minRtt != 0 { + return b.minRtt + } + // min_rtt could be available if the handshake packet gets neutered then + // gets acknowledged. This could only happen for QUIC crypto where we do not + // drop keys. + minRtt := b.rttStats.MinRTT() + if minRtt == 0 { + return 100 * time.Millisecond + } else { + return minRtt + } +} + +// Computes the target congestion window using the specified gain. +func (b *bbrSender) getTargetCongestionWindow(gain float64) congestion.ByteCount { + bdp := bdpFromRttAndBandwidth(b.getMinRtt(), b.bandwidthEstimate()) + congestionWindow := congestion.ByteCount(gain * float64(bdp)) + + // BDP estimate will be zero if no bandwidth samples are available yet. + if congestionWindow == 0 { + congestionWindow = congestion.ByteCount(gain * float64(b.initialCongestionWindow)) + } + + return max(congestionWindow, b.minCongestionWindow) +} + +// The target congestion window during PROBE_RTT. +func (b *bbrSender) probeRttCongestionWindow() congestion.ByteCount { + return b.minCongestionWindow +} + +func (b *bbrSender) maybeUpdateMinRtt(now time.Time, sampleMinRtt time.Duration) bool { + // Do not expire min_rtt if none was ever available. + minRttExpired := b.minRtt != 0 && now.After(b.minRttTimestamp.Add(minRttExpiry)) + if minRttExpired || sampleMinRtt < b.minRtt || b.minRtt == 0 { + b.minRtt = sampleMinRtt + b.minRttTimestamp = now + } + + return minRttExpired +} + +// Enters the STARTUP mode. +func (b *bbrSender) enterStartupMode(now time.Time) { + b.mode = bbrModeStartup + // b.maybeTraceStateChange(logging.CongestionStateStartup) + b.pacingGain = b.highGain + b.congestionWindowGain = b.highCwndGain +} + +// Enters the PROBE_BW mode. +func (b *bbrSender) enterProbeBandwidthMode(now time.Time) { + b.mode = bbrModeProbeBw + // b.maybeTraceStateChange(logging.CongestionStateProbeBw) + b.congestionWindowGain = b.congestionWindowGainConstant + + // Pick a random offset for the gain cycle out of {0, 2..7} range. 1 is + // excluded because in that case increased gain and decreased gain would not + // follow each other. + b.cycleCurrentOffset = int(rand.Int31n(congestion.PacketsPerConnectionID)) % (gainCycleLength - 1) + if b.cycleCurrentOffset >= 1 { + b.cycleCurrentOffset += 1 + } + + b.lastCycleStart = now + b.pacingGain = pacingGain[b.cycleCurrentOffset] +} + +// Updates the round-trip counter if a round-trip has passed. Returns true if +// the counter has been advanced. +func (b *bbrSender) updateRoundTripCounter(lastAckedPacket congestion.PacketNumber) bool { + if b.currentRoundTripEnd == invalidPacketNumber || lastAckedPacket > b.currentRoundTripEnd { + b.roundTripCount++ + b.currentRoundTripEnd = b.lastSentPacket + return true + } + return false +} + +// Updates the current gain used in PROBE_BW mode. +func (b *bbrSender) updateGainCyclePhase(now time.Time, priorInFlight congestion.ByteCount, hasLosses bool) { + // In most cases, the cycle is advanced after an RTT passes. + shouldAdvanceGainCycling := now.After(b.lastCycleStart.Add(b.getMinRtt())) + // If the pacing gain is above 1.0, the connection is trying to probe the + // bandwidth by increasing the number of bytes in flight to at least + // pacing_gain * BDP. Make sure that it actually reaches the target, as long + // as there are no losses suggesting that the buffers are not able to hold + // that much. + if b.pacingGain > 1.0 && !hasLosses && priorInFlight < b.getTargetCongestionWindow(b.pacingGain) { + shouldAdvanceGainCycling = false + } + + // If pacing gain is below 1.0, the connection is trying to drain the extra + // queue which could have been incurred by probing prior to it. If the number + // of bytes in flight falls down to the estimated BDP value earlier, conclude + // that the queue has been successfully drained and exit this cycle early. + if b.pacingGain < 1.0 && b.bytesInFlight <= b.getTargetCongestionWindow(1) { + shouldAdvanceGainCycling = true + } + + if shouldAdvanceGainCycling { + b.cycleCurrentOffset = (b.cycleCurrentOffset + 1) % gainCycleLength + b.lastCycleStart = now + // Stay in low gain mode until the target BDP is hit. + // Low gain mode will be exited immediately when the target BDP is achieved. + if b.drainToTarget && b.pacingGain < 1 && + pacingGain[b.cycleCurrentOffset] == 1 && + b.bytesInFlight > b.getTargetCongestionWindow(1) { + return + } + b.pacingGain = pacingGain[b.cycleCurrentOffset] + } +} + +// Tracks for how many round-trips the bandwidth has not increased +// significantly. +func (b *bbrSender) checkIfFullBandwidthReached(lastPacketSendState *sendTimeState) { + if b.lastSampleIsAppLimited { + return + } + + target := Bandwidth(float64(b.bandwidthAtLastRound) * startupGrowthTarget) + if b.bandwidthEstimate() >= target { + b.bandwidthAtLastRound = b.bandwidthEstimate() + b.roundsWithoutBandwidthGain = 0 + if b.expireAckAggregationInStartup { + // Expire old excess delivery measurements now that bandwidth increased. + b.sampler.ResetMaxAckHeightTracker(0, b.roundTripCount) + } + return + } + + b.roundsWithoutBandwidthGain++ + if b.roundsWithoutBandwidthGain >= b.numStartupRtts || + b.shouldExitStartupDueToLoss(lastPacketSendState) { + b.isAtFullBandwidth = true + } +} + +func (b *bbrSender) maybeApplimited(bytesInFlight congestion.ByteCount) { + congestionWindow := b.GetCongestionWindow() + if bytesInFlight >= congestionWindow { + return + } + availableBytes := congestionWindow - bytesInFlight + drainLimited := b.mode == bbrModeDrain && bytesInFlight > congestionWindow/2 + if !drainLimited || availableBytes > maxBbrBurstPackets*b.maxDatagramSize { + b.sampler.OnAppLimited() + } +} + +// Transitions from STARTUP to DRAIN and from DRAIN to PROBE_BW if +// appropriate. +func (b *bbrSender) maybeExitStartupOrDrain(now time.Time) { + if b.mode == bbrModeStartup && b.isAtFullBandwidth { + b.mode = bbrModeDrain + // b.maybeTraceStateChange(logging.CongestionStateDrain) + b.pacingGain = b.drainGain + b.congestionWindowGain = b.highCwndGain + } + if b.mode == bbrModeDrain && b.bytesInFlight <= b.getTargetCongestionWindow(1) { + b.enterProbeBandwidthMode(now) + } +} + +// Decides whether to enter or exit PROBE_RTT. +func (b *bbrSender) maybeEnterOrExitProbeRtt(now time.Time, isRoundStart, minRttExpired bool) { + if minRttExpired && !b.exitingQuiescence && b.mode != bbrModeProbeRtt { + b.mode = bbrModeProbeRtt + // b.maybeTraceStateChange(logging.CongestionStateProbRtt) + b.pacingGain = 1.0 + // Do not decide on the time to exit PROBE_RTT until the |bytes_in_flight| + // is at the target small value. + b.exitProbeRttAt = time.Time{} + } + + if b.mode == bbrModeProbeRtt { + b.sampler.OnAppLimited() + // b.maybeTraceStateChange(logging.CongestionStateApplicationLimited) + + if b.exitProbeRttAt.IsZero() { + // If the window has reached the appropriate size, schedule exiting + // PROBE_RTT. The CWND during PROBE_RTT is kMinimumCongestionWindow, but + // we allow an extra packet since QUIC checks CWND before sending a + // packet. + if b.bytesInFlight < b.probeRttCongestionWindow()+congestion.MaxPacketBufferSize { + b.exitProbeRttAt = now.Add(probeRttTime) + b.probeRttRoundPassed = false + } + } else { + if isRoundStart { + b.probeRttRoundPassed = true + } + if now.Sub(b.exitProbeRttAt) >= 0 && b.probeRttRoundPassed { + b.minRttTimestamp = now + if !b.isAtFullBandwidth { + b.enterStartupMode(now) + } else { + b.enterProbeBandwidthMode(now) + } + } + } + } + + b.exitingQuiescence = false +} + +// Determines whether BBR needs to enter, exit or advance state of the +// recovery. +func (b *bbrSender) updateRecoveryState(lastAckedPacket congestion.PacketNumber, hasLosses, isRoundStart bool) { + // Disable recovery in startup, if loss-based exit is enabled. + if !b.isAtFullBandwidth { + return + } + + // Exit recovery when there are no losses for a round. + if hasLosses { + b.endRecoveryAt = b.lastSentPacket + } + + switch b.recoveryState { + case bbrRecoveryStateNotInRecovery: + if hasLosses { + b.recoveryState = bbrRecoveryStateConservation + // This will cause the |recovery_window_| to be set to the correct + // value in CalculateRecoveryWindow(). + b.recoveryWindow = 0 + // Since the conservation phase is meant to be lasting for a whole + // round, extend the current round as if it were started right now. + b.currentRoundTripEnd = b.lastSentPacket + } + case bbrRecoveryStateConservation: + if isRoundStart { + b.recoveryState = bbrRecoveryStateGrowth + } + fallthrough + case bbrRecoveryStateGrowth: + // Exit recovery if appropriate. + if !hasLosses && lastAckedPacket > b.endRecoveryAt { + b.recoveryState = bbrRecoveryStateNotInRecovery + } + } +} + +// Determines the appropriate pacing rate for the connection. +func (b *bbrSender) calculatePacingRate(bytesLost congestion.ByteCount) { + if b.bandwidthEstimate() == 0 { + return + } + + targetRate := Bandwidth(b.pacingGain * float64(b.bandwidthEstimate())) + if b.isAtFullBandwidth { + b.pacingRate = targetRate + return + } + + // Pace at the rate of initial_window / RTT as soon as RTT measurements are + // available. + if b.pacingRate == 0 && b.rttStats.MinRTT() != 0 { + b.pacingRate = BandwidthFromDelta(b.initialCongestionWindow, b.rttStats.MinRTT()) + return + } + + if b.detectOvershooting { + b.bytesLostWhileDetectingOvershooting += bytesLost + // Check for overshooting with network parameters adjusted when pacing rate + // > target_rate and loss has been detected. + if b.pacingRate > targetRate && b.bytesLostWhileDetectingOvershooting > 0 { + if b.hasNoAppLimitedSample || + b.bytesLostWhileDetectingOvershooting*congestion.ByteCount(b.bytesLostMultiplierWhileDetectingOvershooting) > b.initialCongestionWindow { + // We are fairly sure overshoot happens if 1) there is at least one + // non app-limited bw sample or 2) half of IW gets lost. Slow pacing + // rate. + b.pacingRate = max(targetRate, BandwidthFromDelta(b.cwndToCalculateMinPacingRate, b.rttStats.MinRTT())) + b.bytesLostWhileDetectingOvershooting = 0 + b.detectOvershooting = false + } + } + } + + // Do not decrease the pacing rate during startup. + b.pacingRate = max(b.pacingRate, targetRate) +} + +// Determines the appropriate congestion window for the connection. +func (b *bbrSender) calculateCongestionWindow(bytesAcked, excessAcked congestion.ByteCount) { + if b.mode == bbrModeProbeRtt { + return + } + + targetWindow := b.getTargetCongestionWindow(b.congestionWindowGain) + if b.isAtFullBandwidth { + // Add the max recently measured ack aggregation to CWND. + targetWindow += b.sampler.MaxAckHeight() + } else if b.enableAckAggregationDuringStartup { + // Add the most recent excess acked. Because CWND never decreases in + // STARTUP, this will automatically create a very localized max filter. + targetWindow += excessAcked + } + + // Instead of immediately setting the target CWND as the new one, BBR grows + // the CWND towards |target_window| by only increasing it |bytes_acked| at a + // time. + if b.isAtFullBandwidth { + b.congestionWindow = min(targetWindow, b.congestionWindow+bytesAcked) + } else if b.congestionWindow < targetWindow || + b.sampler.TotalBytesAcked() < b.initialCongestionWindow { + // If the connection is not yet out of startup phase, do not decrease the + // window. + b.congestionWindow += bytesAcked + } + + // Enforce the limits on the congestion window. + b.congestionWindow = max(b.congestionWindow, b.minCongestionWindow) + b.congestionWindow = min(b.congestionWindow, b.maxCongestionWindow) +} + +// Determines the appropriate window that constrains the in-flight during recovery. +func (b *bbrSender) calculateRecoveryWindow(bytesAcked, bytesLost congestion.ByteCount) { + if b.recoveryState == bbrRecoveryStateNotInRecovery { + return + } + + // Set up the initial recovery window. + if b.recoveryWindow == 0 { + b.recoveryWindow = b.bytesInFlight + bytesAcked + b.recoveryWindow = max(b.minCongestionWindow, b.recoveryWindow) + return + } + + // Remove losses from the recovery window, while accounting for a potential + // integer underflow. + if b.recoveryWindow >= bytesLost { + b.recoveryWindow = b.recoveryWindow - bytesLost + } else { + b.recoveryWindow = b.maxDatagramSize + } + + // In CONSERVATION mode, just subtracting losses is sufficient. In GROWTH, + // release additional |bytes_acked| to achieve a slow-start-like behavior. + if b.recoveryState == bbrRecoveryStateGrowth { + b.recoveryWindow += bytesAcked + } + + // Always allow sending at least |bytes_acked| in response. + b.recoveryWindow = max(b.recoveryWindow, b.bytesInFlight+bytesAcked) + b.recoveryWindow = max(b.minCongestionWindow, b.recoveryWindow) +} + +// Return whether we should exit STARTUP due to excessive loss. +func (b *bbrSender) shouldExitStartupDueToLoss(lastPacketSendState *sendTimeState) bool { + if b.numLossEventsInRound < defaultStartupFullLossCount || !lastPacketSendState.isValid { + return false + } + + inflightAtSend := lastPacketSendState.bytesInFlight + + if inflightAtSend > 0 && b.bytesLostInRound > 0 { + return b.bytesLostInRound > congestion.ByteCount(float64(inflightAtSend)*quicBbr2DefaultLossThreshold) + } + return false +} + +func bdpFromRttAndBandwidth(rtt time.Duration, bandwidth Bandwidth) congestion.ByteCount { + return congestion.ByteCount(rtt) * congestion.ByteCount(bandwidth) / congestion.ByteCount(BytesPerSecond) / congestion.ByteCount(time.Second) +} + +func GetInitialPacketSize(addr net.Addr) congestion.ByteCount { + // If this is not a UDP address, we don't know anything about the MTU. + // Use the minimum size of an Initial packet as the max packet size. + if udpAddr, ok := addr.(*net.UDPAddr); ok { + if udpAddr.IP.To4() != nil { + return congestion.InitialPacketSizeIPv4 + } else { + return congestion.InitialPacketSizeIPv6 + } + } else { + return congestion.MinInitialPacketSize + } +} diff --git a/transport/internet/hysteria2/congestion/bbr/clock.go b/transport/internet/hysteria2/congestion/bbr/clock.go new file mode 100644 index 0000000000..a66344fb71 --- /dev/null +++ b/transport/internet/hysteria2/congestion/bbr/clock.go @@ -0,0 +1,18 @@ +package bbr + +import "time" + +// A Clock returns the current time +type Clock interface { + Now() time.Time +} + +// DefaultClock implements the Clock interface using the Go stdlib clock. +type DefaultClock struct{} + +var _ Clock = DefaultClock{} + +// Now gets the current time +func (DefaultClock) Now() time.Time { + return time.Now() +} diff --git a/transport/internet/hysteria2/congestion/bbr/packet_number_indexed_queue.go b/transport/internet/hysteria2/congestion/bbr/packet_number_indexed_queue.go new file mode 100644 index 0000000000..ac4c51aafa --- /dev/null +++ b/transport/internet/hysteria2/congestion/bbr/packet_number_indexed_queue.go @@ -0,0 +1,198 @@ +package bbr + +import ( + "github.com/apernet/quic-go/congestion" +) + +// packetNumberIndexedQueue is a queue of mostly continuous numbered entries +// which supports the following operations: +// - adding elements to the end of the queue, or at some point past the end +// - removing elements in any order +// - retrieving elements +// If all elements are inserted in order, all of the operations above are +// amortized O(1) time. +// +// Internally, the data structure is a deque where each element is marked as +// present or not. The deque starts at the lowest present index. Whenever an +// element is removed, it's marked as not present, and the front of the deque is +// cleared of elements that are not present. +// +// The tail of the queue is not cleared due to the assumption of entries being +// inserted in order, though removing all elements of the queue will return it +// to its initial state. +// +// Note that this data structure is inherently hazardous, since an addition of +// just two entries will cause it to consume all of the memory available. +// Because of that, it is not a general-purpose container and should not be used +// as one. + +type entryWrapper[T any] struct { + present bool + entry T +} + +type packetNumberIndexedQueue[T any] struct { + entries RingBuffer[entryWrapper[T]] + numberOfPresentEntries int + firstPacket congestion.PacketNumber +} + +func newPacketNumberIndexedQueue[T any](size int) *packetNumberIndexedQueue[T] { + q := &packetNumberIndexedQueue[T]{ + firstPacket: invalidPacketNumber, + } + + q.entries.Init(size) + + return q +} + +// Emplace inserts data associated |packet_number| into (or past) the end of the +// queue, filling up the missing intermediate entries as necessary. Returns +// true if the element has been inserted successfully, false if it was already +// in the queue or inserted out of order. +func (p *packetNumberIndexedQueue[T]) Emplace(packetNumber congestion.PacketNumber, entry *T) bool { + if packetNumber == invalidPacketNumber || entry == nil { + return false + } + + if p.IsEmpty() { + p.entries.PushBack(entryWrapper[T]{ + present: true, + entry: *entry, + }) + p.numberOfPresentEntries = 1 + p.firstPacket = packetNumber + return true + } + + // Do not allow insertion out-of-order. + if packetNumber <= p.LastPacket() { + return false + } + + // Handle potentially missing elements. + offset := int(packetNumber - p.FirstPacket()) + if gap := offset - p.entries.Len(); gap > 0 { + for i := 0; i < gap; i++ { + p.entries.PushBack(entryWrapper[T]{}) + } + } + + p.entries.PushBack(entryWrapper[T]{ + present: true, + entry: *entry, + }) + p.numberOfPresentEntries++ + return true +} + +// GetEntry Retrieve the entry associated with the packet number. Returns the pointer +// to the entry in case of success, or nullptr if the entry does not exist. +func (p *packetNumberIndexedQueue[T]) GetEntry(packetNumber congestion.PacketNumber) *T { + ew := p.getEntryWraper(packetNumber) + if ew == nil { + return nil + } + + return &ew.entry +} + +// Remove, Same as above, but if an entry is present in the queue, also call f(entry) +// before removing it. +func (p *packetNumberIndexedQueue[T]) Remove(packetNumber congestion.PacketNumber, f func(T)) bool { + ew := p.getEntryWraper(packetNumber) + if ew == nil { + return false + } + if f != nil { + f(ew.entry) + } + ew.present = false + p.numberOfPresentEntries-- + + if packetNumber == p.FirstPacket() { + p.clearup() + } + + return true +} + +// RemoveUpTo, but not including |packet_number|. +// Unused slots in the front are also removed, which means when the function +// returns, |first_packet()| can be larger than |packet_number|. +func (p *packetNumberIndexedQueue[T]) RemoveUpTo(packetNumber congestion.PacketNumber) { + for !p.entries.Empty() && + p.firstPacket != invalidPacketNumber && + p.firstPacket < packetNumber { + if p.entries.Front().present { + p.numberOfPresentEntries-- + } + p.entries.PopFront() + p.firstPacket++ + } + p.clearup() + +} + +// IsEmpty return if queue is empty. +func (p *packetNumberIndexedQueue[T]) IsEmpty() bool { + return p.numberOfPresentEntries == 0 +} + +// NumberOfPresentEntries returns the number of entries in the queue. +func (p *packetNumberIndexedQueue[T]) NumberOfPresentEntries() int { + return p.numberOfPresentEntries +} + +// EntrySlotsUsed returns the number of entries allocated in the underlying deque. This is +// proportional to the memory usage of the queue. +func (p *packetNumberIndexedQueue[T]) EntrySlotsUsed() int { + return p.entries.Len() +} + +// LastPacket returns packet number of the first entry in the queue. +func (p *packetNumberIndexedQueue[T]) FirstPacket() (packetNumber congestion.PacketNumber) { + return p.firstPacket +} + +// LastPacket returns packet number of the last entry ever inserted in the queue. Note that the +// entry in question may have already been removed. Zero if the queue is +// empty. +func (p *packetNumberIndexedQueue[T]) LastPacket() (packetNumber congestion.PacketNumber) { + if p.IsEmpty() { + return invalidPacketNumber + } + + return p.firstPacket + congestion.PacketNumber(p.entries.Len()-1) +} + +func (p *packetNumberIndexedQueue[T]) clearup() { + for !p.entries.Empty() && !p.entries.Front().present { + p.entries.PopFront() + p.firstPacket++ + } + if p.entries.Empty() { + p.firstPacket = invalidPacketNumber + } +} + +func (p *packetNumberIndexedQueue[T]) getEntryWraper(packetNumber congestion.PacketNumber) *entryWrapper[T] { + if packetNumber == invalidPacketNumber || + p.IsEmpty() || + packetNumber < p.firstPacket { + return nil + } + + offset := int(packetNumber - p.firstPacket) + if offset >= p.entries.Len() { + return nil + } + + ew := p.entries.Offset(offset) + if ew == nil || !ew.present { + return nil + } + + return ew +} diff --git a/transport/internet/hysteria2/congestion/bbr/ringbuffer.go b/transport/internet/hysteria2/congestion/bbr/ringbuffer.go new file mode 100644 index 0000000000..ed92d4ce01 --- /dev/null +++ b/transport/internet/hysteria2/congestion/bbr/ringbuffer.go @@ -0,0 +1,118 @@ +package bbr + +// A RingBuffer is a ring buffer. +// It acts as a heap that doesn't cause any allocations. +type RingBuffer[T any] struct { + ring []T + headPos, tailPos int + full bool +} + +// Init preallocs a buffer with a certain size. +func (r *RingBuffer[T]) Init(size int) { + r.ring = make([]T, size) +} + +// Len returns the number of elements in the ring buffer. +func (r *RingBuffer[T]) Len() int { + if r.full { + return len(r.ring) + } + if r.tailPos >= r.headPos { + return r.tailPos - r.headPos + } + return r.tailPos - r.headPos + len(r.ring) +} + +// Empty says if the ring buffer is empty. +func (r *RingBuffer[T]) Empty() bool { + return !r.full && r.headPos == r.tailPos +} + +// PushBack adds a new element. +// If the ring buffer is full, its capacity is increased first. +func (r *RingBuffer[T]) PushBack(t T) { + if r.full || len(r.ring) == 0 { + r.grow() + } + r.ring[r.tailPos] = t + r.tailPos++ + if r.tailPos == len(r.ring) { + r.tailPos = 0 + } + if r.tailPos == r.headPos { + r.full = true + } +} + +// PopFront returns the next element. +// It must not be called when the buffer is empty, that means that +// callers might need to check if there are elements in the buffer first. +func (r *RingBuffer[T]) PopFront() T { + if r.Empty() { + panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: pop from an empty queue") + } + r.full = false + t := r.ring[r.headPos] + r.ring[r.headPos] = *new(T) + r.headPos++ + if r.headPos == len(r.ring) { + r.headPos = 0 + } + return t +} + +// Offset returns the offset element. +// It must not be called when the buffer is empty, that means that +// callers might need to check if there are elements in the buffer first +// and check if the index larger than buffer length. +func (r *RingBuffer[T]) Offset(index int) *T { + if r.Empty() || index >= r.Len() { + panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: offset from invalid index") + } + offset := (r.headPos + index) % len(r.ring) + return &r.ring[offset] +} + +// Front returns the front element. +// It must not be called when the buffer is empty, that means that +// callers might need to check if there are elements in the buffer first. +func (r *RingBuffer[T]) Front() *T { + if r.Empty() { + panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: front from an empty queue") + } + return &r.ring[r.headPos] +} + +// Back returns the back element. +// It must not be called when the buffer is empty, that means that +// callers might need to check if there are elements in the buffer first. +func (r *RingBuffer[T]) Back() *T { + if r.Empty() { + panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: back from an empty queue") + } + return r.Offset(r.Len() - 1) +} + +// Grow the maximum size of the queue. +// This method assume the queue is full. +func (r *RingBuffer[T]) grow() { + oldRing := r.ring + newSize := len(oldRing) * 2 + if newSize == 0 { + newSize = 1 + } + r.ring = make([]T, newSize) + headLen := copy(r.ring, oldRing[r.headPos:]) + copy(r.ring[headLen:], oldRing[:r.headPos]) + r.headPos, r.tailPos, r.full = 0, len(oldRing), false +} + +// Clear removes all elements. +func (r *RingBuffer[T]) Clear() { + var zeroValue T + for i := range r.ring { + r.ring[i] = zeroValue + } + r.headPos, r.tailPos, r.full = 0, 0, false +} diff --git a/transport/internet/hysteria2/congestion/bbr/windowed_filter.go b/transport/internet/hysteria2/congestion/bbr/windowed_filter.go new file mode 100644 index 0000000000..bd9a5f7211 --- /dev/null +++ b/transport/internet/hysteria2/congestion/bbr/windowed_filter.go @@ -0,0 +1,162 @@ +package bbr + +import ( + "golang.org/x/exp/constraints" +) + +// Implements Kathleen Nichols' algorithm for tracking the minimum (or maximum) +// estimate of a stream of samples over some fixed time interval. (E.g., +// the minimum RTT over the past five minutes.) The algorithm keeps track of +// the best, second best, and third best min (or max) estimates, maintaining an +// invariant that the measurement time of the n'th best >= n-1'th best. + +// The algorithm works as follows. On a reset, all three estimates are set to +// the same sample. The second best estimate is then recorded in the second +// quarter of the window, and a third best estimate is recorded in the second +// half of the window, bounding the worst case error when the true min is +// monotonically increasing (or true max is monotonically decreasing) over the +// window. +// +// A new best sample replaces all three estimates, since the new best is lower +// (or higher) than everything else in the window and it is the most recent. +// The window thus effectively gets reset on every new min. The same property +// holds true for second best and third best estimates. Specifically, when a +// sample arrives that is better than the second best but not better than the +// best, it replaces the second and third best estimates but not the best +// estimate. Similarly, a sample that is better than the third best estimate +// but not the other estimates replaces only the third best estimate. +// +// Finally, when the best expires, it is replaced by the second best, which in +// turn is replaced by the third best. The newest sample replaces the third +// best. + +type WindowedFilterValue interface { + any +} + +type WindowedFilterTime interface { + constraints.Integer | constraints.Float +} + +type WindowedFilter[V WindowedFilterValue, T WindowedFilterTime] struct { + // Time length of window. + windowLength T + estimates []entry[V, T] + comparator func(V, V) int +} + +type entry[V WindowedFilterValue, T WindowedFilterTime] struct { + sample V + time T +} + +// Compares two values and returns true if the first is greater than or equal +// to the second. +func MaxFilter[O constraints.Ordered](a, b O) int { + if a > b { + return 1 + } else if a < b { + return -1 + } + return 0 +} + +// Compares two values and returns true if the first is less than or equal +// to the second. +func MinFilter[O constraints.Ordered](a, b O) int { + if a < b { + return 1 + } else if a > b { + return -1 + } + return 0 +} + +func NewWindowedFilter[V WindowedFilterValue, T WindowedFilterTime](windowLength T, comparator func(V, V) int) *WindowedFilter[V, T] { + return &WindowedFilter[V, T]{ + windowLength: windowLength, + estimates: make([]entry[V, T], 3), + comparator: comparator, + } +} + +// Changes the window length. Does not update any current samples. +func (f *WindowedFilter[V, T]) SetWindowLength(windowLength T) { + f.windowLength = windowLength +} + +func (f *WindowedFilter[V, T]) GetBest() V { + return f.estimates[0].sample +} + +func (f *WindowedFilter[V, T]) GetSecondBest() V { + return f.estimates[1].sample +} + +func (f *WindowedFilter[V, T]) GetThirdBest() V { + return f.estimates[2].sample +} + +// Updates best estimates with |sample|, and expires and updates best +// estimates as necessary. +func (f *WindowedFilter[V, T]) Update(newSample V, newTime T) { + // Reset all estimates if they have not yet been initialized, if new sample + // is a new best, or if the newest recorded estimate is too old. + if f.comparator(f.estimates[0].sample, *new(V)) == 0 || + f.comparator(newSample, f.estimates[0].sample) >= 0 || + newTime-f.estimates[2].time > f.windowLength { + f.Reset(newSample, newTime) + return + } + + if f.comparator(newSample, f.estimates[1].sample) >= 0 { + f.estimates[1] = entry[V, T]{newSample, newTime} + f.estimates[2] = f.estimates[1] + } else if f.comparator(newSample, f.estimates[2].sample) >= 0 { + f.estimates[2] = entry[V, T]{newSample, newTime} + } + + // Expire and update estimates as necessary. + if newTime-f.estimates[0].time > f.windowLength { + // The best estimate hasn't been updated for an entire window, so promote + // second and third best estimates. + f.estimates[0] = f.estimates[1] + f.estimates[1] = f.estimates[2] + f.estimates[2] = entry[V, T]{newSample, newTime} + // Need to iterate one more time. Check if the new best estimate is + // outside the window as well, since it may also have been recorded a + // long time ago. Don't need to iterate once more since we cover that + // case at the beginning of the method. + if newTime-f.estimates[0].time > f.windowLength { + f.estimates[0] = f.estimates[1] + f.estimates[1] = f.estimates[2] + } + return + } + if f.comparator(f.estimates[1].sample, f.estimates[0].sample) == 0 && + newTime-f.estimates[1].time > f.windowLength/4 { + // A quarter of the window has passed without a better sample, so the + // second-best estimate is taken from the second quarter of the window. + f.estimates[1] = entry[V, T]{newSample, newTime} + f.estimates[2] = f.estimates[1] + return + } + + if f.comparator(f.estimates[2].sample, f.estimates[1].sample) == 0 && + newTime-f.estimates[2].time > f.windowLength/2 { + // We've passed a half of the window without a better estimate, so take + // a third-best estimate from the second half of the window. + f.estimates[2] = entry[V, T]{newSample, newTime} + } +} + +// Resets all estimates to new sample. +func (f *WindowedFilter[V, T]) Reset(newSample V, newTime T) { + f.estimates[2] = entry[V, T]{newSample, newTime} + f.estimates[1] = f.estimates[2] + f.estimates[0] = f.estimates[1] +} + +func (f *WindowedFilter[V, T]) Clear() { + f.estimates = make([]entry[V, T], 3) +} diff --git a/transport/internet/hysteria2/congestion/brutal/brutal.go b/transport/internet/hysteria2/congestion/brutal/brutal.go new file mode 100644 index 0000000000..dbc31588c5 --- /dev/null +++ b/transport/internet/hysteria2/congestion/brutal/brutal.go @@ -0,0 +1,181 @@ +package brutal + +import ( + "fmt" + "os" + "strconv" + "time" + + "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/common" + + "github.com/apernet/quic-go/congestion" +) + +const ( + pktInfoSlotCount = 5 // slot index is based on seconds, so this is basically how many seconds we sample + minSampleCount = 50 + minAckRate = 0.8 + congestionWindowMultiplier = 2 + + debugEnv = "HYSTERIA_BRUTAL_DEBUG" + debugPrintInterval = 2 +) + +var _ congestion.CongestionControl = &BrutalSender{} + +type BrutalSender struct { + rttStats congestion.RTTStatsProvider + bps congestion.ByteCount + maxDatagramSize congestion.ByteCount + pacer *common.Pacer + + pktInfoSlots [pktInfoSlotCount]pktInfo + ackRate float64 + + debug bool + lastAckPrintTimestamp int64 +} + +type pktInfo struct { + Timestamp int64 + AckCount uint64 + LossCount uint64 +} + +func NewBrutalSender(bps uint64) *BrutalSender { + debug, _ := strconv.ParseBool(os.Getenv(debugEnv)) + bs := &BrutalSender{ + bps: congestion.ByteCount(bps), + maxDatagramSize: congestion.InitialPacketSizeIPv4, + ackRate: 1, + debug: debug, + } + bs.pacer = common.NewPacer(func() congestion.ByteCount { + return congestion.ByteCount(float64(bs.bps) / bs.ackRate) + }) + return bs +} + +func (b *BrutalSender) SetRTTStatsProvider(rttStats congestion.RTTStatsProvider) { + b.rttStats = rttStats +} + +func (b *BrutalSender) TimeUntilSend(bytesInFlight congestion.ByteCount) time.Time { + return b.pacer.TimeUntilSend() +} + +func (b *BrutalSender) HasPacingBudget(now time.Time) bool { + return b.pacer.Budget(now) >= b.maxDatagramSize +} + +func (b *BrutalSender) CanSend(bytesInFlight congestion.ByteCount) bool { + return bytesInFlight < b.GetCongestionWindow() +} + +func (b *BrutalSender) GetCongestionWindow() congestion.ByteCount { + rtt := b.rttStats.SmoothedRTT() + if rtt <= 0 { + return 10240 + } + return congestion.ByteCount(float64(b.bps) * rtt.Seconds() * congestionWindowMultiplier / b.ackRate) +} + +func (b *BrutalSender) OnPacketSent(sentTime time.Time, bytesInFlight congestion.ByteCount, + packetNumber congestion.PacketNumber, bytes congestion.ByteCount, isRetransmittable bool, +) { + b.pacer.SentPacket(sentTime, bytes) +} + +func (b *BrutalSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes congestion.ByteCount, + priorInFlight congestion.ByteCount, eventTime time.Time, +) { + // Stub +} + +func (b *BrutalSender) OnCongestionEvent(number congestion.PacketNumber, lostBytes congestion.ByteCount, + priorInFlight congestion.ByteCount, +) { + // Stub +} + +func (b *BrutalSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, eventTime time.Time, ackedPackets []congestion.AckedPacketInfo, lostPackets []congestion.LostPacketInfo) { + currentTimestamp := eventTime.Unix() + slot := currentTimestamp % pktInfoSlotCount + if b.pktInfoSlots[slot].Timestamp == currentTimestamp { + b.pktInfoSlots[slot].LossCount += uint64(len(lostPackets)) + b.pktInfoSlots[slot].AckCount += uint64(len(ackedPackets)) + } else { + // uninitialized slot or too old, reset + b.pktInfoSlots[slot].Timestamp = currentTimestamp + b.pktInfoSlots[slot].AckCount = uint64(len(ackedPackets)) + b.pktInfoSlots[slot].LossCount = uint64(len(lostPackets)) + } + b.updateAckRate(currentTimestamp) +} + +func (b *BrutalSender) SetMaxDatagramSize(size congestion.ByteCount) { + b.maxDatagramSize = size + b.pacer.SetMaxDatagramSize(size) + if b.debug { + b.debugPrint("SetMaxDatagramSize: %d", size) + } +} + +func (b *BrutalSender) updateAckRate(currentTimestamp int64) { + minTimestamp := currentTimestamp - pktInfoSlotCount + var ackCount, lossCount uint64 + for _, info := range b.pktInfoSlots { + if info.Timestamp < minTimestamp { + continue + } + ackCount += info.AckCount + lossCount += info.LossCount + } + if ackCount+lossCount < minSampleCount { + b.ackRate = 1 + if b.canPrintAckRate(currentTimestamp) { + b.lastAckPrintTimestamp = currentTimestamp + b.debugPrint("Not enough samples (total=%d, ack=%d, loss=%d, rtt=%d)", + ackCount+lossCount, ackCount, lossCount, b.rttStats.SmoothedRTT().Milliseconds()) + } + return + } + rate := float64(ackCount) / float64(ackCount+lossCount) + if rate < minAckRate { + b.ackRate = minAckRate + if b.canPrintAckRate(currentTimestamp) { + b.lastAckPrintTimestamp = currentTimestamp + b.debugPrint("ACK rate too low: %.2f, clamped to %.2f (total=%d, ack=%d, loss=%d, rtt=%d)", + rate, minAckRate, ackCount+lossCount, ackCount, lossCount, b.rttStats.SmoothedRTT().Milliseconds()) + } + return + } + b.ackRate = rate + if b.canPrintAckRate(currentTimestamp) { + b.lastAckPrintTimestamp = currentTimestamp + b.debugPrint("ACK rate: %.2f (total=%d, ack=%d, loss=%d, rtt=%d)", + rate, ackCount+lossCount, ackCount, lossCount, b.rttStats.SmoothedRTT().Milliseconds()) + } +} + +func (b *BrutalSender) InSlowStart() bool { + return false +} + +func (b *BrutalSender) InRecovery() bool { + return false +} + +func (b *BrutalSender) MaybeExitSlowStart() {} + +func (b *BrutalSender) OnRetransmissionTimeout(packetsRetransmitted bool) {} + +func (b *BrutalSender) canPrintAckRate(currentTimestamp int64) bool { + return b.debug && currentTimestamp-b.lastAckPrintTimestamp >= debugPrintInterval +} + +func (b *BrutalSender) debugPrint(format string, a ...any) { + fmt.Printf("[BrutalSender] [%s] %s\n", + time.Now().Format("15:04:05"), + fmt.Sprintf(format, a...)) +} diff --git a/transport/internet/hysteria2/congestion/common/pacer.go b/transport/internet/hysteria2/congestion/common/pacer.go new file mode 100644 index 0000000000..4e089a3147 --- /dev/null +++ b/transport/internet/hysteria2/congestion/common/pacer.go @@ -0,0 +1,95 @@ +package common + +import ( + "math" + "time" + + "github.com/apernet/quic-go/congestion" +) + +const ( + maxBurstPackets = 10 +) + +// Pacer implements a token bucket pacing algorithm. +type Pacer struct { + budgetAtLastSent congestion.ByteCount + maxDatagramSize congestion.ByteCount + lastSentTime time.Time + getBandwidth func() congestion.ByteCount // in bytes/s +} + +func NewPacer(getBandwidth func() congestion.ByteCount) *Pacer { + p := &Pacer{ + budgetAtLastSent: maxBurstPackets * congestion.InitialPacketSizeIPv4, + maxDatagramSize: congestion.InitialPacketSizeIPv4, + getBandwidth: getBandwidth, + } + return p +} + +func (p *Pacer) SentPacket(sendTime time.Time, size congestion.ByteCount) { + budget := p.Budget(sendTime) + if size > budget { + p.budgetAtLastSent = 0 + } else { + p.budgetAtLastSent = budget - size + } + p.lastSentTime = sendTime +} + +func (p *Pacer) Budget(now time.Time) congestion.ByteCount { + if p.lastSentTime.IsZero() { + return p.maxBurstSize() + } + budget := p.budgetAtLastSent + (p.getBandwidth()*congestion.ByteCount(now.Sub(p.lastSentTime).Nanoseconds()))/1e9 + if budget < 0 { // protect against overflows + budget = congestion.ByteCount(1<<62 - 1) + } + return minByteCount(p.maxBurstSize(), budget) +} + +func (p *Pacer) maxBurstSize() congestion.ByteCount { + return maxByteCount( + congestion.ByteCount((congestion.MinPacingDelay+time.Millisecond).Nanoseconds())*p.getBandwidth()/1e9, + maxBurstPackets*p.maxDatagramSize, + ) +} + +// TimeUntilSend returns when the next packet should be sent. +// It returns the zero value of time.Time if a packet can be sent immediately. +func (p *Pacer) TimeUntilSend() time.Time { + if p.budgetAtLastSent >= p.maxDatagramSize { + return time.Time{} + } + return p.lastSentTime.Add(maxDuration( + congestion.MinPacingDelay, + time.Duration(math.Ceil(float64(p.maxDatagramSize-p.budgetAtLastSent)*1e9/ + float64(p.getBandwidth())))*time.Nanosecond, + )) +} + +func (p *Pacer) SetMaxDatagramSize(s congestion.ByteCount) { + p.maxDatagramSize = s +} + +func maxByteCount(a, b congestion.ByteCount) congestion.ByteCount { + if a < b { + return b + } + return a +} + +func minByteCount(a, b congestion.ByteCount) congestion.ByteCount { + if a < b { + return a + } + return b +} + +func maxDuration(a, b time.Duration) time.Duration { + if a > b { + return a + } + return b +} diff --git a/transport/internet/hysteria2/congestion/utils.go b/transport/internet/hysteria2/congestion/utils.go new file mode 100644 index 0000000000..3ff68f6fc1 --- /dev/null +++ b/transport/internet/hysteria2/congestion/utils.go @@ -0,0 +1,19 @@ +package congestion + +import ( + "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/bbr" + "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/brutal" + + "github.com/apernet/quic-go" +) + +func UseBBR(conn quic.Connection) { + conn.SetCongestionControl(bbr.NewBbrSender( + bbr.DefaultClock{}, + bbr.GetInitialPacketSize(conn.RemoteAddr()), + )) +} + +func UseBrutal(conn quic.Connection, tx uint64) { + conn.SetCongestionControl(brutal.NewBrutalSender(tx)) +} diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go new file mode 100644 index 0000000000..241e08cecd --- /dev/null +++ b/transport/internet/hysteria2/conn.go @@ -0,0 +1,199 @@ +package hysteria2 + +import ( + "crypto/cipher" + "crypto/rand" + "errors" + "syscall" + "time" + + "github.com/apernet/quic-go" + + "github.com/v2fly/v2ray-core/v5/common" + "github.com/v2fly/v2ray-core/v5/common/buf" + "github.com/v2fly/v2ray-core/v5/common/net" + "github.com/v2fly/v2ray-core/v5/transport/internet" +) + +type sysConn struct { + conn *net.UDPConn + header internet.PacketHeader + auth cipher.AEAD +} + +func wrapSysConn(rawConn *net.UDPConn, config *Config) (*sysConn, error) { + header, err := getHeader(config) + if err != nil { + return nil, err + } + auth, err := getAuth(config) + if err != nil { + return nil, err + } + return &sysConn{ + conn: rawConn, + header: header, + auth: auth, + }, nil +} + +var errInvalidPacket = errors.New("invalid packet") + +func (c *sysConn) readFromInternal(p []byte) (int, net.Addr, error) { + buffer := getBuffer() + defer putBuffer(buffer) + + nBytes, addr, err := c.conn.ReadFrom(buffer) + if err != nil { + return 0, nil, err + } + + payload := buffer[:nBytes] + if c.header != nil { + if len(payload) <= int(c.header.Size()) { + return 0, nil, errInvalidPacket + } + payload = payload[c.header.Size():] + } + + if c.auth == nil { + n := copy(p, payload) + return n, addr, nil + } + + if len(payload) <= c.auth.NonceSize() { + return 0, nil, errInvalidPacket + } + + nonce := payload[:c.auth.NonceSize()] + payload = payload[c.auth.NonceSize():] + + p, err = c.auth.Open(p[:0], nonce, payload, nil) + if err != nil { + return 0, nil, errInvalidPacket + } + + return len(p), addr, nil +} + +func (c *sysConn) ReadFrom(p []byte) (int, net.Addr, error) { + if c.header == nil && c.auth == nil { + return c.conn.ReadFrom(p) + } + + for { + n, addr, err := c.readFromInternal(p) + if err != nil && err != errInvalidPacket { + return 0, nil, err + } + if err == nil { + return n, addr, nil + } + } +} + +func (c *sysConn) WriteTo(p []byte, addr net.Addr) (int, error) { + if c.header == nil && c.auth == nil { + return c.conn.WriteTo(p, addr) + } + + buffer := getBuffer() + defer putBuffer(buffer) + + payload := buffer + n := 0 + if c.header != nil { + c.header.Serialize(payload) + n = int(c.header.Size()) + } + + if c.auth == nil { + nBytes := copy(payload[n:], p) + n += nBytes + } else { + nounce := payload[n : n+c.auth.NonceSize()] + common.Must2(rand.Read(nounce)) + n += c.auth.NonceSize() + pp := c.auth.Seal(payload[:n], nounce, p, nil) + n = len(pp) + } + + return c.conn.WriteTo(payload[:n], addr) +} + +func (c *sysConn) Close() error { + return c.conn.Close() +} + +func (c *sysConn) LocalAddr() net.Addr { + return c.conn.LocalAddr() +} + +func (c *sysConn) SetReadBuffer(bytes int) error { + return c.conn.SetReadBuffer(bytes) +} + +func (c *sysConn) SetWriteBuffer(bytes int) error { + return c.conn.SetWriteBuffer(bytes) +} + +func (c *sysConn) SetDeadline(t time.Time) error { + return c.conn.SetDeadline(t) +} + +func (c *sysConn) SetReadDeadline(t time.Time) error { + return c.conn.SetReadDeadline(t) +} + +func (c *sysConn) SetWriteDeadline(t time.Time) error { + return c.conn.SetWriteDeadline(t) +} + +func (c *sysConn) SyscallConn() (syscall.RawConn, error) { + return c.conn.SyscallConn() +} + +type interConn struct { + stream quic.Stream + local net.Addr + remote net.Addr +} + +func (c *interConn) Read(b []byte) (int, error) { + return c.stream.Read(b) +} + +func (c *interConn) WriteMultiBuffer(mb buf.MultiBuffer) error { + mb = buf.Compact(mb) + mb, err := buf.WriteMultiBuffer(c, mb) + buf.ReleaseMulti(mb) + return err +} + +func (c *interConn) Write(b []byte) (int, error) { + return c.stream.Write(b) +} + +func (c *interConn) Close() error { + return c.stream.Close() +} + +func (c *interConn) LocalAddr() net.Addr { + return c.local +} + +func (c *interConn) RemoteAddr() net.Addr { + return c.remote +} + +func (c *interConn) SetDeadline(t time.Time) error { + return c.stream.SetDeadline(t) +} + +func (c *interConn) SetReadDeadline(t time.Time) error { + return c.stream.SetReadDeadline(t) +} + +func (c *interConn) SetWriteDeadline(t time.Time) error { + return c.stream.SetWriteDeadline(t) +} diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go new file mode 100644 index 0000000000..ec1dd42dfb --- /dev/null +++ b/transport/internet/hysteria2/dialer.go @@ -0,0 +1,62 @@ +package hysteria2 + +import ( + "context" + + hy "github.com/apernet/hysteria/core/client" + + "github.com/v2fly/v2ray-core/v5/common" + "github.com/v2fly/v2ray-core/v5/common/net" + "github.com/v2fly/v2ray-core/v5/transport/internet" + "github.com/v2fly/v2ray-core/v5/transport/internet/tls" +) + +var RunningClient map[net.Destination]hy.Client + +var errConnectionClosed = newError("connection closed") + +func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hy.TLSConfig, error) { + tlsConfig := tls.ConfigFromStreamSettings(streamSettings) + if tlsConfig == nil { + tlsConfig = &tls.Config{ + ServerName: internalDomain, + AllowInsecure: true, + } + } + res := &hy.TLSConfig{ServerName: tlsConfig.ServerName, InsecureSkipVerify: tlsConfig.AllowInsecure} + return res, nil +} + +func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { + var client hy.Client + client, found := RunningClient[dest] + if !found { + var err error + tlsConfig, err := InitTLSConifg(streamSettings) + if err != nil { + return nil, err + } + client, err = hy.NewClient(&hy.Config{TLSConfig: *tlsConfig}) + if err != nil { + return nil, err + } + RunningClient[dest] = client + } + + stream, err := client.OpenStream() + if err != nil { + return nil, err + } + + quicConn := client.GetQuicConn() + conn := &interConn{ + stream: stream, + local: quicConn.LocalAddr(), + remote: quicConn.RemoteAddr(), + } + return conn, nil +} + +func init() { + common.Must(internet.RegisterTransportDialer(protocolName, Dial)) +} diff --git a/transport/internet/hysteria2/errors.generated.go b/transport/internet/hysteria2/errors.generated.go new file mode 100644 index 0000000000..1053170313 --- /dev/null +++ b/transport/internet/hysteria2/errors.generated.go @@ -0,0 +1,9 @@ +package hysteria2 + +import "github.com/v2fly/v2ray-core/v5/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go new file mode 100644 index 0000000000..4688336ff8 --- /dev/null +++ b/transport/internet/hysteria2/hub.go @@ -0,0 +1,139 @@ +package hysteria2 + +import ( + "context" + "time" + + "github.com/apernet/quic-go" + + "github.com/v2fly/v2ray-core/v5/common" + "github.com/v2fly/v2ray-core/v5/common/net" + "github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert" + "github.com/v2fly/v2ray-core/v5/common/signal/done" + "github.com/v2fly/v2ray-core/v5/transport/internet" + "github.com/v2fly/v2ray-core/v5/transport/internet/tls" +) + +// Listener is an internet.Listener that listens for TCP connections. +type Listener struct { + rawConn *sysConn + listener *quic.Listener + done *done.Instance + addConn internet.ConnHandler + config *Config +} + +func (l *Listener) acceptStreams(conn quic.Connection) { + for { + stream, err := conn.AcceptStream(context.Background()) + if err != nil { + newError("failed to accept stream").Base(err).WriteToLog() + select { + case <-conn.Context().Done(): + return + case <-l.done.Wait(): + if err := conn.CloseWithError(0, ""); err != nil { + newError("failed to close connection").Base(err).WriteToLog() + } + return + default: + time.Sleep(time.Second) + continue + } + } + + conn := &interConn{ + stream: stream, + local: conn.LocalAddr(), + remote: conn.RemoteAddr(), + } + + l.addConn(conn) + } +} + +func (l *Listener) keepAccepting() { + for { + conn, err := l.listener.Accept(context.Background()) + if err != nil { + newError("failed to accept QUIC connections").Base(err).WriteToLog() + if l.done.Done() { + break + } + continue + } + SetCongestion(conn, l.config) + go l.acceptStreams(conn) + } +} + +// Addr implements internet.Listener.Addr. +func (l *Listener) Addr() net.Addr { + return l.listener.Addr() +} + +// Close implements internet.Listener.Close. +func (l *Listener) Close() error { + l.done.Close() + l.listener.Close() + l.rawConn.Close() + return nil +} + +// Listen creates a new Listener based on configurations. +func Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) { + if address.Family().IsDomain() { + return nil, newError("domain address is not allows for listening quic") + } + + tlsConfig := tls.ConfigFromStreamSettings(streamSettings) + if tlsConfig == nil { + tlsConfig = &tls.Config{ + Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil, cert.DNSNames(internalDomain), cert.CommonName(internalDomain)))}, + } + } + + config := streamSettings.ProtocolSettings.(*Config) + rawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{ + IP: address.IP(), + Port: int(port), + }, streamSettings.SocketSettings) + if err != nil { + return nil, err + } + + quicConfig := InitQuicConfig() + + conn, err := wrapSysConn(rawConn.(*net.UDPConn), config) + if err != nil { + conn.Close() + return nil, err + } + + tr := quic.Transport{ + Conn: conn, + ConnectionIDLength: 12, + } + + qListener, err := tr.Listen(tlsConfig.GetTLSConfig(), quicConfig) + if err != nil { + conn.Close() + return nil, err + } + + listener := &Listener{ + done: done.New(), + rawConn: conn, + listener: qListener, + addConn: handler, + config: config, + } + + go listener.keepAccepting() + + return listener, nil +} + +func init() { + common.Must(internet.RegisterTransportListener(protocolName, Listen)) +} diff --git a/transport/internet/hysteria2/hysteria.go b/transport/internet/hysteria2/hysteria.go new file mode 100644 index 0000000000..b7c90362fc --- /dev/null +++ b/transport/internet/hysteria2/hysteria.go @@ -0,0 +1,25 @@ +package hysteria2 + +import ( + "github.com/v2fly/v2ray-core/v5/common" + "github.com/v2fly/v2ray-core/v5/transport/internet" +) + +//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen + +// Here is some modification needs to be done before update quic vendor. +// * use bytespool in buffer_pool.go +// * set MaxReceivePacketSize to 1452 - 32 (16 bytes auth, 16 bytes head) +// +// + +const ( + protocolName = "hysteria2" + internalDomain = "hysteria2.internal.v2fly.org" +) + +func init() { + common.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} { + return new(Config) + })) +} diff --git a/transport/internet/hysteria2/pool.go b/transport/internet/hysteria2/pool.go new file mode 100644 index 0000000000..c3c9e1508c --- /dev/null +++ b/transport/internet/hysteria2/pool.go @@ -0,0 +1,21 @@ +package hysteria2 + +import ( + "sync" + + "github.com/v2fly/v2ray-core/v5/common/bytespool" +) + +var pool *sync.Pool + +func init() { + pool = bytespool.GetPool(2048) +} + +func getBuffer() []byte { + return pool.Get().([]byte) +} + +func putBuffer(p []byte) { + pool.Put(p) // nolint: staticcheck +} From a392cf2d47ea6ec49447e08e6ccd3b283c128a25 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Fri, 10 Nov 2023 22:01:49 +0800 Subject: [PATCH 22/81] remove unused code --- transport/internet/hysteria2/config.go | 13 - transport/internet/hysteria2/config.pb.go | 47 +- transport/internet/hysteria2/config.proto | 1 + .../hysteria2/congestion/bbr/bandwidth.go | 27 - .../congestion/bbr/bandwidth_sampler.go | 875 ---------------- .../hysteria2/congestion/bbr/bbr_sender.go | 942 ------------------ .../hysteria2/congestion/bbr/clock.go | 18 - .../bbr/packet_number_indexed_queue.go | 198 ---- .../hysteria2/congestion/bbr/ringbuffer.go | 118 --- .../congestion/bbr/windowed_filter.go | 162 --- .../hysteria2/congestion/brutal/brutal.go | 181 ---- .../hysteria2/congestion/common/pacer.go | 95 -- .../internet/hysteria2/congestion/utils.go | 19 - transport/internet/hysteria2/conn.go | 144 --- transport/internet/hysteria2/dialer.go | 61 +- transport/internet/hysteria2/pool.go | 21 - 16 files changed, 78 insertions(+), 2844 deletions(-) delete mode 100644 transport/internet/hysteria2/congestion/bbr/bandwidth.go delete mode 100644 transport/internet/hysteria2/congestion/bbr/bandwidth_sampler.go delete mode 100644 transport/internet/hysteria2/congestion/bbr/bbr_sender.go delete mode 100644 transport/internet/hysteria2/congestion/bbr/clock.go delete mode 100644 transport/internet/hysteria2/congestion/bbr/packet_number_indexed_queue.go delete mode 100644 transport/internet/hysteria2/congestion/bbr/ringbuffer.go delete mode 100644 transport/internet/hysteria2/congestion/bbr/windowed_filter.go delete mode 100644 transport/internet/hysteria2/congestion/brutal/brutal.go delete mode 100644 transport/internet/hysteria2/congestion/common/pacer.go delete mode 100644 transport/internet/hysteria2/congestion/utils.go delete mode 100644 transport/internet/hysteria2/pool.go diff --git a/transport/internet/hysteria2/config.go b/transport/internet/hysteria2/config.go index 60f71accd7..9b55b5ec19 100644 --- a/transport/internet/hysteria2/config.go +++ b/transport/internet/hysteria2/config.go @@ -34,16 +34,3 @@ func getAuth(config *Config) (cipher.AEAD, error) { return nil, newError("unsupported security type") } - -func getHeader(config *Config) (internet.PacketHeader, error) { - if config.Header == nil { - return nil, nil - } - - msg, err := serial.GetInstanceOf(config.Header) - if err != nil { - return nil, err - } - - return internet.CreatePacketHeader(msg) -} diff --git a/transport/internet/hysteria2/config.pb.go b/transport/internet/hysteria2/config.pb.go index bd49699df3..fe49641e0d 100644 --- a/transport/internet/hysteria2/config.pb.go +++ b/transport/internet/hysteria2/config.pb.go @@ -78,6 +78,7 @@ type Config struct { Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` Security *protocol.SecurityConfig `protobuf:"bytes,2,opt,name=security,proto3" json:"security,omitempty"` + Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` Congestion *Congestion `protobuf:"bytes,4,opt,name=congestion,proto3" json:"congestion,omitempty"` } @@ -127,6 +128,13 @@ func (x *Config) GetSecurity() *protocol.SecurityConfig { return nil } +func (x *Config) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + func (x *Config) GetCongestion() *Congestion { if x != nil { return x.Congestion @@ -150,30 +158,31 @@ var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x4d, 0x62, 0x70, 0x73, 0x22, - 0xce, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0xea, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, - 0x72, 0x69, 0x74, 0x79, 0x12, 0x4e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, - 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x2e, 0x43, 0x6f, - 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, - 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x16, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x09, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, - 0x42, 0x96, 0x01, 0x0a, 0x2b, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, - 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, - 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, - 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, - 0x02, 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, - 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x72, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x12, 0x4e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, + 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x16, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, + 0x74, 0x12, 0x09, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x42, 0x96, 0x01, 0x0a, + 0x2b, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x3b, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, + 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, 0x27, 0x56, 0x32, + 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x48, 0x79, 0x73, 0x74, + 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/transport/internet/hysteria2/config.proto b/transport/internet/hysteria2/config.proto index 548035caeb..2ef517e31a 100644 --- a/transport/internet/hysteria2/config.proto +++ b/transport/internet/hysteria2/config.proto @@ -22,5 +22,6 @@ message Config { string key = 1; v2ray.core.common.protocol.SecurityConfig security = 2; + string password = 3; Congestion congestion = 4; } diff --git a/transport/internet/hysteria2/congestion/bbr/bandwidth.go b/transport/internet/hysteria2/congestion/bbr/bandwidth.go deleted file mode 100644 index 52deb24965..0000000000 --- a/transport/internet/hysteria2/congestion/bbr/bandwidth.go +++ /dev/null @@ -1,27 +0,0 @@ -package bbr - -import ( - "math" - "time" - - "github.com/apernet/quic-go/congestion" -) - -const ( - infBandwidth = Bandwidth(math.MaxUint64) -) - -// Bandwidth of a connection -type Bandwidth uint64 - -const ( - // BitsPerSecond is 1 bit per second - BitsPerSecond Bandwidth = 1 - // BytesPerSecond is 1 byte per second - BytesPerSecond = 8 * BitsPerSecond -) - -// BandwidthFromDelta calculates the bandwidth from a number of bytes and a time delta -func BandwidthFromDelta(bytes congestion.ByteCount, delta time.Duration) Bandwidth { - return Bandwidth(bytes) * Bandwidth(time.Second) / Bandwidth(delta) * BytesPerSecond -} diff --git a/transport/internet/hysteria2/congestion/bbr/bandwidth_sampler.go b/transport/internet/hysteria2/congestion/bbr/bandwidth_sampler.go deleted file mode 100644 index 266af81f5b..0000000000 --- a/transport/internet/hysteria2/congestion/bbr/bandwidth_sampler.go +++ /dev/null @@ -1,875 +0,0 @@ -//nolint:golint,unused -package bbr - -import ( - "math" - "time" - - "github.com/apernet/quic-go/congestion" -) - -const ( - infRTT = time.Duration(math.MaxInt64) - defaultConnectionStateMapQueueSize = 256 - defaultCandidatesBufferSize = 256 -) - -type roundTripCount uint64 - -// SendTimeState is a subset of ConnectionStateOnSentPacket which is returned -// to the caller when the packet is acked or lost. -type sendTimeState struct { - // Whether other states in this object is valid. - isValid bool - // Whether the sender is app limited at the time the packet was sent. - // App limited bandwidth sample might be artificially low because the sender - // did not have enough data to send in order to saturate the link. - isAppLimited bool - // Total number of sent bytes at the time the packet was sent. - // Includes the packet itself. - totalBytesSent congestion.ByteCount - // Total number of acked bytes at the time the packet was sent. - totalBytesAcked congestion.ByteCount - // Total number of lost bytes at the time the packet was sent. - totalBytesLost congestion.ByteCount - // Total number of inflight bytes at the time the packet was sent. - // Includes the packet itself. - // It should be equal to |total_bytes_sent| minus the sum of - // |total_bytes_acked|, |total_bytes_lost| and total neutered bytes. - bytesInFlight congestion.ByteCount -} - -func newSendTimeState( - isAppLimited bool, - totalBytesSent congestion.ByteCount, - totalBytesAcked congestion.ByteCount, - totalBytesLost congestion.ByteCount, - bytesInFlight congestion.ByteCount, -) *sendTimeState { - return &sendTimeState{ - isValid: true, - isAppLimited: isAppLimited, - totalBytesSent: totalBytesSent, - totalBytesAcked: totalBytesAcked, - totalBytesLost: totalBytesLost, - bytesInFlight: bytesInFlight, - } -} - -type extraAckedEvent struct { - // The excess bytes acknowlwedged in the time delta for this event. - extraAcked congestion.ByteCount - - // The bytes acknowledged and time delta from the event. - bytesAcked congestion.ByteCount - timeDelta time.Duration - // The round trip of the event. - round roundTripCount -} - -func maxExtraAckedEventFunc(a, b extraAckedEvent) int { - if a.extraAcked > b.extraAcked { - return 1 - } else if a.extraAcked < b.extraAcked { - return -1 - } - return 0 -} - -// BandwidthSample -type bandwidthSample struct { - // The bandwidth at that particular sample. Zero if no valid bandwidth sample - // is available. - bandwidth Bandwidth - // The RTT measurement at this particular sample. Zero if no RTT sample is - // available. Does not correct for delayed ack time. - rtt time.Duration - // |send_rate| is computed from the current packet being acked('P') and an - // earlier packet that is acked before P was sent. - sendRate Bandwidth - // States captured when the packet was sent. - stateAtSend sendTimeState -} - -func newBandwidthSample() *bandwidthSample { - return &bandwidthSample{ - sendRate: infBandwidth, - } -} - -// MaxAckHeightTracker is part of the BandwidthSampler. It is called after every -// ack event to keep track the degree of ack aggregation(a.k.a "ack height"). -type maxAckHeightTracker struct { - // Tracks the maximum number of bytes acked faster than the estimated - // bandwidth. - maxAckHeightFilter *WindowedFilter[extraAckedEvent, roundTripCount] - // The time this aggregation started and the number of bytes acked during it. - aggregationEpochStartTime time.Time - aggregationEpochBytes congestion.ByteCount - // The last sent packet number before the current aggregation epoch started. - lastSentPacketNumberBeforeEpoch congestion.PacketNumber - // The number of ack aggregation epochs ever started, including the ongoing - // one. Stats only. - numAckAggregationEpochs uint64 - ackAggregationBandwidthThreshold float64 - startNewAggregationEpochAfterFullRound bool - reduceExtraAckedOnBandwidthIncrease bool -} - -func newMaxAckHeightTracker(windowLength roundTripCount) *maxAckHeightTracker { - return &maxAckHeightTracker{ - maxAckHeightFilter: NewWindowedFilter(windowLength, maxExtraAckedEventFunc), - lastSentPacketNumberBeforeEpoch: invalidPacketNumber, - ackAggregationBandwidthThreshold: 1.0, - } -} - -func (m *maxAckHeightTracker) Get() congestion.ByteCount { - return m.maxAckHeightFilter.GetBest().extraAcked -} - -func (m *maxAckHeightTracker) Update( - bandwidthEstimate Bandwidth, - isNewMaxBandwidth bool, - roundTripCount roundTripCount, - lastSentPacketNumber congestion.PacketNumber, - lastAckedPacketNumber congestion.PacketNumber, - ackTime time.Time, - bytesAcked congestion.ByteCount, -) congestion.ByteCount { - forceNewEpoch := false - - if m.reduceExtraAckedOnBandwidthIncrease && isNewMaxBandwidth { - // Save and clear existing entries. - best := m.maxAckHeightFilter.GetBest() - secondBest := m.maxAckHeightFilter.GetSecondBest() - thirdBest := m.maxAckHeightFilter.GetThirdBest() - m.maxAckHeightFilter.Clear() - - // Reinsert the heights into the filter after recalculating. - expectedBytesAcked := bytesFromBandwidthAndTimeDelta(bandwidthEstimate, best.timeDelta) - if expectedBytesAcked < best.bytesAcked { - best.extraAcked = best.bytesAcked - expectedBytesAcked - m.maxAckHeightFilter.Update(best, best.round) - } - expectedBytesAcked = bytesFromBandwidthAndTimeDelta(bandwidthEstimate, secondBest.timeDelta) - if expectedBytesAcked < secondBest.bytesAcked { - secondBest.extraAcked = secondBest.bytesAcked - expectedBytesAcked - m.maxAckHeightFilter.Update(secondBest, secondBest.round) - } - expectedBytesAcked = bytesFromBandwidthAndTimeDelta(bandwidthEstimate, thirdBest.timeDelta) - if expectedBytesAcked < thirdBest.bytesAcked { - thirdBest.extraAcked = thirdBest.bytesAcked - expectedBytesAcked - m.maxAckHeightFilter.Update(thirdBest, thirdBest.round) - } - } - - // If any packet sent after the start of the epoch has been acked, start a new - // epoch. - if m.startNewAggregationEpochAfterFullRound && - m.lastSentPacketNumberBeforeEpoch != invalidPacketNumber && - lastAckedPacketNumber != invalidPacketNumber && - lastAckedPacketNumber > m.lastSentPacketNumberBeforeEpoch { - forceNewEpoch = true - } - if m.aggregationEpochStartTime.IsZero() || forceNewEpoch { - m.aggregationEpochBytes = bytesAcked - m.aggregationEpochStartTime = ackTime - m.lastSentPacketNumberBeforeEpoch = lastSentPacketNumber - m.numAckAggregationEpochs++ - return 0 - } - - // Compute how many bytes are expected to be delivered, assuming max bandwidth - // is correct. - aggregationDelta := ackTime.Sub(m.aggregationEpochStartTime) - expectedBytesAcked := bytesFromBandwidthAndTimeDelta(bandwidthEstimate, aggregationDelta) - // Reset the current aggregation epoch as soon as the ack arrival rate is less - // than or equal to the max bandwidth. - if m.aggregationEpochBytes <= congestion.ByteCount(m.ackAggregationBandwidthThreshold*float64(expectedBytesAcked)) { - // Reset to start measuring a new aggregation epoch. - m.aggregationEpochBytes = bytesAcked - m.aggregationEpochStartTime = ackTime - m.lastSentPacketNumberBeforeEpoch = lastSentPacketNumber - m.numAckAggregationEpochs++ - return 0 - } - - m.aggregationEpochBytes += bytesAcked - - // Compute how many extra bytes were delivered vs max bandwidth. - extraBytesAcked := m.aggregationEpochBytes - expectedBytesAcked - newEvent := extraAckedEvent{ - extraAcked: expectedBytesAcked, - bytesAcked: m.aggregationEpochBytes, - timeDelta: aggregationDelta, - } - m.maxAckHeightFilter.Update(newEvent, roundTripCount) - return extraBytesAcked -} - -func (m *maxAckHeightTracker) SetFilterWindowLength(length roundTripCount) { - m.maxAckHeightFilter.SetWindowLength(length) -} - -func (m *maxAckHeightTracker) Reset(newHeight congestion.ByteCount, newTime roundTripCount) { - newEvent := extraAckedEvent{ - extraAcked: newHeight, - round: newTime, - } - m.maxAckHeightFilter.Reset(newEvent, newTime) -} - -func (m *maxAckHeightTracker) SetAckAggregationBandwidthThreshold(threshold float64) { - m.ackAggregationBandwidthThreshold = threshold -} - -func (m *maxAckHeightTracker) SetStartNewAggregationEpochAfterFullRound(value bool) { - m.startNewAggregationEpochAfterFullRound = value -} - -func (m *maxAckHeightTracker) SetReduceExtraAckedOnBandwidthIncrease(value bool) { - m.reduceExtraAckedOnBandwidthIncrease = value -} - -func (m *maxAckHeightTracker) AckAggregationBandwidthThreshold() float64 { - return m.ackAggregationBandwidthThreshold -} - -func (m *maxAckHeightTracker) NumAckAggregationEpochs() uint64 { - return m.numAckAggregationEpochs -} - -// AckPoint represents a point on the ack line. -type ackPoint struct { - ackTime time.Time - totalBytesAcked congestion.ByteCount -} - -// RecentAckPoints maintains the most recent 2 ack points at distinct times. -type recentAckPoints struct { - ackPoints [2]ackPoint -} - -func (r *recentAckPoints) Update(ackTime time.Time, totalBytesAcked congestion.ByteCount) { - if ackTime.Before(r.ackPoints[1].ackTime) { - r.ackPoints[1].ackTime = ackTime - } else if ackTime.After(r.ackPoints[1].ackTime) { - r.ackPoints[0] = r.ackPoints[1] - r.ackPoints[1].ackTime = ackTime - } - - r.ackPoints[1].totalBytesAcked = totalBytesAcked -} - -func (r *recentAckPoints) Clear() { - r.ackPoints[0] = ackPoint{} - r.ackPoints[1] = ackPoint{} -} - -func (r *recentAckPoints) MostRecentPoint() *ackPoint { - return &r.ackPoints[1] -} - -func (r *recentAckPoints) LessRecentPoint() *ackPoint { - if r.ackPoints[0].totalBytesAcked != 0 { - return &r.ackPoints[0] - } - - return &r.ackPoints[1] -} - -// ConnectionStateOnSentPacket represents the information about a sent packet -// and the state of the connection at the moment the packet was sent, -// specifically the information about the most recently acknowledged packet at -// that moment. -type connectionStateOnSentPacket struct { - // Time at which the packet is sent. - sentTime time.Time - // Size of the packet. - size congestion.ByteCount - // The value of |totalBytesSentAtLastAckedPacket| at the time the - // packet was sent. - totalBytesSentAtLastAckedPacket congestion.ByteCount - // The value of |lastAckedPacketSentTime| at the time the packet was - // sent. - lastAckedPacketSentTime time.Time - // The value of |lastAckedPacketAckTime| at the time the packet was - // sent. - lastAckedPacketAckTime time.Time - // Send time states that are returned to the congestion controller when the - // packet is acked or lost. - sendTimeState sendTimeState -} - -// Snapshot constructor. Records the current state of the bandwidth -// sampler. -// |bytes_in_flight| is the bytes in flight right after the packet is sent. -func newConnectionStateOnSentPacket( - sentTime time.Time, - size congestion.ByteCount, - bytesInFlight congestion.ByteCount, - sampler *bandwidthSampler, -) *connectionStateOnSentPacket { - return &connectionStateOnSentPacket{ - sentTime: sentTime, - size: size, - totalBytesSentAtLastAckedPacket: sampler.totalBytesSentAtLastAckedPacket, - lastAckedPacketSentTime: sampler.lastAckedPacketSentTime, - lastAckedPacketAckTime: sampler.lastAckedPacketAckTime, - sendTimeState: *newSendTimeState( - sampler.isAppLimited, - sampler.totalBytesSent, - sampler.totalBytesAcked, - sampler.totalBytesLost, - bytesInFlight, - ), - } -} - -// BandwidthSampler keeps track of sent and acknowledged packets and outputs a -// bandwidth sample for every packet acknowledged. The samples are taken for -// individual packets, and are not filtered; the consumer has to filter the -// bandwidth samples itself. In certain cases, the sampler will locally severely -// underestimate the bandwidth, hence a maximum filter with a size of at least -// one RTT is recommended. -// -// This class bases its samples on the slope of two curves: the number of bytes -// sent over time, and the number of bytes acknowledged as received over time. -// It produces a sample of both slopes for every packet that gets acknowledged, -// based on a slope between two points on each of the corresponding curves. Note -// that due to the packet loss, the number of bytes on each curve might get -// further and further away from each other, meaning that it is not feasible to -// compare byte values coming from different curves with each other. -// -// The obvious points for measuring slope sample are the ones corresponding to -// the packet that was just acknowledged. Let us denote them as S_1 (point at -// which the current packet was sent) and A_1 (point at which the current packet -// was acknowledged). However, taking a slope requires two points on each line, -// so estimating bandwidth requires picking a packet in the past with respect to -// which the slope is measured. -// -// For that purpose, BandwidthSampler always keeps track of the most recently -// acknowledged packet, and records it together with every outgoing packet. -// When a packet gets acknowledged (A_1), it has not only information about when -// it itself was sent (S_1), but also the information about the latest -// acknowledged packet right before it was sent (S_0 and A_0). -// -// Based on that data, send and ack rate are estimated as: -// -// send_rate = (bytes(S_1) - bytes(S_0)) / (time(S_1) - time(S_0)) -// ack_rate = (bytes(A_1) - bytes(A_0)) / (time(A_1) - time(A_0)) -// -// Here, the ack rate is intuitively the rate we want to treat as bandwidth. -// However, in certain cases (e.g. ack compression) the ack rate at a point may -// end up higher than the rate at which the data was originally sent, which is -// not indicative of the real bandwidth. Hence, we use the send rate as an upper -// bound, and the sample value is -// -// rate_sample = min(send_rate, ack_rate) -// -// An important edge case handled by the sampler is tracking the app-limited -// samples. There are multiple meaning of "app-limited" used interchangeably, -// hence it is important to understand and to be able to distinguish between -// them. -// -// Meaning 1: connection state. The connection is said to be app-limited when -// there is no outstanding data to send. This means that certain bandwidth -// samples in the future would not be an accurate indication of the link -// capacity, and it is important to inform consumer about that. Whenever -// connection becomes app-limited, the sampler is notified via OnAppLimited() -// method. -// -// Meaning 2: a phase in the bandwidth sampler. As soon as the bandwidth -// sampler becomes notified about the connection being app-limited, it enters -// app-limited phase. In that phase, all *sent* packets are marked as -// app-limited. Note that the connection itself does not have to be -// app-limited during the app-limited phase, and in fact it will not be -// (otherwise how would it send packets?). The boolean flag below indicates -// whether the sampler is in that phase. -// -// Meaning 3: a flag on the sent packet and on the sample. If a sent packet is -// sent during the app-limited phase, the resulting sample related to the -// packet will be marked as app-limited. -// -// With the terminology issue out of the way, let us consider the question of -// what kind of situation it addresses. -// -// Consider a scenario where we first send packets 1 to 20 at a regular -// bandwidth, and then immediately run out of data. After a few seconds, we send -// packets 21 to 60, and only receive ack for 21 between sending packets 40 and -// 41. In this case, when we sample bandwidth for packets 21 to 40, the S_0/A_0 -// we use to compute the slope is going to be packet 20, a few seconds apart -// from the current packet, hence the resulting estimate would be extremely low -// and not indicative of anything. Only at packet 41 the S_0/A_0 will become 21, -// meaning that the bandwidth sample would exclude the quiescence. -// -// Based on the analysis of that scenario, we implement the following rule: once -// OnAppLimited() is called, all sent packets will produce app-limited samples -// up until an ack for a packet that was sent after OnAppLimited() was called. -// Note that while the scenario above is not the only scenario when the -// connection is app-limited, the approach works in other cases too. - -type congestionEventSample struct { - // The maximum bandwidth sample from all acked packets. - // QuicBandwidth::Zero() if no samples are available. - sampleMaxBandwidth Bandwidth - // Whether |sample_max_bandwidth| is from a app-limited sample. - sampleIsAppLimited bool - // The minimum rtt sample from all acked packets. - // QuicTime::Delta::Infinite() if no samples are available. - sampleRtt time.Duration - // For each packet p in acked packets, this is the max value of INFLIGHT(p), - // where INFLIGHT(p) is the number of bytes acked while p is inflight. - sampleMaxInflight congestion.ByteCount - // The send state of the largest packet in acked_packets, unless it is - // empty. If acked_packets is empty, it's the send state of the largest - // packet in lost_packets. - lastPacketSendState sendTimeState - // The number of extra bytes acked from this ack event, compared to what is - // expected from the flow's bandwidth. Larger value means more ack - // aggregation. - extraAcked congestion.ByteCount -} - -func newCongestionEventSample() *congestionEventSample { - return &congestionEventSample{ - sampleRtt: infRTT, - } -} - -type bandwidthSampler struct { - // The total number of congestion controlled bytes sent during the connection. - totalBytesSent congestion.ByteCount - - // The total number of congestion controlled bytes which were acknowledged. - totalBytesAcked congestion.ByteCount - - // The total number of congestion controlled bytes which were lost. - totalBytesLost congestion.ByteCount - - // The total number of congestion controlled bytes which have been neutered. - totalBytesNeutered congestion.ByteCount - - // The value of |total_bytes_sent_| at the time the last acknowledged packet - // was sent. Valid only when |last_acked_packet_sent_time_| is valid. - totalBytesSentAtLastAckedPacket congestion.ByteCount - - // The time at which the last acknowledged packet was sent. Set to - // QuicTime::Zero() if no valid timestamp is available. - lastAckedPacketSentTime time.Time - - // The time at which the most recent packet was acknowledged. - lastAckedPacketAckTime time.Time - - // The most recently sent packet. - lastSentPacket congestion.PacketNumber - - // The most recently acked packet. - lastAckedPacket congestion.PacketNumber - - // Indicates whether the bandwidth sampler is currently in an app-limited - // phase. - isAppLimited bool - - // The packet that will be acknowledged after this one will cause the sampler - // to exit the app-limited phase. - endOfAppLimitedPhase congestion.PacketNumber - - // Record of the connection state at the point where each packet in flight was - // sent, indexed by the packet number. - connectionStateMap *packetNumberIndexedQueue[connectionStateOnSentPacket] - - recentAckPoints recentAckPoints - a0Candidates RingBuffer[ackPoint] - - // Maximum number of tracked packets. - maxTrackedPackets congestion.ByteCount - - maxAckHeightTracker *maxAckHeightTracker - totalBytesAckedAfterLastAckEvent congestion.ByteCount - - // True if connection option 'BSAO' is set. - overestimateAvoidance bool - - // True if connection option 'BBRB' is set. - limitMaxAckHeightTrackerBySendRate bool -} - -func newBandwidthSampler(maxAckHeightTrackerWindowLength roundTripCount) *bandwidthSampler { - b := &bandwidthSampler{ - maxAckHeightTracker: newMaxAckHeightTracker(maxAckHeightTrackerWindowLength), - connectionStateMap: newPacketNumberIndexedQueue[connectionStateOnSentPacket](defaultConnectionStateMapQueueSize), - lastSentPacket: invalidPacketNumber, - lastAckedPacket: invalidPacketNumber, - endOfAppLimitedPhase: invalidPacketNumber, - } - - b.a0Candidates.Init(defaultCandidatesBufferSize) - - return b -} - -func (b *bandwidthSampler) MaxAckHeight() congestion.ByteCount { - return b.maxAckHeightTracker.Get() -} - -func (b *bandwidthSampler) NumAckAggregationEpochs() uint64 { - return b.maxAckHeightTracker.NumAckAggregationEpochs() -} - -func (b *bandwidthSampler) SetMaxAckHeightTrackerWindowLength(length roundTripCount) { - b.maxAckHeightTracker.SetFilterWindowLength(length) -} - -func (b *bandwidthSampler) ResetMaxAckHeightTracker(newHeight congestion.ByteCount, newTime roundTripCount) { - b.maxAckHeightTracker.Reset(newHeight, newTime) -} - -func (b *bandwidthSampler) SetStartNewAggregationEpochAfterFullRound(value bool) { - b.maxAckHeightTracker.SetStartNewAggregationEpochAfterFullRound(value) -} - -func (b *bandwidthSampler) SetLimitMaxAckHeightTrackerBySendRate(value bool) { - b.limitMaxAckHeightTrackerBySendRate = value -} - -func (b *bandwidthSampler) SetReduceExtraAckedOnBandwidthIncrease(value bool) { - b.maxAckHeightTracker.SetReduceExtraAckedOnBandwidthIncrease(value) -} - -func (b *bandwidthSampler) EnableOverestimateAvoidance() { - if b.overestimateAvoidance { - return - } - - b.overestimateAvoidance = true - b.maxAckHeightTracker.SetAckAggregationBandwidthThreshold(2.0) -} - -func (b *bandwidthSampler) IsOverestimateAvoidanceEnabled() bool { - return b.overestimateAvoidance -} - -func (b *bandwidthSampler) OnPacketSent( - sentTime time.Time, - packetNumber congestion.PacketNumber, - bytes congestion.ByteCount, - bytesInFlight congestion.ByteCount, - isRetransmittable bool, -) { - b.lastSentPacket = packetNumber - - if !isRetransmittable { - return - } - - b.totalBytesSent += bytes - - // If there are no packets in flight, the time at which the new transmission - // opens can be treated as the A_0 point for the purpose of bandwidth - // sampling. This underestimates bandwidth to some extent, and produces some - // artificially low samples for most packets in flight, but it provides with - // samples at important points where we would not have them otherwise, most - // importantly at the beginning of the connection. - if bytesInFlight == 0 { - b.lastAckedPacketAckTime = sentTime - if b.overestimateAvoidance { - b.recentAckPoints.Clear() - b.recentAckPoints.Update(sentTime, b.totalBytesAcked) - b.a0Candidates.Clear() - b.a0Candidates.PushBack(*b.recentAckPoints.MostRecentPoint()) - } - b.totalBytesSentAtLastAckedPacket = b.totalBytesSent - - // In this situation ack compression is not a concern, set send rate to - // effectively infinite. - b.lastAckedPacketSentTime = sentTime - } - - b.connectionStateMap.Emplace(packetNumber, newConnectionStateOnSentPacket( - sentTime, - bytes, - bytesInFlight+bytes, - b, - )) -} - -func (b *bandwidthSampler) OnCongestionEvent( - ackTime time.Time, - ackedPackets []congestion.AckedPacketInfo, - lostPackets []congestion.LostPacketInfo, - maxBandwidth Bandwidth, - estBandwidthUpperBound Bandwidth, - roundTripCount roundTripCount, -) congestionEventSample { - eventSample := newCongestionEventSample() - - var lastLostPacketSendState sendTimeState - - for _, p := range lostPackets { - sendState := b.OnPacketLost(p.PacketNumber, p.BytesLost) - if sendState.isValid { - lastLostPacketSendState = sendState - } - } - - if len(ackedPackets) == 0 { - // Only populate send state for a loss-only event. - eventSample.lastPacketSendState = lastLostPacketSendState - return *eventSample - } - - var lastAckedPacketSendState sendTimeState - var maxSendRate Bandwidth - - for _, p := range ackedPackets { - sample := b.onPacketAcknowledged(ackTime, p.PacketNumber) - if !sample.stateAtSend.isValid { - continue - } - - lastAckedPacketSendState = sample.stateAtSend - - if sample.rtt != 0 { - eventSample.sampleRtt = min(eventSample.sampleRtt, sample.rtt) - } - if sample.bandwidth > eventSample.sampleMaxBandwidth { - eventSample.sampleMaxBandwidth = sample.bandwidth - eventSample.sampleIsAppLimited = sample.stateAtSend.isAppLimited - } - if sample.sendRate != infBandwidth { - maxSendRate = max(maxSendRate, sample.sendRate) - } - inflightSample := b.totalBytesAcked - lastAckedPacketSendState.totalBytesAcked - if inflightSample > eventSample.sampleMaxInflight { - eventSample.sampleMaxInflight = inflightSample - } - } - - if !lastLostPacketSendState.isValid { - eventSample.lastPacketSendState = lastAckedPacketSendState - } else if !lastAckedPacketSendState.isValid { - eventSample.lastPacketSendState = lastLostPacketSendState - } else { - // If two packets are inflight and an alarm is armed to lose a packet and it - // wakes up late, then the first of two in flight packets could have been - // acknowledged before the wakeup, which re-evaluates loss detection, and - // could declare the later of the two lost. - if lostPackets[len(lostPackets)-1].PacketNumber > ackedPackets[len(ackedPackets)-1].PacketNumber { - eventSample.lastPacketSendState = lastLostPacketSendState - } else { - eventSample.lastPacketSendState = lastAckedPacketSendState - } - } - - isNewMaxBandwidth := eventSample.sampleMaxBandwidth > maxBandwidth - maxBandwidth = max(maxBandwidth, eventSample.sampleMaxBandwidth) - if b.limitMaxAckHeightTrackerBySendRate { - maxBandwidth = max(maxBandwidth, maxSendRate) - } - - eventSample.extraAcked = b.onAckEventEnd(min(estBandwidthUpperBound, maxBandwidth), isNewMaxBandwidth, roundTripCount) - - return *eventSample -} - -func (b *bandwidthSampler) OnPacketLost(packetNumber congestion.PacketNumber, bytesLost congestion.ByteCount) (s sendTimeState) { - b.totalBytesLost += bytesLost - if sentPacketPointer := b.connectionStateMap.GetEntry(packetNumber); sentPacketPointer != nil { - sentPacketToSendTimeState(sentPacketPointer, &s) - } - return s -} - -func (b *bandwidthSampler) OnPacketNeutered(packetNumber congestion.PacketNumber) { - b.connectionStateMap.Remove(packetNumber, func(sentPacket connectionStateOnSentPacket) { - b.totalBytesNeutered += sentPacket.size - }) -} - -func (b *bandwidthSampler) OnAppLimited() { - b.isAppLimited = true - b.endOfAppLimitedPhase = b.lastSentPacket -} - -func (b *bandwidthSampler) RemoveObsoletePackets(leastUnacked congestion.PacketNumber) { - // A packet can become obsolete when it is removed from QuicUnackedPacketMap's - // view of inflight before it is acked or marked as lost. For example, when - // QuicSentPacketManager::RetransmitCryptoPackets retransmits a crypto packet, - // the packet is removed from QuicUnackedPacketMap's inflight, but is not - // marked as acked or lost in the BandwidthSampler. - b.connectionStateMap.RemoveUpTo(leastUnacked) -} - -func (b *bandwidthSampler) TotalBytesSent() congestion.ByteCount { - return b.totalBytesSent -} - -func (b *bandwidthSampler) TotalBytesLost() congestion.ByteCount { - return b.totalBytesLost -} - -func (b *bandwidthSampler) TotalBytesAcked() congestion.ByteCount { - return b.totalBytesAcked -} - -func (b *bandwidthSampler) TotalBytesNeutered() congestion.ByteCount { - return b.totalBytesNeutered -} - -func (b *bandwidthSampler) IsAppLimited() bool { - return b.isAppLimited -} - -func (b *bandwidthSampler) EndOfAppLimitedPhase() congestion.PacketNumber { - return b.endOfAppLimitedPhase -} - -func (b *bandwidthSampler) max_ack_height() congestion.ByteCount { - return b.maxAckHeightTracker.Get() -} - -func (b *bandwidthSampler) chooseA0Point(totalBytesAcked congestion.ByteCount, a0 *ackPoint) bool { - if b.a0Candidates.Empty() { - return false - } - - if b.a0Candidates.Len() == 1 { - *a0 = *b.a0Candidates.Front() - return true - } - - for i := 1; i < b.a0Candidates.Len(); i++ { - if b.a0Candidates.Offset(i).totalBytesAcked > totalBytesAcked { - *a0 = *b.a0Candidates.Offset(i - 1) - if i > 1 { - for j := 0; j < i-1; j++ { - b.a0Candidates.PopFront() - } - } - return true - } - } - - *a0 = *b.a0Candidates.Back() - for k := 0; k < b.a0Candidates.Len()-1; k++ { - b.a0Candidates.PopFront() - } - return true -} - -func (b *bandwidthSampler) onPacketAcknowledged(ackTime time.Time, packetNumber congestion.PacketNumber) bandwidthSample { - sample := newBandwidthSample() - b.lastAckedPacket = packetNumber - sentPacketPointer := b.connectionStateMap.GetEntry(packetNumber) - if sentPacketPointer == nil { - return *sample - } - - // OnPacketAcknowledgedInner - b.totalBytesAcked += sentPacketPointer.size - b.totalBytesSentAtLastAckedPacket = sentPacketPointer.sendTimeState.totalBytesSent - b.lastAckedPacketSentTime = sentPacketPointer.sentTime - b.lastAckedPacketAckTime = ackTime - if b.overestimateAvoidance { - b.recentAckPoints.Update(ackTime, b.totalBytesAcked) - } - - if b.isAppLimited { - // Exit app-limited phase in two cases: - // (1) end_of_app_limited_phase_ is not initialized, i.e., so far all - // packets are sent while there are buffered packets or pending data. - // (2) The current acked packet is after the sent packet marked as the end - // of the app limit phase. - if b.endOfAppLimitedPhase == invalidPacketNumber || - packetNumber > b.endOfAppLimitedPhase { - b.isAppLimited = false - } - } - - // There might have been no packets acknowledged at the moment when the - // current packet was sent. In that case, there is no bandwidth sample to - // make. - if sentPacketPointer.lastAckedPacketSentTime.IsZero() { - return *sample - } - - // Infinite rate indicates that the sampler is supposed to discard the - // current send rate sample and use only the ack rate. - sendRate := infBandwidth - if sentPacketPointer.sentTime.After(sentPacketPointer.lastAckedPacketSentTime) { - sendRate = BandwidthFromDelta( - sentPacketPointer.sendTimeState.totalBytesSent-sentPacketPointer.totalBytesSentAtLastAckedPacket, - sentPacketPointer.sentTime.Sub(sentPacketPointer.lastAckedPacketSentTime)) - } - - var a0 ackPoint - if b.overestimateAvoidance && b.chooseA0Point(sentPacketPointer.sendTimeState.totalBytesAcked, &a0) { - } else { - a0.ackTime = sentPacketPointer.lastAckedPacketAckTime - a0.totalBytesAcked = sentPacketPointer.sendTimeState.totalBytesAcked - } - - // During the slope calculation, ensure that ack time of the current packet is - // always larger than the time of the previous packet, otherwise division by - // zero or integer underflow can occur. - if ackTime.Sub(a0.ackTime) <= 0 { - return *sample - } - - ackRate := BandwidthFromDelta(b.totalBytesAcked-a0.totalBytesAcked, ackTime.Sub(a0.ackTime)) - - sample.bandwidth = min(sendRate, ackRate) - // Note: this sample does not account for delayed acknowledgement time. This - // means that the RTT measurements here can be artificially high, especially - // on low bandwidth connections. - sample.rtt = ackTime.Sub(sentPacketPointer.sentTime) - sample.sendRate = sendRate - sentPacketToSendTimeState(sentPacketPointer, &sample.stateAtSend) - - return *sample -} - -func (b *bandwidthSampler) onAckEventEnd( - bandwidthEstimate Bandwidth, - isNewMaxBandwidth bool, - roundTripCount roundTripCount, -) congestion.ByteCount { - newlyAckedBytes := b.totalBytesAcked - b.totalBytesAckedAfterLastAckEvent - if newlyAckedBytes == 0 { - return 0 - } - b.totalBytesAckedAfterLastAckEvent = b.totalBytesAcked - extraAcked := b.maxAckHeightTracker.Update( - bandwidthEstimate, - isNewMaxBandwidth, - roundTripCount, - b.lastSentPacket, - b.lastAckedPacket, - b.lastAckedPacketAckTime, - newlyAckedBytes) - // If |extra_acked| is zero, i.e. this ack event marks the start of a new ack - // aggregation epoch, save LessRecentPoint, which is the last ack point of the - // previous epoch, as a A0 candidate. - if b.overestimateAvoidance && extraAcked == 0 { - b.a0Candidates.PushBack(*b.recentAckPoints.LessRecentPoint()) - } - return extraAcked -} - -func sentPacketToSendTimeState(sentPacket *connectionStateOnSentPacket, sendTimeState *sendTimeState) { - *sendTimeState = sentPacket.sendTimeState - sendTimeState.isValid = true -} - -// BytesFromBandwidthAndTimeDelta calculates the bytes -// from a bandwidth(bits per second) and a time delta -func bytesFromBandwidthAndTimeDelta(bandwidth Bandwidth, delta time.Duration) congestion.ByteCount { - return (congestion.ByteCount(bandwidth) * congestion.ByteCount(delta)) / - (congestion.ByteCount(time.Second) * 8) -} - -func timeDeltaFromBytesAndBandwidth(bytes congestion.ByteCount, bandwidth Bandwidth) time.Duration { - return time.Duration(bytes*8) * time.Second / time.Duration(bandwidth) -} diff --git a/transport/internet/hysteria2/congestion/bbr/bbr_sender.go b/transport/internet/hysteria2/congestion/bbr/bbr_sender.go deleted file mode 100644 index 26958a4f3d..0000000000 --- a/transport/internet/hysteria2/congestion/bbr/bbr_sender.go +++ /dev/null @@ -1,942 +0,0 @@ -//nolint:golint,unused -package bbr - -import ( - "fmt" - "math/rand" - "net" - "time" - - "github.com/apernet/quic-go/congestion" - - "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/common" -) - -// BbrSender implements BBR congestion control algorithm. BBR aims to estimate -// the current available Bottleneck Bandwidth and RTT (hence the name), and -// regulates the pacing rate and the size of the congestion window based on -// those signals. -// -// BBR relies on pacing in order to function properly. Do not use BBR when -// pacing is disabled. -// - -const ( - minBps = 65536 // 64 kbps - - invalidPacketNumber = -1 - initialCongestionWindowPackets = 32 - - // Constants based on TCP defaults. - // The minimum CWND to ensure delayed acks don't reduce bandwidth measurements. - // Does not inflate the pacing rate. - defaultMinimumCongestionWindow = 4 * congestion.ByteCount(congestion.InitialPacketSizeIPv4) - - // The gain used for the STARTUP, equal to 2/ln(2). - defaultHighGain = 2.885 - // The newly derived gain for STARTUP, equal to 4 * ln(2) - derivedHighGain = 2.773 - // The newly derived CWND gain for STARTUP, 2. - derivedHighCWNDGain = 2.0 -) - -// The cycle of gains used during the PROBE_BW stage. -var pacingGain = [...]float64{1.25, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0} - -const ( - // The length of the gain cycle. - gainCycleLength = len(pacingGain) - // The size of the bandwidth filter window, in round-trips. - bandwidthWindowSize = gainCycleLength + 2 - - // The time after which the current min_rtt value expires. - minRttExpiry = 10 * time.Second - // The minimum time the connection can spend in PROBE_RTT mode. - probeRttTime = 200 * time.Millisecond - // If the bandwidth does not increase by the factor of |kStartupGrowthTarget| - // within |kRoundTripsWithoutGrowthBeforeExitingStartup| rounds, the connection - // will exit the STARTUP mode. - startupGrowthTarget = 1.25 - roundTripsWithoutGrowthBeforeExitingStartup = int64(3) - - // Flag. - defaultStartupFullLossCount = 8 - quicBbr2DefaultLossThreshold = 0.02 - maxBbrBurstPackets = 3 -) - -type bbrMode int - -const ( - // Startup phase of the connection. - bbrModeStartup = iota - // After achieving the highest possible bandwidth during the startup, lower - // the pacing rate in order to drain the queue. - bbrModeDrain - // Cruising mode. - bbrModeProbeBw - // Temporarily slow down sending in order to empty the buffer and measure - // the real minimum RTT. - bbrModeProbeRtt -) - -// Indicates how the congestion control limits the amount of bytes in flight. -type bbrRecoveryState int - -const ( - // Do not limit. - bbrRecoveryStateNotInRecovery = iota - // Allow an extra outstanding byte for each byte acknowledged. - bbrRecoveryStateConservation - // Allow two extra outstanding bytes for each byte acknowledged (slow - // start). - bbrRecoveryStateGrowth -) - -type bbrSender struct { - rttStats congestion.RTTStatsProvider - clock Clock - pacer *common.Pacer - - mode bbrMode - - // Bandwidth sampler provides BBR with the bandwidth measurements at - // individual points. - sampler *bandwidthSampler - - // The number of the round trips that have occurred during the connection. - roundTripCount roundTripCount - - // The packet number of the most recently sent packet. - lastSentPacket congestion.PacketNumber - // Acknowledgement of any packet after |current_round_trip_end_| will cause - // the round trip counter to advance. - currentRoundTripEnd congestion.PacketNumber - - // Number of congestion events with some losses, in the current round. - numLossEventsInRound uint64 - - // Number of total bytes lost in the current round. - bytesLostInRound congestion.ByteCount - - // The filter that tracks the maximum bandwidth over the multiple recent - // round-trips. - maxBandwidth *WindowedFilter[Bandwidth, roundTripCount] - - // Minimum RTT estimate. Automatically expires within 10 seconds (and - // triggers PROBE_RTT mode) if no new value is sampled during that period. - minRtt time.Duration - // The time at which the current value of |min_rtt_| was assigned. - minRttTimestamp time.Time - - // The maximum allowed number of bytes in flight. - congestionWindow congestion.ByteCount - - // The initial value of the |congestion_window_|. - initialCongestionWindow congestion.ByteCount - - // The largest value the |congestion_window_| can achieve. - maxCongestionWindow congestion.ByteCount - - // The smallest value the |congestion_window_| can achieve. - minCongestionWindow congestion.ByteCount - - // The pacing gain applied during the STARTUP phase. - highGain float64 - - // The CWND gain applied during the STARTUP phase. - highCwndGain float64 - - // The pacing gain applied during the DRAIN phase. - drainGain float64 - - // The current pacing rate of the connection. - pacingRate Bandwidth - - // The gain currently applied to the pacing rate. - pacingGain float64 - // The gain currently applied to the congestion window. - congestionWindowGain float64 - - // The gain used for the congestion window during PROBE_BW. Latched from - // quic_bbr_cwnd_gain flag. - congestionWindowGainConstant float64 - // The number of RTTs to stay in STARTUP mode. Defaults to 3. - numStartupRtts int64 - - // Number of round-trips in PROBE_BW mode, used for determining the current - // pacing gain cycle. - cycleCurrentOffset int - // The time at which the last pacing gain cycle was started. - lastCycleStart time.Time - - // Indicates whether the connection has reached the full bandwidth mode. - isAtFullBandwidth bool - // Number of rounds during which there was no significant bandwidth increase. - roundsWithoutBandwidthGain int64 - // The bandwidth compared to which the increase is measured. - bandwidthAtLastRound Bandwidth - - // Set to true upon exiting quiescence. - exitingQuiescence bool - - // Time at which PROBE_RTT has to be exited. Setting it to zero indicates - // that the time is yet unknown as the number of packets in flight has not - // reached the required value. - exitProbeRttAt time.Time - // Indicates whether a round-trip has passed since PROBE_RTT became active. - probeRttRoundPassed bool - - // Indicates whether the most recent bandwidth sample was marked as - // app-limited. - lastSampleIsAppLimited bool - // Indicates whether any non app-limited samples have been recorded. - hasNoAppLimitedSample bool - - // Current state of recovery. - recoveryState bbrRecoveryState - // Receiving acknowledgement of a packet after |end_recovery_at_| will cause - // BBR to exit the recovery mode. A value above zero indicates at least one - // loss has been detected, so it must not be set back to zero. - endRecoveryAt congestion.PacketNumber - // A window used to limit the number of bytes in flight during loss recovery. - recoveryWindow congestion.ByteCount - // If true, consider all samples in recovery app-limited. - isAppLimitedRecovery bool // not used - - // When true, pace at 1.5x and disable packet conservation in STARTUP. - slowerStartup bool // not used - // When true, disables packet conservation in STARTUP. - rateBasedStartup bool // not used - - // When true, add the most recent ack aggregation measurement during STARTUP. - enableAckAggregationDuringStartup bool - // When true, expire the windowed ack aggregation values in STARTUP when - // bandwidth increases more than 25%. - expireAckAggregationInStartup bool - - // If true, will not exit low gain mode until bytes_in_flight drops below BDP - // or it's time for high gain mode. - drainToTarget bool - - // If true, slow down pacing rate in STARTUP when overshooting is detected. - detectOvershooting bool - // Bytes lost while detect_overshooting_ is true. - bytesLostWhileDetectingOvershooting congestion.ByteCount - // Slow down pacing rate if - // bytes_lost_while_detecting_overshooting_ * - // bytes_lost_multiplier_while_detecting_overshooting_ > IW. - bytesLostMultiplierWhileDetectingOvershooting uint8 - // When overshooting is detected, do not drop pacing_rate_ below this value / - // min_rtt. - cwndToCalculateMinPacingRate congestion.ByteCount - - // Max congestion window when adjusting network parameters. - maxCongestionWindowWithNetworkParametersAdjusted congestion.ByteCount // not used - - // Params. - maxDatagramSize congestion.ByteCount - // Recorded on packet sent. equivalent |unacked_packets_->bytes_in_flight()| - bytesInFlight congestion.ByteCount -} - -var _ congestion.CongestionControl = &bbrSender{} - -func NewBbrSender( - clock Clock, - initialMaxDatagramSize congestion.ByteCount, -) *bbrSender { - return newBbrSender( - clock, - initialMaxDatagramSize, - initialCongestionWindowPackets*initialMaxDatagramSize, - congestion.MaxCongestionWindowPackets*initialMaxDatagramSize, - ) -} - -func newBbrSender( - clock Clock, - initialMaxDatagramSize, - initialCongestionWindow, - initialMaxCongestionWindow congestion.ByteCount, -) *bbrSender { - b := &bbrSender{ - clock: clock, - mode: bbrModeStartup, - sampler: newBandwidthSampler(roundTripCount(bandwidthWindowSize)), - lastSentPacket: invalidPacketNumber, - currentRoundTripEnd: invalidPacketNumber, - maxBandwidth: NewWindowedFilter(roundTripCount(bandwidthWindowSize), MaxFilter[Bandwidth]), - congestionWindow: initialCongestionWindow, - initialCongestionWindow: initialCongestionWindow, - maxCongestionWindow: initialMaxCongestionWindow, - minCongestionWindow: defaultMinimumCongestionWindow, - highGain: defaultHighGain, - highCwndGain: defaultHighGain, - drainGain: 1.0 / defaultHighGain, - pacingGain: 1.0, - congestionWindowGain: 1.0, - congestionWindowGainConstant: 2.0, - numStartupRtts: roundTripsWithoutGrowthBeforeExitingStartup, - recoveryState: bbrRecoveryStateNotInRecovery, - endRecoveryAt: invalidPacketNumber, - recoveryWindow: initialMaxCongestionWindow, - bytesLostMultiplierWhileDetectingOvershooting: 2, - cwndToCalculateMinPacingRate: initialCongestionWindow, - maxCongestionWindowWithNetworkParametersAdjusted: initialMaxCongestionWindow, - maxDatagramSize: initialMaxDatagramSize, - } - b.pacer = common.NewPacer(b.bandwidthForPacer) - - /* - if b.tracer != nil { - b.lastState = logging.CongestionStateStartup - b.tracer.UpdatedCongestionState(logging.CongestionStateStartup) - } - */ - - b.enterStartupMode(b.clock.Now()) - b.setHighCwndGain(derivedHighCWNDGain) - - return b -} - -func (b *bbrSender) SetRTTStatsProvider(provider congestion.RTTStatsProvider) { - b.rttStats = provider -} - -// TimeUntilSend implements the SendAlgorithm interface. -func (b *bbrSender) TimeUntilSend(bytesInFlight congestion.ByteCount) time.Time { - return b.pacer.TimeUntilSend() -} - -// HasPacingBudget implements the SendAlgorithm interface. -func (b *bbrSender) HasPacingBudget(now time.Time) bool { - return b.pacer.Budget(now) >= b.maxDatagramSize -} - -// OnPacketSent implements the SendAlgorithm interface. -func (b *bbrSender) OnPacketSent( - sentTime time.Time, - bytesInFlight congestion.ByteCount, - packetNumber congestion.PacketNumber, - bytes congestion.ByteCount, - isRetransmittable bool, -) { - b.pacer.SentPacket(sentTime, bytes) - - b.lastSentPacket = packetNumber - b.bytesInFlight = bytesInFlight - - if bytesInFlight == 0 { - b.exitingQuiescence = true - } - - b.sampler.OnPacketSent(sentTime, packetNumber, bytes, bytesInFlight, isRetransmittable) -} - -// CanSend implements the SendAlgorithm interface. -func (b *bbrSender) CanSend(bytesInFlight congestion.ByteCount) bool { - return bytesInFlight < b.GetCongestionWindow() -} - -// MaybeExitSlowStart implements the SendAlgorithm interface. -func (b *bbrSender) MaybeExitSlowStart() { - // Do nothing -} - -// OnPacketAcked implements the SendAlgorithm interface. -func (b *bbrSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes, priorInFlight congestion.ByteCount, eventTime time.Time) { - // Do nothing. -} - -// OnPacketLost implements the SendAlgorithm interface. -func (b *bbrSender) OnPacketLost(number congestion.PacketNumber, lostBytes, priorInFlight congestion.ByteCount) { - // Do nothing. -} - -// OnRetransmissionTimeout implements the SendAlgorithm interface. -func (b *bbrSender) OnRetransmissionTimeout(packetsRetransmitted bool) { - // Do nothing. -} - -// SetMaxDatagramSize implements the SendAlgorithm interface. -func (b *bbrSender) SetMaxDatagramSize(s congestion.ByteCount) { - if s < b.maxDatagramSize { - panic(fmt.Sprintf("congestion BUG: decreased max datagram size from %d to %d", b.maxDatagramSize, s)) - } - cwndIsMinCwnd := b.congestionWindow == b.minCongestionWindow - b.maxDatagramSize = s - if cwndIsMinCwnd { - b.congestionWindow = b.minCongestionWindow - } - b.pacer.SetMaxDatagramSize(s) -} - -// InSlowStart implements the SendAlgorithmWithDebugInfos interface. -func (b *bbrSender) InSlowStart() bool { - return b.mode == bbrModeStartup -} - -// InRecovery implements the SendAlgorithmWithDebugInfos interface. -func (b *bbrSender) InRecovery() bool { - return b.recoveryState != bbrRecoveryStateNotInRecovery -} - -// GetCongestionWindow implements the SendAlgorithmWithDebugInfos interface. -func (b *bbrSender) GetCongestionWindow() congestion.ByteCount { - if b.mode == bbrModeProbeRtt { - return b.probeRttCongestionWindow() - } - - if b.InRecovery() { - return min(b.congestionWindow, b.recoveryWindow) - } - - return b.congestionWindow -} - -func (b *bbrSender) OnCongestionEvent(number congestion.PacketNumber, lostBytes, priorInFlight congestion.ByteCount) { - // Do nothing. -} - -func (b *bbrSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, eventTime time.Time, ackedPackets []congestion.AckedPacketInfo, lostPackets []congestion.LostPacketInfo) { - totalBytesAckedBefore := b.sampler.TotalBytesAcked() - totalBytesLostBefore := b.sampler.TotalBytesLost() - - var isRoundStart, minRttExpired bool - var excessAcked, bytesLost congestion.ByteCount - - // The send state of the largest packet in acked_packets, unless it is - // empty. If acked_packets is empty, it's the send state of the largest - // packet in lost_packets. - var lastPacketSendState sendTimeState - - b.maybeApplimited(priorInFlight) - - // Update bytesInFlight - b.bytesInFlight = priorInFlight - for _, p := range ackedPackets { - b.bytesInFlight -= p.BytesAcked - } - for _, p := range lostPackets { - b.bytesInFlight -= p.BytesLost - } - - if len(ackedPackets) != 0 { - lastAckedPacket := ackedPackets[len(ackedPackets)-1].PacketNumber - isRoundStart = b.updateRoundTripCounter(lastAckedPacket) - b.updateRecoveryState(lastAckedPacket, len(lostPackets) != 0, isRoundStart) - } - - sample := b.sampler.OnCongestionEvent(eventTime, - ackedPackets, lostPackets, b.maxBandwidth.GetBest(), infBandwidth, b.roundTripCount) - if sample.lastPacketSendState.isValid { - b.lastSampleIsAppLimited = sample.lastPacketSendState.isAppLimited - b.hasNoAppLimitedSample = b.hasNoAppLimitedSample || !b.lastSampleIsAppLimited - } - // Avoid updating |max_bandwidth_| if a) this is a loss-only event, or b) all - // packets in |acked_packets| did not generate valid samples. (e.g. ack of - // ack-only packets). In both cases, sampler_.total_bytes_acked() will not - // change. - if totalBytesAckedBefore != b.sampler.TotalBytesAcked() { - if !sample.sampleIsAppLimited || sample.sampleMaxBandwidth > b.maxBandwidth.GetBest() { - b.maxBandwidth.Update(sample.sampleMaxBandwidth, b.roundTripCount) - } - } - - if sample.sampleRtt != infRTT { - minRttExpired = b.maybeUpdateMinRtt(eventTime, sample.sampleRtt) - } - bytesLost = b.sampler.TotalBytesLost() - totalBytesLostBefore - - excessAcked = sample.extraAcked - lastPacketSendState = sample.lastPacketSendState - - if len(lostPackets) != 0 { - b.numLossEventsInRound++ - b.bytesLostInRound += bytesLost - } - - // Handle logic specific to PROBE_BW mode. - if b.mode == bbrModeProbeBw { - b.updateGainCyclePhase(eventTime, priorInFlight, len(lostPackets) != 0) - } - - // Handle logic specific to STARTUP and DRAIN modes. - if isRoundStart && !b.isAtFullBandwidth { - b.checkIfFullBandwidthReached(&lastPacketSendState) - } - - b.maybeExitStartupOrDrain(eventTime) - - // Handle logic specific to PROBE_RTT. - b.maybeEnterOrExitProbeRtt(eventTime, isRoundStart, minRttExpired) - - // Calculate number of packets acked and lost. - bytesAcked := b.sampler.TotalBytesAcked() - totalBytesAckedBefore - - // After the model is updated, recalculate the pacing rate and congestion - // window. - b.calculatePacingRate(bytesLost) - b.calculateCongestionWindow(bytesAcked, excessAcked) - b.calculateRecoveryWindow(bytesAcked, bytesLost) - - // Cleanup internal state. - // This is where we clean up obsolete (acked or lost) packets from the bandwidth sampler. - // The "least unacked" should actually be FirstOutstanding, but since we are not passing - // that through OnCongestionEventEx, we will only do an estimate using acked/lost packets - // for now. Because of fast retransmission, they should differ by no more than 2 packets. - // (this is controlled by packetThreshold in quic-go's sentPacketHandler) - var leastUnacked congestion.PacketNumber - if len(ackedPackets) != 0 { - leastUnacked = ackedPackets[len(ackedPackets)-1].PacketNumber - 2 - } else { - leastUnacked = lostPackets[len(lostPackets)-1].PacketNumber + 1 - } - b.sampler.RemoveObsoletePackets(leastUnacked) - - if isRoundStart { - b.numLossEventsInRound = 0 - b.bytesLostInRound = 0 - } -} - -func (b *bbrSender) PacingRate() Bandwidth { - if b.pacingRate == 0 { - return Bandwidth(b.highGain * float64( - BandwidthFromDelta(b.initialCongestionWindow, b.getMinRtt()))) - } - - return b.pacingRate -} - -func (b *bbrSender) hasGoodBandwidthEstimateForResumption() bool { - return b.hasNonAppLimitedSample() -} - -func (b *bbrSender) hasNonAppLimitedSample() bool { - return b.hasNoAppLimitedSample -} - -// Sets the pacing gain used in STARTUP. Must be greater than 1. -func (b *bbrSender) setHighGain(highGain float64) { - b.highGain = highGain - if b.mode == bbrModeStartup { - b.pacingGain = highGain - } -} - -// Sets the CWND gain used in STARTUP. Must be greater than 1. -func (b *bbrSender) setHighCwndGain(highCwndGain float64) { - b.highCwndGain = highCwndGain - if b.mode == bbrModeStartup { - b.congestionWindowGain = highCwndGain - } -} - -// Sets the gain used in DRAIN. Must be less than 1. -func (b *bbrSender) setDrainGain(drainGain float64) { - b.drainGain = drainGain -} - -// What's the current estimated bandwidth in bytes per second. -func (b *bbrSender) bandwidthEstimate() Bandwidth { - return b.maxBandwidth.GetBest() -} - -func (b *bbrSender) bandwidthForPacer() congestion.ByteCount { - bps := congestion.ByteCount(float64(b.bandwidthEstimate()) * b.congestionWindowGain / float64(BytesPerSecond)) - if bps < minBps { - // We need to make sure that the bandwidth value for pacer is never zero, - // otherwise it will go into an edge case where HasPacingBudget = false - // but TimeUntilSend is before, causing the quic-go send loop to go crazy and get stuck. - return minBps - } - return bps -} - -// Returns the current estimate of the RTT of the connection. Outside of the -// edge cases, this is minimum RTT. -func (b *bbrSender) getMinRtt() time.Duration { - if b.minRtt != 0 { - return b.minRtt - } - // min_rtt could be available if the handshake packet gets neutered then - // gets acknowledged. This could only happen for QUIC crypto where we do not - // drop keys. - minRtt := b.rttStats.MinRTT() - if minRtt == 0 { - return 100 * time.Millisecond - } else { - return minRtt - } -} - -// Computes the target congestion window using the specified gain. -func (b *bbrSender) getTargetCongestionWindow(gain float64) congestion.ByteCount { - bdp := bdpFromRttAndBandwidth(b.getMinRtt(), b.bandwidthEstimate()) - congestionWindow := congestion.ByteCount(gain * float64(bdp)) - - // BDP estimate will be zero if no bandwidth samples are available yet. - if congestionWindow == 0 { - congestionWindow = congestion.ByteCount(gain * float64(b.initialCongestionWindow)) - } - - return max(congestionWindow, b.minCongestionWindow) -} - -// The target congestion window during PROBE_RTT. -func (b *bbrSender) probeRttCongestionWindow() congestion.ByteCount { - return b.minCongestionWindow -} - -func (b *bbrSender) maybeUpdateMinRtt(now time.Time, sampleMinRtt time.Duration) bool { - // Do not expire min_rtt if none was ever available. - minRttExpired := b.minRtt != 0 && now.After(b.minRttTimestamp.Add(minRttExpiry)) - if minRttExpired || sampleMinRtt < b.minRtt || b.minRtt == 0 { - b.minRtt = sampleMinRtt - b.minRttTimestamp = now - } - - return minRttExpired -} - -// Enters the STARTUP mode. -func (b *bbrSender) enterStartupMode(now time.Time) { - b.mode = bbrModeStartup - // b.maybeTraceStateChange(logging.CongestionStateStartup) - b.pacingGain = b.highGain - b.congestionWindowGain = b.highCwndGain -} - -// Enters the PROBE_BW mode. -func (b *bbrSender) enterProbeBandwidthMode(now time.Time) { - b.mode = bbrModeProbeBw - // b.maybeTraceStateChange(logging.CongestionStateProbeBw) - b.congestionWindowGain = b.congestionWindowGainConstant - - // Pick a random offset for the gain cycle out of {0, 2..7} range. 1 is - // excluded because in that case increased gain and decreased gain would not - // follow each other. - b.cycleCurrentOffset = int(rand.Int31n(congestion.PacketsPerConnectionID)) % (gainCycleLength - 1) - if b.cycleCurrentOffset >= 1 { - b.cycleCurrentOffset += 1 - } - - b.lastCycleStart = now - b.pacingGain = pacingGain[b.cycleCurrentOffset] -} - -// Updates the round-trip counter if a round-trip has passed. Returns true if -// the counter has been advanced. -func (b *bbrSender) updateRoundTripCounter(lastAckedPacket congestion.PacketNumber) bool { - if b.currentRoundTripEnd == invalidPacketNumber || lastAckedPacket > b.currentRoundTripEnd { - b.roundTripCount++ - b.currentRoundTripEnd = b.lastSentPacket - return true - } - return false -} - -// Updates the current gain used in PROBE_BW mode. -func (b *bbrSender) updateGainCyclePhase(now time.Time, priorInFlight congestion.ByteCount, hasLosses bool) { - // In most cases, the cycle is advanced after an RTT passes. - shouldAdvanceGainCycling := now.After(b.lastCycleStart.Add(b.getMinRtt())) - // If the pacing gain is above 1.0, the connection is trying to probe the - // bandwidth by increasing the number of bytes in flight to at least - // pacing_gain * BDP. Make sure that it actually reaches the target, as long - // as there are no losses suggesting that the buffers are not able to hold - // that much. - if b.pacingGain > 1.0 && !hasLosses && priorInFlight < b.getTargetCongestionWindow(b.pacingGain) { - shouldAdvanceGainCycling = false - } - - // If pacing gain is below 1.0, the connection is trying to drain the extra - // queue which could have been incurred by probing prior to it. If the number - // of bytes in flight falls down to the estimated BDP value earlier, conclude - // that the queue has been successfully drained and exit this cycle early. - if b.pacingGain < 1.0 && b.bytesInFlight <= b.getTargetCongestionWindow(1) { - shouldAdvanceGainCycling = true - } - - if shouldAdvanceGainCycling { - b.cycleCurrentOffset = (b.cycleCurrentOffset + 1) % gainCycleLength - b.lastCycleStart = now - // Stay in low gain mode until the target BDP is hit. - // Low gain mode will be exited immediately when the target BDP is achieved. - if b.drainToTarget && b.pacingGain < 1 && - pacingGain[b.cycleCurrentOffset] == 1 && - b.bytesInFlight > b.getTargetCongestionWindow(1) { - return - } - b.pacingGain = pacingGain[b.cycleCurrentOffset] - } -} - -// Tracks for how many round-trips the bandwidth has not increased -// significantly. -func (b *bbrSender) checkIfFullBandwidthReached(lastPacketSendState *sendTimeState) { - if b.lastSampleIsAppLimited { - return - } - - target := Bandwidth(float64(b.bandwidthAtLastRound) * startupGrowthTarget) - if b.bandwidthEstimate() >= target { - b.bandwidthAtLastRound = b.bandwidthEstimate() - b.roundsWithoutBandwidthGain = 0 - if b.expireAckAggregationInStartup { - // Expire old excess delivery measurements now that bandwidth increased. - b.sampler.ResetMaxAckHeightTracker(0, b.roundTripCount) - } - return - } - - b.roundsWithoutBandwidthGain++ - if b.roundsWithoutBandwidthGain >= b.numStartupRtts || - b.shouldExitStartupDueToLoss(lastPacketSendState) { - b.isAtFullBandwidth = true - } -} - -func (b *bbrSender) maybeApplimited(bytesInFlight congestion.ByteCount) { - congestionWindow := b.GetCongestionWindow() - if bytesInFlight >= congestionWindow { - return - } - availableBytes := congestionWindow - bytesInFlight - drainLimited := b.mode == bbrModeDrain && bytesInFlight > congestionWindow/2 - if !drainLimited || availableBytes > maxBbrBurstPackets*b.maxDatagramSize { - b.sampler.OnAppLimited() - } -} - -// Transitions from STARTUP to DRAIN and from DRAIN to PROBE_BW if -// appropriate. -func (b *bbrSender) maybeExitStartupOrDrain(now time.Time) { - if b.mode == bbrModeStartup && b.isAtFullBandwidth { - b.mode = bbrModeDrain - // b.maybeTraceStateChange(logging.CongestionStateDrain) - b.pacingGain = b.drainGain - b.congestionWindowGain = b.highCwndGain - } - if b.mode == bbrModeDrain && b.bytesInFlight <= b.getTargetCongestionWindow(1) { - b.enterProbeBandwidthMode(now) - } -} - -// Decides whether to enter or exit PROBE_RTT. -func (b *bbrSender) maybeEnterOrExitProbeRtt(now time.Time, isRoundStart, minRttExpired bool) { - if minRttExpired && !b.exitingQuiescence && b.mode != bbrModeProbeRtt { - b.mode = bbrModeProbeRtt - // b.maybeTraceStateChange(logging.CongestionStateProbRtt) - b.pacingGain = 1.0 - // Do not decide on the time to exit PROBE_RTT until the |bytes_in_flight| - // is at the target small value. - b.exitProbeRttAt = time.Time{} - } - - if b.mode == bbrModeProbeRtt { - b.sampler.OnAppLimited() - // b.maybeTraceStateChange(logging.CongestionStateApplicationLimited) - - if b.exitProbeRttAt.IsZero() { - // If the window has reached the appropriate size, schedule exiting - // PROBE_RTT. The CWND during PROBE_RTT is kMinimumCongestionWindow, but - // we allow an extra packet since QUIC checks CWND before sending a - // packet. - if b.bytesInFlight < b.probeRttCongestionWindow()+congestion.MaxPacketBufferSize { - b.exitProbeRttAt = now.Add(probeRttTime) - b.probeRttRoundPassed = false - } - } else { - if isRoundStart { - b.probeRttRoundPassed = true - } - if now.Sub(b.exitProbeRttAt) >= 0 && b.probeRttRoundPassed { - b.minRttTimestamp = now - if !b.isAtFullBandwidth { - b.enterStartupMode(now) - } else { - b.enterProbeBandwidthMode(now) - } - } - } - } - - b.exitingQuiescence = false -} - -// Determines whether BBR needs to enter, exit or advance state of the -// recovery. -func (b *bbrSender) updateRecoveryState(lastAckedPacket congestion.PacketNumber, hasLosses, isRoundStart bool) { - // Disable recovery in startup, if loss-based exit is enabled. - if !b.isAtFullBandwidth { - return - } - - // Exit recovery when there are no losses for a round. - if hasLosses { - b.endRecoveryAt = b.lastSentPacket - } - - switch b.recoveryState { - case bbrRecoveryStateNotInRecovery: - if hasLosses { - b.recoveryState = bbrRecoveryStateConservation - // This will cause the |recovery_window_| to be set to the correct - // value in CalculateRecoveryWindow(). - b.recoveryWindow = 0 - // Since the conservation phase is meant to be lasting for a whole - // round, extend the current round as if it were started right now. - b.currentRoundTripEnd = b.lastSentPacket - } - case bbrRecoveryStateConservation: - if isRoundStart { - b.recoveryState = bbrRecoveryStateGrowth - } - fallthrough - case bbrRecoveryStateGrowth: - // Exit recovery if appropriate. - if !hasLosses && lastAckedPacket > b.endRecoveryAt { - b.recoveryState = bbrRecoveryStateNotInRecovery - } - } -} - -// Determines the appropriate pacing rate for the connection. -func (b *bbrSender) calculatePacingRate(bytesLost congestion.ByteCount) { - if b.bandwidthEstimate() == 0 { - return - } - - targetRate := Bandwidth(b.pacingGain * float64(b.bandwidthEstimate())) - if b.isAtFullBandwidth { - b.pacingRate = targetRate - return - } - - // Pace at the rate of initial_window / RTT as soon as RTT measurements are - // available. - if b.pacingRate == 0 && b.rttStats.MinRTT() != 0 { - b.pacingRate = BandwidthFromDelta(b.initialCongestionWindow, b.rttStats.MinRTT()) - return - } - - if b.detectOvershooting { - b.bytesLostWhileDetectingOvershooting += bytesLost - // Check for overshooting with network parameters adjusted when pacing rate - // > target_rate and loss has been detected. - if b.pacingRate > targetRate && b.bytesLostWhileDetectingOvershooting > 0 { - if b.hasNoAppLimitedSample || - b.bytesLostWhileDetectingOvershooting*congestion.ByteCount(b.bytesLostMultiplierWhileDetectingOvershooting) > b.initialCongestionWindow { - // We are fairly sure overshoot happens if 1) there is at least one - // non app-limited bw sample or 2) half of IW gets lost. Slow pacing - // rate. - b.pacingRate = max(targetRate, BandwidthFromDelta(b.cwndToCalculateMinPacingRate, b.rttStats.MinRTT())) - b.bytesLostWhileDetectingOvershooting = 0 - b.detectOvershooting = false - } - } - } - - // Do not decrease the pacing rate during startup. - b.pacingRate = max(b.pacingRate, targetRate) -} - -// Determines the appropriate congestion window for the connection. -func (b *bbrSender) calculateCongestionWindow(bytesAcked, excessAcked congestion.ByteCount) { - if b.mode == bbrModeProbeRtt { - return - } - - targetWindow := b.getTargetCongestionWindow(b.congestionWindowGain) - if b.isAtFullBandwidth { - // Add the max recently measured ack aggregation to CWND. - targetWindow += b.sampler.MaxAckHeight() - } else if b.enableAckAggregationDuringStartup { - // Add the most recent excess acked. Because CWND never decreases in - // STARTUP, this will automatically create a very localized max filter. - targetWindow += excessAcked - } - - // Instead of immediately setting the target CWND as the new one, BBR grows - // the CWND towards |target_window| by only increasing it |bytes_acked| at a - // time. - if b.isAtFullBandwidth { - b.congestionWindow = min(targetWindow, b.congestionWindow+bytesAcked) - } else if b.congestionWindow < targetWindow || - b.sampler.TotalBytesAcked() < b.initialCongestionWindow { - // If the connection is not yet out of startup phase, do not decrease the - // window. - b.congestionWindow += bytesAcked - } - - // Enforce the limits on the congestion window. - b.congestionWindow = max(b.congestionWindow, b.minCongestionWindow) - b.congestionWindow = min(b.congestionWindow, b.maxCongestionWindow) -} - -// Determines the appropriate window that constrains the in-flight during recovery. -func (b *bbrSender) calculateRecoveryWindow(bytesAcked, bytesLost congestion.ByteCount) { - if b.recoveryState == bbrRecoveryStateNotInRecovery { - return - } - - // Set up the initial recovery window. - if b.recoveryWindow == 0 { - b.recoveryWindow = b.bytesInFlight + bytesAcked - b.recoveryWindow = max(b.minCongestionWindow, b.recoveryWindow) - return - } - - // Remove losses from the recovery window, while accounting for a potential - // integer underflow. - if b.recoveryWindow >= bytesLost { - b.recoveryWindow = b.recoveryWindow - bytesLost - } else { - b.recoveryWindow = b.maxDatagramSize - } - - // In CONSERVATION mode, just subtracting losses is sufficient. In GROWTH, - // release additional |bytes_acked| to achieve a slow-start-like behavior. - if b.recoveryState == bbrRecoveryStateGrowth { - b.recoveryWindow += bytesAcked - } - - // Always allow sending at least |bytes_acked| in response. - b.recoveryWindow = max(b.recoveryWindow, b.bytesInFlight+bytesAcked) - b.recoveryWindow = max(b.minCongestionWindow, b.recoveryWindow) -} - -// Return whether we should exit STARTUP due to excessive loss. -func (b *bbrSender) shouldExitStartupDueToLoss(lastPacketSendState *sendTimeState) bool { - if b.numLossEventsInRound < defaultStartupFullLossCount || !lastPacketSendState.isValid { - return false - } - - inflightAtSend := lastPacketSendState.bytesInFlight - - if inflightAtSend > 0 && b.bytesLostInRound > 0 { - return b.bytesLostInRound > congestion.ByteCount(float64(inflightAtSend)*quicBbr2DefaultLossThreshold) - } - return false -} - -func bdpFromRttAndBandwidth(rtt time.Duration, bandwidth Bandwidth) congestion.ByteCount { - return congestion.ByteCount(rtt) * congestion.ByteCount(bandwidth) / congestion.ByteCount(BytesPerSecond) / congestion.ByteCount(time.Second) -} - -func GetInitialPacketSize(addr net.Addr) congestion.ByteCount { - // If this is not a UDP address, we don't know anything about the MTU. - // Use the minimum size of an Initial packet as the max packet size. - if udpAddr, ok := addr.(*net.UDPAddr); ok { - if udpAddr.IP.To4() != nil { - return congestion.InitialPacketSizeIPv4 - } else { - return congestion.InitialPacketSizeIPv6 - } - } else { - return congestion.MinInitialPacketSize - } -} diff --git a/transport/internet/hysteria2/congestion/bbr/clock.go b/transport/internet/hysteria2/congestion/bbr/clock.go deleted file mode 100644 index a66344fb71..0000000000 --- a/transport/internet/hysteria2/congestion/bbr/clock.go +++ /dev/null @@ -1,18 +0,0 @@ -package bbr - -import "time" - -// A Clock returns the current time -type Clock interface { - Now() time.Time -} - -// DefaultClock implements the Clock interface using the Go stdlib clock. -type DefaultClock struct{} - -var _ Clock = DefaultClock{} - -// Now gets the current time -func (DefaultClock) Now() time.Time { - return time.Now() -} diff --git a/transport/internet/hysteria2/congestion/bbr/packet_number_indexed_queue.go b/transport/internet/hysteria2/congestion/bbr/packet_number_indexed_queue.go deleted file mode 100644 index ac4c51aafa..0000000000 --- a/transport/internet/hysteria2/congestion/bbr/packet_number_indexed_queue.go +++ /dev/null @@ -1,198 +0,0 @@ -package bbr - -import ( - "github.com/apernet/quic-go/congestion" -) - -// packetNumberIndexedQueue is a queue of mostly continuous numbered entries -// which supports the following operations: -// - adding elements to the end of the queue, or at some point past the end -// - removing elements in any order -// - retrieving elements -// If all elements are inserted in order, all of the operations above are -// amortized O(1) time. -// -// Internally, the data structure is a deque where each element is marked as -// present or not. The deque starts at the lowest present index. Whenever an -// element is removed, it's marked as not present, and the front of the deque is -// cleared of elements that are not present. -// -// The tail of the queue is not cleared due to the assumption of entries being -// inserted in order, though removing all elements of the queue will return it -// to its initial state. -// -// Note that this data structure is inherently hazardous, since an addition of -// just two entries will cause it to consume all of the memory available. -// Because of that, it is not a general-purpose container and should not be used -// as one. - -type entryWrapper[T any] struct { - present bool - entry T -} - -type packetNumberIndexedQueue[T any] struct { - entries RingBuffer[entryWrapper[T]] - numberOfPresentEntries int - firstPacket congestion.PacketNumber -} - -func newPacketNumberIndexedQueue[T any](size int) *packetNumberIndexedQueue[T] { - q := &packetNumberIndexedQueue[T]{ - firstPacket: invalidPacketNumber, - } - - q.entries.Init(size) - - return q -} - -// Emplace inserts data associated |packet_number| into (or past) the end of the -// queue, filling up the missing intermediate entries as necessary. Returns -// true if the element has been inserted successfully, false if it was already -// in the queue or inserted out of order. -func (p *packetNumberIndexedQueue[T]) Emplace(packetNumber congestion.PacketNumber, entry *T) bool { - if packetNumber == invalidPacketNumber || entry == nil { - return false - } - - if p.IsEmpty() { - p.entries.PushBack(entryWrapper[T]{ - present: true, - entry: *entry, - }) - p.numberOfPresentEntries = 1 - p.firstPacket = packetNumber - return true - } - - // Do not allow insertion out-of-order. - if packetNumber <= p.LastPacket() { - return false - } - - // Handle potentially missing elements. - offset := int(packetNumber - p.FirstPacket()) - if gap := offset - p.entries.Len(); gap > 0 { - for i := 0; i < gap; i++ { - p.entries.PushBack(entryWrapper[T]{}) - } - } - - p.entries.PushBack(entryWrapper[T]{ - present: true, - entry: *entry, - }) - p.numberOfPresentEntries++ - return true -} - -// GetEntry Retrieve the entry associated with the packet number. Returns the pointer -// to the entry in case of success, or nullptr if the entry does not exist. -func (p *packetNumberIndexedQueue[T]) GetEntry(packetNumber congestion.PacketNumber) *T { - ew := p.getEntryWraper(packetNumber) - if ew == nil { - return nil - } - - return &ew.entry -} - -// Remove, Same as above, but if an entry is present in the queue, also call f(entry) -// before removing it. -func (p *packetNumberIndexedQueue[T]) Remove(packetNumber congestion.PacketNumber, f func(T)) bool { - ew := p.getEntryWraper(packetNumber) - if ew == nil { - return false - } - if f != nil { - f(ew.entry) - } - ew.present = false - p.numberOfPresentEntries-- - - if packetNumber == p.FirstPacket() { - p.clearup() - } - - return true -} - -// RemoveUpTo, but not including |packet_number|. -// Unused slots in the front are also removed, which means when the function -// returns, |first_packet()| can be larger than |packet_number|. -func (p *packetNumberIndexedQueue[T]) RemoveUpTo(packetNumber congestion.PacketNumber) { - for !p.entries.Empty() && - p.firstPacket != invalidPacketNumber && - p.firstPacket < packetNumber { - if p.entries.Front().present { - p.numberOfPresentEntries-- - } - p.entries.PopFront() - p.firstPacket++ - } - p.clearup() - -} - -// IsEmpty return if queue is empty. -func (p *packetNumberIndexedQueue[T]) IsEmpty() bool { - return p.numberOfPresentEntries == 0 -} - -// NumberOfPresentEntries returns the number of entries in the queue. -func (p *packetNumberIndexedQueue[T]) NumberOfPresentEntries() int { - return p.numberOfPresentEntries -} - -// EntrySlotsUsed returns the number of entries allocated in the underlying deque. This is -// proportional to the memory usage of the queue. -func (p *packetNumberIndexedQueue[T]) EntrySlotsUsed() int { - return p.entries.Len() -} - -// LastPacket returns packet number of the first entry in the queue. -func (p *packetNumberIndexedQueue[T]) FirstPacket() (packetNumber congestion.PacketNumber) { - return p.firstPacket -} - -// LastPacket returns packet number of the last entry ever inserted in the queue. Note that the -// entry in question may have already been removed. Zero if the queue is -// empty. -func (p *packetNumberIndexedQueue[T]) LastPacket() (packetNumber congestion.PacketNumber) { - if p.IsEmpty() { - return invalidPacketNumber - } - - return p.firstPacket + congestion.PacketNumber(p.entries.Len()-1) -} - -func (p *packetNumberIndexedQueue[T]) clearup() { - for !p.entries.Empty() && !p.entries.Front().present { - p.entries.PopFront() - p.firstPacket++ - } - if p.entries.Empty() { - p.firstPacket = invalidPacketNumber - } -} - -func (p *packetNumberIndexedQueue[T]) getEntryWraper(packetNumber congestion.PacketNumber) *entryWrapper[T] { - if packetNumber == invalidPacketNumber || - p.IsEmpty() || - packetNumber < p.firstPacket { - return nil - } - - offset := int(packetNumber - p.firstPacket) - if offset >= p.entries.Len() { - return nil - } - - ew := p.entries.Offset(offset) - if ew == nil || !ew.present { - return nil - } - - return ew -} diff --git a/transport/internet/hysteria2/congestion/bbr/ringbuffer.go b/transport/internet/hysteria2/congestion/bbr/ringbuffer.go deleted file mode 100644 index ed92d4ce01..0000000000 --- a/transport/internet/hysteria2/congestion/bbr/ringbuffer.go +++ /dev/null @@ -1,118 +0,0 @@ -package bbr - -// A RingBuffer is a ring buffer. -// It acts as a heap that doesn't cause any allocations. -type RingBuffer[T any] struct { - ring []T - headPos, tailPos int - full bool -} - -// Init preallocs a buffer with a certain size. -func (r *RingBuffer[T]) Init(size int) { - r.ring = make([]T, size) -} - -// Len returns the number of elements in the ring buffer. -func (r *RingBuffer[T]) Len() int { - if r.full { - return len(r.ring) - } - if r.tailPos >= r.headPos { - return r.tailPos - r.headPos - } - return r.tailPos - r.headPos + len(r.ring) -} - -// Empty says if the ring buffer is empty. -func (r *RingBuffer[T]) Empty() bool { - return !r.full && r.headPos == r.tailPos -} - -// PushBack adds a new element. -// If the ring buffer is full, its capacity is increased first. -func (r *RingBuffer[T]) PushBack(t T) { - if r.full || len(r.ring) == 0 { - r.grow() - } - r.ring[r.tailPos] = t - r.tailPos++ - if r.tailPos == len(r.ring) { - r.tailPos = 0 - } - if r.tailPos == r.headPos { - r.full = true - } -} - -// PopFront returns the next element. -// It must not be called when the buffer is empty, that means that -// callers might need to check if there are elements in the buffer first. -func (r *RingBuffer[T]) PopFront() T { - if r.Empty() { - panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: pop from an empty queue") - } - r.full = false - t := r.ring[r.headPos] - r.ring[r.headPos] = *new(T) - r.headPos++ - if r.headPos == len(r.ring) { - r.headPos = 0 - } - return t -} - -// Offset returns the offset element. -// It must not be called when the buffer is empty, that means that -// callers might need to check if there are elements in the buffer first -// and check if the index larger than buffer length. -func (r *RingBuffer[T]) Offset(index int) *T { - if r.Empty() || index >= r.Len() { - panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: offset from invalid index") - } - offset := (r.headPos + index) % len(r.ring) - return &r.ring[offset] -} - -// Front returns the front element. -// It must not be called when the buffer is empty, that means that -// callers might need to check if there are elements in the buffer first. -func (r *RingBuffer[T]) Front() *T { - if r.Empty() { - panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: front from an empty queue") - } - return &r.ring[r.headPos] -} - -// Back returns the back element. -// It must not be called when the buffer is empty, that means that -// callers might need to check if there are elements in the buffer first. -func (r *RingBuffer[T]) Back() *T { - if r.Empty() { - panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: back from an empty queue") - } - return r.Offset(r.Len() - 1) -} - -// Grow the maximum size of the queue. -// This method assume the queue is full. -func (r *RingBuffer[T]) grow() { - oldRing := r.ring - newSize := len(oldRing) * 2 - if newSize == 0 { - newSize = 1 - } - r.ring = make([]T, newSize) - headLen := copy(r.ring, oldRing[r.headPos:]) - copy(r.ring[headLen:], oldRing[:r.headPos]) - r.headPos, r.tailPos, r.full = 0, len(oldRing), false -} - -// Clear removes all elements. -func (r *RingBuffer[T]) Clear() { - var zeroValue T - for i := range r.ring { - r.ring[i] = zeroValue - } - r.headPos, r.tailPos, r.full = 0, 0, false -} diff --git a/transport/internet/hysteria2/congestion/bbr/windowed_filter.go b/transport/internet/hysteria2/congestion/bbr/windowed_filter.go deleted file mode 100644 index bd9a5f7211..0000000000 --- a/transport/internet/hysteria2/congestion/bbr/windowed_filter.go +++ /dev/null @@ -1,162 +0,0 @@ -package bbr - -import ( - "golang.org/x/exp/constraints" -) - -// Implements Kathleen Nichols' algorithm for tracking the minimum (or maximum) -// estimate of a stream of samples over some fixed time interval. (E.g., -// the minimum RTT over the past five minutes.) The algorithm keeps track of -// the best, second best, and third best min (or max) estimates, maintaining an -// invariant that the measurement time of the n'th best >= n-1'th best. - -// The algorithm works as follows. On a reset, all three estimates are set to -// the same sample. The second best estimate is then recorded in the second -// quarter of the window, and a third best estimate is recorded in the second -// half of the window, bounding the worst case error when the true min is -// monotonically increasing (or true max is monotonically decreasing) over the -// window. -// -// A new best sample replaces all three estimates, since the new best is lower -// (or higher) than everything else in the window and it is the most recent. -// The window thus effectively gets reset on every new min. The same property -// holds true for second best and third best estimates. Specifically, when a -// sample arrives that is better than the second best but not better than the -// best, it replaces the second and third best estimates but not the best -// estimate. Similarly, a sample that is better than the third best estimate -// but not the other estimates replaces only the third best estimate. -// -// Finally, when the best expires, it is replaced by the second best, which in -// turn is replaced by the third best. The newest sample replaces the third -// best. - -type WindowedFilterValue interface { - any -} - -type WindowedFilterTime interface { - constraints.Integer | constraints.Float -} - -type WindowedFilter[V WindowedFilterValue, T WindowedFilterTime] struct { - // Time length of window. - windowLength T - estimates []entry[V, T] - comparator func(V, V) int -} - -type entry[V WindowedFilterValue, T WindowedFilterTime] struct { - sample V - time T -} - -// Compares two values and returns true if the first is greater than or equal -// to the second. -func MaxFilter[O constraints.Ordered](a, b O) int { - if a > b { - return 1 - } else if a < b { - return -1 - } - return 0 -} - -// Compares two values and returns true if the first is less than or equal -// to the second. -func MinFilter[O constraints.Ordered](a, b O) int { - if a < b { - return 1 - } else if a > b { - return -1 - } - return 0 -} - -func NewWindowedFilter[V WindowedFilterValue, T WindowedFilterTime](windowLength T, comparator func(V, V) int) *WindowedFilter[V, T] { - return &WindowedFilter[V, T]{ - windowLength: windowLength, - estimates: make([]entry[V, T], 3), - comparator: comparator, - } -} - -// Changes the window length. Does not update any current samples. -func (f *WindowedFilter[V, T]) SetWindowLength(windowLength T) { - f.windowLength = windowLength -} - -func (f *WindowedFilter[V, T]) GetBest() V { - return f.estimates[0].sample -} - -func (f *WindowedFilter[V, T]) GetSecondBest() V { - return f.estimates[1].sample -} - -func (f *WindowedFilter[V, T]) GetThirdBest() V { - return f.estimates[2].sample -} - -// Updates best estimates with |sample|, and expires and updates best -// estimates as necessary. -func (f *WindowedFilter[V, T]) Update(newSample V, newTime T) { - // Reset all estimates if they have not yet been initialized, if new sample - // is a new best, or if the newest recorded estimate is too old. - if f.comparator(f.estimates[0].sample, *new(V)) == 0 || - f.comparator(newSample, f.estimates[0].sample) >= 0 || - newTime-f.estimates[2].time > f.windowLength { - f.Reset(newSample, newTime) - return - } - - if f.comparator(newSample, f.estimates[1].sample) >= 0 { - f.estimates[1] = entry[V, T]{newSample, newTime} - f.estimates[2] = f.estimates[1] - } else if f.comparator(newSample, f.estimates[2].sample) >= 0 { - f.estimates[2] = entry[V, T]{newSample, newTime} - } - - // Expire and update estimates as necessary. - if newTime-f.estimates[0].time > f.windowLength { - // The best estimate hasn't been updated for an entire window, so promote - // second and third best estimates. - f.estimates[0] = f.estimates[1] - f.estimates[1] = f.estimates[2] - f.estimates[2] = entry[V, T]{newSample, newTime} - // Need to iterate one more time. Check if the new best estimate is - // outside the window as well, since it may also have been recorded a - // long time ago. Don't need to iterate once more since we cover that - // case at the beginning of the method. - if newTime-f.estimates[0].time > f.windowLength { - f.estimates[0] = f.estimates[1] - f.estimates[1] = f.estimates[2] - } - return - } - if f.comparator(f.estimates[1].sample, f.estimates[0].sample) == 0 && - newTime-f.estimates[1].time > f.windowLength/4 { - // A quarter of the window has passed without a better sample, so the - // second-best estimate is taken from the second quarter of the window. - f.estimates[1] = entry[V, T]{newSample, newTime} - f.estimates[2] = f.estimates[1] - return - } - - if f.comparator(f.estimates[2].sample, f.estimates[1].sample) == 0 && - newTime-f.estimates[2].time > f.windowLength/2 { - // We've passed a half of the window without a better estimate, so take - // a third-best estimate from the second half of the window. - f.estimates[2] = entry[V, T]{newSample, newTime} - } -} - -// Resets all estimates to new sample. -func (f *WindowedFilter[V, T]) Reset(newSample V, newTime T) { - f.estimates[2] = entry[V, T]{newSample, newTime} - f.estimates[1] = f.estimates[2] - f.estimates[0] = f.estimates[1] -} - -func (f *WindowedFilter[V, T]) Clear() { - f.estimates = make([]entry[V, T], 3) -} diff --git a/transport/internet/hysteria2/congestion/brutal/brutal.go b/transport/internet/hysteria2/congestion/brutal/brutal.go deleted file mode 100644 index dbc31588c5..0000000000 --- a/transport/internet/hysteria2/congestion/brutal/brutal.go +++ /dev/null @@ -1,181 +0,0 @@ -package brutal - -import ( - "fmt" - "os" - "strconv" - "time" - - "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/common" - - "github.com/apernet/quic-go/congestion" -) - -const ( - pktInfoSlotCount = 5 // slot index is based on seconds, so this is basically how many seconds we sample - minSampleCount = 50 - minAckRate = 0.8 - congestionWindowMultiplier = 2 - - debugEnv = "HYSTERIA_BRUTAL_DEBUG" - debugPrintInterval = 2 -) - -var _ congestion.CongestionControl = &BrutalSender{} - -type BrutalSender struct { - rttStats congestion.RTTStatsProvider - bps congestion.ByteCount - maxDatagramSize congestion.ByteCount - pacer *common.Pacer - - pktInfoSlots [pktInfoSlotCount]pktInfo - ackRate float64 - - debug bool - lastAckPrintTimestamp int64 -} - -type pktInfo struct { - Timestamp int64 - AckCount uint64 - LossCount uint64 -} - -func NewBrutalSender(bps uint64) *BrutalSender { - debug, _ := strconv.ParseBool(os.Getenv(debugEnv)) - bs := &BrutalSender{ - bps: congestion.ByteCount(bps), - maxDatagramSize: congestion.InitialPacketSizeIPv4, - ackRate: 1, - debug: debug, - } - bs.pacer = common.NewPacer(func() congestion.ByteCount { - return congestion.ByteCount(float64(bs.bps) / bs.ackRate) - }) - return bs -} - -func (b *BrutalSender) SetRTTStatsProvider(rttStats congestion.RTTStatsProvider) { - b.rttStats = rttStats -} - -func (b *BrutalSender) TimeUntilSend(bytesInFlight congestion.ByteCount) time.Time { - return b.pacer.TimeUntilSend() -} - -func (b *BrutalSender) HasPacingBudget(now time.Time) bool { - return b.pacer.Budget(now) >= b.maxDatagramSize -} - -func (b *BrutalSender) CanSend(bytesInFlight congestion.ByteCount) bool { - return bytesInFlight < b.GetCongestionWindow() -} - -func (b *BrutalSender) GetCongestionWindow() congestion.ByteCount { - rtt := b.rttStats.SmoothedRTT() - if rtt <= 0 { - return 10240 - } - return congestion.ByteCount(float64(b.bps) * rtt.Seconds() * congestionWindowMultiplier / b.ackRate) -} - -func (b *BrutalSender) OnPacketSent(sentTime time.Time, bytesInFlight congestion.ByteCount, - packetNumber congestion.PacketNumber, bytes congestion.ByteCount, isRetransmittable bool, -) { - b.pacer.SentPacket(sentTime, bytes) -} - -func (b *BrutalSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes congestion.ByteCount, - priorInFlight congestion.ByteCount, eventTime time.Time, -) { - // Stub -} - -func (b *BrutalSender) OnCongestionEvent(number congestion.PacketNumber, lostBytes congestion.ByteCount, - priorInFlight congestion.ByteCount, -) { - // Stub -} - -func (b *BrutalSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, eventTime time.Time, ackedPackets []congestion.AckedPacketInfo, lostPackets []congestion.LostPacketInfo) { - currentTimestamp := eventTime.Unix() - slot := currentTimestamp % pktInfoSlotCount - if b.pktInfoSlots[slot].Timestamp == currentTimestamp { - b.pktInfoSlots[slot].LossCount += uint64(len(lostPackets)) - b.pktInfoSlots[slot].AckCount += uint64(len(ackedPackets)) - } else { - // uninitialized slot or too old, reset - b.pktInfoSlots[slot].Timestamp = currentTimestamp - b.pktInfoSlots[slot].AckCount = uint64(len(ackedPackets)) - b.pktInfoSlots[slot].LossCount = uint64(len(lostPackets)) - } - b.updateAckRate(currentTimestamp) -} - -func (b *BrutalSender) SetMaxDatagramSize(size congestion.ByteCount) { - b.maxDatagramSize = size - b.pacer.SetMaxDatagramSize(size) - if b.debug { - b.debugPrint("SetMaxDatagramSize: %d", size) - } -} - -func (b *BrutalSender) updateAckRate(currentTimestamp int64) { - minTimestamp := currentTimestamp - pktInfoSlotCount - var ackCount, lossCount uint64 - for _, info := range b.pktInfoSlots { - if info.Timestamp < minTimestamp { - continue - } - ackCount += info.AckCount - lossCount += info.LossCount - } - if ackCount+lossCount < minSampleCount { - b.ackRate = 1 - if b.canPrintAckRate(currentTimestamp) { - b.lastAckPrintTimestamp = currentTimestamp - b.debugPrint("Not enough samples (total=%d, ack=%d, loss=%d, rtt=%d)", - ackCount+lossCount, ackCount, lossCount, b.rttStats.SmoothedRTT().Milliseconds()) - } - return - } - rate := float64(ackCount) / float64(ackCount+lossCount) - if rate < minAckRate { - b.ackRate = minAckRate - if b.canPrintAckRate(currentTimestamp) { - b.lastAckPrintTimestamp = currentTimestamp - b.debugPrint("ACK rate too low: %.2f, clamped to %.2f (total=%d, ack=%d, loss=%d, rtt=%d)", - rate, minAckRate, ackCount+lossCount, ackCount, lossCount, b.rttStats.SmoothedRTT().Milliseconds()) - } - return - } - b.ackRate = rate - if b.canPrintAckRate(currentTimestamp) { - b.lastAckPrintTimestamp = currentTimestamp - b.debugPrint("ACK rate: %.2f (total=%d, ack=%d, loss=%d, rtt=%d)", - rate, ackCount+lossCount, ackCount, lossCount, b.rttStats.SmoothedRTT().Milliseconds()) - } -} - -func (b *BrutalSender) InSlowStart() bool { - return false -} - -func (b *BrutalSender) InRecovery() bool { - return false -} - -func (b *BrutalSender) MaybeExitSlowStart() {} - -func (b *BrutalSender) OnRetransmissionTimeout(packetsRetransmitted bool) {} - -func (b *BrutalSender) canPrintAckRate(currentTimestamp int64) bool { - return b.debug && currentTimestamp-b.lastAckPrintTimestamp >= debugPrintInterval -} - -func (b *BrutalSender) debugPrint(format string, a ...any) { - fmt.Printf("[BrutalSender] [%s] %s\n", - time.Now().Format("15:04:05"), - fmt.Sprintf(format, a...)) -} diff --git a/transport/internet/hysteria2/congestion/common/pacer.go b/transport/internet/hysteria2/congestion/common/pacer.go deleted file mode 100644 index 4e089a3147..0000000000 --- a/transport/internet/hysteria2/congestion/common/pacer.go +++ /dev/null @@ -1,95 +0,0 @@ -package common - -import ( - "math" - "time" - - "github.com/apernet/quic-go/congestion" -) - -const ( - maxBurstPackets = 10 -) - -// Pacer implements a token bucket pacing algorithm. -type Pacer struct { - budgetAtLastSent congestion.ByteCount - maxDatagramSize congestion.ByteCount - lastSentTime time.Time - getBandwidth func() congestion.ByteCount // in bytes/s -} - -func NewPacer(getBandwidth func() congestion.ByteCount) *Pacer { - p := &Pacer{ - budgetAtLastSent: maxBurstPackets * congestion.InitialPacketSizeIPv4, - maxDatagramSize: congestion.InitialPacketSizeIPv4, - getBandwidth: getBandwidth, - } - return p -} - -func (p *Pacer) SentPacket(sendTime time.Time, size congestion.ByteCount) { - budget := p.Budget(sendTime) - if size > budget { - p.budgetAtLastSent = 0 - } else { - p.budgetAtLastSent = budget - size - } - p.lastSentTime = sendTime -} - -func (p *Pacer) Budget(now time.Time) congestion.ByteCount { - if p.lastSentTime.IsZero() { - return p.maxBurstSize() - } - budget := p.budgetAtLastSent + (p.getBandwidth()*congestion.ByteCount(now.Sub(p.lastSentTime).Nanoseconds()))/1e9 - if budget < 0 { // protect against overflows - budget = congestion.ByteCount(1<<62 - 1) - } - return minByteCount(p.maxBurstSize(), budget) -} - -func (p *Pacer) maxBurstSize() congestion.ByteCount { - return maxByteCount( - congestion.ByteCount((congestion.MinPacingDelay+time.Millisecond).Nanoseconds())*p.getBandwidth()/1e9, - maxBurstPackets*p.maxDatagramSize, - ) -} - -// TimeUntilSend returns when the next packet should be sent. -// It returns the zero value of time.Time if a packet can be sent immediately. -func (p *Pacer) TimeUntilSend() time.Time { - if p.budgetAtLastSent >= p.maxDatagramSize { - return time.Time{} - } - return p.lastSentTime.Add(maxDuration( - congestion.MinPacingDelay, - time.Duration(math.Ceil(float64(p.maxDatagramSize-p.budgetAtLastSent)*1e9/ - float64(p.getBandwidth())))*time.Nanosecond, - )) -} - -func (p *Pacer) SetMaxDatagramSize(s congestion.ByteCount) { - p.maxDatagramSize = s -} - -func maxByteCount(a, b congestion.ByteCount) congestion.ByteCount { - if a < b { - return b - } - return a -} - -func minByteCount(a, b congestion.ByteCount) congestion.ByteCount { - if a < b { - return a - } - return b -} - -func maxDuration(a, b time.Duration) time.Duration { - if a > b { - return a - } - return b -} diff --git a/transport/internet/hysteria2/congestion/utils.go b/transport/internet/hysteria2/congestion/utils.go deleted file mode 100644 index 3ff68f6fc1..0000000000 --- a/transport/internet/hysteria2/congestion/utils.go +++ /dev/null @@ -1,19 +0,0 @@ -package congestion - -import ( - "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/bbr" - "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/brutal" - - "github.com/apernet/quic-go" -) - -func UseBBR(conn quic.Connection) { - conn.SetCongestionControl(bbr.NewBbrSender( - bbr.DefaultClock{}, - bbr.GetInitialPacketSize(conn.RemoteAddr()), - )) -} - -func UseBrutal(conn quic.Connection, tx uint64) { - conn.SetCongestionControl(brutal.NewBrutalSender(tx)) -} diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index 241e08cecd..0187c405bb 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -1,158 +1,14 @@ package hysteria2 import ( - "crypto/cipher" - "crypto/rand" - "errors" - "syscall" "time" "github.com/apernet/quic-go" - "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" - "github.com/v2fly/v2ray-core/v5/transport/internet" ) -type sysConn struct { - conn *net.UDPConn - header internet.PacketHeader - auth cipher.AEAD -} - -func wrapSysConn(rawConn *net.UDPConn, config *Config) (*sysConn, error) { - header, err := getHeader(config) - if err != nil { - return nil, err - } - auth, err := getAuth(config) - if err != nil { - return nil, err - } - return &sysConn{ - conn: rawConn, - header: header, - auth: auth, - }, nil -} - -var errInvalidPacket = errors.New("invalid packet") - -func (c *sysConn) readFromInternal(p []byte) (int, net.Addr, error) { - buffer := getBuffer() - defer putBuffer(buffer) - - nBytes, addr, err := c.conn.ReadFrom(buffer) - if err != nil { - return 0, nil, err - } - - payload := buffer[:nBytes] - if c.header != nil { - if len(payload) <= int(c.header.Size()) { - return 0, nil, errInvalidPacket - } - payload = payload[c.header.Size():] - } - - if c.auth == nil { - n := copy(p, payload) - return n, addr, nil - } - - if len(payload) <= c.auth.NonceSize() { - return 0, nil, errInvalidPacket - } - - nonce := payload[:c.auth.NonceSize()] - payload = payload[c.auth.NonceSize():] - - p, err = c.auth.Open(p[:0], nonce, payload, nil) - if err != nil { - return 0, nil, errInvalidPacket - } - - return len(p), addr, nil -} - -func (c *sysConn) ReadFrom(p []byte) (int, net.Addr, error) { - if c.header == nil && c.auth == nil { - return c.conn.ReadFrom(p) - } - - for { - n, addr, err := c.readFromInternal(p) - if err != nil && err != errInvalidPacket { - return 0, nil, err - } - if err == nil { - return n, addr, nil - } - } -} - -func (c *sysConn) WriteTo(p []byte, addr net.Addr) (int, error) { - if c.header == nil && c.auth == nil { - return c.conn.WriteTo(p, addr) - } - - buffer := getBuffer() - defer putBuffer(buffer) - - payload := buffer - n := 0 - if c.header != nil { - c.header.Serialize(payload) - n = int(c.header.Size()) - } - - if c.auth == nil { - nBytes := copy(payload[n:], p) - n += nBytes - } else { - nounce := payload[n : n+c.auth.NonceSize()] - common.Must2(rand.Read(nounce)) - n += c.auth.NonceSize() - pp := c.auth.Seal(payload[:n], nounce, p, nil) - n = len(pp) - } - - return c.conn.WriteTo(payload[:n], addr) -} - -func (c *sysConn) Close() error { - return c.conn.Close() -} - -func (c *sysConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *sysConn) SetReadBuffer(bytes int) error { - return c.conn.SetReadBuffer(bytes) -} - -func (c *sysConn) SetWriteBuffer(bytes int) error { - return c.conn.SetWriteBuffer(bytes) -} - -func (c *sysConn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -func (c *sysConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *sysConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} - -func (c *sysConn) SyscallConn() (syscall.RawConn, error) { - return c.conn.SyscallConn() -} - type interConn struct { stream quic.Stream local net.Addr diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index ec1dd42dfb..6b7951f5ea 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -11,9 +11,7 @@ import ( "github.com/v2fly/v2ray-core/v5/transport/internet/tls" ) -var RunningClient map[net.Destination]hy.Client - -var errConnectionClosed = newError("connection closed") +var RunningClient map[net.Destination](hy.Client) func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hy.TLSConfig, error) { tlsConfig := tls.ConfigFromStreamSettings(streamSettings) @@ -23,24 +21,63 @@ func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hy.TLSConfig, AllowInsecure: true, } } - res := &hy.TLSConfig{ServerName: tlsConfig.ServerName, InsecureSkipVerify: tlsConfig.AllowInsecure} + res := &hy.TLSConfig{ + ServerName: tlsConfig.ServerName, + InsecureSkipVerify: tlsConfig.AllowInsecure, + } return res, nil } +func InitAddress(dest net.Destination) (net.Addr, error) { + var destAddr *net.UDPAddr + if dest.Address.Family().IsIP() { + destAddr = &net.UDPAddr{ + IP: dest.Address.IP(), + Port: int(dest.Port), + } + } else { + addr, err := net.ResolveUDPAddr("udp", dest.NetAddr()) + if err != nil { + return nil, err + } + destAddr = addr + } + return destAddr, nil +} + +func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hy.Client, error) { + tlsConfig, err := InitTLSConifg(streamSettings) + if err != nil { + return nil, err + } + + serverAddr, err := InitAddress(dest) + if err != nil { + return nil, err + } + + client, err := hy.NewClient(&hy.Config{ + TLSConfig: *tlsConfig, + Auth: streamSettings.ProtocolName, + ServerAddr: serverAddr, + }) + if err != nil { + return nil, err + } + + RunningClient[dest] = client + return client, nil +} + func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { var client hy.Client client, found := RunningClient[dest] if !found { var err error - tlsConfig, err := InitTLSConifg(streamSettings) - if err != nil { - return nil, err - } - client, err = hy.NewClient(&hy.Config{TLSConfig: *tlsConfig}) + client, err = NewHyClient(dest, streamSettings) if err != nil { return nil, err } - RunningClient[dest] = client } stream, err := client.OpenStream() @@ -49,12 +86,12 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me } quicConn := client.GetQuicConn() - conn := &interConn{ + internetConn := &interConn{ stream: stream, local: quicConn.LocalAddr(), remote: quicConn.RemoteAddr(), } - return conn, nil + return internetConn, nil } func init() { diff --git a/transport/internet/hysteria2/pool.go b/transport/internet/hysteria2/pool.go deleted file mode 100644 index c3c9e1508c..0000000000 --- a/transport/internet/hysteria2/pool.go +++ /dev/null @@ -1,21 +0,0 @@ -package hysteria2 - -import ( - "sync" - - "github.com/v2fly/v2ray-core/v5/common/bytespool" -) - -var pool *sync.Pool - -func init() { - pool = bytespool.GetPool(2048) -} - -func getBuffer() []byte { - return pool.Get().([]byte) -} - -func putBuffer(p []byte) { - pool.Put(p) // nolint: staticcheck -} From 3bac98aa2a5a106247dc7c51490dae1cf01aa387 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Mon, 13 Nov 2023 13:52:57 +0800 Subject: [PATCH 23/81] update server side --- transport/internet/hysteria2/conn.go | 144 +++++++++++++++++++++++++++ transport/internet/hysteria2/hub.go | 100 +++++-------------- 2 files changed, 168 insertions(+), 76 deletions(-) diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index 0187c405bb..241e08cecd 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -1,14 +1,158 @@ package hysteria2 import ( + "crypto/cipher" + "crypto/rand" + "errors" + "syscall" "time" "github.com/apernet/quic-go" + "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" + "github.com/v2fly/v2ray-core/v5/transport/internet" ) +type sysConn struct { + conn *net.UDPConn + header internet.PacketHeader + auth cipher.AEAD +} + +func wrapSysConn(rawConn *net.UDPConn, config *Config) (*sysConn, error) { + header, err := getHeader(config) + if err != nil { + return nil, err + } + auth, err := getAuth(config) + if err != nil { + return nil, err + } + return &sysConn{ + conn: rawConn, + header: header, + auth: auth, + }, nil +} + +var errInvalidPacket = errors.New("invalid packet") + +func (c *sysConn) readFromInternal(p []byte) (int, net.Addr, error) { + buffer := getBuffer() + defer putBuffer(buffer) + + nBytes, addr, err := c.conn.ReadFrom(buffer) + if err != nil { + return 0, nil, err + } + + payload := buffer[:nBytes] + if c.header != nil { + if len(payload) <= int(c.header.Size()) { + return 0, nil, errInvalidPacket + } + payload = payload[c.header.Size():] + } + + if c.auth == nil { + n := copy(p, payload) + return n, addr, nil + } + + if len(payload) <= c.auth.NonceSize() { + return 0, nil, errInvalidPacket + } + + nonce := payload[:c.auth.NonceSize()] + payload = payload[c.auth.NonceSize():] + + p, err = c.auth.Open(p[:0], nonce, payload, nil) + if err != nil { + return 0, nil, errInvalidPacket + } + + return len(p), addr, nil +} + +func (c *sysConn) ReadFrom(p []byte) (int, net.Addr, error) { + if c.header == nil && c.auth == nil { + return c.conn.ReadFrom(p) + } + + for { + n, addr, err := c.readFromInternal(p) + if err != nil && err != errInvalidPacket { + return 0, nil, err + } + if err == nil { + return n, addr, nil + } + } +} + +func (c *sysConn) WriteTo(p []byte, addr net.Addr) (int, error) { + if c.header == nil && c.auth == nil { + return c.conn.WriteTo(p, addr) + } + + buffer := getBuffer() + defer putBuffer(buffer) + + payload := buffer + n := 0 + if c.header != nil { + c.header.Serialize(payload) + n = int(c.header.Size()) + } + + if c.auth == nil { + nBytes := copy(payload[n:], p) + n += nBytes + } else { + nounce := payload[n : n+c.auth.NonceSize()] + common.Must2(rand.Read(nounce)) + n += c.auth.NonceSize() + pp := c.auth.Seal(payload[:n], nounce, p, nil) + n = len(pp) + } + + return c.conn.WriteTo(payload[:n], addr) +} + +func (c *sysConn) Close() error { + return c.conn.Close() +} + +func (c *sysConn) LocalAddr() net.Addr { + return c.conn.LocalAddr() +} + +func (c *sysConn) SetReadBuffer(bytes int) error { + return c.conn.SetReadBuffer(bytes) +} + +func (c *sysConn) SetWriteBuffer(bytes int) error { + return c.conn.SetWriteBuffer(bytes) +} + +func (c *sysConn) SetDeadline(t time.Time) error { + return c.conn.SetDeadline(t) +} + +func (c *sysConn) SetReadDeadline(t time.Time) error { + return c.conn.SetReadDeadline(t) +} + +func (c *sysConn) SetWriteDeadline(t time.Time) error { + return c.conn.SetWriteDeadline(t) +} + +func (c *sysConn) SyscallConn() (syscall.RawConn, error) { + return c.conn.SyscallConn() +} + type interConn struct { stream quic.Stream local net.Addr diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 4688336ff8..7f22c27368 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -2,8 +2,8 @@ package hysteria2 import ( "context" - "time" + hy "github.com/apernet/hysteria/core/server" "github.com/apernet/quic-go" "github.com/v2fly/v2ray-core/v5/common" @@ -23,50 +23,6 @@ type Listener struct { config *Config } -func (l *Listener) acceptStreams(conn quic.Connection) { - for { - stream, err := conn.AcceptStream(context.Background()) - if err != nil { - newError("failed to accept stream").Base(err).WriteToLog() - select { - case <-conn.Context().Done(): - return - case <-l.done.Wait(): - if err := conn.CloseWithError(0, ""); err != nil { - newError("failed to close connection").Base(err).WriteToLog() - } - return - default: - time.Sleep(time.Second) - continue - } - } - - conn := &interConn{ - stream: stream, - local: conn.LocalAddr(), - remote: conn.RemoteAddr(), - } - - l.addConn(conn) - } -} - -func (l *Listener) keepAccepting() { - for { - conn, err := l.listener.Accept(context.Background()) - if err != nil { - newError("failed to accept QUIC connections").Base(err).WriteToLog() - if l.done.Done() { - break - } - continue - } - SetCongestion(conn, l.config) - go l.acceptStreams(conn) - } -} - // Addr implements internet.Listener.Addr. func (l *Listener) Addr() net.Addr { return l.listener.Addr() @@ -74,25 +30,29 @@ func (l *Listener) Addr() net.Addr { // Close implements internet.Listener.Close. func (l *Listener) Close() error { - l.done.Close() - l.listener.Close() - l.rawConn.Close() return nil } +func GetTLSConfig(streamSettings *internet.MemoryStreamConfig) *hy.TLSConfig { + tlsSetting := tls.ConfigFromStreamSettings(streamSettings) + if tlsSetting == nil { + tlsSetting = &tls.Config{ + Certificate: []*tls.Certificate{ + tls.ParseCertificate( + cert.MustGenerate(nil, cert.DNSNames(internalDomain), cert.CommonName(internalDomain)), + ), + }, + } + } + return &hy.TLSConfig{Certificates: tlsSetting.GetTLSConfig().Certificates} +} + // Listen creates a new Listener based on configurations. func Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) { if address.Family().IsDomain() { return nil, newError("domain address is not allows for listening quic") } - tlsConfig := tls.ConfigFromStreamSettings(streamSettings) - if tlsConfig == nil { - tlsConfig = &tls.Config{ - Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil, cert.DNSNames(internalDomain), cert.CommonName(internalDomain)))}, - } - } - config := streamSettings.ProtocolSettings.(*Config) rawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{ IP: address.IP(), @@ -102,35 +62,23 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti return nil, err } - quicConfig := InitQuicConfig() - - conn, err := wrapSysConn(rawConn.(*net.UDPConn), config) - if err != nil { - conn.Close() - return nil, err - } - - tr := quic.Transport{ - Conn: conn, - ConnectionIDLength: 12, - } + hyServer, err := hy.NewServer(&hy.Config{ + Conn: rawConn, + TLSConfig: *GetTLSConfig(streamSettings), + }) - qListener, err := tr.Listen(tlsConfig.GetTLSConfig(), quicConfig) + err = hyServer.Serve() if err != nil { - conn.Close() + rawConn.Close() return nil, err } listener := &Listener{ - done: done.New(), - rawConn: conn, - listener: qListener, - addConn: handler, - config: config, + done: done.New(), + addConn: handler, + config: config, } - go listener.keepAccepting() - return listener, nil } From 983fc00d7c0309a5d4b5d7afb7b810fbf0ec80c6 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Tue, 14 Nov 2023 16:01:27 +0800 Subject: [PATCH 24/81] update hysteria2 transport --- config.pb.go | 2 +- go.mod | 4 +- go.sum | 4 +- transport/internet/hysteria2/config.go | 36 ---- transport/internet/hysteria2/conn.go | 189 +++++------------- transport/internet/hysteria2/dialer.go | 11 +- .../internet/hysteria2/errors.generated.go | 9 - transport/internet/hysteria2/hub.go | 84 +++++--- transport/internet/hysteria2/hy2_test.go | 95 +++++++++ transport/internet/quic/config.pb.go | 84 ++++---- transport/internet/quic/config.proto | 2 +- 11 files changed, 253 insertions(+), 267 deletions(-) delete mode 100644 transport/internet/hysteria2/config.go delete mode 100644 transport/internet/hysteria2/errors.generated.go create mode 100644 transport/internet/hysteria2/hy2_test.go diff --git a/config.pb.go b/config.pb.go index dd80bf4d55..1a1cfefcb3 100644 --- a/config.pb.go +++ b/config.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.31.0 -// protoc v4.24.4 +// protoc v4.24.3 // source: config.proto package core diff --git a/go.mod b/go.mod index 38e3669bb3..dfa0246167 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 golang.org/x/net v0.17.0 golang.org/x/sync v0.4.0 - golang.org/x/sys v0.13.0 + golang.org/x/sys v0.14.0 google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 @@ -40,7 +40,7 @@ require ( h12.io/socks v1.0.3 ) -replace github.com/apernet/hysteria/core => ../../hysteria/core +replace github.com/apernet/hysteria/core => ../hysteria/core require ( github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 // indirect diff --git a/go.sum b/go.sum index f3aa5eb0f3..058364c05a 100644 --- a/go.sum +++ b/go.sum @@ -472,8 +472,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/transport/internet/hysteria2/config.go b/transport/internet/hysteria2/config.go deleted file mode 100644 index 9b55b5ec19..0000000000 --- a/transport/internet/hysteria2/config.go +++ /dev/null @@ -1,36 +0,0 @@ -package hysteria2 - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/sha256" - - "golang.org/x/crypto/chacha20poly1305" - - "github.com/v2fly/v2ray-core/v5/common" - "github.com/v2fly/v2ray-core/v5/common/protocol" - "github.com/v2fly/v2ray-core/v5/common/serial" - "github.com/v2fly/v2ray-core/v5/transport/internet" -) - -func getAuth(config *Config) (cipher.AEAD, error) { - security := config.Security.GetSecurityType() - if security == protocol.SecurityType_NONE { - return nil, nil - } - - salted := []byte(config.Key + "v2ray-quic-salt") - key := sha256.Sum256(salted) - - if security == protocol.SecurityType_AES128_GCM { - block, err := aes.NewCipher(key[:16]) - common.Must(err) - return cipher.NewGCM(block) - } - - if security == protocol.SecurityType_CHACHA20_POLY1305 { - return chacha20poly1305.New(key[:]) - } - - return nil, newError("unsupported security type") -} diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index 241e08cecd..d6add8417c 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -1,162 +1,65 @@ package hysteria2 import ( - "crypto/cipher" - "crypto/rand" - "errors" - "syscall" + "fmt" "time" "github.com/apernet/quic-go" + "github.com/apernet/quic-go/quicvarint" - "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" - "github.com/v2fly/v2ray-core/v5/transport/internet" ) -type sysConn struct { - conn *net.UDPConn - header internet.PacketHeader - auth cipher.AEAD -} +type interConn struct { + stream quic.Stream + local net.Addr + remote net.Addr -func wrapSysConn(rawConn *net.UDPConn, config *Config) (*sysConn, error) { - header, err := getHeader(config) - if err != nil { - return nil, err - } - auth, err := getAuth(config) - if err != nil { - return nil, err - } - return &sysConn{ - conn: rawConn, - header: header, - auth: auth, - }, nil + isClient bool + isWriteFrameType bool } -var errInvalidPacket = errors.New("invalid packet") - -func (c *sysConn) readFromInternal(p []byte) (int, net.Addr, error) { - buffer := getBuffer() - defer putBuffer(buffer) - - nBytes, addr, err := c.conn.ReadFrom(buffer) - if err != nil { - return 0, nil, err - } - - payload := buffer[:nBytes] - if c.header != nil { - if len(payload) <= int(c.header.Size()) { - return 0, nil, errInvalidPacket - } - payload = payload[c.header.Size():] - } - - if c.auth == nil { - n := copy(p, payload) - return n, addr, nil - } - - if len(payload) <= c.auth.NonceSize() { - return 0, nil, errInvalidPacket - } - - nonce := payload[:c.auth.NonceSize()] - payload = payload[c.auth.NonceSize():] +const ( + FrameTypeTCPRequest = 0x401 - p, err = c.auth.Open(p[:0], nonce, payload, nil) - if err != nil { - return 0, nil, errInvalidPacket - } - - return len(p), addr, nil -} - -func (c *sysConn) ReadFrom(p []byte) (int, net.Addr, error) { - if c.header == nil && c.auth == nil { - return c.conn.ReadFrom(p) - } + maxVarInt1 = 63 + maxVarInt2 = 16383 + maxVarInt4 = 1073741823 + maxVarInt8 = 4611686018427387903 +) - for { - n, addr, err := c.readFromInternal(p) - if err != nil && err != errInvalidPacket { - return 0, nil, err - } - if err == nil { - return n, addr, nil - } +// varintPut is like quicvarint.Append, but instead of appending to a slice, +// it writes to a fixed-size buffer. Returns the number of bytes written. +func varintPut(b []byte, i uint64) int { + if i <= maxVarInt1 { + b[0] = uint8(i) + return 1 } -} - -func (c *sysConn) WriteTo(p []byte, addr net.Addr) (int, error) { - if c.header == nil && c.auth == nil { - return c.conn.WriteTo(p, addr) + if i <= maxVarInt2 { + b[0] = uint8(i>>8) | 0x40 + b[1] = uint8(i) + return 2 } - - buffer := getBuffer() - defer putBuffer(buffer) - - payload := buffer - n := 0 - if c.header != nil { - c.header.Serialize(payload) - n = int(c.header.Size()) + if i <= maxVarInt4 { + b[0] = uint8(i>>24) | 0x80 + b[1] = uint8(i >> 16) + b[2] = uint8(i >> 8) + b[3] = uint8(i) + return 4 } - - if c.auth == nil { - nBytes := copy(payload[n:], p) - n += nBytes - } else { - nounce := payload[n : n+c.auth.NonceSize()] - common.Must2(rand.Read(nounce)) - n += c.auth.NonceSize() - pp := c.auth.Seal(payload[:n], nounce, p, nil) - n = len(pp) + if i <= maxVarInt8 { + b[0] = uint8(i>>56) | 0xc0 + b[1] = uint8(i >> 48) + b[2] = uint8(i >> 40) + b[3] = uint8(i >> 32) + b[4] = uint8(i >> 24) + b[5] = uint8(i >> 16) + b[6] = uint8(i >> 8) + b[7] = uint8(i) + return 8 } - - return c.conn.WriteTo(payload[:n], addr) -} - -func (c *sysConn) Close() error { - return c.conn.Close() -} - -func (c *sysConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *sysConn) SetReadBuffer(bytes int) error { - return c.conn.SetReadBuffer(bytes) -} - -func (c *sysConn) SetWriteBuffer(bytes int) error { - return c.conn.SetWriteBuffer(bytes) -} - -func (c *sysConn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -func (c *sysConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *sysConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} - -func (c *sysConn) SyscallConn() (syscall.RawConn, error) { - return c.conn.SyscallConn() -} - -type interConn struct { - stream quic.Stream - local net.Addr - remote net.Addr + panic(fmt.Sprintf("%#x doesn't fit into 62 bits", i)) } func (c *interConn) Read(b []byte) (int, error) { @@ -171,6 +74,14 @@ func (c *interConn) WriteMultiBuffer(mb buf.MultiBuffer) error { } func (c *interConn) Write(b []byte) (int, error) { + if c.isClient && !c.isWriteFrameType { + c.isWriteFrameType = true + frameSize := int(quicvarint.Len(FrameTypeTCPRequest)) + buf := make([]byte, frameSize+len(b)) + i := varintPut(buf, FrameTypeTCPRequest) + copy(buf[i:], b) + return c.stream.Write(buf) + } return c.stream.Write(b) } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 6b7951f5ea..4607e376cb 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -56,9 +56,10 @@ func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConf return nil, err } + config := streamSettings.ProtocolSettings.(*Config) client, err := hy.NewClient(&hy.Config{ TLSConfig: *tlsConfig, - Auth: streamSettings.ProtocolName, + Auth: config.GetPassword(), ServerAddr: serverAddr, }) if err != nil { @@ -87,13 +88,15 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me quicConn := client.GetQuicConn() internetConn := &interConn{ - stream: stream, - local: quicConn.LocalAddr(), - remote: quicConn.RemoteAddr(), + stream: stream, + local: quicConn.LocalAddr(), + remote: quicConn.RemoteAddr(), + isClient: true, } return internetConn, nil } func init() { + RunningClient = make(map[net.Destination]hy.Client) common.Must(internet.RegisterTransportDialer(protocolName, Dial)) } diff --git a/transport/internet/hysteria2/errors.generated.go b/transport/internet/hysteria2/errors.generated.go deleted file mode 100644 index 1053170313..0000000000 --- a/transport/internet/hysteria2/errors.generated.go +++ /dev/null @@ -1,9 +0,0 @@ -package hysteria2 - -import "github.com/v2fly/v2ray-core/v5/common/errors" - -type errPathObjHolder struct{} - -func newError(values ...interface{}) *errors.Error { - return errors.New(values...).WithPathObj(errPathObjHolder{}) -} diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 7f22c27368..6f255e4090 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -5,52 +5,51 @@ import ( hy "github.com/apernet/hysteria/core/server" "github.com/apernet/quic-go" + "github.com/apernet/quic-go/http3" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert" - "github.com/v2fly/v2ray-core/v5/common/signal/done" "github.com/v2fly/v2ray-core/v5/transport/internet" "github.com/v2fly/v2ray-core/v5/transport/internet/tls" ) // Listener is an internet.Listener that listens for TCP connections. type Listener struct { - rawConn *sysConn - listener *quic.Listener - done *done.Instance + hyServer hy.Server + rawConn net.PacketConn addConn internet.ConnHandler - config *Config } // Addr implements internet.Listener.Addr. func (l *Listener) Addr() net.Addr { - return l.listener.Addr() + return l.rawConn.LocalAddr() } // Close implements internet.Listener.Close. func (l *Listener) Close() error { - return nil + return l.hyServer.Close() } -func GetTLSConfig(streamSettings *internet.MemoryStreamConfig) *hy.TLSConfig { - tlsSetting := tls.ConfigFromStreamSettings(streamSettings) - if tlsSetting == nil { - tlsSetting = &tls.Config{ - Certificate: []*tls.Certificate{ - tls.ParseCertificate( - cert.MustGenerate(nil, cert.DNSNames(internalDomain), cert.CommonName(internalDomain)), - ), - }, - } +func (l *Listener) ProxyStreamHijacker(ft http3.FrameType, conn quic.Connection, stream quic.Stream, err error) (bool, error) { + if err != nil { + l.Close() + return false, err } - return &hy.TLSConfig{Certificates: tlsSetting.GetTLSConfig().Certificates} + + internetConn := &interConn{ + stream: stream, + local: conn.LocalAddr(), + remote: conn.RemoteAddr(), + } + l.addConn(internetConn) + return true, nil } // Listen creates a new Listener based on configurations. func Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) { if address.Family().IsDomain() { - return nil, newError("domain address is not allows for listening quic") + return nil, nil } config := streamSettings.ProtocolSettings.(*Config) @@ -62,24 +61,47 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti return nil, err } + listener := &Listener{ + rawConn: rawConn, + addConn: handler, + } + hyServer, err := hy.NewServer(&hy.Config{ - Conn: rawConn, - TLSConfig: *GetTLSConfig(streamSettings), + Conn: rawConn, + TLSConfig: *GetTLSConfig(streamSettings), + IgnoreClientBandwidth: false, + Authenticator: &Authenticator{Password: config.GetPassword()}, + StreamHijacker: listener.ProxyStreamHijacker, // acceptStreams }) - err = hyServer.Serve() - if err != nil { - rawConn.Close() - return nil, err - } + listener.hyServer = hyServer + go hyServer.Serve() + return listener, nil +} - listener := &Listener{ - done: done.New(), - addConn: handler, - config: config, +func GetTLSConfig(streamSettings *internet.MemoryStreamConfig) *hy.TLSConfig { + tlsSetting := tls.ConfigFromStreamSettings(streamSettings) + if tlsSetting == nil { + tlsSetting = &tls.Config{ + Certificate: []*tls.Certificate{ + tls.ParseCertificate( + cert.MustGenerate(nil, cert.DNSNames(internalDomain), cert.CommonName(internalDomain)), + ), + }, + } } + return &hy.TLSConfig{Certificates: tlsSetting.GetTLSConfig().Certificates} +} - return listener, nil +type Authenticator struct { + Password string +} + +func (a *Authenticator) Authenticate(addr net.Addr, auth string, tx uint64) (ok bool, id string) { + if auth == a.Password || a.Password == "" { + return true, "user" + } + return false, "" } func init() { diff --git a/transport/internet/hysteria2/hy2_test.go b/transport/internet/hysteria2/hy2_test.go new file mode 100644 index 0000000000..6c3ac862cf --- /dev/null +++ b/transport/internet/hysteria2/hy2_test.go @@ -0,0 +1,95 @@ +package hysteria2_test + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + + "github.com/v2fly/v2ray-core/v5/common" + "github.com/v2fly/v2ray-core/v5/common/buf" + "github.com/v2fly/v2ray-core/v5/common/net" + "github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert" + "github.com/v2fly/v2ray-core/v5/testing/servers/udp" + "github.com/v2fly/v2ray-core/v5/transport/internet" + "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" + "github.com/v2fly/v2ray-core/v5/transport/internet/tls" +) + +func TestHTTP3Connection(t *testing.T) { + port := udp.PickPort() + + listener, err := hysteria2.Listen(context.Background(), net.LocalHostIP, port, &internet.MemoryStreamConfig{ + ProtocolName: "hysteria2", + ProtocolSettings: &hysteria2.Config{Password: "123"}, + SecurityType: "tls", + SecuritySettings: &tls.Config{ + Certificate: []*tls.Certificate{ + tls.ParseCertificate( + cert.MustGenerate(nil, + cert.DNSNames("www.v2fly.org"), + ), + ), + }, + }, + }, func(conn internet.Connection) { + go func() { + defer conn.Close() + + b := buf.New() + defer b.Release() + + for { + b.Clear() + if _, err := b.ReadFrom(conn); err != nil { + fmt.Println(err) + return + } + fmt.Println(len(b.Bytes())) + common.Must2(conn.Write(b.Bytes())) + } + }() + }) + common.Must(err) + + defer listener.Close() + + time.Sleep(time.Second) + + dctx := context.Background() + conn, err := hysteria2.Dial(dctx, net.TCPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{ + ProtocolName: "hysteria2", + ProtocolSettings: &hysteria2.Config{Password: "123"}, + SecurityType: "tls", + SecuritySettings: &tls.Config{ + ServerName: "www.v2fly.org", + AllowInsecure: true, + }, + }) + common.Must(err) + defer conn.Close() + + const N = 20 + b1 := make([]byte, N) + b2 := buf.New() + b1[0] = 0x19 + + common.Must2(conn.Write(b1)) + + b2.Clear() + common.Must2(b2.ReadFullFrom(conn, N)) + fmt.Println(b2.Bytes()) + if r := cmp.Diff(b2.Bytes(), b1); r != "" { + t.Error(r) + } + + common.Must2(conn.Write(b1)) + + b2.Clear() + common.Must2(b2.ReadFullFrom(conn, N)) + if r := cmp.Diff(b2.Bytes(), b1); r != "" { + t.Error(r) + } +} diff --git a/transport/internet/quic/config.pb.go b/transport/internet/quic/config.pb.go index e4d3a62672..d814ddcbbe 100644 --- a/transport/internet/quic/config.pb.go +++ b/transport/internet/quic/config.pb.go @@ -148,44 +148,44 @@ var File_transport_internet_quic_config_proto protoreflect.FileDescriptor var file_transport_internet_quic_config_proto_rawDesc = []byte{ 0x0a, 0x24, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x71, 0x75, 0x69, 0x63, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x22, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x27, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3d, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, - 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x6e, - 0x64, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xf7, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, - 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, - 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x67, - 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, - 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, - 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, - 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x09, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x04, 0x71, 0x75, 0x69, 0x63, 0x42, - 0x87, 0x01, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x50, 0x01, 0x5a, 0x36, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, - 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, - 0x71, 0x75, 0x69, 0x63, 0xaa, 0x02, 0x22, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, - 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x51, 0x75, 0x69, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x1a, + 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3d, 0x0a, 0x0a, 0x43, + 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, + 0x09, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xfc, 0x01, 0x0a, 0x06, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, + 0x2c, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x53, 0x0a, + 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x33, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x2e, 0x43, 0x6f, 0x6e, 0x67, + 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x6f, 0x72, 0x74, 0x12, 0x04, 0x71, 0x75, 0x69, 0x63, 0x42, 0x87, 0x01, 0x0a, 0x26, 0x63, 0x6f, + 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, + 0x71, 0x75, 0x69, 0x63, 0x50, 0x01, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, + 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, + 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x71, 0x75, 0x69, 0x63, 0xaa, 0x02, + 0x22, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x51, + 0x75, 0x69, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -202,15 +202,15 @@ func file_transport_internet_quic_config_proto_rawDescGZIP() []byte { var file_transport_internet_quic_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_transport_internet_quic_config_proto_goTypes = []interface{}{ - (*Congestion)(nil), // 0: v2ray.core.transport.internet.quic.Congestion - (*Config)(nil), // 1: v2ray.core.transport.internet.quic.Config + (*Congestion)(nil), // 0: v2ray.core.transport.internet.hysteria2.Congestion + (*Config)(nil), // 1: v2ray.core.transport.internet.hysteria2.Config (*protocol.SecurityConfig)(nil), // 2: v2ray.core.common.protocol.SecurityConfig (*anypb.Any)(nil), // 3: google.protobuf.Any } var file_transport_internet_quic_config_proto_depIdxs = []int32{ - 2, // 0: v2ray.core.transport.internet.quic.Config.security:type_name -> v2ray.core.common.protocol.SecurityConfig - 3, // 1: v2ray.core.transport.internet.quic.Config.header:type_name -> google.protobuf.Any - 0, // 2: v2ray.core.transport.internet.quic.Config.congestion:type_name -> v2ray.core.transport.internet.quic.Congestion + 2, // 0: v2ray.core.transport.internet.hysteria2.Config.security:type_name -> v2ray.core.common.protocol.SecurityConfig + 3, // 1: v2ray.core.transport.internet.hysteria2.Config.header:type_name -> google.protobuf.Any + 0, // 2: v2ray.core.transport.internet.hysteria2.Config.congestion:type_name -> v2ray.core.transport.internet.hysteria2.Congestion 3, // [3:3] is the sub-list for method output_type 3, // [3:3] is the sub-list for method input_type 3, // [3:3] is the sub-list for extension type_name diff --git a/transport/internet/quic/config.proto b/transport/internet/quic/config.proto index effda6fc04..591535e220 100644 --- a/transport/internet/quic/config.proto +++ b/transport/internet/quic/config.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package v2ray.core.transport.internet.quic; +package v2ray.core.transport.internet.hysteria2; option csharp_namespace = "V2Ray.Core.Transport.Internet.Quic"; option go_package = "github.com/v2fly/v2ray-core/v5/transport/internet/quic"; option java_package = "com.v2ray.core.transport.internet.quic"; From 29359a88c14ca83b27188c63fca0735cc39847f0 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Sun, 26 Nov 2023 16:16:46 +0800 Subject: [PATCH 25/81] rebase to original quic-go --- app/dns/nameserver_quic.go | 2 +- common/protocol/quic/sniff.go | 2 +- .../internet/quic/congestion/bbr/bandwidth.go | 27 - .../quic/congestion/bbr/bandwidth_sampler.go | 875 ---------------- .../quic/congestion/bbr/bbr_sender.go | 942 ------------------ .../internet/quic/congestion/bbr/clock.go | 18 - .../bbr/packet_number_indexed_queue.go | 198 ---- .../quic/congestion/bbr/ringbuffer.go | 118 --- .../quic/congestion/bbr/windowed_filter.go | 162 --- .../internet/quic/congestion/brutal/brutal.go | 181 ---- .../internet/quic/congestion/common/pacer.go | 95 -- transport/internet/quic/congestion/utils.go | 19 - transport/internet/quic/conn.go | 2 +- transport/internet/quic/dialer.go | 75 +- transport/internet/quic/hub.go | 14 +- 15 files changed, 38 insertions(+), 2692 deletions(-) delete mode 100644 transport/internet/quic/congestion/bbr/bandwidth.go delete mode 100644 transport/internet/quic/congestion/bbr/bandwidth_sampler.go delete mode 100644 transport/internet/quic/congestion/bbr/bbr_sender.go delete mode 100644 transport/internet/quic/congestion/bbr/clock.go delete mode 100644 transport/internet/quic/congestion/bbr/packet_number_indexed_queue.go delete mode 100644 transport/internet/quic/congestion/bbr/ringbuffer.go delete mode 100644 transport/internet/quic/congestion/bbr/windowed_filter.go delete mode 100644 transport/internet/quic/congestion/brutal/brutal.go delete mode 100644 transport/internet/quic/congestion/common/pacer.go delete mode 100644 transport/internet/quic/congestion/utils.go diff --git a/app/dns/nameserver_quic.go b/app/dns/nameserver_quic.go index ed30afabb7..28e6922575 100644 --- a/app/dns/nameserver_quic.go +++ b/app/dns/nameserver_quic.go @@ -9,7 +9,7 @@ import ( "sync/atomic" "time" - "github.com/apernet/quic-go" + "github.com/quic-go/quic-go" "golang.org/x/net/dns/dnsmessage" "github.com/v2fly/v2ray-core/v5/common" diff --git a/common/protocol/quic/sniff.go b/common/protocol/quic/sniff.go index 1957f5199f..f8fcd0ba10 100644 --- a/common/protocol/quic/sniff.go +++ b/common/protocol/quic/sniff.go @@ -7,7 +7,7 @@ import ( "encoding/binary" "io" - "github.com/apernet/quic-go/quicvarint" + "github.com/quic-go/quic-go/quicvarint" "golang.org/x/crypto/hkdf" "github.com/v2fly/v2ray-core/v5/common" diff --git a/transport/internet/quic/congestion/bbr/bandwidth.go b/transport/internet/quic/congestion/bbr/bandwidth.go deleted file mode 100644 index 52deb24965..0000000000 --- a/transport/internet/quic/congestion/bbr/bandwidth.go +++ /dev/null @@ -1,27 +0,0 @@ -package bbr - -import ( - "math" - "time" - - "github.com/apernet/quic-go/congestion" -) - -const ( - infBandwidth = Bandwidth(math.MaxUint64) -) - -// Bandwidth of a connection -type Bandwidth uint64 - -const ( - // BitsPerSecond is 1 bit per second - BitsPerSecond Bandwidth = 1 - // BytesPerSecond is 1 byte per second - BytesPerSecond = 8 * BitsPerSecond -) - -// BandwidthFromDelta calculates the bandwidth from a number of bytes and a time delta -func BandwidthFromDelta(bytes congestion.ByteCount, delta time.Duration) Bandwidth { - return Bandwidth(bytes) * Bandwidth(time.Second) / Bandwidth(delta) * BytesPerSecond -} diff --git a/transport/internet/quic/congestion/bbr/bandwidth_sampler.go b/transport/internet/quic/congestion/bbr/bandwidth_sampler.go deleted file mode 100644 index 266af81f5b..0000000000 --- a/transport/internet/quic/congestion/bbr/bandwidth_sampler.go +++ /dev/null @@ -1,875 +0,0 @@ -//nolint:golint,unused -package bbr - -import ( - "math" - "time" - - "github.com/apernet/quic-go/congestion" -) - -const ( - infRTT = time.Duration(math.MaxInt64) - defaultConnectionStateMapQueueSize = 256 - defaultCandidatesBufferSize = 256 -) - -type roundTripCount uint64 - -// SendTimeState is a subset of ConnectionStateOnSentPacket which is returned -// to the caller when the packet is acked or lost. -type sendTimeState struct { - // Whether other states in this object is valid. - isValid bool - // Whether the sender is app limited at the time the packet was sent. - // App limited bandwidth sample might be artificially low because the sender - // did not have enough data to send in order to saturate the link. - isAppLimited bool - // Total number of sent bytes at the time the packet was sent. - // Includes the packet itself. - totalBytesSent congestion.ByteCount - // Total number of acked bytes at the time the packet was sent. - totalBytesAcked congestion.ByteCount - // Total number of lost bytes at the time the packet was sent. - totalBytesLost congestion.ByteCount - // Total number of inflight bytes at the time the packet was sent. - // Includes the packet itself. - // It should be equal to |total_bytes_sent| minus the sum of - // |total_bytes_acked|, |total_bytes_lost| and total neutered bytes. - bytesInFlight congestion.ByteCount -} - -func newSendTimeState( - isAppLimited bool, - totalBytesSent congestion.ByteCount, - totalBytesAcked congestion.ByteCount, - totalBytesLost congestion.ByteCount, - bytesInFlight congestion.ByteCount, -) *sendTimeState { - return &sendTimeState{ - isValid: true, - isAppLimited: isAppLimited, - totalBytesSent: totalBytesSent, - totalBytesAcked: totalBytesAcked, - totalBytesLost: totalBytesLost, - bytesInFlight: bytesInFlight, - } -} - -type extraAckedEvent struct { - // The excess bytes acknowlwedged in the time delta for this event. - extraAcked congestion.ByteCount - - // The bytes acknowledged and time delta from the event. - bytesAcked congestion.ByteCount - timeDelta time.Duration - // The round trip of the event. - round roundTripCount -} - -func maxExtraAckedEventFunc(a, b extraAckedEvent) int { - if a.extraAcked > b.extraAcked { - return 1 - } else if a.extraAcked < b.extraAcked { - return -1 - } - return 0 -} - -// BandwidthSample -type bandwidthSample struct { - // The bandwidth at that particular sample. Zero if no valid bandwidth sample - // is available. - bandwidth Bandwidth - // The RTT measurement at this particular sample. Zero if no RTT sample is - // available. Does not correct for delayed ack time. - rtt time.Duration - // |send_rate| is computed from the current packet being acked('P') and an - // earlier packet that is acked before P was sent. - sendRate Bandwidth - // States captured when the packet was sent. - stateAtSend sendTimeState -} - -func newBandwidthSample() *bandwidthSample { - return &bandwidthSample{ - sendRate: infBandwidth, - } -} - -// MaxAckHeightTracker is part of the BandwidthSampler. It is called after every -// ack event to keep track the degree of ack aggregation(a.k.a "ack height"). -type maxAckHeightTracker struct { - // Tracks the maximum number of bytes acked faster than the estimated - // bandwidth. - maxAckHeightFilter *WindowedFilter[extraAckedEvent, roundTripCount] - // The time this aggregation started and the number of bytes acked during it. - aggregationEpochStartTime time.Time - aggregationEpochBytes congestion.ByteCount - // The last sent packet number before the current aggregation epoch started. - lastSentPacketNumberBeforeEpoch congestion.PacketNumber - // The number of ack aggregation epochs ever started, including the ongoing - // one. Stats only. - numAckAggregationEpochs uint64 - ackAggregationBandwidthThreshold float64 - startNewAggregationEpochAfterFullRound bool - reduceExtraAckedOnBandwidthIncrease bool -} - -func newMaxAckHeightTracker(windowLength roundTripCount) *maxAckHeightTracker { - return &maxAckHeightTracker{ - maxAckHeightFilter: NewWindowedFilter(windowLength, maxExtraAckedEventFunc), - lastSentPacketNumberBeforeEpoch: invalidPacketNumber, - ackAggregationBandwidthThreshold: 1.0, - } -} - -func (m *maxAckHeightTracker) Get() congestion.ByteCount { - return m.maxAckHeightFilter.GetBest().extraAcked -} - -func (m *maxAckHeightTracker) Update( - bandwidthEstimate Bandwidth, - isNewMaxBandwidth bool, - roundTripCount roundTripCount, - lastSentPacketNumber congestion.PacketNumber, - lastAckedPacketNumber congestion.PacketNumber, - ackTime time.Time, - bytesAcked congestion.ByteCount, -) congestion.ByteCount { - forceNewEpoch := false - - if m.reduceExtraAckedOnBandwidthIncrease && isNewMaxBandwidth { - // Save and clear existing entries. - best := m.maxAckHeightFilter.GetBest() - secondBest := m.maxAckHeightFilter.GetSecondBest() - thirdBest := m.maxAckHeightFilter.GetThirdBest() - m.maxAckHeightFilter.Clear() - - // Reinsert the heights into the filter after recalculating. - expectedBytesAcked := bytesFromBandwidthAndTimeDelta(bandwidthEstimate, best.timeDelta) - if expectedBytesAcked < best.bytesAcked { - best.extraAcked = best.bytesAcked - expectedBytesAcked - m.maxAckHeightFilter.Update(best, best.round) - } - expectedBytesAcked = bytesFromBandwidthAndTimeDelta(bandwidthEstimate, secondBest.timeDelta) - if expectedBytesAcked < secondBest.bytesAcked { - secondBest.extraAcked = secondBest.bytesAcked - expectedBytesAcked - m.maxAckHeightFilter.Update(secondBest, secondBest.round) - } - expectedBytesAcked = bytesFromBandwidthAndTimeDelta(bandwidthEstimate, thirdBest.timeDelta) - if expectedBytesAcked < thirdBest.bytesAcked { - thirdBest.extraAcked = thirdBest.bytesAcked - expectedBytesAcked - m.maxAckHeightFilter.Update(thirdBest, thirdBest.round) - } - } - - // If any packet sent after the start of the epoch has been acked, start a new - // epoch. - if m.startNewAggregationEpochAfterFullRound && - m.lastSentPacketNumberBeforeEpoch != invalidPacketNumber && - lastAckedPacketNumber != invalidPacketNumber && - lastAckedPacketNumber > m.lastSentPacketNumberBeforeEpoch { - forceNewEpoch = true - } - if m.aggregationEpochStartTime.IsZero() || forceNewEpoch { - m.aggregationEpochBytes = bytesAcked - m.aggregationEpochStartTime = ackTime - m.lastSentPacketNumberBeforeEpoch = lastSentPacketNumber - m.numAckAggregationEpochs++ - return 0 - } - - // Compute how many bytes are expected to be delivered, assuming max bandwidth - // is correct. - aggregationDelta := ackTime.Sub(m.aggregationEpochStartTime) - expectedBytesAcked := bytesFromBandwidthAndTimeDelta(bandwidthEstimate, aggregationDelta) - // Reset the current aggregation epoch as soon as the ack arrival rate is less - // than or equal to the max bandwidth. - if m.aggregationEpochBytes <= congestion.ByteCount(m.ackAggregationBandwidthThreshold*float64(expectedBytesAcked)) { - // Reset to start measuring a new aggregation epoch. - m.aggregationEpochBytes = bytesAcked - m.aggregationEpochStartTime = ackTime - m.lastSentPacketNumberBeforeEpoch = lastSentPacketNumber - m.numAckAggregationEpochs++ - return 0 - } - - m.aggregationEpochBytes += bytesAcked - - // Compute how many extra bytes were delivered vs max bandwidth. - extraBytesAcked := m.aggregationEpochBytes - expectedBytesAcked - newEvent := extraAckedEvent{ - extraAcked: expectedBytesAcked, - bytesAcked: m.aggregationEpochBytes, - timeDelta: aggregationDelta, - } - m.maxAckHeightFilter.Update(newEvent, roundTripCount) - return extraBytesAcked -} - -func (m *maxAckHeightTracker) SetFilterWindowLength(length roundTripCount) { - m.maxAckHeightFilter.SetWindowLength(length) -} - -func (m *maxAckHeightTracker) Reset(newHeight congestion.ByteCount, newTime roundTripCount) { - newEvent := extraAckedEvent{ - extraAcked: newHeight, - round: newTime, - } - m.maxAckHeightFilter.Reset(newEvent, newTime) -} - -func (m *maxAckHeightTracker) SetAckAggregationBandwidthThreshold(threshold float64) { - m.ackAggregationBandwidthThreshold = threshold -} - -func (m *maxAckHeightTracker) SetStartNewAggregationEpochAfterFullRound(value bool) { - m.startNewAggregationEpochAfterFullRound = value -} - -func (m *maxAckHeightTracker) SetReduceExtraAckedOnBandwidthIncrease(value bool) { - m.reduceExtraAckedOnBandwidthIncrease = value -} - -func (m *maxAckHeightTracker) AckAggregationBandwidthThreshold() float64 { - return m.ackAggregationBandwidthThreshold -} - -func (m *maxAckHeightTracker) NumAckAggregationEpochs() uint64 { - return m.numAckAggregationEpochs -} - -// AckPoint represents a point on the ack line. -type ackPoint struct { - ackTime time.Time - totalBytesAcked congestion.ByteCount -} - -// RecentAckPoints maintains the most recent 2 ack points at distinct times. -type recentAckPoints struct { - ackPoints [2]ackPoint -} - -func (r *recentAckPoints) Update(ackTime time.Time, totalBytesAcked congestion.ByteCount) { - if ackTime.Before(r.ackPoints[1].ackTime) { - r.ackPoints[1].ackTime = ackTime - } else if ackTime.After(r.ackPoints[1].ackTime) { - r.ackPoints[0] = r.ackPoints[1] - r.ackPoints[1].ackTime = ackTime - } - - r.ackPoints[1].totalBytesAcked = totalBytesAcked -} - -func (r *recentAckPoints) Clear() { - r.ackPoints[0] = ackPoint{} - r.ackPoints[1] = ackPoint{} -} - -func (r *recentAckPoints) MostRecentPoint() *ackPoint { - return &r.ackPoints[1] -} - -func (r *recentAckPoints) LessRecentPoint() *ackPoint { - if r.ackPoints[0].totalBytesAcked != 0 { - return &r.ackPoints[0] - } - - return &r.ackPoints[1] -} - -// ConnectionStateOnSentPacket represents the information about a sent packet -// and the state of the connection at the moment the packet was sent, -// specifically the information about the most recently acknowledged packet at -// that moment. -type connectionStateOnSentPacket struct { - // Time at which the packet is sent. - sentTime time.Time - // Size of the packet. - size congestion.ByteCount - // The value of |totalBytesSentAtLastAckedPacket| at the time the - // packet was sent. - totalBytesSentAtLastAckedPacket congestion.ByteCount - // The value of |lastAckedPacketSentTime| at the time the packet was - // sent. - lastAckedPacketSentTime time.Time - // The value of |lastAckedPacketAckTime| at the time the packet was - // sent. - lastAckedPacketAckTime time.Time - // Send time states that are returned to the congestion controller when the - // packet is acked or lost. - sendTimeState sendTimeState -} - -// Snapshot constructor. Records the current state of the bandwidth -// sampler. -// |bytes_in_flight| is the bytes in flight right after the packet is sent. -func newConnectionStateOnSentPacket( - sentTime time.Time, - size congestion.ByteCount, - bytesInFlight congestion.ByteCount, - sampler *bandwidthSampler, -) *connectionStateOnSentPacket { - return &connectionStateOnSentPacket{ - sentTime: sentTime, - size: size, - totalBytesSentAtLastAckedPacket: sampler.totalBytesSentAtLastAckedPacket, - lastAckedPacketSentTime: sampler.lastAckedPacketSentTime, - lastAckedPacketAckTime: sampler.lastAckedPacketAckTime, - sendTimeState: *newSendTimeState( - sampler.isAppLimited, - sampler.totalBytesSent, - sampler.totalBytesAcked, - sampler.totalBytesLost, - bytesInFlight, - ), - } -} - -// BandwidthSampler keeps track of sent and acknowledged packets and outputs a -// bandwidth sample for every packet acknowledged. The samples are taken for -// individual packets, and are not filtered; the consumer has to filter the -// bandwidth samples itself. In certain cases, the sampler will locally severely -// underestimate the bandwidth, hence a maximum filter with a size of at least -// one RTT is recommended. -// -// This class bases its samples on the slope of two curves: the number of bytes -// sent over time, and the number of bytes acknowledged as received over time. -// It produces a sample of both slopes for every packet that gets acknowledged, -// based on a slope between two points on each of the corresponding curves. Note -// that due to the packet loss, the number of bytes on each curve might get -// further and further away from each other, meaning that it is not feasible to -// compare byte values coming from different curves with each other. -// -// The obvious points for measuring slope sample are the ones corresponding to -// the packet that was just acknowledged. Let us denote them as S_1 (point at -// which the current packet was sent) and A_1 (point at which the current packet -// was acknowledged). However, taking a slope requires two points on each line, -// so estimating bandwidth requires picking a packet in the past with respect to -// which the slope is measured. -// -// For that purpose, BandwidthSampler always keeps track of the most recently -// acknowledged packet, and records it together with every outgoing packet. -// When a packet gets acknowledged (A_1), it has not only information about when -// it itself was sent (S_1), but also the information about the latest -// acknowledged packet right before it was sent (S_0 and A_0). -// -// Based on that data, send and ack rate are estimated as: -// -// send_rate = (bytes(S_1) - bytes(S_0)) / (time(S_1) - time(S_0)) -// ack_rate = (bytes(A_1) - bytes(A_0)) / (time(A_1) - time(A_0)) -// -// Here, the ack rate is intuitively the rate we want to treat as bandwidth. -// However, in certain cases (e.g. ack compression) the ack rate at a point may -// end up higher than the rate at which the data was originally sent, which is -// not indicative of the real bandwidth. Hence, we use the send rate as an upper -// bound, and the sample value is -// -// rate_sample = min(send_rate, ack_rate) -// -// An important edge case handled by the sampler is tracking the app-limited -// samples. There are multiple meaning of "app-limited" used interchangeably, -// hence it is important to understand and to be able to distinguish between -// them. -// -// Meaning 1: connection state. The connection is said to be app-limited when -// there is no outstanding data to send. This means that certain bandwidth -// samples in the future would not be an accurate indication of the link -// capacity, and it is important to inform consumer about that. Whenever -// connection becomes app-limited, the sampler is notified via OnAppLimited() -// method. -// -// Meaning 2: a phase in the bandwidth sampler. As soon as the bandwidth -// sampler becomes notified about the connection being app-limited, it enters -// app-limited phase. In that phase, all *sent* packets are marked as -// app-limited. Note that the connection itself does not have to be -// app-limited during the app-limited phase, and in fact it will not be -// (otherwise how would it send packets?). The boolean flag below indicates -// whether the sampler is in that phase. -// -// Meaning 3: a flag on the sent packet and on the sample. If a sent packet is -// sent during the app-limited phase, the resulting sample related to the -// packet will be marked as app-limited. -// -// With the terminology issue out of the way, let us consider the question of -// what kind of situation it addresses. -// -// Consider a scenario where we first send packets 1 to 20 at a regular -// bandwidth, and then immediately run out of data. After a few seconds, we send -// packets 21 to 60, and only receive ack for 21 between sending packets 40 and -// 41. In this case, when we sample bandwidth for packets 21 to 40, the S_0/A_0 -// we use to compute the slope is going to be packet 20, a few seconds apart -// from the current packet, hence the resulting estimate would be extremely low -// and not indicative of anything. Only at packet 41 the S_0/A_0 will become 21, -// meaning that the bandwidth sample would exclude the quiescence. -// -// Based on the analysis of that scenario, we implement the following rule: once -// OnAppLimited() is called, all sent packets will produce app-limited samples -// up until an ack for a packet that was sent after OnAppLimited() was called. -// Note that while the scenario above is not the only scenario when the -// connection is app-limited, the approach works in other cases too. - -type congestionEventSample struct { - // The maximum bandwidth sample from all acked packets. - // QuicBandwidth::Zero() if no samples are available. - sampleMaxBandwidth Bandwidth - // Whether |sample_max_bandwidth| is from a app-limited sample. - sampleIsAppLimited bool - // The minimum rtt sample from all acked packets. - // QuicTime::Delta::Infinite() if no samples are available. - sampleRtt time.Duration - // For each packet p in acked packets, this is the max value of INFLIGHT(p), - // where INFLIGHT(p) is the number of bytes acked while p is inflight. - sampleMaxInflight congestion.ByteCount - // The send state of the largest packet in acked_packets, unless it is - // empty. If acked_packets is empty, it's the send state of the largest - // packet in lost_packets. - lastPacketSendState sendTimeState - // The number of extra bytes acked from this ack event, compared to what is - // expected from the flow's bandwidth. Larger value means more ack - // aggregation. - extraAcked congestion.ByteCount -} - -func newCongestionEventSample() *congestionEventSample { - return &congestionEventSample{ - sampleRtt: infRTT, - } -} - -type bandwidthSampler struct { - // The total number of congestion controlled bytes sent during the connection. - totalBytesSent congestion.ByteCount - - // The total number of congestion controlled bytes which were acknowledged. - totalBytesAcked congestion.ByteCount - - // The total number of congestion controlled bytes which were lost. - totalBytesLost congestion.ByteCount - - // The total number of congestion controlled bytes which have been neutered. - totalBytesNeutered congestion.ByteCount - - // The value of |total_bytes_sent_| at the time the last acknowledged packet - // was sent. Valid only when |last_acked_packet_sent_time_| is valid. - totalBytesSentAtLastAckedPacket congestion.ByteCount - - // The time at which the last acknowledged packet was sent. Set to - // QuicTime::Zero() if no valid timestamp is available. - lastAckedPacketSentTime time.Time - - // The time at which the most recent packet was acknowledged. - lastAckedPacketAckTime time.Time - - // The most recently sent packet. - lastSentPacket congestion.PacketNumber - - // The most recently acked packet. - lastAckedPacket congestion.PacketNumber - - // Indicates whether the bandwidth sampler is currently in an app-limited - // phase. - isAppLimited bool - - // The packet that will be acknowledged after this one will cause the sampler - // to exit the app-limited phase. - endOfAppLimitedPhase congestion.PacketNumber - - // Record of the connection state at the point where each packet in flight was - // sent, indexed by the packet number. - connectionStateMap *packetNumberIndexedQueue[connectionStateOnSentPacket] - - recentAckPoints recentAckPoints - a0Candidates RingBuffer[ackPoint] - - // Maximum number of tracked packets. - maxTrackedPackets congestion.ByteCount - - maxAckHeightTracker *maxAckHeightTracker - totalBytesAckedAfterLastAckEvent congestion.ByteCount - - // True if connection option 'BSAO' is set. - overestimateAvoidance bool - - // True if connection option 'BBRB' is set. - limitMaxAckHeightTrackerBySendRate bool -} - -func newBandwidthSampler(maxAckHeightTrackerWindowLength roundTripCount) *bandwidthSampler { - b := &bandwidthSampler{ - maxAckHeightTracker: newMaxAckHeightTracker(maxAckHeightTrackerWindowLength), - connectionStateMap: newPacketNumberIndexedQueue[connectionStateOnSentPacket](defaultConnectionStateMapQueueSize), - lastSentPacket: invalidPacketNumber, - lastAckedPacket: invalidPacketNumber, - endOfAppLimitedPhase: invalidPacketNumber, - } - - b.a0Candidates.Init(defaultCandidatesBufferSize) - - return b -} - -func (b *bandwidthSampler) MaxAckHeight() congestion.ByteCount { - return b.maxAckHeightTracker.Get() -} - -func (b *bandwidthSampler) NumAckAggregationEpochs() uint64 { - return b.maxAckHeightTracker.NumAckAggregationEpochs() -} - -func (b *bandwidthSampler) SetMaxAckHeightTrackerWindowLength(length roundTripCount) { - b.maxAckHeightTracker.SetFilterWindowLength(length) -} - -func (b *bandwidthSampler) ResetMaxAckHeightTracker(newHeight congestion.ByteCount, newTime roundTripCount) { - b.maxAckHeightTracker.Reset(newHeight, newTime) -} - -func (b *bandwidthSampler) SetStartNewAggregationEpochAfterFullRound(value bool) { - b.maxAckHeightTracker.SetStartNewAggregationEpochAfterFullRound(value) -} - -func (b *bandwidthSampler) SetLimitMaxAckHeightTrackerBySendRate(value bool) { - b.limitMaxAckHeightTrackerBySendRate = value -} - -func (b *bandwidthSampler) SetReduceExtraAckedOnBandwidthIncrease(value bool) { - b.maxAckHeightTracker.SetReduceExtraAckedOnBandwidthIncrease(value) -} - -func (b *bandwidthSampler) EnableOverestimateAvoidance() { - if b.overestimateAvoidance { - return - } - - b.overestimateAvoidance = true - b.maxAckHeightTracker.SetAckAggregationBandwidthThreshold(2.0) -} - -func (b *bandwidthSampler) IsOverestimateAvoidanceEnabled() bool { - return b.overestimateAvoidance -} - -func (b *bandwidthSampler) OnPacketSent( - sentTime time.Time, - packetNumber congestion.PacketNumber, - bytes congestion.ByteCount, - bytesInFlight congestion.ByteCount, - isRetransmittable bool, -) { - b.lastSentPacket = packetNumber - - if !isRetransmittable { - return - } - - b.totalBytesSent += bytes - - // If there are no packets in flight, the time at which the new transmission - // opens can be treated as the A_0 point for the purpose of bandwidth - // sampling. This underestimates bandwidth to some extent, and produces some - // artificially low samples for most packets in flight, but it provides with - // samples at important points where we would not have them otherwise, most - // importantly at the beginning of the connection. - if bytesInFlight == 0 { - b.lastAckedPacketAckTime = sentTime - if b.overestimateAvoidance { - b.recentAckPoints.Clear() - b.recentAckPoints.Update(sentTime, b.totalBytesAcked) - b.a0Candidates.Clear() - b.a0Candidates.PushBack(*b.recentAckPoints.MostRecentPoint()) - } - b.totalBytesSentAtLastAckedPacket = b.totalBytesSent - - // In this situation ack compression is not a concern, set send rate to - // effectively infinite. - b.lastAckedPacketSentTime = sentTime - } - - b.connectionStateMap.Emplace(packetNumber, newConnectionStateOnSentPacket( - sentTime, - bytes, - bytesInFlight+bytes, - b, - )) -} - -func (b *bandwidthSampler) OnCongestionEvent( - ackTime time.Time, - ackedPackets []congestion.AckedPacketInfo, - lostPackets []congestion.LostPacketInfo, - maxBandwidth Bandwidth, - estBandwidthUpperBound Bandwidth, - roundTripCount roundTripCount, -) congestionEventSample { - eventSample := newCongestionEventSample() - - var lastLostPacketSendState sendTimeState - - for _, p := range lostPackets { - sendState := b.OnPacketLost(p.PacketNumber, p.BytesLost) - if sendState.isValid { - lastLostPacketSendState = sendState - } - } - - if len(ackedPackets) == 0 { - // Only populate send state for a loss-only event. - eventSample.lastPacketSendState = lastLostPacketSendState - return *eventSample - } - - var lastAckedPacketSendState sendTimeState - var maxSendRate Bandwidth - - for _, p := range ackedPackets { - sample := b.onPacketAcknowledged(ackTime, p.PacketNumber) - if !sample.stateAtSend.isValid { - continue - } - - lastAckedPacketSendState = sample.stateAtSend - - if sample.rtt != 0 { - eventSample.sampleRtt = min(eventSample.sampleRtt, sample.rtt) - } - if sample.bandwidth > eventSample.sampleMaxBandwidth { - eventSample.sampleMaxBandwidth = sample.bandwidth - eventSample.sampleIsAppLimited = sample.stateAtSend.isAppLimited - } - if sample.sendRate != infBandwidth { - maxSendRate = max(maxSendRate, sample.sendRate) - } - inflightSample := b.totalBytesAcked - lastAckedPacketSendState.totalBytesAcked - if inflightSample > eventSample.sampleMaxInflight { - eventSample.sampleMaxInflight = inflightSample - } - } - - if !lastLostPacketSendState.isValid { - eventSample.lastPacketSendState = lastAckedPacketSendState - } else if !lastAckedPacketSendState.isValid { - eventSample.lastPacketSendState = lastLostPacketSendState - } else { - // If two packets are inflight and an alarm is armed to lose a packet and it - // wakes up late, then the first of two in flight packets could have been - // acknowledged before the wakeup, which re-evaluates loss detection, and - // could declare the later of the two lost. - if lostPackets[len(lostPackets)-1].PacketNumber > ackedPackets[len(ackedPackets)-1].PacketNumber { - eventSample.lastPacketSendState = lastLostPacketSendState - } else { - eventSample.lastPacketSendState = lastAckedPacketSendState - } - } - - isNewMaxBandwidth := eventSample.sampleMaxBandwidth > maxBandwidth - maxBandwidth = max(maxBandwidth, eventSample.sampleMaxBandwidth) - if b.limitMaxAckHeightTrackerBySendRate { - maxBandwidth = max(maxBandwidth, maxSendRate) - } - - eventSample.extraAcked = b.onAckEventEnd(min(estBandwidthUpperBound, maxBandwidth), isNewMaxBandwidth, roundTripCount) - - return *eventSample -} - -func (b *bandwidthSampler) OnPacketLost(packetNumber congestion.PacketNumber, bytesLost congestion.ByteCount) (s sendTimeState) { - b.totalBytesLost += bytesLost - if sentPacketPointer := b.connectionStateMap.GetEntry(packetNumber); sentPacketPointer != nil { - sentPacketToSendTimeState(sentPacketPointer, &s) - } - return s -} - -func (b *bandwidthSampler) OnPacketNeutered(packetNumber congestion.PacketNumber) { - b.connectionStateMap.Remove(packetNumber, func(sentPacket connectionStateOnSentPacket) { - b.totalBytesNeutered += sentPacket.size - }) -} - -func (b *bandwidthSampler) OnAppLimited() { - b.isAppLimited = true - b.endOfAppLimitedPhase = b.lastSentPacket -} - -func (b *bandwidthSampler) RemoveObsoletePackets(leastUnacked congestion.PacketNumber) { - // A packet can become obsolete when it is removed from QuicUnackedPacketMap's - // view of inflight before it is acked or marked as lost. For example, when - // QuicSentPacketManager::RetransmitCryptoPackets retransmits a crypto packet, - // the packet is removed from QuicUnackedPacketMap's inflight, but is not - // marked as acked or lost in the BandwidthSampler. - b.connectionStateMap.RemoveUpTo(leastUnacked) -} - -func (b *bandwidthSampler) TotalBytesSent() congestion.ByteCount { - return b.totalBytesSent -} - -func (b *bandwidthSampler) TotalBytesLost() congestion.ByteCount { - return b.totalBytesLost -} - -func (b *bandwidthSampler) TotalBytesAcked() congestion.ByteCount { - return b.totalBytesAcked -} - -func (b *bandwidthSampler) TotalBytesNeutered() congestion.ByteCount { - return b.totalBytesNeutered -} - -func (b *bandwidthSampler) IsAppLimited() bool { - return b.isAppLimited -} - -func (b *bandwidthSampler) EndOfAppLimitedPhase() congestion.PacketNumber { - return b.endOfAppLimitedPhase -} - -func (b *bandwidthSampler) max_ack_height() congestion.ByteCount { - return b.maxAckHeightTracker.Get() -} - -func (b *bandwidthSampler) chooseA0Point(totalBytesAcked congestion.ByteCount, a0 *ackPoint) bool { - if b.a0Candidates.Empty() { - return false - } - - if b.a0Candidates.Len() == 1 { - *a0 = *b.a0Candidates.Front() - return true - } - - for i := 1; i < b.a0Candidates.Len(); i++ { - if b.a0Candidates.Offset(i).totalBytesAcked > totalBytesAcked { - *a0 = *b.a0Candidates.Offset(i - 1) - if i > 1 { - for j := 0; j < i-1; j++ { - b.a0Candidates.PopFront() - } - } - return true - } - } - - *a0 = *b.a0Candidates.Back() - for k := 0; k < b.a0Candidates.Len()-1; k++ { - b.a0Candidates.PopFront() - } - return true -} - -func (b *bandwidthSampler) onPacketAcknowledged(ackTime time.Time, packetNumber congestion.PacketNumber) bandwidthSample { - sample := newBandwidthSample() - b.lastAckedPacket = packetNumber - sentPacketPointer := b.connectionStateMap.GetEntry(packetNumber) - if sentPacketPointer == nil { - return *sample - } - - // OnPacketAcknowledgedInner - b.totalBytesAcked += sentPacketPointer.size - b.totalBytesSentAtLastAckedPacket = sentPacketPointer.sendTimeState.totalBytesSent - b.lastAckedPacketSentTime = sentPacketPointer.sentTime - b.lastAckedPacketAckTime = ackTime - if b.overestimateAvoidance { - b.recentAckPoints.Update(ackTime, b.totalBytesAcked) - } - - if b.isAppLimited { - // Exit app-limited phase in two cases: - // (1) end_of_app_limited_phase_ is not initialized, i.e., so far all - // packets are sent while there are buffered packets or pending data. - // (2) The current acked packet is after the sent packet marked as the end - // of the app limit phase. - if b.endOfAppLimitedPhase == invalidPacketNumber || - packetNumber > b.endOfAppLimitedPhase { - b.isAppLimited = false - } - } - - // There might have been no packets acknowledged at the moment when the - // current packet was sent. In that case, there is no bandwidth sample to - // make. - if sentPacketPointer.lastAckedPacketSentTime.IsZero() { - return *sample - } - - // Infinite rate indicates that the sampler is supposed to discard the - // current send rate sample and use only the ack rate. - sendRate := infBandwidth - if sentPacketPointer.sentTime.After(sentPacketPointer.lastAckedPacketSentTime) { - sendRate = BandwidthFromDelta( - sentPacketPointer.sendTimeState.totalBytesSent-sentPacketPointer.totalBytesSentAtLastAckedPacket, - sentPacketPointer.sentTime.Sub(sentPacketPointer.lastAckedPacketSentTime)) - } - - var a0 ackPoint - if b.overestimateAvoidance && b.chooseA0Point(sentPacketPointer.sendTimeState.totalBytesAcked, &a0) { - } else { - a0.ackTime = sentPacketPointer.lastAckedPacketAckTime - a0.totalBytesAcked = sentPacketPointer.sendTimeState.totalBytesAcked - } - - // During the slope calculation, ensure that ack time of the current packet is - // always larger than the time of the previous packet, otherwise division by - // zero or integer underflow can occur. - if ackTime.Sub(a0.ackTime) <= 0 { - return *sample - } - - ackRate := BandwidthFromDelta(b.totalBytesAcked-a0.totalBytesAcked, ackTime.Sub(a0.ackTime)) - - sample.bandwidth = min(sendRate, ackRate) - // Note: this sample does not account for delayed acknowledgement time. This - // means that the RTT measurements here can be artificially high, especially - // on low bandwidth connections. - sample.rtt = ackTime.Sub(sentPacketPointer.sentTime) - sample.sendRate = sendRate - sentPacketToSendTimeState(sentPacketPointer, &sample.stateAtSend) - - return *sample -} - -func (b *bandwidthSampler) onAckEventEnd( - bandwidthEstimate Bandwidth, - isNewMaxBandwidth bool, - roundTripCount roundTripCount, -) congestion.ByteCount { - newlyAckedBytes := b.totalBytesAcked - b.totalBytesAckedAfterLastAckEvent - if newlyAckedBytes == 0 { - return 0 - } - b.totalBytesAckedAfterLastAckEvent = b.totalBytesAcked - extraAcked := b.maxAckHeightTracker.Update( - bandwidthEstimate, - isNewMaxBandwidth, - roundTripCount, - b.lastSentPacket, - b.lastAckedPacket, - b.lastAckedPacketAckTime, - newlyAckedBytes) - // If |extra_acked| is zero, i.e. this ack event marks the start of a new ack - // aggregation epoch, save LessRecentPoint, which is the last ack point of the - // previous epoch, as a A0 candidate. - if b.overestimateAvoidance && extraAcked == 0 { - b.a0Candidates.PushBack(*b.recentAckPoints.LessRecentPoint()) - } - return extraAcked -} - -func sentPacketToSendTimeState(sentPacket *connectionStateOnSentPacket, sendTimeState *sendTimeState) { - *sendTimeState = sentPacket.sendTimeState - sendTimeState.isValid = true -} - -// BytesFromBandwidthAndTimeDelta calculates the bytes -// from a bandwidth(bits per second) and a time delta -func bytesFromBandwidthAndTimeDelta(bandwidth Bandwidth, delta time.Duration) congestion.ByteCount { - return (congestion.ByteCount(bandwidth) * congestion.ByteCount(delta)) / - (congestion.ByteCount(time.Second) * 8) -} - -func timeDeltaFromBytesAndBandwidth(bytes congestion.ByteCount, bandwidth Bandwidth) time.Duration { - return time.Duration(bytes*8) * time.Second / time.Duration(bandwidth) -} diff --git a/transport/internet/quic/congestion/bbr/bbr_sender.go b/transport/internet/quic/congestion/bbr/bbr_sender.go deleted file mode 100644 index 26958a4f3d..0000000000 --- a/transport/internet/quic/congestion/bbr/bbr_sender.go +++ /dev/null @@ -1,942 +0,0 @@ -//nolint:golint,unused -package bbr - -import ( - "fmt" - "math/rand" - "net" - "time" - - "github.com/apernet/quic-go/congestion" - - "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/common" -) - -// BbrSender implements BBR congestion control algorithm. BBR aims to estimate -// the current available Bottleneck Bandwidth and RTT (hence the name), and -// regulates the pacing rate and the size of the congestion window based on -// those signals. -// -// BBR relies on pacing in order to function properly. Do not use BBR when -// pacing is disabled. -// - -const ( - minBps = 65536 // 64 kbps - - invalidPacketNumber = -1 - initialCongestionWindowPackets = 32 - - // Constants based on TCP defaults. - // The minimum CWND to ensure delayed acks don't reduce bandwidth measurements. - // Does not inflate the pacing rate. - defaultMinimumCongestionWindow = 4 * congestion.ByteCount(congestion.InitialPacketSizeIPv4) - - // The gain used for the STARTUP, equal to 2/ln(2). - defaultHighGain = 2.885 - // The newly derived gain for STARTUP, equal to 4 * ln(2) - derivedHighGain = 2.773 - // The newly derived CWND gain for STARTUP, 2. - derivedHighCWNDGain = 2.0 -) - -// The cycle of gains used during the PROBE_BW stage. -var pacingGain = [...]float64{1.25, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0} - -const ( - // The length of the gain cycle. - gainCycleLength = len(pacingGain) - // The size of the bandwidth filter window, in round-trips. - bandwidthWindowSize = gainCycleLength + 2 - - // The time after which the current min_rtt value expires. - minRttExpiry = 10 * time.Second - // The minimum time the connection can spend in PROBE_RTT mode. - probeRttTime = 200 * time.Millisecond - // If the bandwidth does not increase by the factor of |kStartupGrowthTarget| - // within |kRoundTripsWithoutGrowthBeforeExitingStartup| rounds, the connection - // will exit the STARTUP mode. - startupGrowthTarget = 1.25 - roundTripsWithoutGrowthBeforeExitingStartup = int64(3) - - // Flag. - defaultStartupFullLossCount = 8 - quicBbr2DefaultLossThreshold = 0.02 - maxBbrBurstPackets = 3 -) - -type bbrMode int - -const ( - // Startup phase of the connection. - bbrModeStartup = iota - // After achieving the highest possible bandwidth during the startup, lower - // the pacing rate in order to drain the queue. - bbrModeDrain - // Cruising mode. - bbrModeProbeBw - // Temporarily slow down sending in order to empty the buffer and measure - // the real minimum RTT. - bbrModeProbeRtt -) - -// Indicates how the congestion control limits the amount of bytes in flight. -type bbrRecoveryState int - -const ( - // Do not limit. - bbrRecoveryStateNotInRecovery = iota - // Allow an extra outstanding byte for each byte acknowledged. - bbrRecoveryStateConservation - // Allow two extra outstanding bytes for each byte acknowledged (slow - // start). - bbrRecoveryStateGrowth -) - -type bbrSender struct { - rttStats congestion.RTTStatsProvider - clock Clock - pacer *common.Pacer - - mode bbrMode - - // Bandwidth sampler provides BBR with the bandwidth measurements at - // individual points. - sampler *bandwidthSampler - - // The number of the round trips that have occurred during the connection. - roundTripCount roundTripCount - - // The packet number of the most recently sent packet. - lastSentPacket congestion.PacketNumber - // Acknowledgement of any packet after |current_round_trip_end_| will cause - // the round trip counter to advance. - currentRoundTripEnd congestion.PacketNumber - - // Number of congestion events with some losses, in the current round. - numLossEventsInRound uint64 - - // Number of total bytes lost in the current round. - bytesLostInRound congestion.ByteCount - - // The filter that tracks the maximum bandwidth over the multiple recent - // round-trips. - maxBandwidth *WindowedFilter[Bandwidth, roundTripCount] - - // Minimum RTT estimate. Automatically expires within 10 seconds (and - // triggers PROBE_RTT mode) if no new value is sampled during that period. - minRtt time.Duration - // The time at which the current value of |min_rtt_| was assigned. - minRttTimestamp time.Time - - // The maximum allowed number of bytes in flight. - congestionWindow congestion.ByteCount - - // The initial value of the |congestion_window_|. - initialCongestionWindow congestion.ByteCount - - // The largest value the |congestion_window_| can achieve. - maxCongestionWindow congestion.ByteCount - - // The smallest value the |congestion_window_| can achieve. - minCongestionWindow congestion.ByteCount - - // The pacing gain applied during the STARTUP phase. - highGain float64 - - // The CWND gain applied during the STARTUP phase. - highCwndGain float64 - - // The pacing gain applied during the DRAIN phase. - drainGain float64 - - // The current pacing rate of the connection. - pacingRate Bandwidth - - // The gain currently applied to the pacing rate. - pacingGain float64 - // The gain currently applied to the congestion window. - congestionWindowGain float64 - - // The gain used for the congestion window during PROBE_BW. Latched from - // quic_bbr_cwnd_gain flag. - congestionWindowGainConstant float64 - // The number of RTTs to stay in STARTUP mode. Defaults to 3. - numStartupRtts int64 - - // Number of round-trips in PROBE_BW mode, used for determining the current - // pacing gain cycle. - cycleCurrentOffset int - // The time at which the last pacing gain cycle was started. - lastCycleStart time.Time - - // Indicates whether the connection has reached the full bandwidth mode. - isAtFullBandwidth bool - // Number of rounds during which there was no significant bandwidth increase. - roundsWithoutBandwidthGain int64 - // The bandwidth compared to which the increase is measured. - bandwidthAtLastRound Bandwidth - - // Set to true upon exiting quiescence. - exitingQuiescence bool - - // Time at which PROBE_RTT has to be exited. Setting it to zero indicates - // that the time is yet unknown as the number of packets in flight has not - // reached the required value. - exitProbeRttAt time.Time - // Indicates whether a round-trip has passed since PROBE_RTT became active. - probeRttRoundPassed bool - - // Indicates whether the most recent bandwidth sample was marked as - // app-limited. - lastSampleIsAppLimited bool - // Indicates whether any non app-limited samples have been recorded. - hasNoAppLimitedSample bool - - // Current state of recovery. - recoveryState bbrRecoveryState - // Receiving acknowledgement of a packet after |end_recovery_at_| will cause - // BBR to exit the recovery mode. A value above zero indicates at least one - // loss has been detected, so it must not be set back to zero. - endRecoveryAt congestion.PacketNumber - // A window used to limit the number of bytes in flight during loss recovery. - recoveryWindow congestion.ByteCount - // If true, consider all samples in recovery app-limited. - isAppLimitedRecovery bool // not used - - // When true, pace at 1.5x and disable packet conservation in STARTUP. - slowerStartup bool // not used - // When true, disables packet conservation in STARTUP. - rateBasedStartup bool // not used - - // When true, add the most recent ack aggregation measurement during STARTUP. - enableAckAggregationDuringStartup bool - // When true, expire the windowed ack aggregation values in STARTUP when - // bandwidth increases more than 25%. - expireAckAggregationInStartup bool - - // If true, will not exit low gain mode until bytes_in_flight drops below BDP - // or it's time for high gain mode. - drainToTarget bool - - // If true, slow down pacing rate in STARTUP when overshooting is detected. - detectOvershooting bool - // Bytes lost while detect_overshooting_ is true. - bytesLostWhileDetectingOvershooting congestion.ByteCount - // Slow down pacing rate if - // bytes_lost_while_detecting_overshooting_ * - // bytes_lost_multiplier_while_detecting_overshooting_ > IW. - bytesLostMultiplierWhileDetectingOvershooting uint8 - // When overshooting is detected, do not drop pacing_rate_ below this value / - // min_rtt. - cwndToCalculateMinPacingRate congestion.ByteCount - - // Max congestion window when adjusting network parameters. - maxCongestionWindowWithNetworkParametersAdjusted congestion.ByteCount // not used - - // Params. - maxDatagramSize congestion.ByteCount - // Recorded on packet sent. equivalent |unacked_packets_->bytes_in_flight()| - bytesInFlight congestion.ByteCount -} - -var _ congestion.CongestionControl = &bbrSender{} - -func NewBbrSender( - clock Clock, - initialMaxDatagramSize congestion.ByteCount, -) *bbrSender { - return newBbrSender( - clock, - initialMaxDatagramSize, - initialCongestionWindowPackets*initialMaxDatagramSize, - congestion.MaxCongestionWindowPackets*initialMaxDatagramSize, - ) -} - -func newBbrSender( - clock Clock, - initialMaxDatagramSize, - initialCongestionWindow, - initialMaxCongestionWindow congestion.ByteCount, -) *bbrSender { - b := &bbrSender{ - clock: clock, - mode: bbrModeStartup, - sampler: newBandwidthSampler(roundTripCount(bandwidthWindowSize)), - lastSentPacket: invalidPacketNumber, - currentRoundTripEnd: invalidPacketNumber, - maxBandwidth: NewWindowedFilter(roundTripCount(bandwidthWindowSize), MaxFilter[Bandwidth]), - congestionWindow: initialCongestionWindow, - initialCongestionWindow: initialCongestionWindow, - maxCongestionWindow: initialMaxCongestionWindow, - minCongestionWindow: defaultMinimumCongestionWindow, - highGain: defaultHighGain, - highCwndGain: defaultHighGain, - drainGain: 1.0 / defaultHighGain, - pacingGain: 1.0, - congestionWindowGain: 1.0, - congestionWindowGainConstant: 2.0, - numStartupRtts: roundTripsWithoutGrowthBeforeExitingStartup, - recoveryState: bbrRecoveryStateNotInRecovery, - endRecoveryAt: invalidPacketNumber, - recoveryWindow: initialMaxCongestionWindow, - bytesLostMultiplierWhileDetectingOvershooting: 2, - cwndToCalculateMinPacingRate: initialCongestionWindow, - maxCongestionWindowWithNetworkParametersAdjusted: initialMaxCongestionWindow, - maxDatagramSize: initialMaxDatagramSize, - } - b.pacer = common.NewPacer(b.bandwidthForPacer) - - /* - if b.tracer != nil { - b.lastState = logging.CongestionStateStartup - b.tracer.UpdatedCongestionState(logging.CongestionStateStartup) - } - */ - - b.enterStartupMode(b.clock.Now()) - b.setHighCwndGain(derivedHighCWNDGain) - - return b -} - -func (b *bbrSender) SetRTTStatsProvider(provider congestion.RTTStatsProvider) { - b.rttStats = provider -} - -// TimeUntilSend implements the SendAlgorithm interface. -func (b *bbrSender) TimeUntilSend(bytesInFlight congestion.ByteCount) time.Time { - return b.pacer.TimeUntilSend() -} - -// HasPacingBudget implements the SendAlgorithm interface. -func (b *bbrSender) HasPacingBudget(now time.Time) bool { - return b.pacer.Budget(now) >= b.maxDatagramSize -} - -// OnPacketSent implements the SendAlgorithm interface. -func (b *bbrSender) OnPacketSent( - sentTime time.Time, - bytesInFlight congestion.ByteCount, - packetNumber congestion.PacketNumber, - bytes congestion.ByteCount, - isRetransmittable bool, -) { - b.pacer.SentPacket(sentTime, bytes) - - b.lastSentPacket = packetNumber - b.bytesInFlight = bytesInFlight - - if bytesInFlight == 0 { - b.exitingQuiescence = true - } - - b.sampler.OnPacketSent(sentTime, packetNumber, bytes, bytesInFlight, isRetransmittable) -} - -// CanSend implements the SendAlgorithm interface. -func (b *bbrSender) CanSend(bytesInFlight congestion.ByteCount) bool { - return bytesInFlight < b.GetCongestionWindow() -} - -// MaybeExitSlowStart implements the SendAlgorithm interface. -func (b *bbrSender) MaybeExitSlowStart() { - // Do nothing -} - -// OnPacketAcked implements the SendAlgorithm interface. -func (b *bbrSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes, priorInFlight congestion.ByteCount, eventTime time.Time) { - // Do nothing. -} - -// OnPacketLost implements the SendAlgorithm interface. -func (b *bbrSender) OnPacketLost(number congestion.PacketNumber, lostBytes, priorInFlight congestion.ByteCount) { - // Do nothing. -} - -// OnRetransmissionTimeout implements the SendAlgorithm interface. -func (b *bbrSender) OnRetransmissionTimeout(packetsRetransmitted bool) { - // Do nothing. -} - -// SetMaxDatagramSize implements the SendAlgorithm interface. -func (b *bbrSender) SetMaxDatagramSize(s congestion.ByteCount) { - if s < b.maxDatagramSize { - panic(fmt.Sprintf("congestion BUG: decreased max datagram size from %d to %d", b.maxDatagramSize, s)) - } - cwndIsMinCwnd := b.congestionWindow == b.minCongestionWindow - b.maxDatagramSize = s - if cwndIsMinCwnd { - b.congestionWindow = b.minCongestionWindow - } - b.pacer.SetMaxDatagramSize(s) -} - -// InSlowStart implements the SendAlgorithmWithDebugInfos interface. -func (b *bbrSender) InSlowStart() bool { - return b.mode == bbrModeStartup -} - -// InRecovery implements the SendAlgorithmWithDebugInfos interface. -func (b *bbrSender) InRecovery() bool { - return b.recoveryState != bbrRecoveryStateNotInRecovery -} - -// GetCongestionWindow implements the SendAlgorithmWithDebugInfos interface. -func (b *bbrSender) GetCongestionWindow() congestion.ByteCount { - if b.mode == bbrModeProbeRtt { - return b.probeRttCongestionWindow() - } - - if b.InRecovery() { - return min(b.congestionWindow, b.recoveryWindow) - } - - return b.congestionWindow -} - -func (b *bbrSender) OnCongestionEvent(number congestion.PacketNumber, lostBytes, priorInFlight congestion.ByteCount) { - // Do nothing. -} - -func (b *bbrSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, eventTime time.Time, ackedPackets []congestion.AckedPacketInfo, lostPackets []congestion.LostPacketInfo) { - totalBytesAckedBefore := b.sampler.TotalBytesAcked() - totalBytesLostBefore := b.sampler.TotalBytesLost() - - var isRoundStart, minRttExpired bool - var excessAcked, bytesLost congestion.ByteCount - - // The send state of the largest packet in acked_packets, unless it is - // empty. If acked_packets is empty, it's the send state of the largest - // packet in lost_packets. - var lastPacketSendState sendTimeState - - b.maybeApplimited(priorInFlight) - - // Update bytesInFlight - b.bytesInFlight = priorInFlight - for _, p := range ackedPackets { - b.bytesInFlight -= p.BytesAcked - } - for _, p := range lostPackets { - b.bytesInFlight -= p.BytesLost - } - - if len(ackedPackets) != 0 { - lastAckedPacket := ackedPackets[len(ackedPackets)-1].PacketNumber - isRoundStart = b.updateRoundTripCounter(lastAckedPacket) - b.updateRecoveryState(lastAckedPacket, len(lostPackets) != 0, isRoundStart) - } - - sample := b.sampler.OnCongestionEvent(eventTime, - ackedPackets, lostPackets, b.maxBandwidth.GetBest(), infBandwidth, b.roundTripCount) - if sample.lastPacketSendState.isValid { - b.lastSampleIsAppLimited = sample.lastPacketSendState.isAppLimited - b.hasNoAppLimitedSample = b.hasNoAppLimitedSample || !b.lastSampleIsAppLimited - } - // Avoid updating |max_bandwidth_| if a) this is a loss-only event, or b) all - // packets in |acked_packets| did not generate valid samples. (e.g. ack of - // ack-only packets). In both cases, sampler_.total_bytes_acked() will not - // change. - if totalBytesAckedBefore != b.sampler.TotalBytesAcked() { - if !sample.sampleIsAppLimited || sample.sampleMaxBandwidth > b.maxBandwidth.GetBest() { - b.maxBandwidth.Update(sample.sampleMaxBandwidth, b.roundTripCount) - } - } - - if sample.sampleRtt != infRTT { - minRttExpired = b.maybeUpdateMinRtt(eventTime, sample.sampleRtt) - } - bytesLost = b.sampler.TotalBytesLost() - totalBytesLostBefore - - excessAcked = sample.extraAcked - lastPacketSendState = sample.lastPacketSendState - - if len(lostPackets) != 0 { - b.numLossEventsInRound++ - b.bytesLostInRound += bytesLost - } - - // Handle logic specific to PROBE_BW mode. - if b.mode == bbrModeProbeBw { - b.updateGainCyclePhase(eventTime, priorInFlight, len(lostPackets) != 0) - } - - // Handle logic specific to STARTUP and DRAIN modes. - if isRoundStart && !b.isAtFullBandwidth { - b.checkIfFullBandwidthReached(&lastPacketSendState) - } - - b.maybeExitStartupOrDrain(eventTime) - - // Handle logic specific to PROBE_RTT. - b.maybeEnterOrExitProbeRtt(eventTime, isRoundStart, minRttExpired) - - // Calculate number of packets acked and lost. - bytesAcked := b.sampler.TotalBytesAcked() - totalBytesAckedBefore - - // After the model is updated, recalculate the pacing rate and congestion - // window. - b.calculatePacingRate(bytesLost) - b.calculateCongestionWindow(bytesAcked, excessAcked) - b.calculateRecoveryWindow(bytesAcked, bytesLost) - - // Cleanup internal state. - // This is where we clean up obsolete (acked or lost) packets from the bandwidth sampler. - // The "least unacked" should actually be FirstOutstanding, but since we are not passing - // that through OnCongestionEventEx, we will only do an estimate using acked/lost packets - // for now. Because of fast retransmission, they should differ by no more than 2 packets. - // (this is controlled by packetThreshold in quic-go's sentPacketHandler) - var leastUnacked congestion.PacketNumber - if len(ackedPackets) != 0 { - leastUnacked = ackedPackets[len(ackedPackets)-1].PacketNumber - 2 - } else { - leastUnacked = lostPackets[len(lostPackets)-1].PacketNumber + 1 - } - b.sampler.RemoveObsoletePackets(leastUnacked) - - if isRoundStart { - b.numLossEventsInRound = 0 - b.bytesLostInRound = 0 - } -} - -func (b *bbrSender) PacingRate() Bandwidth { - if b.pacingRate == 0 { - return Bandwidth(b.highGain * float64( - BandwidthFromDelta(b.initialCongestionWindow, b.getMinRtt()))) - } - - return b.pacingRate -} - -func (b *bbrSender) hasGoodBandwidthEstimateForResumption() bool { - return b.hasNonAppLimitedSample() -} - -func (b *bbrSender) hasNonAppLimitedSample() bool { - return b.hasNoAppLimitedSample -} - -// Sets the pacing gain used in STARTUP. Must be greater than 1. -func (b *bbrSender) setHighGain(highGain float64) { - b.highGain = highGain - if b.mode == bbrModeStartup { - b.pacingGain = highGain - } -} - -// Sets the CWND gain used in STARTUP. Must be greater than 1. -func (b *bbrSender) setHighCwndGain(highCwndGain float64) { - b.highCwndGain = highCwndGain - if b.mode == bbrModeStartup { - b.congestionWindowGain = highCwndGain - } -} - -// Sets the gain used in DRAIN. Must be less than 1. -func (b *bbrSender) setDrainGain(drainGain float64) { - b.drainGain = drainGain -} - -// What's the current estimated bandwidth in bytes per second. -func (b *bbrSender) bandwidthEstimate() Bandwidth { - return b.maxBandwidth.GetBest() -} - -func (b *bbrSender) bandwidthForPacer() congestion.ByteCount { - bps := congestion.ByteCount(float64(b.bandwidthEstimate()) * b.congestionWindowGain / float64(BytesPerSecond)) - if bps < minBps { - // We need to make sure that the bandwidth value for pacer is never zero, - // otherwise it will go into an edge case where HasPacingBudget = false - // but TimeUntilSend is before, causing the quic-go send loop to go crazy and get stuck. - return minBps - } - return bps -} - -// Returns the current estimate of the RTT of the connection. Outside of the -// edge cases, this is minimum RTT. -func (b *bbrSender) getMinRtt() time.Duration { - if b.minRtt != 0 { - return b.minRtt - } - // min_rtt could be available if the handshake packet gets neutered then - // gets acknowledged. This could only happen for QUIC crypto where we do not - // drop keys. - minRtt := b.rttStats.MinRTT() - if minRtt == 0 { - return 100 * time.Millisecond - } else { - return minRtt - } -} - -// Computes the target congestion window using the specified gain. -func (b *bbrSender) getTargetCongestionWindow(gain float64) congestion.ByteCount { - bdp := bdpFromRttAndBandwidth(b.getMinRtt(), b.bandwidthEstimate()) - congestionWindow := congestion.ByteCount(gain * float64(bdp)) - - // BDP estimate will be zero if no bandwidth samples are available yet. - if congestionWindow == 0 { - congestionWindow = congestion.ByteCount(gain * float64(b.initialCongestionWindow)) - } - - return max(congestionWindow, b.minCongestionWindow) -} - -// The target congestion window during PROBE_RTT. -func (b *bbrSender) probeRttCongestionWindow() congestion.ByteCount { - return b.minCongestionWindow -} - -func (b *bbrSender) maybeUpdateMinRtt(now time.Time, sampleMinRtt time.Duration) bool { - // Do not expire min_rtt if none was ever available. - minRttExpired := b.minRtt != 0 && now.After(b.minRttTimestamp.Add(minRttExpiry)) - if minRttExpired || sampleMinRtt < b.minRtt || b.minRtt == 0 { - b.minRtt = sampleMinRtt - b.minRttTimestamp = now - } - - return minRttExpired -} - -// Enters the STARTUP mode. -func (b *bbrSender) enterStartupMode(now time.Time) { - b.mode = bbrModeStartup - // b.maybeTraceStateChange(logging.CongestionStateStartup) - b.pacingGain = b.highGain - b.congestionWindowGain = b.highCwndGain -} - -// Enters the PROBE_BW mode. -func (b *bbrSender) enterProbeBandwidthMode(now time.Time) { - b.mode = bbrModeProbeBw - // b.maybeTraceStateChange(logging.CongestionStateProbeBw) - b.congestionWindowGain = b.congestionWindowGainConstant - - // Pick a random offset for the gain cycle out of {0, 2..7} range. 1 is - // excluded because in that case increased gain and decreased gain would not - // follow each other. - b.cycleCurrentOffset = int(rand.Int31n(congestion.PacketsPerConnectionID)) % (gainCycleLength - 1) - if b.cycleCurrentOffset >= 1 { - b.cycleCurrentOffset += 1 - } - - b.lastCycleStart = now - b.pacingGain = pacingGain[b.cycleCurrentOffset] -} - -// Updates the round-trip counter if a round-trip has passed. Returns true if -// the counter has been advanced. -func (b *bbrSender) updateRoundTripCounter(lastAckedPacket congestion.PacketNumber) bool { - if b.currentRoundTripEnd == invalidPacketNumber || lastAckedPacket > b.currentRoundTripEnd { - b.roundTripCount++ - b.currentRoundTripEnd = b.lastSentPacket - return true - } - return false -} - -// Updates the current gain used in PROBE_BW mode. -func (b *bbrSender) updateGainCyclePhase(now time.Time, priorInFlight congestion.ByteCount, hasLosses bool) { - // In most cases, the cycle is advanced after an RTT passes. - shouldAdvanceGainCycling := now.After(b.lastCycleStart.Add(b.getMinRtt())) - // If the pacing gain is above 1.0, the connection is trying to probe the - // bandwidth by increasing the number of bytes in flight to at least - // pacing_gain * BDP. Make sure that it actually reaches the target, as long - // as there are no losses suggesting that the buffers are not able to hold - // that much. - if b.pacingGain > 1.0 && !hasLosses && priorInFlight < b.getTargetCongestionWindow(b.pacingGain) { - shouldAdvanceGainCycling = false - } - - // If pacing gain is below 1.0, the connection is trying to drain the extra - // queue which could have been incurred by probing prior to it. If the number - // of bytes in flight falls down to the estimated BDP value earlier, conclude - // that the queue has been successfully drained and exit this cycle early. - if b.pacingGain < 1.0 && b.bytesInFlight <= b.getTargetCongestionWindow(1) { - shouldAdvanceGainCycling = true - } - - if shouldAdvanceGainCycling { - b.cycleCurrentOffset = (b.cycleCurrentOffset + 1) % gainCycleLength - b.lastCycleStart = now - // Stay in low gain mode until the target BDP is hit. - // Low gain mode will be exited immediately when the target BDP is achieved. - if b.drainToTarget && b.pacingGain < 1 && - pacingGain[b.cycleCurrentOffset] == 1 && - b.bytesInFlight > b.getTargetCongestionWindow(1) { - return - } - b.pacingGain = pacingGain[b.cycleCurrentOffset] - } -} - -// Tracks for how many round-trips the bandwidth has not increased -// significantly. -func (b *bbrSender) checkIfFullBandwidthReached(lastPacketSendState *sendTimeState) { - if b.lastSampleIsAppLimited { - return - } - - target := Bandwidth(float64(b.bandwidthAtLastRound) * startupGrowthTarget) - if b.bandwidthEstimate() >= target { - b.bandwidthAtLastRound = b.bandwidthEstimate() - b.roundsWithoutBandwidthGain = 0 - if b.expireAckAggregationInStartup { - // Expire old excess delivery measurements now that bandwidth increased. - b.sampler.ResetMaxAckHeightTracker(0, b.roundTripCount) - } - return - } - - b.roundsWithoutBandwidthGain++ - if b.roundsWithoutBandwidthGain >= b.numStartupRtts || - b.shouldExitStartupDueToLoss(lastPacketSendState) { - b.isAtFullBandwidth = true - } -} - -func (b *bbrSender) maybeApplimited(bytesInFlight congestion.ByteCount) { - congestionWindow := b.GetCongestionWindow() - if bytesInFlight >= congestionWindow { - return - } - availableBytes := congestionWindow - bytesInFlight - drainLimited := b.mode == bbrModeDrain && bytesInFlight > congestionWindow/2 - if !drainLimited || availableBytes > maxBbrBurstPackets*b.maxDatagramSize { - b.sampler.OnAppLimited() - } -} - -// Transitions from STARTUP to DRAIN and from DRAIN to PROBE_BW if -// appropriate. -func (b *bbrSender) maybeExitStartupOrDrain(now time.Time) { - if b.mode == bbrModeStartup && b.isAtFullBandwidth { - b.mode = bbrModeDrain - // b.maybeTraceStateChange(logging.CongestionStateDrain) - b.pacingGain = b.drainGain - b.congestionWindowGain = b.highCwndGain - } - if b.mode == bbrModeDrain && b.bytesInFlight <= b.getTargetCongestionWindow(1) { - b.enterProbeBandwidthMode(now) - } -} - -// Decides whether to enter or exit PROBE_RTT. -func (b *bbrSender) maybeEnterOrExitProbeRtt(now time.Time, isRoundStart, minRttExpired bool) { - if minRttExpired && !b.exitingQuiescence && b.mode != bbrModeProbeRtt { - b.mode = bbrModeProbeRtt - // b.maybeTraceStateChange(logging.CongestionStateProbRtt) - b.pacingGain = 1.0 - // Do not decide on the time to exit PROBE_RTT until the |bytes_in_flight| - // is at the target small value. - b.exitProbeRttAt = time.Time{} - } - - if b.mode == bbrModeProbeRtt { - b.sampler.OnAppLimited() - // b.maybeTraceStateChange(logging.CongestionStateApplicationLimited) - - if b.exitProbeRttAt.IsZero() { - // If the window has reached the appropriate size, schedule exiting - // PROBE_RTT. The CWND during PROBE_RTT is kMinimumCongestionWindow, but - // we allow an extra packet since QUIC checks CWND before sending a - // packet. - if b.bytesInFlight < b.probeRttCongestionWindow()+congestion.MaxPacketBufferSize { - b.exitProbeRttAt = now.Add(probeRttTime) - b.probeRttRoundPassed = false - } - } else { - if isRoundStart { - b.probeRttRoundPassed = true - } - if now.Sub(b.exitProbeRttAt) >= 0 && b.probeRttRoundPassed { - b.minRttTimestamp = now - if !b.isAtFullBandwidth { - b.enterStartupMode(now) - } else { - b.enterProbeBandwidthMode(now) - } - } - } - } - - b.exitingQuiescence = false -} - -// Determines whether BBR needs to enter, exit or advance state of the -// recovery. -func (b *bbrSender) updateRecoveryState(lastAckedPacket congestion.PacketNumber, hasLosses, isRoundStart bool) { - // Disable recovery in startup, if loss-based exit is enabled. - if !b.isAtFullBandwidth { - return - } - - // Exit recovery when there are no losses for a round. - if hasLosses { - b.endRecoveryAt = b.lastSentPacket - } - - switch b.recoveryState { - case bbrRecoveryStateNotInRecovery: - if hasLosses { - b.recoveryState = bbrRecoveryStateConservation - // This will cause the |recovery_window_| to be set to the correct - // value in CalculateRecoveryWindow(). - b.recoveryWindow = 0 - // Since the conservation phase is meant to be lasting for a whole - // round, extend the current round as if it were started right now. - b.currentRoundTripEnd = b.lastSentPacket - } - case bbrRecoveryStateConservation: - if isRoundStart { - b.recoveryState = bbrRecoveryStateGrowth - } - fallthrough - case bbrRecoveryStateGrowth: - // Exit recovery if appropriate. - if !hasLosses && lastAckedPacket > b.endRecoveryAt { - b.recoveryState = bbrRecoveryStateNotInRecovery - } - } -} - -// Determines the appropriate pacing rate for the connection. -func (b *bbrSender) calculatePacingRate(bytesLost congestion.ByteCount) { - if b.bandwidthEstimate() == 0 { - return - } - - targetRate := Bandwidth(b.pacingGain * float64(b.bandwidthEstimate())) - if b.isAtFullBandwidth { - b.pacingRate = targetRate - return - } - - // Pace at the rate of initial_window / RTT as soon as RTT measurements are - // available. - if b.pacingRate == 0 && b.rttStats.MinRTT() != 0 { - b.pacingRate = BandwidthFromDelta(b.initialCongestionWindow, b.rttStats.MinRTT()) - return - } - - if b.detectOvershooting { - b.bytesLostWhileDetectingOvershooting += bytesLost - // Check for overshooting with network parameters adjusted when pacing rate - // > target_rate and loss has been detected. - if b.pacingRate > targetRate && b.bytesLostWhileDetectingOvershooting > 0 { - if b.hasNoAppLimitedSample || - b.bytesLostWhileDetectingOvershooting*congestion.ByteCount(b.bytesLostMultiplierWhileDetectingOvershooting) > b.initialCongestionWindow { - // We are fairly sure overshoot happens if 1) there is at least one - // non app-limited bw sample or 2) half of IW gets lost. Slow pacing - // rate. - b.pacingRate = max(targetRate, BandwidthFromDelta(b.cwndToCalculateMinPacingRate, b.rttStats.MinRTT())) - b.bytesLostWhileDetectingOvershooting = 0 - b.detectOvershooting = false - } - } - } - - // Do not decrease the pacing rate during startup. - b.pacingRate = max(b.pacingRate, targetRate) -} - -// Determines the appropriate congestion window for the connection. -func (b *bbrSender) calculateCongestionWindow(bytesAcked, excessAcked congestion.ByteCount) { - if b.mode == bbrModeProbeRtt { - return - } - - targetWindow := b.getTargetCongestionWindow(b.congestionWindowGain) - if b.isAtFullBandwidth { - // Add the max recently measured ack aggregation to CWND. - targetWindow += b.sampler.MaxAckHeight() - } else if b.enableAckAggregationDuringStartup { - // Add the most recent excess acked. Because CWND never decreases in - // STARTUP, this will automatically create a very localized max filter. - targetWindow += excessAcked - } - - // Instead of immediately setting the target CWND as the new one, BBR grows - // the CWND towards |target_window| by only increasing it |bytes_acked| at a - // time. - if b.isAtFullBandwidth { - b.congestionWindow = min(targetWindow, b.congestionWindow+bytesAcked) - } else if b.congestionWindow < targetWindow || - b.sampler.TotalBytesAcked() < b.initialCongestionWindow { - // If the connection is not yet out of startup phase, do not decrease the - // window. - b.congestionWindow += bytesAcked - } - - // Enforce the limits on the congestion window. - b.congestionWindow = max(b.congestionWindow, b.minCongestionWindow) - b.congestionWindow = min(b.congestionWindow, b.maxCongestionWindow) -} - -// Determines the appropriate window that constrains the in-flight during recovery. -func (b *bbrSender) calculateRecoveryWindow(bytesAcked, bytesLost congestion.ByteCount) { - if b.recoveryState == bbrRecoveryStateNotInRecovery { - return - } - - // Set up the initial recovery window. - if b.recoveryWindow == 0 { - b.recoveryWindow = b.bytesInFlight + bytesAcked - b.recoveryWindow = max(b.minCongestionWindow, b.recoveryWindow) - return - } - - // Remove losses from the recovery window, while accounting for a potential - // integer underflow. - if b.recoveryWindow >= bytesLost { - b.recoveryWindow = b.recoveryWindow - bytesLost - } else { - b.recoveryWindow = b.maxDatagramSize - } - - // In CONSERVATION mode, just subtracting losses is sufficient. In GROWTH, - // release additional |bytes_acked| to achieve a slow-start-like behavior. - if b.recoveryState == bbrRecoveryStateGrowth { - b.recoveryWindow += bytesAcked - } - - // Always allow sending at least |bytes_acked| in response. - b.recoveryWindow = max(b.recoveryWindow, b.bytesInFlight+bytesAcked) - b.recoveryWindow = max(b.minCongestionWindow, b.recoveryWindow) -} - -// Return whether we should exit STARTUP due to excessive loss. -func (b *bbrSender) shouldExitStartupDueToLoss(lastPacketSendState *sendTimeState) bool { - if b.numLossEventsInRound < defaultStartupFullLossCount || !lastPacketSendState.isValid { - return false - } - - inflightAtSend := lastPacketSendState.bytesInFlight - - if inflightAtSend > 0 && b.bytesLostInRound > 0 { - return b.bytesLostInRound > congestion.ByteCount(float64(inflightAtSend)*quicBbr2DefaultLossThreshold) - } - return false -} - -func bdpFromRttAndBandwidth(rtt time.Duration, bandwidth Bandwidth) congestion.ByteCount { - return congestion.ByteCount(rtt) * congestion.ByteCount(bandwidth) / congestion.ByteCount(BytesPerSecond) / congestion.ByteCount(time.Second) -} - -func GetInitialPacketSize(addr net.Addr) congestion.ByteCount { - // If this is not a UDP address, we don't know anything about the MTU. - // Use the minimum size of an Initial packet as the max packet size. - if udpAddr, ok := addr.(*net.UDPAddr); ok { - if udpAddr.IP.To4() != nil { - return congestion.InitialPacketSizeIPv4 - } else { - return congestion.InitialPacketSizeIPv6 - } - } else { - return congestion.MinInitialPacketSize - } -} diff --git a/transport/internet/quic/congestion/bbr/clock.go b/transport/internet/quic/congestion/bbr/clock.go deleted file mode 100644 index a66344fb71..0000000000 --- a/transport/internet/quic/congestion/bbr/clock.go +++ /dev/null @@ -1,18 +0,0 @@ -package bbr - -import "time" - -// A Clock returns the current time -type Clock interface { - Now() time.Time -} - -// DefaultClock implements the Clock interface using the Go stdlib clock. -type DefaultClock struct{} - -var _ Clock = DefaultClock{} - -// Now gets the current time -func (DefaultClock) Now() time.Time { - return time.Now() -} diff --git a/transport/internet/quic/congestion/bbr/packet_number_indexed_queue.go b/transport/internet/quic/congestion/bbr/packet_number_indexed_queue.go deleted file mode 100644 index ac4c51aafa..0000000000 --- a/transport/internet/quic/congestion/bbr/packet_number_indexed_queue.go +++ /dev/null @@ -1,198 +0,0 @@ -package bbr - -import ( - "github.com/apernet/quic-go/congestion" -) - -// packetNumberIndexedQueue is a queue of mostly continuous numbered entries -// which supports the following operations: -// - adding elements to the end of the queue, or at some point past the end -// - removing elements in any order -// - retrieving elements -// If all elements are inserted in order, all of the operations above are -// amortized O(1) time. -// -// Internally, the data structure is a deque where each element is marked as -// present or not. The deque starts at the lowest present index. Whenever an -// element is removed, it's marked as not present, and the front of the deque is -// cleared of elements that are not present. -// -// The tail of the queue is not cleared due to the assumption of entries being -// inserted in order, though removing all elements of the queue will return it -// to its initial state. -// -// Note that this data structure is inherently hazardous, since an addition of -// just two entries will cause it to consume all of the memory available. -// Because of that, it is not a general-purpose container and should not be used -// as one. - -type entryWrapper[T any] struct { - present bool - entry T -} - -type packetNumberIndexedQueue[T any] struct { - entries RingBuffer[entryWrapper[T]] - numberOfPresentEntries int - firstPacket congestion.PacketNumber -} - -func newPacketNumberIndexedQueue[T any](size int) *packetNumberIndexedQueue[T] { - q := &packetNumberIndexedQueue[T]{ - firstPacket: invalidPacketNumber, - } - - q.entries.Init(size) - - return q -} - -// Emplace inserts data associated |packet_number| into (or past) the end of the -// queue, filling up the missing intermediate entries as necessary. Returns -// true if the element has been inserted successfully, false if it was already -// in the queue or inserted out of order. -func (p *packetNumberIndexedQueue[T]) Emplace(packetNumber congestion.PacketNumber, entry *T) bool { - if packetNumber == invalidPacketNumber || entry == nil { - return false - } - - if p.IsEmpty() { - p.entries.PushBack(entryWrapper[T]{ - present: true, - entry: *entry, - }) - p.numberOfPresentEntries = 1 - p.firstPacket = packetNumber - return true - } - - // Do not allow insertion out-of-order. - if packetNumber <= p.LastPacket() { - return false - } - - // Handle potentially missing elements. - offset := int(packetNumber - p.FirstPacket()) - if gap := offset - p.entries.Len(); gap > 0 { - for i := 0; i < gap; i++ { - p.entries.PushBack(entryWrapper[T]{}) - } - } - - p.entries.PushBack(entryWrapper[T]{ - present: true, - entry: *entry, - }) - p.numberOfPresentEntries++ - return true -} - -// GetEntry Retrieve the entry associated with the packet number. Returns the pointer -// to the entry in case of success, or nullptr if the entry does not exist. -func (p *packetNumberIndexedQueue[T]) GetEntry(packetNumber congestion.PacketNumber) *T { - ew := p.getEntryWraper(packetNumber) - if ew == nil { - return nil - } - - return &ew.entry -} - -// Remove, Same as above, but if an entry is present in the queue, also call f(entry) -// before removing it. -func (p *packetNumberIndexedQueue[T]) Remove(packetNumber congestion.PacketNumber, f func(T)) bool { - ew := p.getEntryWraper(packetNumber) - if ew == nil { - return false - } - if f != nil { - f(ew.entry) - } - ew.present = false - p.numberOfPresentEntries-- - - if packetNumber == p.FirstPacket() { - p.clearup() - } - - return true -} - -// RemoveUpTo, but not including |packet_number|. -// Unused slots in the front are also removed, which means when the function -// returns, |first_packet()| can be larger than |packet_number|. -func (p *packetNumberIndexedQueue[T]) RemoveUpTo(packetNumber congestion.PacketNumber) { - for !p.entries.Empty() && - p.firstPacket != invalidPacketNumber && - p.firstPacket < packetNumber { - if p.entries.Front().present { - p.numberOfPresentEntries-- - } - p.entries.PopFront() - p.firstPacket++ - } - p.clearup() - -} - -// IsEmpty return if queue is empty. -func (p *packetNumberIndexedQueue[T]) IsEmpty() bool { - return p.numberOfPresentEntries == 0 -} - -// NumberOfPresentEntries returns the number of entries in the queue. -func (p *packetNumberIndexedQueue[T]) NumberOfPresentEntries() int { - return p.numberOfPresentEntries -} - -// EntrySlotsUsed returns the number of entries allocated in the underlying deque. This is -// proportional to the memory usage of the queue. -func (p *packetNumberIndexedQueue[T]) EntrySlotsUsed() int { - return p.entries.Len() -} - -// LastPacket returns packet number of the first entry in the queue. -func (p *packetNumberIndexedQueue[T]) FirstPacket() (packetNumber congestion.PacketNumber) { - return p.firstPacket -} - -// LastPacket returns packet number of the last entry ever inserted in the queue. Note that the -// entry in question may have already been removed. Zero if the queue is -// empty. -func (p *packetNumberIndexedQueue[T]) LastPacket() (packetNumber congestion.PacketNumber) { - if p.IsEmpty() { - return invalidPacketNumber - } - - return p.firstPacket + congestion.PacketNumber(p.entries.Len()-1) -} - -func (p *packetNumberIndexedQueue[T]) clearup() { - for !p.entries.Empty() && !p.entries.Front().present { - p.entries.PopFront() - p.firstPacket++ - } - if p.entries.Empty() { - p.firstPacket = invalidPacketNumber - } -} - -func (p *packetNumberIndexedQueue[T]) getEntryWraper(packetNumber congestion.PacketNumber) *entryWrapper[T] { - if packetNumber == invalidPacketNumber || - p.IsEmpty() || - packetNumber < p.firstPacket { - return nil - } - - offset := int(packetNumber - p.firstPacket) - if offset >= p.entries.Len() { - return nil - } - - ew := p.entries.Offset(offset) - if ew == nil || !ew.present { - return nil - } - - return ew -} diff --git a/transport/internet/quic/congestion/bbr/ringbuffer.go b/transport/internet/quic/congestion/bbr/ringbuffer.go deleted file mode 100644 index ed92d4ce01..0000000000 --- a/transport/internet/quic/congestion/bbr/ringbuffer.go +++ /dev/null @@ -1,118 +0,0 @@ -package bbr - -// A RingBuffer is a ring buffer. -// It acts as a heap that doesn't cause any allocations. -type RingBuffer[T any] struct { - ring []T - headPos, tailPos int - full bool -} - -// Init preallocs a buffer with a certain size. -func (r *RingBuffer[T]) Init(size int) { - r.ring = make([]T, size) -} - -// Len returns the number of elements in the ring buffer. -func (r *RingBuffer[T]) Len() int { - if r.full { - return len(r.ring) - } - if r.tailPos >= r.headPos { - return r.tailPos - r.headPos - } - return r.tailPos - r.headPos + len(r.ring) -} - -// Empty says if the ring buffer is empty. -func (r *RingBuffer[T]) Empty() bool { - return !r.full && r.headPos == r.tailPos -} - -// PushBack adds a new element. -// If the ring buffer is full, its capacity is increased first. -func (r *RingBuffer[T]) PushBack(t T) { - if r.full || len(r.ring) == 0 { - r.grow() - } - r.ring[r.tailPos] = t - r.tailPos++ - if r.tailPos == len(r.ring) { - r.tailPos = 0 - } - if r.tailPos == r.headPos { - r.full = true - } -} - -// PopFront returns the next element. -// It must not be called when the buffer is empty, that means that -// callers might need to check if there are elements in the buffer first. -func (r *RingBuffer[T]) PopFront() T { - if r.Empty() { - panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: pop from an empty queue") - } - r.full = false - t := r.ring[r.headPos] - r.ring[r.headPos] = *new(T) - r.headPos++ - if r.headPos == len(r.ring) { - r.headPos = 0 - } - return t -} - -// Offset returns the offset element. -// It must not be called when the buffer is empty, that means that -// callers might need to check if there are elements in the buffer first -// and check if the index larger than buffer length. -func (r *RingBuffer[T]) Offset(index int) *T { - if r.Empty() || index >= r.Len() { - panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: offset from invalid index") - } - offset := (r.headPos + index) % len(r.ring) - return &r.ring[offset] -} - -// Front returns the front element. -// It must not be called when the buffer is empty, that means that -// callers might need to check if there are elements in the buffer first. -func (r *RingBuffer[T]) Front() *T { - if r.Empty() { - panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: front from an empty queue") - } - return &r.ring[r.headPos] -} - -// Back returns the back element. -// It must not be called when the buffer is empty, that means that -// callers might need to check if there are elements in the buffer first. -func (r *RingBuffer[T]) Back() *T { - if r.Empty() { - panic("github.com/quic-go/quic-go/internal/utils/ringbuffer: back from an empty queue") - } - return r.Offset(r.Len() - 1) -} - -// Grow the maximum size of the queue. -// This method assume the queue is full. -func (r *RingBuffer[T]) grow() { - oldRing := r.ring - newSize := len(oldRing) * 2 - if newSize == 0 { - newSize = 1 - } - r.ring = make([]T, newSize) - headLen := copy(r.ring, oldRing[r.headPos:]) - copy(r.ring[headLen:], oldRing[:r.headPos]) - r.headPos, r.tailPos, r.full = 0, len(oldRing), false -} - -// Clear removes all elements. -func (r *RingBuffer[T]) Clear() { - var zeroValue T - for i := range r.ring { - r.ring[i] = zeroValue - } - r.headPos, r.tailPos, r.full = 0, 0, false -} diff --git a/transport/internet/quic/congestion/bbr/windowed_filter.go b/transport/internet/quic/congestion/bbr/windowed_filter.go deleted file mode 100644 index bd9a5f7211..0000000000 --- a/transport/internet/quic/congestion/bbr/windowed_filter.go +++ /dev/null @@ -1,162 +0,0 @@ -package bbr - -import ( - "golang.org/x/exp/constraints" -) - -// Implements Kathleen Nichols' algorithm for tracking the minimum (or maximum) -// estimate of a stream of samples over some fixed time interval. (E.g., -// the minimum RTT over the past five minutes.) The algorithm keeps track of -// the best, second best, and third best min (or max) estimates, maintaining an -// invariant that the measurement time of the n'th best >= n-1'th best. - -// The algorithm works as follows. On a reset, all three estimates are set to -// the same sample. The second best estimate is then recorded in the second -// quarter of the window, and a third best estimate is recorded in the second -// half of the window, bounding the worst case error when the true min is -// monotonically increasing (or true max is monotonically decreasing) over the -// window. -// -// A new best sample replaces all three estimates, since the new best is lower -// (or higher) than everything else in the window and it is the most recent. -// The window thus effectively gets reset on every new min. The same property -// holds true for second best and third best estimates. Specifically, when a -// sample arrives that is better than the second best but not better than the -// best, it replaces the second and third best estimates but not the best -// estimate. Similarly, a sample that is better than the third best estimate -// but not the other estimates replaces only the third best estimate. -// -// Finally, when the best expires, it is replaced by the second best, which in -// turn is replaced by the third best. The newest sample replaces the third -// best. - -type WindowedFilterValue interface { - any -} - -type WindowedFilterTime interface { - constraints.Integer | constraints.Float -} - -type WindowedFilter[V WindowedFilterValue, T WindowedFilterTime] struct { - // Time length of window. - windowLength T - estimates []entry[V, T] - comparator func(V, V) int -} - -type entry[V WindowedFilterValue, T WindowedFilterTime] struct { - sample V - time T -} - -// Compares two values and returns true if the first is greater than or equal -// to the second. -func MaxFilter[O constraints.Ordered](a, b O) int { - if a > b { - return 1 - } else if a < b { - return -1 - } - return 0 -} - -// Compares two values and returns true if the first is less than or equal -// to the second. -func MinFilter[O constraints.Ordered](a, b O) int { - if a < b { - return 1 - } else if a > b { - return -1 - } - return 0 -} - -func NewWindowedFilter[V WindowedFilterValue, T WindowedFilterTime](windowLength T, comparator func(V, V) int) *WindowedFilter[V, T] { - return &WindowedFilter[V, T]{ - windowLength: windowLength, - estimates: make([]entry[V, T], 3), - comparator: comparator, - } -} - -// Changes the window length. Does not update any current samples. -func (f *WindowedFilter[V, T]) SetWindowLength(windowLength T) { - f.windowLength = windowLength -} - -func (f *WindowedFilter[V, T]) GetBest() V { - return f.estimates[0].sample -} - -func (f *WindowedFilter[V, T]) GetSecondBest() V { - return f.estimates[1].sample -} - -func (f *WindowedFilter[V, T]) GetThirdBest() V { - return f.estimates[2].sample -} - -// Updates best estimates with |sample|, and expires and updates best -// estimates as necessary. -func (f *WindowedFilter[V, T]) Update(newSample V, newTime T) { - // Reset all estimates if they have not yet been initialized, if new sample - // is a new best, or if the newest recorded estimate is too old. - if f.comparator(f.estimates[0].sample, *new(V)) == 0 || - f.comparator(newSample, f.estimates[0].sample) >= 0 || - newTime-f.estimates[2].time > f.windowLength { - f.Reset(newSample, newTime) - return - } - - if f.comparator(newSample, f.estimates[1].sample) >= 0 { - f.estimates[1] = entry[V, T]{newSample, newTime} - f.estimates[2] = f.estimates[1] - } else if f.comparator(newSample, f.estimates[2].sample) >= 0 { - f.estimates[2] = entry[V, T]{newSample, newTime} - } - - // Expire and update estimates as necessary. - if newTime-f.estimates[0].time > f.windowLength { - // The best estimate hasn't been updated for an entire window, so promote - // second and third best estimates. - f.estimates[0] = f.estimates[1] - f.estimates[1] = f.estimates[2] - f.estimates[2] = entry[V, T]{newSample, newTime} - // Need to iterate one more time. Check if the new best estimate is - // outside the window as well, since it may also have been recorded a - // long time ago. Don't need to iterate once more since we cover that - // case at the beginning of the method. - if newTime-f.estimates[0].time > f.windowLength { - f.estimates[0] = f.estimates[1] - f.estimates[1] = f.estimates[2] - } - return - } - if f.comparator(f.estimates[1].sample, f.estimates[0].sample) == 0 && - newTime-f.estimates[1].time > f.windowLength/4 { - // A quarter of the window has passed without a better sample, so the - // second-best estimate is taken from the second quarter of the window. - f.estimates[1] = entry[V, T]{newSample, newTime} - f.estimates[2] = f.estimates[1] - return - } - - if f.comparator(f.estimates[2].sample, f.estimates[1].sample) == 0 && - newTime-f.estimates[2].time > f.windowLength/2 { - // We've passed a half of the window without a better estimate, so take - // a third-best estimate from the second half of the window. - f.estimates[2] = entry[V, T]{newSample, newTime} - } -} - -// Resets all estimates to new sample. -func (f *WindowedFilter[V, T]) Reset(newSample V, newTime T) { - f.estimates[2] = entry[V, T]{newSample, newTime} - f.estimates[1] = f.estimates[2] - f.estimates[0] = f.estimates[1] -} - -func (f *WindowedFilter[V, T]) Clear() { - f.estimates = make([]entry[V, T], 3) -} diff --git a/transport/internet/quic/congestion/brutal/brutal.go b/transport/internet/quic/congestion/brutal/brutal.go deleted file mode 100644 index dbc31588c5..0000000000 --- a/transport/internet/quic/congestion/brutal/brutal.go +++ /dev/null @@ -1,181 +0,0 @@ -package brutal - -import ( - "fmt" - "os" - "strconv" - "time" - - "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/common" - - "github.com/apernet/quic-go/congestion" -) - -const ( - pktInfoSlotCount = 5 // slot index is based on seconds, so this is basically how many seconds we sample - minSampleCount = 50 - minAckRate = 0.8 - congestionWindowMultiplier = 2 - - debugEnv = "HYSTERIA_BRUTAL_DEBUG" - debugPrintInterval = 2 -) - -var _ congestion.CongestionControl = &BrutalSender{} - -type BrutalSender struct { - rttStats congestion.RTTStatsProvider - bps congestion.ByteCount - maxDatagramSize congestion.ByteCount - pacer *common.Pacer - - pktInfoSlots [pktInfoSlotCount]pktInfo - ackRate float64 - - debug bool - lastAckPrintTimestamp int64 -} - -type pktInfo struct { - Timestamp int64 - AckCount uint64 - LossCount uint64 -} - -func NewBrutalSender(bps uint64) *BrutalSender { - debug, _ := strconv.ParseBool(os.Getenv(debugEnv)) - bs := &BrutalSender{ - bps: congestion.ByteCount(bps), - maxDatagramSize: congestion.InitialPacketSizeIPv4, - ackRate: 1, - debug: debug, - } - bs.pacer = common.NewPacer(func() congestion.ByteCount { - return congestion.ByteCount(float64(bs.bps) / bs.ackRate) - }) - return bs -} - -func (b *BrutalSender) SetRTTStatsProvider(rttStats congestion.RTTStatsProvider) { - b.rttStats = rttStats -} - -func (b *BrutalSender) TimeUntilSend(bytesInFlight congestion.ByteCount) time.Time { - return b.pacer.TimeUntilSend() -} - -func (b *BrutalSender) HasPacingBudget(now time.Time) bool { - return b.pacer.Budget(now) >= b.maxDatagramSize -} - -func (b *BrutalSender) CanSend(bytesInFlight congestion.ByteCount) bool { - return bytesInFlight < b.GetCongestionWindow() -} - -func (b *BrutalSender) GetCongestionWindow() congestion.ByteCount { - rtt := b.rttStats.SmoothedRTT() - if rtt <= 0 { - return 10240 - } - return congestion.ByteCount(float64(b.bps) * rtt.Seconds() * congestionWindowMultiplier / b.ackRate) -} - -func (b *BrutalSender) OnPacketSent(sentTime time.Time, bytesInFlight congestion.ByteCount, - packetNumber congestion.PacketNumber, bytes congestion.ByteCount, isRetransmittable bool, -) { - b.pacer.SentPacket(sentTime, bytes) -} - -func (b *BrutalSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes congestion.ByteCount, - priorInFlight congestion.ByteCount, eventTime time.Time, -) { - // Stub -} - -func (b *BrutalSender) OnCongestionEvent(number congestion.PacketNumber, lostBytes congestion.ByteCount, - priorInFlight congestion.ByteCount, -) { - // Stub -} - -func (b *BrutalSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, eventTime time.Time, ackedPackets []congestion.AckedPacketInfo, lostPackets []congestion.LostPacketInfo) { - currentTimestamp := eventTime.Unix() - slot := currentTimestamp % pktInfoSlotCount - if b.pktInfoSlots[slot].Timestamp == currentTimestamp { - b.pktInfoSlots[slot].LossCount += uint64(len(lostPackets)) - b.pktInfoSlots[slot].AckCount += uint64(len(ackedPackets)) - } else { - // uninitialized slot or too old, reset - b.pktInfoSlots[slot].Timestamp = currentTimestamp - b.pktInfoSlots[slot].AckCount = uint64(len(ackedPackets)) - b.pktInfoSlots[slot].LossCount = uint64(len(lostPackets)) - } - b.updateAckRate(currentTimestamp) -} - -func (b *BrutalSender) SetMaxDatagramSize(size congestion.ByteCount) { - b.maxDatagramSize = size - b.pacer.SetMaxDatagramSize(size) - if b.debug { - b.debugPrint("SetMaxDatagramSize: %d", size) - } -} - -func (b *BrutalSender) updateAckRate(currentTimestamp int64) { - minTimestamp := currentTimestamp - pktInfoSlotCount - var ackCount, lossCount uint64 - for _, info := range b.pktInfoSlots { - if info.Timestamp < minTimestamp { - continue - } - ackCount += info.AckCount - lossCount += info.LossCount - } - if ackCount+lossCount < minSampleCount { - b.ackRate = 1 - if b.canPrintAckRate(currentTimestamp) { - b.lastAckPrintTimestamp = currentTimestamp - b.debugPrint("Not enough samples (total=%d, ack=%d, loss=%d, rtt=%d)", - ackCount+lossCount, ackCount, lossCount, b.rttStats.SmoothedRTT().Milliseconds()) - } - return - } - rate := float64(ackCount) / float64(ackCount+lossCount) - if rate < minAckRate { - b.ackRate = minAckRate - if b.canPrintAckRate(currentTimestamp) { - b.lastAckPrintTimestamp = currentTimestamp - b.debugPrint("ACK rate too low: %.2f, clamped to %.2f (total=%d, ack=%d, loss=%d, rtt=%d)", - rate, minAckRate, ackCount+lossCount, ackCount, lossCount, b.rttStats.SmoothedRTT().Milliseconds()) - } - return - } - b.ackRate = rate - if b.canPrintAckRate(currentTimestamp) { - b.lastAckPrintTimestamp = currentTimestamp - b.debugPrint("ACK rate: %.2f (total=%d, ack=%d, loss=%d, rtt=%d)", - rate, ackCount+lossCount, ackCount, lossCount, b.rttStats.SmoothedRTT().Milliseconds()) - } -} - -func (b *BrutalSender) InSlowStart() bool { - return false -} - -func (b *BrutalSender) InRecovery() bool { - return false -} - -func (b *BrutalSender) MaybeExitSlowStart() {} - -func (b *BrutalSender) OnRetransmissionTimeout(packetsRetransmitted bool) {} - -func (b *BrutalSender) canPrintAckRate(currentTimestamp int64) bool { - return b.debug && currentTimestamp-b.lastAckPrintTimestamp >= debugPrintInterval -} - -func (b *BrutalSender) debugPrint(format string, a ...any) { - fmt.Printf("[BrutalSender] [%s] %s\n", - time.Now().Format("15:04:05"), - fmt.Sprintf(format, a...)) -} diff --git a/transport/internet/quic/congestion/common/pacer.go b/transport/internet/quic/congestion/common/pacer.go deleted file mode 100644 index 4e089a3147..0000000000 --- a/transport/internet/quic/congestion/common/pacer.go +++ /dev/null @@ -1,95 +0,0 @@ -package common - -import ( - "math" - "time" - - "github.com/apernet/quic-go/congestion" -) - -const ( - maxBurstPackets = 10 -) - -// Pacer implements a token bucket pacing algorithm. -type Pacer struct { - budgetAtLastSent congestion.ByteCount - maxDatagramSize congestion.ByteCount - lastSentTime time.Time - getBandwidth func() congestion.ByteCount // in bytes/s -} - -func NewPacer(getBandwidth func() congestion.ByteCount) *Pacer { - p := &Pacer{ - budgetAtLastSent: maxBurstPackets * congestion.InitialPacketSizeIPv4, - maxDatagramSize: congestion.InitialPacketSizeIPv4, - getBandwidth: getBandwidth, - } - return p -} - -func (p *Pacer) SentPacket(sendTime time.Time, size congestion.ByteCount) { - budget := p.Budget(sendTime) - if size > budget { - p.budgetAtLastSent = 0 - } else { - p.budgetAtLastSent = budget - size - } - p.lastSentTime = sendTime -} - -func (p *Pacer) Budget(now time.Time) congestion.ByteCount { - if p.lastSentTime.IsZero() { - return p.maxBurstSize() - } - budget := p.budgetAtLastSent + (p.getBandwidth()*congestion.ByteCount(now.Sub(p.lastSentTime).Nanoseconds()))/1e9 - if budget < 0 { // protect against overflows - budget = congestion.ByteCount(1<<62 - 1) - } - return minByteCount(p.maxBurstSize(), budget) -} - -func (p *Pacer) maxBurstSize() congestion.ByteCount { - return maxByteCount( - congestion.ByteCount((congestion.MinPacingDelay+time.Millisecond).Nanoseconds())*p.getBandwidth()/1e9, - maxBurstPackets*p.maxDatagramSize, - ) -} - -// TimeUntilSend returns when the next packet should be sent. -// It returns the zero value of time.Time if a packet can be sent immediately. -func (p *Pacer) TimeUntilSend() time.Time { - if p.budgetAtLastSent >= p.maxDatagramSize { - return time.Time{} - } - return p.lastSentTime.Add(maxDuration( - congestion.MinPacingDelay, - time.Duration(math.Ceil(float64(p.maxDatagramSize-p.budgetAtLastSent)*1e9/ - float64(p.getBandwidth())))*time.Nanosecond, - )) -} - -func (p *Pacer) SetMaxDatagramSize(s congestion.ByteCount) { - p.maxDatagramSize = s -} - -func maxByteCount(a, b congestion.ByteCount) congestion.ByteCount { - if a < b { - return b - } - return a -} - -func minByteCount(a, b congestion.ByteCount) congestion.ByteCount { - if a < b { - return a - } - return b -} - -func maxDuration(a, b time.Duration) time.Duration { - if a > b { - return a - } - return b -} diff --git a/transport/internet/quic/congestion/utils.go b/transport/internet/quic/congestion/utils.go deleted file mode 100644 index 3ff68f6fc1..0000000000 --- a/transport/internet/quic/congestion/utils.go +++ /dev/null @@ -1,19 +0,0 @@ -package congestion - -import ( - "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/bbr" - "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion/brutal" - - "github.com/apernet/quic-go" -) - -func UseBBR(conn quic.Connection) { - conn.SetCongestionControl(bbr.NewBbrSender( - bbr.DefaultClock{}, - bbr.GetInitialPacketSize(conn.RemoteAddr()), - )) -} - -func UseBrutal(conn quic.Connection, tx uint64) { - conn.SetCongestionControl(brutal.NewBrutalSender(tx)) -} diff --git a/transport/internet/quic/conn.go b/transport/internet/quic/conn.go index ef3f9ac5ee..492c24288f 100644 --- a/transport/internet/quic/conn.go +++ b/transport/internet/quic/conn.go @@ -7,7 +7,7 @@ import ( "syscall" "time" - "github.com/apernet/quic-go" + "github.com/quic-go/quic-go" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/buf" diff --git a/transport/internet/quic/dialer.go b/transport/internet/quic/dialer.go index 0fe900d908..b52dd4a5ec 100644 --- a/transport/internet/quic/dialer.go +++ b/transport/internet/quic/dialer.go @@ -5,13 +5,12 @@ import ( "sync" "time" - "github.com/apernet/quic-go" + "github.com/quic-go/quic-go" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/task" "github.com/v2fly/v2ray-core/v5/transport/internet" - "github.com/v2fly/v2ray-core/v5/transport/internet/quic/congestion" "github.com/v2fly/v2ray-core/v5/transport/internet/tls" ) @@ -42,9 +41,9 @@ func (c *connectionContext) openStream(destAddr net.Addr) (*interConn, error) { } type clientConnections struct { - access sync.Mutex - runningConnections map[net.Destination][]*connectionContext - cleanup *task.Periodic + access sync.Mutex + conns map[net.Destination][]*connectionContext + cleanup *task.Periodic } func isActive(s quic.Connection) bool { @@ -99,20 +98,20 @@ func (s *clientConnections) cleanConnections() error { s.access.Lock() defer s.access.Unlock() - if len(s.runningConnections) == 0 { + if len(s.conns) == 0 { return nil } newConnMap := make(map[net.Destination][]*connectionContext) - for dest, conns := range s.runningConnections { + for dest, conns := range s.conns { conns = removeInactiveConnections(conns) if len(conns) > 0 { newConnMap[dest] = conns } } - s.runningConnections = newConnMap + s.conns = newConnMap return nil } @@ -120,23 +119,27 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl s.access.Lock() defer s.access.Unlock() - if s.runningConnections == nil { - s.runningConnections = make(map[net.Destination][]*connectionContext) + if s.conns == nil { + s.conns = make(map[net.Destination][]*connectionContext) } dest := net.DestinationFromAddr(destAddr) var conns []*connectionContext - if s, found := s.runningConnections[dest]; found { + if s, found := s.conns[dest]; found { conns = s + } + + { conn := openStream(conns, destAddr) if conn != nil { - newError("dialing QUIC stream to ", dest).WriteToLog() return conn, nil } } + conns = removeInactiveConnections(conns) - newError("dialing QUIC new connection to ", dest).WriteToLog() + + newError("dialing QUIC to ", dest).WriteToLog() rawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{ IP: []byte{0, 0, 0, 0}, @@ -146,7 +149,11 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl return nil, err } - quicConfig := InitQuicConfig() + quicConfig := &quic.Config{ + HandshakeIdleTimeout: time.Second * 8, + MaxIdleTimeout: time.Second * 30, + KeepAlivePeriod: time.Second * 15, + } sysConn, err := wrapSysConn(rawConn.(*net.UDPConn), config) if err != nil { @@ -155,58 +162,28 @@ func (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tl } tr := quic.Transport{ - Conn: sysConn, + Conn: sysConn, + ConnectionIDLength: 12, } - conn, err := tr.DialEarly(context.Background(), destAddr, tlsConfig.GetTLSConfig(tls.WithDestination(dest)), quicConfig) + conn, err := tr.Dial(context.Background(), destAddr, tlsConfig.GetTLSConfig(tls.WithDestination(dest)), quicConfig) if err != nil { sysConn.Close() return nil, err } - SetCongestion(conn, config) context := &connectionContext{ conn: conn, rawConn: sysConn, } - s.runningConnections[dest] = append(conns, context) + s.conns[dest] = append(conns, context) return context.openStream(destAddr) } -func SetCongestion(conn quic.Connection, config *Config) { - congestionType := config.Congestion.GetType() - if congestionType == "brutal" && config.Congestion.GetSendMbps() != 0 { - sendBps := config.Congestion.GetSendMbps() * 1000000 - congestion.UseBrutal(conn, sendBps) - } else if congestionType == "bbr" { - congestion.UseBBR(conn) - } - newError("[QUIC] using congestion: ", congestionType).WriteToLog() -} - -const ( - defaultStreamReceiveWindow = 8388608 // 8MB - defaultConnReceiveWindow = defaultStreamReceiveWindow * 5 / 2 // 20MB - defaultMaxIdleTimeout = 30 * time.Second - defaultKeepAlivePeriod = 10 * time.Second - defaultHandshakeIdleTimeout = 10 * time.Second -) - -func InitQuicConfig() *quic.Config { - quicConfig := &quic.Config{ - HandshakeIdleTimeout: defaultHandshakeIdleTimeout, - MaxIdleTimeout: defaultMaxIdleTimeout, - KeepAlivePeriod: defaultKeepAlivePeriod, - InitialStreamReceiveWindow: defaultStreamReceiveWindow, - InitialConnectionReceiveWindow: defaultConnReceiveWindow, - } - return quicConfig -} - var client clientConnections func init() { - client.runningConnections = make(map[net.Destination][]*connectionContext) + client.conns = make(map[net.Destination][]*connectionContext) client.cleanup = &task.Periodic{ Interval: time.Minute, Execute: client.cleanConnections, diff --git a/transport/internet/quic/hub.go b/transport/internet/quic/hub.go index 9d5d3b9303..9a89ba7db0 100644 --- a/transport/internet/quic/hub.go +++ b/transport/internet/quic/hub.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/apernet/quic-go" + "github.com/quic-go/quic-go" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/net" @@ -20,7 +20,6 @@ type Listener struct { listener *quic.Listener done *done.Instance addConn internet.ConnHandler - config *Config } func (l *Listener) acceptStreams(conn quic.Connection) { @@ -60,9 +59,9 @@ func (l *Listener) keepAccepting() { if l.done.Done() { break } + time.Sleep(time.Second) continue } - SetCongestion(conn, l.config) go l.acceptStreams(conn) } } @@ -102,7 +101,13 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti return nil, err } - quicConfig := InitQuicConfig() + quicConfig := &quic.Config{ + HandshakeIdleTimeout: time.Second * 8, + MaxIdleTimeout: time.Second * 45, + MaxIncomingStreams: 32, + MaxIncomingUniStreams: -1, + KeepAlivePeriod: time.Second * 15, + } conn, err := wrapSysConn(rawConn.(*net.UDPConn), config) if err != nil { @@ -126,7 +131,6 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti rawConn: conn, listener: qListener, addConn: handler, - config: config, } go listener.keepAccepting() From 7305037a0d1658adddee6143dd36b6e76fcc532a Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Thu, 7 Dec 2023 00:43:41 +0800 Subject: [PATCH 26/81] update --- config.pb.go | 2 +- transport/internet/hysteria2/conn.go | 6 +- .../internet/hysteria2/errors.generated.go | 9 + transport/internet/hysteria2/hy2_test.go | 7 +- .../hysteria2/{hysteria.go => hysteria2.go} | 6 - transport/internet/quic/config.pb.go | 178 +++++------------- transport/internet/quic/config.proto | 9 +- 7 files changed, 63 insertions(+), 154 deletions(-) create mode 100644 transport/internet/hysteria2/errors.generated.go rename transport/internet/hysteria2/{hysteria.go => hysteria2.go} (68%) diff --git a/config.pb.go b/config.pb.go index 1a1cfefcb3..dd80bf4d55 100644 --- a/config.pb.go +++ b/config.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.31.0 -// protoc v4.24.3 +// protoc v4.24.4 // source: config.proto package core diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index d6add8417c..b0d500595c 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -17,7 +17,7 @@ type interConn struct { remote net.Addr isClient bool - isWriteFrameType bool + isWroteFrameType bool } const ( @@ -74,8 +74,8 @@ func (c *interConn) WriteMultiBuffer(mb buf.MultiBuffer) error { } func (c *interConn) Write(b []byte) (int, error) { - if c.isClient && !c.isWriteFrameType { - c.isWriteFrameType = true + if c.isClient && !c.isWroteFrameType { + c.isWroteFrameType = true frameSize := int(quicvarint.Len(FrameTypeTCPRequest)) buf := make([]byte, frameSize+len(b)) i := varintPut(buf, FrameTypeTCPRequest) diff --git a/transport/internet/hysteria2/errors.generated.go b/transport/internet/hysteria2/errors.generated.go new file mode 100644 index 0000000000..1053170313 --- /dev/null +++ b/transport/internet/hysteria2/errors.generated.go @@ -0,0 +1,9 @@ +package hysteria2 + +import "github.com/v2fly/v2ray-core/v5/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/transport/internet/hysteria2/hy2_test.go b/transport/internet/hysteria2/hy2_test.go index 6c3ac862cf..9fb0bfcca1 100644 --- a/transport/internet/hysteria2/hy2_test.go +++ b/transport/internet/hysteria2/hy2_test.go @@ -2,6 +2,7 @@ package hysteria2_test import ( "context" + "crypto/rand" "fmt" "testing" "time" @@ -47,7 +48,6 @@ func TestHTTP3Connection(t *testing.T) { fmt.Println(err) return } - fmt.Println(len(b.Bytes())) common.Must2(conn.Write(b.Bytes())) } }() @@ -71,16 +71,15 @@ func TestHTTP3Connection(t *testing.T) { common.Must(err) defer conn.Close() - const N = 20 + const N = 1024 b1 := make([]byte, N) + common.Must2(rand.Read(b1)) b2 := buf.New() - b1[0] = 0x19 common.Must2(conn.Write(b1)) b2.Clear() common.Must2(b2.ReadFullFrom(conn, N)) - fmt.Println(b2.Bytes()) if r := cmp.Diff(b2.Bytes(), b1); r != "" { t.Error(r) } diff --git a/transport/internet/hysteria2/hysteria.go b/transport/internet/hysteria2/hysteria2.go similarity index 68% rename from transport/internet/hysteria2/hysteria.go rename to transport/internet/hysteria2/hysteria2.go index b7c90362fc..3280d6a5dc 100644 --- a/transport/internet/hysteria2/hysteria.go +++ b/transport/internet/hysteria2/hysteria2.go @@ -7,12 +7,6 @@ import ( //go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen -// Here is some modification needs to be done before update quic vendor. -// * use bytespool in buffer_pool.go -// * set MaxReceivePacketSize to 1452 - 32 (16 bytes auth, 16 bytes head) -// -// - const ( protocolName = "hysteria2" internalDomain = "hysteria2.internal.v2fly.org" diff --git a/transport/internet/quic/config.pb.go b/transport/internet/quic/config.pb.go index d814ddcbbe..77d44ee36f 100644 --- a/transport/internet/quic/config.pb.go +++ b/transport/internet/quic/config.pb.go @@ -17,76 +17,20 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type Congestion struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - SendMbps uint64 `protobuf:"varint,2,opt,name=send_mbps,json=sendMbps,proto3" json:"send_mbps,omitempty"` -} - -func (x *Congestion) Reset() { - *x = Congestion{} - if protoimpl.UnsafeEnabled { - mi := &file_transport_internet_quic_config_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Congestion) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Congestion) ProtoMessage() {} - -func (x *Congestion) ProtoReflect() protoreflect.Message { - mi := &file_transport_internet_quic_config_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Congestion.ProtoReflect.Descriptor instead. -func (*Congestion) Descriptor() ([]byte, []int) { - return file_transport_internet_quic_config_proto_rawDescGZIP(), []int{0} -} - -func (x *Congestion) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *Congestion) GetSendMbps() uint64 { - if x != nil { - return x.SendMbps - } - return 0 -} - type Config struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Security *protocol.SecurityConfig `protobuf:"bytes,2,opt,name=security,proto3" json:"security,omitempty"` - Header *anypb.Any `protobuf:"bytes,3,opt,name=header,proto3" json:"header,omitempty"` - Congestion *Congestion `protobuf:"bytes,4,opt,name=congestion,proto3" json:"congestion,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Security *protocol.SecurityConfig `protobuf:"bytes,2,opt,name=security,proto3" json:"security,omitempty"` + Header *anypb.Any `protobuf:"bytes,3,opt,name=header,proto3" json:"header,omitempty"` } func (x *Config) Reset() { *x = Config{} if protoimpl.UnsafeEnabled { - mi := &file_transport_internet_quic_config_proto_msgTypes[1] + mi := &file_transport_internet_quic_config_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -99,7 +43,7 @@ func (x *Config) String() string { func (*Config) ProtoMessage() {} func (x *Config) ProtoReflect() protoreflect.Message { - mi := &file_transport_internet_quic_config_proto_msgTypes[1] + mi := &file_transport_internet_quic_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -112,7 +56,7 @@ func (x *Config) ProtoReflect() protoreflect.Message { // Deprecated: Use Config.ProtoReflect.Descriptor instead. func (*Config) Descriptor() ([]byte, []int) { - return file_transport_internet_quic_config_proto_rawDescGZIP(), []int{1} + return file_transport_internet_quic_config_proto_rawDescGZIP(), []int{0} } func (x *Config) GetKey() string { @@ -136,56 +80,40 @@ func (x *Config) GetHeader() *anypb.Any { return nil } -func (x *Config) GetCongestion() *Congestion { - if x != nil { - return x.Congestion - } - return nil -} - var File_transport_internet_quic_config_proto protoreflect.FileDescriptor var file_transport_internet_quic_config_proto_rawDesc = []byte{ 0x0a, 0x24, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x71, 0x75, 0x69, 0x63, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x27, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x22, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x1a, - 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3d, 0x0a, 0x0a, 0x43, - 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, - 0x09, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xfc, 0x01, 0x0a, 0x06, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, - 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, - 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, - 0x2c, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x53, 0x0a, - 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x33, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x2e, 0x43, 0x6f, 0x6e, 0x67, - 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, - 0x6f, 0x6e, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, - 0x6f, 0x72, 0x74, 0x12, 0x04, 0x71, 0x75, 0x69, 0x63, 0x42, 0x87, 0x01, 0x0a, 0x26, 0x63, 0x6f, - 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, - 0x71, 0x75, 0x69, 0x63, 0x50, 0x01, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, - 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x71, 0x75, 0x69, 0x63, 0xaa, 0x02, - 0x22, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x51, - 0x75, 0x69, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa7, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x06, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, + 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, + 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x04, 0x71, 0x75, 0x69, 0x63, + 0x42, 0x87, 0x01, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x50, 0x01, 0x5a, 0x36, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x2f, 0x71, 0x75, 0x69, 0x63, 0xaa, 0x02, 0x22, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, + 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x51, 0x75, 0x69, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -200,22 +128,20 @@ func file_transport_internet_quic_config_proto_rawDescGZIP() []byte { return file_transport_internet_quic_config_proto_rawDescData } -var file_transport_internet_quic_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_transport_internet_quic_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_transport_internet_quic_config_proto_goTypes = []interface{}{ - (*Congestion)(nil), // 0: v2ray.core.transport.internet.hysteria2.Congestion - (*Config)(nil), // 1: v2ray.core.transport.internet.hysteria2.Config - (*protocol.SecurityConfig)(nil), // 2: v2ray.core.common.protocol.SecurityConfig - (*anypb.Any)(nil), // 3: google.protobuf.Any + (*Config)(nil), // 0: v2ray.core.transport.internet.quic.Config + (*protocol.SecurityConfig)(nil), // 1: v2ray.core.common.protocol.SecurityConfig + (*anypb.Any)(nil), // 2: google.protobuf.Any } var file_transport_internet_quic_config_proto_depIdxs = []int32{ - 2, // 0: v2ray.core.transport.internet.hysteria2.Config.security:type_name -> v2ray.core.common.protocol.SecurityConfig - 3, // 1: v2ray.core.transport.internet.hysteria2.Config.header:type_name -> google.protobuf.Any - 0, // 2: v2ray.core.transport.internet.hysteria2.Config.congestion:type_name -> v2ray.core.transport.internet.hysteria2.Congestion - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 1, // 0: v2ray.core.transport.internet.quic.Config.security:type_name -> v2ray.core.common.protocol.SecurityConfig + 2, // 1: v2ray.core.transport.internet.quic.Config.header:type_name -> google.protobuf.Any + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_transport_internet_quic_config_proto_init() } @@ -225,18 +151,6 @@ func file_transport_internet_quic_config_proto_init() { } if !protoimpl.UnsafeEnabled { file_transport_internet_quic_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Congestion); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_transport_internet_quic_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Config); i { case 0: return &v.state @@ -255,7 +169,7 @@ func file_transport_internet_quic_config_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_transport_internet_quic_config_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 1, NumExtensions: 0, NumServices: 0, }, diff --git a/transport/internet/quic/config.proto b/transport/internet/quic/config.proto index 591535e220..256f8a583d 100644 --- a/transport/internet/quic/config.proto +++ b/transport/internet/quic/config.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package v2ray.core.transport.internet.hysteria2; +package v2ray.core.transport.internet.quic; option csharp_namespace = "V2Ray.Core.Transport.Internet.Quic"; option go_package = "github.com/v2fly/v2ray-core/v5/transport/internet/quic"; option java_package = "com.v2ray.core.transport.internet.quic"; @@ -11,12 +11,6 @@ import "common/protocol/headers.proto"; import "common/protoext/extensions.proto"; -message Congestion{ - string type = 1; - - uint64 send_mbps = 2; -} - message Config { option (v2ray.core.common.protoext.message_opt).type = "transport"; option (v2ray.core.common.protoext.message_opt).short_name = "quic"; @@ -24,5 +18,4 @@ message Config { string key = 1; v2ray.core.common.protocol.SecurityConfig security = 2; google.protobuf.Any header = 3; - Congestion congestion = 4; } From 3b0a885da720f1e362bd32785a1773ee25ff5253 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Thu, 7 Dec 2023 01:28:50 +0800 Subject: [PATCH 27/81] update test case --- main/distro/all/all.go | 2 + testing/scenarios/transport_test.go | 295 +--------------------- transport/internet/hysteria2/config.pb.go | 92 ++++--- transport/internet/hysteria2/config.proto | 5 +- transport/internet/hysteria2/hy2_test.go | 6 +- 5 files changed, 71 insertions(+), 329 deletions(-) diff --git a/main/distro/all/all.go b/main/distro/all/all.go index 200f122830..aa7748cb7f 100644 --- a/main/distro/all/all.go +++ b/main/distro/all/all.go @@ -78,6 +78,8 @@ import ( _ "github.com/v2fly/v2ray-core/v5/transport/internet/httpupgrade" + _ "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" + // Transport headers _ "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http" _ "github.com/v2fly/v2ray-core/v5/transport/internet/headers/noop" diff --git a/testing/scenarios/transport_test.go b/testing/scenarios/transport_test.go index 4f002cf9c3..99983fa214 100644 --- a/testing/scenarios/transport_test.go +++ b/testing/scenarios/transport_test.go @@ -29,6 +29,7 @@ import ( "github.com/v2fly/v2ray-core/v5/transport/internet/domainsocket" "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http" "github.com/v2fly/v2ray-core/v5/transport/internet/headers/wechat" + "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" "github.com/v2fly/v2ray-core/v5/transport/internet/quic" tcptransport "github.com/v2fly/v2ray-core/v5/transport/internet/tcp" ) @@ -384,7 +385,7 @@ func TestVMessQuic(t *testing.T) { } } -func TestVMessQuicBBR(t *testing.T) { +func TestVMessHysteria2(t *testing.T) { tcpServer := tcp.Server{ MsgProcessor: xor, } @@ -406,288 +407,16 @@ func TestVMessQuicBBR(t *testing.T) { PortRange: net.SinglePortRange(serverPort), Listen: net.NewIPOrDomain(net.LocalHostIP), StreamSettings: &internet.StreamConfig{ - ProtocolName: "quic", - TransportSettings: []*internet.TransportConfig{ - { - ProtocolName: "quic", - Settings: serial.ToTypedMessage(&quic.Config{ - Header: serial.ToTypedMessage(&wechat.VideoConfig{}), - Security: &protocol.SecurityConfig{ - Type: protocol.SecurityType_NONE, - }, - Congestion: &quic.Congestion{Type: "bbr"}, - }), - }, - }, - }, - }), - ProxySettings: serial.ToTypedMessage(&inbound.Config{ - User: []*protocol.User{ - { - Account: serial.ToTypedMessage(&vmess.Account{ - Id: userID.String(), - AlterId: 0, - }), - }, - }, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - ProxySettings: serial.ToTypedMessage(&freedom.Config{}), - }, - }, - } - - clientPort := tcp.PickPort() - clientConfig := &core.Config{ - App: []*anypb.Any{ - serial.ToTypedMessage(&log.Config{ - Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, - }), - }, - Inbound: []*core.InboundHandlerConfig{ - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: net.SinglePortRange(clientPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - }), - ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ - Address: net.NewIPOrDomain(dest.Address), - Port: uint32(dest.Port), - NetworkList: &net.NetworkList{ - Network: []net.Network{net.Network_TCP}, - }, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ - StreamSettings: &internet.StreamConfig{ - ProtocolName: "quic", - TransportSettings: []*internet.TransportConfig{ - { - ProtocolName: "quic", - Settings: serial.ToTypedMessage(&quic.Config{ - Header: serial.ToTypedMessage(&wechat.VideoConfig{}), - Security: &protocol.SecurityConfig{ - Type: protocol.SecurityType_NONE, - }, - Congestion: &quic.Congestion{Type: "bbr"}, - }), - }, - }, - }, - }), - ProxySettings: serial.ToTypedMessage(&outbound.Config{ - Receiver: []*protocol.ServerEndpoint{ - { - Address: net.NewIPOrDomain(net.LocalHostIP), - Port: uint32(serverPort), - User: []*protocol.User{ - { - Account: serial.ToTypedMessage(&vmess.Account{ - Id: userID.String(), - AlterId: 0, - SecuritySettings: &protocol.SecurityConfig{ - Type: protocol.SecurityType_AES128_GCM, - }, - }), - }, - }, - }, - }, - }), - }, - }, - } - - servers, err := InitializeServerConfigs(serverConfig, clientConfig) - if err != nil { - t.Fatal("Failed to initialize all servers: ", err.Error()) - } - defer CloseAllServers(servers) - - var errg errgroup.Group - for i := 0; i < 10; i++ { - errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) - } - - if err := errg.Wait(); err != nil { - t.Error(err) - } -} - -func TestVMessQuicBrutal(t *testing.T) { - tcpServer := tcp.Server{ - MsgProcessor: xor, - } - dest, err := tcpServer.Start() - common.Must(err) - defer tcpServer.Close() - - userID := protocol.NewID(uuid.New()) - serverPort := udp.PickPort() - serverConfig := &core.Config{ - App: []*anypb.Any{ - serial.ToTypedMessage(&log.Config{ - Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, - }), - }, - Inbound: []*core.InboundHandlerConfig{ - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: net.SinglePortRange(serverPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - StreamSettings: &internet.StreamConfig{ - ProtocolName: "quic", - TransportSettings: []*internet.TransportConfig{ - { - ProtocolName: "quic", - Settings: serial.ToTypedMessage(&quic.Config{ - Header: serial.ToTypedMessage(&wechat.VideoConfig{}), - Security: &protocol.SecurityConfig{ - Type: protocol.SecurityType_NONE, - }, - Congestion: &quic.Congestion{Type: "brutal", SendMbps: 300}, - }), - }, - }, - }, - }), - ProxySettings: serial.ToTypedMessage(&inbound.Config{ - User: []*protocol.User{ - { - Account: serial.ToTypedMessage(&vmess.Account{ - Id: userID.String(), - AlterId: 0, - }), - }, - }, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - ProxySettings: serial.ToTypedMessage(&freedom.Config{}), - }, - }, - } - - clientPort := tcp.PickPort() - clientConfig := &core.Config{ - App: []*anypb.Any{ - serial.ToTypedMessage(&log.Config{ - Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, - }), - }, - Inbound: []*core.InboundHandlerConfig{ - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: net.SinglePortRange(clientPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - }), - ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ - Address: net.NewIPOrDomain(dest.Address), - Port: uint32(dest.Port), - NetworkList: &net.NetworkList{ - Network: []net.Network{net.Network_TCP}, - }, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ - StreamSettings: &internet.StreamConfig{ - ProtocolName: "quic", + ProtocolName: "hysteria2", TransportSettings: []*internet.TransportConfig{ { - ProtocolName: "quic", - Settings: serial.ToTypedMessage(&quic.Config{ - Header: serial.ToTypedMessage(&wechat.VideoConfig{}), + ProtocolName: "hysteria2", + Settings: serial.ToTypedMessage(&hysteria2.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &quic.Congestion{Type: "brutal", SendMbps: 300}, - }), - }, - }, - }, - }), - ProxySettings: serial.ToTypedMessage(&outbound.Config{ - Receiver: []*protocol.ServerEndpoint{ - { - Address: net.NewIPOrDomain(net.LocalHostIP), - Port: uint32(serverPort), - User: []*protocol.User{ - { - Account: serial.ToTypedMessage(&vmess.Account{ - Id: userID.String(), - AlterId: 0, - SecuritySettings: &protocol.SecurityConfig{ - Type: protocol.SecurityType_AES128_GCM, - }, - }), - }, - }, - }, - }, - }), - }, - }, - } - - servers, err := InitializeServerConfigs(serverConfig, clientConfig) - if err != nil { - t.Fatal("Failed to initialize all servers: ", err.Error()) - } - defer CloseAllServers(servers) - - var errg errgroup.Group - for i := 0; i < 10; i++ { - errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) - } - - if err := errg.Wait(); err != nil { - t.Error(err) - } -} - -func TestVMessQuicBrutalBBR(t *testing.T) { - tcpServer := tcp.Server{ - MsgProcessor: xor, - } - dest, err := tcpServer.Start() - common.Must(err) - defer tcpServer.Close() - - userID := protocol.NewID(uuid.New()) - serverPort := udp.PickPort() - serverConfig := &core.Config{ - App: []*anypb.Any{ - serial.ToTypedMessage(&log.Config{ - Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, - }), - }, - Inbound: []*core.InboundHandlerConfig{ - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: net.SinglePortRange(serverPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - StreamSettings: &internet.StreamConfig{ - ProtocolName: "quic", - TransportSettings: []*internet.TransportConfig{ - { - ProtocolName: "quic", - Settings: serial.ToTypedMessage(&quic.Config{ - Header: serial.ToTypedMessage(&wechat.VideoConfig{}), - Security: &protocol.SecurityConfig{ - Type: protocol.SecurityType_NONE, - }, - Congestion: &quic.Congestion{Type: "bbr"}, + Congestion: &hysteria2.Congestion{Type: "bbr"}, + Password: "password", }), }, }, @@ -738,16 +467,16 @@ func TestVMessQuicBrutalBBR(t *testing.T) { { SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ StreamSettings: &internet.StreamConfig{ - ProtocolName: "quic", + ProtocolName: "hysteria2", TransportSettings: []*internet.TransportConfig{ { - ProtocolName: "quic", - Settings: serial.ToTypedMessage(&quic.Config{ - Header: serial.ToTypedMessage(&wechat.VideoConfig{}), + ProtocolName: "hysteria2", + Settings: serial.ToTypedMessage(&hysteria2.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &quic.Congestion{Type: "brutal", SendMbps: 300}, + Congestion: &hysteria2.Congestion{Type: "bbr"}, + Password: "password", }), }, }, diff --git a/transport/internet/hysteria2/config.pb.go b/transport/internet/hysteria2/config.pb.go index fe49641e0d..2692257720 100644 --- a/transport/internet/hysteria2/config.pb.go +++ b/transport/internet/hysteria2/config.pb.go @@ -22,7 +22,8 @@ type Congestion struct { unknownFields protoimpl.UnknownFields Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - SendMbps uint64 `protobuf:"varint,2,opt,name=send_mbps,json=sendMbps,proto3" json:"send_mbps,omitempty"` + UpMbps uint64 `protobuf:"varint,2,opt,name=up_mbps,json=upMbps,proto3" json:"up_mbps,omitempty"` + DownMbps uint64 `protobuf:"varint,3,opt,name=down_mbps,json=downMbps,proto3" json:"down_mbps,omitempty"` } func (x *Congestion) Reset() { @@ -64,9 +65,16 @@ func (x *Congestion) GetType() string { return "" } -func (x *Congestion) GetSendMbps() uint64 { +func (x *Congestion) GetUpMbps() uint64 { if x != nil { - return x.SendMbps + return x.UpMbps + } + return 0 +} + +func (x *Congestion) GetDownMbps() uint64 { + if x != nil { + return x.DownMbps } return 0 } @@ -147,42 +155,44 @@ var File_transport_internet_hysteria2_config_proto protoreflect.FileDescriptor var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ 0x0a, 0x29, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x2f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x22, 0x76, 0x32, 0x72, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x27, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x1a, - 0x1d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, - 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x3d, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x4d, 0x62, 0x70, 0x73, 0x22, - 0xea, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, - 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, - 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, - 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, - 0x72, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x12, 0x4e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, - 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x71, 0x75, 0x69, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, - 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x16, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, - 0x74, 0x12, 0x09, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x42, 0x96, 0x01, 0x0a, - 0x2b, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, + 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, + 0x72, 0x69, 0x61, 0x32, 0x1a, 0x1d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x56, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x70, 0x5f, 0x6d, 0x62, + 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x70, 0x4d, 0x62, 0x70, 0x73, + 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xef, 0x01, + 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, + 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, + 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, + 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x53, + 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x3b, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, - 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, 0x27, 0x56, 0x32, - 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x48, 0x79, 0x73, 0x74, - 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x2e, 0x43, 0x6f, 0x6e, + 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x16, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x70, 0x6f, 0x72, 0x74, 0x12, 0x09, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x42, + 0x96, 0x01, 0x0a, 0x2b, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, + 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, + 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, + 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, + 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x48, + 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -199,13 +209,13 @@ func file_transport_internet_hysteria2_config_proto_rawDescGZIP() []byte { var file_transport_internet_hysteria2_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_transport_internet_hysteria2_config_proto_goTypes = []interface{}{ - (*Congestion)(nil), // 0: v2ray.core.transport.internet.quic.Congestion - (*Config)(nil), // 1: v2ray.core.transport.internet.quic.Config + (*Congestion)(nil), // 0: v2ray.core.transport.internet.hysteria2.Congestion + (*Config)(nil), // 1: v2ray.core.transport.internet.hysteria2.Config (*protocol.SecurityConfig)(nil), // 2: v2ray.core.common.protocol.SecurityConfig } var file_transport_internet_hysteria2_config_proto_depIdxs = []int32{ - 2, // 0: v2ray.core.transport.internet.quic.Config.security:type_name -> v2ray.core.common.protocol.SecurityConfig - 0, // 1: v2ray.core.transport.internet.quic.Config.congestion:type_name -> v2ray.core.transport.internet.quic.Congestion + 2, // 0: v2ray.core.transport.internet.hysteria2.Config.security:type_name -> v2ray.core.common.protocol.SecurityConfig + 0, // 1: v2ray.core.transport.internet.hysteria2.Config.congestion:type_name -> v2ray.core.transport.internet.hysteria2.Congestion 2, // [2:2] is the sub-list for method output_type 2, // [2:2] is the sub-list for method input_type 2, // [2:2] is the sub-list for extension type_name diff --git a/transport/internet/hysteria2/config.proto b/transport/internet/hysteria2/config.proto index 2ef517e31a..535bba8ca4 100644 --- a/transport/internet/hysteria2/config.proto +++ b/transport/internet/hysteria2/config.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package v2ray.core.transport.internet.quic; +package v2ray.core.transport.internet.hysteria2; option csharp_namespace = "V2Ray.Core.Transport.Internet.Hysteria2"; option go_package = "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2"; option java_package = "com.v2ray.core.transport.internet.hysteria2"; @@ -13,7 +13,8 @@ import "common/protoext/extensions.proto"; message Congestion{ string type = 1; - uint64 send_mbps = 2; + uint64 up_mbps = 2; + uint64 down_mbps = 3; } message Config { diff --git a/transport/internet/hysteria2/hy2_test.go b/transport/internet/hysteria2/hy2_test.go index 9fb0bfcca1..73272c14bc 100644 --- a/transport/internet/hysteria2/hy2_test.go +++ b/transport/internet/hysteria2/hy2_test.go @@ -2,7 +2,6 @@ package hysteria2_test import ( "context" - "crypto/rand" "fmt" "testing" "time" @@ -48,6 +47,7 @@ func TestHTTP3Connection(t *testing.T) { fmt.Println(err) return } + fmt.Println(len(b.Bytes())) common.Must2(conn.Write(b.Bytes())) } }() @@ -71,15 +71,15 @@ func TestHTTP3Connection(t *testing.T) { common.Must(err) defer conn.Close() - const N = 1024 + const N = 1 b1 := make([]byte, N) - common.Must2(rand.Read(b1)) b2 := buf.New() common.Must2(conn.Write(b1)) b2.Clear() common.Must2(b2.ReadFullFrom(conn, N)) + fmt.Println(b2.Bytes()) if r := cmp.Diff(b2.Bytes(), b1); r != "" { t.Error(r) } From 32920f616050ff0a0fa51c721269df3ef77deb64 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Tue, 13 Feb 2024 20:00:29 +0800 Subject: [PATCH 28/81] test ok --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- transport/internet/hysteria2/conn.go | 12 ------------ transport/internet/hysteria2/dialer.go | 16 +++++++++++----- transport/internet/hysteria2/hub.go | 5 +---- transport/internet/hysteria2/hy2_test.go | 6 +++--- 6 files changed, 30 insertions(+), 39 deletions(-) diff --git a/go.mod b/go.mod index f7c9dfae94..8295f768c0 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/adrg/xdg v0.4.0 github.com/apernet/hysteria/core v1.3.5 - github.com/apernet/quic-go v0.39.4-0.20231029220436-0faa281e4a77 + github.com/apernet/quic-go v0.41.1-0.20240122005439-5bf4609c416f github.com/go-chi/chi/v5 v5.0.10 github.com/go-chi/render v1.0.3 github.com/go-playground/validator/v10 v10.16.0 @@ -32,11 +32,11 @@ require ( github.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432 go.starlark.net v0.0.0-20230612165344-9532f5667272 go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 - golang.org/x/crypto v0.16.0 + golang.org/x/crypto v0.17.0 golang.org/x/net v0.19.0 golang.org/x/sync v0.5.0 golang.org/x/sys v0.15.0 - google.golang.org/grpc v1.59.0 + google.golang.org/grpc v1.61.0 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 gvisor.dev/gvisor v0.0.0-20231020174304-b8a429915ff1 @@ -85,9 +85,9 @@ require ( golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect golang.org/x/mod v0.13.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/time v0.4.0 // indirect golang.org/x/tools v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect ) replace github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 => github.com/xiaokangwang/struc v0.0.0-20231031203518-0e381172f248 diff --git a/go.sum b/go.sum index fb4e2327df..c99047955f 100644 --- a/go.sum +++ b/go.sum @@ -25,8 +25,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/apernet/quic-go v0.39.4-0.20231029220436-0faa281e4a77 h1:X45zzYXs02HsYVCi6lQOs4sEvzmCXykxcVvAcQypIqM= -github.com/apernet/quic-go v0.39.4-0.20231029220436-0faa281e4a77/go.mod h1:UwsoszQlzTm+dBDuFEwWBYt46K56WqlFEN0RWLvQ0rE= +github.com/apernet/quic-go v0.41.1-0.20240122005439-5bf4609c416f h1:4jBGc3SlgQT8YFqHhfnK7EVFVY292CxagfNqfPiQZhY= +github.com/apernet/quic-go v0.41.1-0.20240122005439-5bf4609c416f/go.mod h1:4GInxO6ypy63J2NaO5rQx1wRp6K8YHI6zqLG+VswU6I= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -377,8 +377,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -503,8 +503,8 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY= +golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -554,15 +554,15 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= +google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index b0d500595c..38822d1bd5 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -5,7 +5,6 @@ import ( "time" "github.com/apernet/quic-go" - "github.com/apernet/quic-go/quicvarint" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" @@ -15,9 +14,6 @@ type interConn struct { stream quic.Stream local net.Addr remote net.Addr - - isClient bool - isWroteFrameType bool } const ( @@ -74,14 +70,6 @@ func (c *interConn) WriteMultiBuffer(mb buf.MultiBuffer) error { } func (c *interConn) Write(b []byte) (int, error) { - if c.isClient && !c.isWroteFrameType { - c.isWroteFrameType = true - frameSize := int(quicvarint.Len(FrameTypeTCPRequest)) - buf := make([]byte, frameSize+len(b)) - i := varintPut(buf, FrameTypeTCPRequest) - copy(buf[i:], b) - return c.stream.Write(buf) - } return c.stream.Write(b) } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 4607e376cb..0b85619523 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -4,6 +4,7 @@ import ( "context" hy "github.com/apernet/hysteria/core/client" + "github.com/apernet/quic-go/quicvarint" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/net" @@ -57,7 +58,7 @@ func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConf } config := streamSettings.ProtocolSettings.(*Config) - client, err := hy.NewClient(&hy.Config{ + client, _, err := hy.NewClient(&hy.Config{ TLSConfig: *tlsConfig, Auth: config.GetPassword(), ServerAddr: serverAddr, @@ -88,11 +89,16 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me quicConn := client.GetQuicConn() internetConn := &interConn{ - stream: stream, - local: quicConn.LocalAddr(), - remote: quicConn.RemoteAddr(), - isClient: true, + stream: stream, + local: quicConn.LocalAddr(), + remote: quicConn.RemoteAddr(), } + + // write frame type + frameSize := int(quicvarint.Len(FrameTypeTCPRequest)) + buf := make([]byte, frameSize) + varintPut(buf, FrameTypeTCPRequest) + stream.Write(buf) return internetConn, nil } diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 6f255e4090..b11cbd2f6b 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -32,10 +32,7 @@ func (l *Listener) Close() error { } func (l *Listener) ProxyStreamHijacker(ft http3.FrameType, conn quic.Connection, stream quic.Stream, err error) (bool, error) { - if err != nil { - l.Close() - return false, err - } + // err always == nil internetConn := &interConn{ stream: stream, diff --git a/transport/internet/hysteria2/hy2_test.go b/transport/internet/hysteria2/hy2_test.go index 73272c14bc..05def44b68 100644 --- a/transport/internet/hysteria2/hy2_test.go +++ b/transport/internet/hysteria2/hy2_test.go @@ -2,6 +2,7 @@ package hysteria2_test import ( "context" + "crypto/rand" "fmt" "testing" "time" @@ -47,7 +48,6 @@ func TestHTTP3Connection(t *testing.T) { fmt.Println(err) return } - fmt.Println(len(b.Bytes())) common.Must2(conn.Write(b.Bytes())) } }() @@ -71,15 +71,15 @@ func TestHTTP3Connection(t *testing.T) { common.Must(err) defer conn.Close() - const N = 1 + const N = 1000 b1 := make([]byte, N) + common.Must2(rand.Read(b1)) b2 := buf.New() common.Must2(conn.Write(b1)) b2.Clear() common.Must2(b2.ReadFullFrom(conn, N)) - fmt.Println(b2.Bytes()) if r := cmp.Diff(b2.Bytes(), b1); r != "" { t.Error(r) } From 10b1aeef580f1767030fa976cf369c00b026b94a Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Tue, 13 Feb 2024 21:37:10 +0800 Subject: [PATCH 29/81] run with v5 config --- release/config/hysteria2_test.json5 | 62 ++++++++++ testing/scenarios/transport_test.go | 138 +++++++++++++++++++++- transport/internet/hysteria2/config.proto | 1 + transport/internet/hysteria2/dialer.go | 10 +- transport/internet/hysteria2/hub.go | 16 ++- 5 files changed, 220 insertions(+), 7 deletions(-) create mode 100644 release/config/hysteria2_test.json5 diff --git a/release/config/hysteria2_test.json5 b/release/config/hysteria2_test.json5 new file mode 100644 index 0000000000..ca1cf243ad --- /dev/null +++ b/release/config/hysteria2_test.json5 @@ -0,0 +1,62 @@ +{ + "log": { + "access":{"level": "Debug"} + }, + "inbounds": [{ + "port": 1080, + "listen": "127.0.0.1", + "tag": "http", + "protocol": "http" + }, { + "port": 1280, + "listen": "127.0.0.1", + "tag": "hy2_in", + "protocol": "vmess", + "settings": { + "users": ["23ad6b10-8d1a-40f7-8ad0-e3e35cd38297"] + }, + "streamSettings": { + "transport": "hysteria2", + "transportSettings": { + "congestion": { + "type": "bbr" + } + }, + "security": "tls" + } + }], + "outbounds": [{ + "protocol": "freedom", + "tag": "direct" + }, { + "tag": "hy2_out", + "protocol": "vmess", + "settings": { + "address": "127.0.0.1", + "port": 1280, + "uuid": "23ad6b10-8d1a-40f7-8ad0-e3e35cd38297" + }, + "streamSettings": { + "transport": "hysteria2", + "transportSettings": { + "congestion": { + "type": "bbr" + } + }, + "security": "tls" + } + }], + "routing": { + "rules": [{ + "type": "field", + "outboundTag": "direct", + "inboundTag": ["hy2_in"] + }, + { + "type": "field", + "outboundTag": "hy2_out", + "inboundTag": ["http"] + } + ] + } +} diff --git a/testing/scenarios/transport_test.go b/testing/scenarios/transport_test.go index 99983fa214..1fd104779b 100644 --- a/testing/scenarios/transport_test.go +++ b/testing/scenarios/transport_test.go @@ -385,7 +385,7 @@ func TestVMessQuic(t *testing.T) { } } -func TestVMessHysteria2(t *testing.T) { +func TestVMessHysteria2BBR(t *testing.T) { tcpServer := tcp.Server{ MsgProcessor: xor, } @@ -520,3 +520,139 @@ func TestVMessHysteria2(t *testing.T) { t.Error(err) } } + +func TestVMessHysteria2Brutal(t *testing.T) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() + + userID := protocol.NewID(uuid.New()) + serverPort := udp.PickPort() + serverConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(serverPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ + ProtocolName: "hysteria2", + TransportSettings: []*internet.TransportConfig{ + { + ProtocolName: "hysteria2", + Settings: serial.ToTypedMessage(&hysteria2.Config{ + Security: &protocol.SecurityConfig{ + Type: protocol.SecurityType_NONE, + }, + Congestion: &hysteria2.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, + Password: "password", + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&inbound.Config{ + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + AlterId: 0, + }), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(clientPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ + StreamSettings: &internet.StreamConfig{ + ProtocolName: "hysteria2", + TransportSettings: []*internet.TransportConfig{ + { + ProtocolName: "hysteria2", + Settings: serial.ToTypedMessage(&hysteria2.Config{ + Security: &protocol.SecurityConfig{ + Type: protocol.SecurityType_NONE, + }, + Congestion: &hysteria2.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, + Password: "password", + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&outbound.Config{ + Receiver: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + AlterId: 0, + SecuritySettings: &protocol.SecurityConfig{ + Type: protocol.SecurityType_AES128_GCM, + }, + }), + }, + }, + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + if err != nil { + t.Fatal("Failed to initialize all servers: ", err.Error()) + } + defer CloseAllServers(servers) + + var errg errgroup.Group + for i := 0; i < 10; i++ { + errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) + } + + if err := errg.Wait(); err != nil { + t.Error(err) + } +} diff --git a/transport/internet/hysteria2/config.proto b/transport/internet/hysteria2/config.proto index 535bba8ca4..dc61f30286 100644 --- a/transport/internet/hysteria2/config.proto +++ b/transport/internet/hysteria2/config.proto @@ -25,4 +25,5 @@ message Config { v2ray.core.common.protocol.SecurityConfig security = 2; string password = 3; Congestion congestion = 4; + bool ignore_client_bandwidth = 5; } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 0b85619523..2042df4fa3 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -15,16 +15,16 @@ import ( var RunningClient map[net.Destination](hy.Client) func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hy.TLSConfig, error) { - tlsConfig := tls.ConfigFromStreamSettings(streamSettings) - if tlsConfig == nil { - tlsConfig = &tls.Config{ + tlsSetting := CheckTLSConfig(streamSettings, true) + if tlsSetting == nil { + tlsSetting = &tls.Config{ ServerName: internalDomain, AllowInsecure: true, } } res := &hy.TLSConfig{ - ServerName: tlsConfig.ServerName, - InsecureSkipVerify: tlsConfig.AllowInsecure, + ServerName: tlsSetting.ServerName, + InsecureSkipVerify: tlsSetting.AllowInsecure, } return res, nil } diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index b11cbd2f6b..5bea11c7b6 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -70,14 +70,28 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti Authenticator: &Authenticator{Password: config.GetPassword()}, StreamHijacker: listener.ProxyStreamHijacker, // acceptStreams }) + if err != nil { + return nil, err + } listener.hyServer = hyServer go hyServer.Serve() return listener, nil } +func CheckTLSConfig(streamSettings *internet.MemoryStreamConfig, isClient bool) *tls.Config { + if streamSettings == nil || streamSettings.SecuritySettings == nil { + return nil + } + tlsSetting := streamSettings.SecuritySettings.(*tls.Config) + if tlsSetting.ServerName == "" || (len(tlsSetting.Certificate) == 0 && !isClient) { + return nil + } + return tlsSetting +} + func GetTLSConfig(streamSettings *internet.MemoryStreamConfig) *hy.TLSConfig { - tlsSetting := tls.ConfigFromStreamSettings(streamSettings) + tlsSetting := CheckTLSConfig(streamSettings, false) if tlsSetting == nil { tlsSetting = &tls.Config{ Certificate: []*tls.Certificate{ From 8e794b2340222b743f12e918bf0b2ce142204ac2 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Tue, 13 Feb 2024 22:32:33 +0800 Subject: [PATCH 30/81] add to v4 --- infra/conf/v4/transport_internet.go | 35 ++++++++++++++++ release/config/hysteria2_test_v4.json | 60 +++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 release/config/hysteria2_test_v4.json diff --git a/infra/conf/v4/transport_internet.go b/infra/conf/v4/transport_internet.go index 1a18a45d73..09d1562ba3 100644 --- a/infra/conf/v4/transport_internet.go +++ b/infra/conf/v4/transport_internet.go @@ -16,6 +16,7 @@ import ( "github.com/v2fly/v2ray-core/v5/transport/internet/domainsocket" httpheader "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http" "github.com/v2fly/v2ray-core/v5/transport/internet/http" + "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" "github.com/v2fly/v2ray-core/v5/transport/internet/kcp" "github.com/v2fly/v2ray-core/v5/transport/internet/quic" "github.com/v2fly/v2ray-core/v5/transport/internet/tcp" @@ -137,6 +138,27 @@ func (c *TCPConfig) Build() (proto.Message, error) { return config, nil } +type Hy2ConfigCongestion struct { + Type string `json:"type"` + UpMbps uint64 `json:"up_mbps"` + DownMbps uint64 `json:"down_mbps"` +} + +type Hy2Config struct { + Password string `json:"password"` + Congestion Hy2ConfigCongestion `json:"congestion"` +} + +// Build implements Buildable. +func (c *Hy2Config) Build() (proto.Message, error) { + return &hysteria2.Config{Password: c.Password, + Congestion: &hysteria2.Congestion{ + Type: c.Congestion.Type, + DownMbps: c.Congestion.DownMbps, + UpMbps: c.Congestion.UpMbps, + }}, nil +} + type WebSocketConfig struct { Path string `json:"path"` Headers map[string]string `json:"headers"` @@ -279,6 +301,8 @@ func (p TransportProtocol) Build() (string, error) { return "quic", nil case "gun", "grpc": return "gun", nil + case "hy2", "hysteria2": + return "hysteria2", nil default: return "", newError("Config: unknown transport protocol: ", p) } @@ -296,6 +320,7 @@ type StreamConfig struct { QUICSettings *QUICConfig `json:"quicSettings"` GunSettings *GunConfig `json:"gunSettings"` GRPCSettings *GunConfig `json:"grpcSettings"` + Hy2Settings *Hy2Config `json:"hy2Settings"` SocketSettings *socketcfg.SocketConfig `json:"sockopt"` } @@ -397,6 +422,16 @@ func (c *StreamConfig) Build() (*internet.StreamConfig, error) { Settings: serial.ToTypedMessage(gs), }) } + if c.Hy2Settings != nil { + hy2, err := c.Hy2Settings.Build() + if err != nil { + return nil, newError("Failed to build hy2 config.").Base(err) + } + config.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{ + ProtocolName: "hysteria2", + Settings: serial.ToTypedMessage(hy2), + }) + } if c.SocketSettings != nil { ss, err := c.SocketSettings.Build() if err != nil { diff --git a/release/config/hysteria2_test_v4.json b/release/config/hysteria2_test_v4.json new file mode 100644 index 0000000000..47d373c642 --- /dev/null +++ b/release/config/hysteria2_test_v4.json @@ -0,0 +1,60 @@ +{ + "log": { + "loglevel": "debug" + }, + "inbounds": [{ + "port": 1080, + "listen": "127.0.0.1", + "tag": "http", + "protocol": "http" + }, { + "port": 1280, + "listen": "127.0.0.1", + "tag": "hy2_in", + "protocol": "vmess", + "settings": { + "clients": [{ + "id": "23ad6b10-8d1a-40f7-8ad0-e3e35cd38297", + "alterId": 0 + }] + }, + "streamSettings": { + "network": "hysteria2", + "security": "tls" + } + }], + "outbounds": [{ + "protocol": "freedom", + "tag": "direct" + }, { + "tag": "hy2_out", + "protocol": "vmess", + "settings": { + "vnext": [{ + "address": "127.0.0.1", + "port": 1280, + "users": [{ + "id": "23ad6b10-8d1a-40f7-8ad0-e3e35cd38297", + "security": "auto" + }] + }] + }, + "streamSettings": { + "network": "hysteria2", + "security": "tls" + } + }], + "routing": { + "rules": [{ + "type": "field", + "outboundTag": "direct", + "inboundTag": ["hy2_in"] + }, + { + "type": "field", + "outboundTag": "hy2_out", + "inboundTag": ["http"] + } + ] + } +} From 9f266344ac84c83435df84579dd6ed3e43613695 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Wed, 14 Feb 2024 02:30:58 +0800 Subject: [PATCH 31/81] add hysteria2 tcp --- proxy/hysteria2/client.go | 55 ++--------- proxy/hysteria2/config.proto | 3 +- proxy/hysteria2/{trojan.go => hysteria2.go} | 0 proxy/hysteria2/protocol.go | 45 ++++----- testing/scenarios/hysteria2_test.go | 103 ++++++++++++++++++++ transport/internet/hysteria2/conn.go | 4 +- transport/internet/hysteria2/dialer.go | 2 +- 7 files changed, 134 insertions(+), 78 deletions(-) rename proxy/hysteria2/{trojan.go => hysteria2.go} (100%) create mode 100644 testing/scenarios/hysteria2_test.go diff --git a/proxy/hysteria2/client.go b/proxy/hysteria2/client.go index a2612d0ad4..9f041764f5 100644 --- a/proxy/hysteria2/client.go +++ b/proxy/hysteria2/client.go @@ -3,11 +3,11 @@ package hysteria2 import ( "context" + hyProtocol "github.com/apernet/hysteria/core/international/protocol" core "github.com/v2fly/v2ray-core/v5" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" - "github.com/v2fly/v2ray-core/v5/common/net/packetaddr" "github.com/v2fly/v2ray-core/v5/common/protocol" "github.com/v2fly/v2ray-core/v5/common/retry" "github.com/v2fly/v2ray-core/v5/common/session" @@ -17,7 +17,6 @@ import ( "github.com/v2fly/v2ray-core/v5/proxy" "github.com/v2fly/v2ray-core/v5/transport" "github.com/v2fly/v2ray-core/v5/transport/internet" - "github.com/v2fly/v2ray-core/v5/transport/internet/udp" ) // Client is an inbound handler for trojan protocol @@ -87,51 +86,6 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter ctx, cancel := context.WithCancel(ctx) timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) - if packetConn, err := packetaddr.ToPacketAddrConn(link, destination); err == nil { - postRequest := func() error { - defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) - - var buffer [2048]byte - n, addr, err := packetConn.ReadFrom(buffer[:]) - if err != nil { - return newError("failed to read a packet").Base(err) - } - dest := net.DestinationFromAddr(addr) - - bufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn)) - connWriter := &ConnWriter{Writer: bufferWriter, Target: dest, Account: account} - packetWriter := &PacketWriter{Writer: connWriter, Target: dest} - - // write some request payload to buffer - if _, err := packetWriter.WriteTo(buffer[:n], addr); err != nil { - return newError("failed to write a request payload").Base(err) - } - - // Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer - if err = bufferWriter.SetBuffered(false); err != nil { - return newError("failed to flush payload").Base(err).AtWarning() - } - - return udp.CopyPacketConn(packetWriter, packetConn, udp.UpdateActivity(timer)) - } - - getResponse := func() error { - defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) - - packetReader := &PacketReader{Reader: conn} - packetConnectionReader := &PacketConnectionReader{reader: packetReader} - - return udp.CopyPacketConn(packetConn, packetConnectionReader, udp.UpdateActivity(timer)) - } - - responseDoneAndCloseWriter := task.OnSuccess(getResponse, task.Close(link.Writer)) - if err := task.Run(ctx, postRequest, responseDoneAndCloseWriter); err != nil { - return newError("connection ends").Base(err) - } - - return nil - } - postRequest := func() error { defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) @@ -178,6 +132,13 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter Reader: conn, } } else { + ok, msg, err := hyProtocol.ReadTCPResponse(conn) + if err != nil { + return err + } + if !ok { + return newError(msg) + } reader = buf.NewReader(conn) } return buf.Copy(reader, link.Writer, buf.UpdateActivity(timer)) diff --git a/proxy/hysteria2/config.proto b/proxy/hysteria2/config.proto index 9e445f2743..2ef7824687 100644 --- a/proxy/hysteria2/config.proto +++ b/proxy/hysteria2/config.proto @@ -15,8 +15,7 @@ message OBFS { } message Account { - string password = 1; - OBFS obfs = 2; + OBFS obfs = 1; } message ClientConfig { diff --git a/proxy/hysteria2/trojan.go b/proxy/hysteria2/hysteria2.go similarity index 100% rename from proxy/hysteria2/trojan.go rename to proxy/hysteria2/hysteria2.go diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index 8f9438ee45..2a6cf0b078 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -5,9 +5,11 @@ import ( "io" gonet "net" + "github.com/apernet/quic-go/quicvarint" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/protocol" + "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" ) var ( @@ -68,36 +70,27 @@ func (c *ConnWriter) WriteHeader() error { return nil } -func (c *ConnWriter) writeHeader() error { - buffer := buf.StackNew() - defer buffer.Release() - - command := commandTCP - if c.Target.Network == net.Network_UDP { - command = commandUDP - } - - if _, err := buffer.Write(c.Account.Key); err != nil { - return err - } - if _, err := buffer.Write(crlf); err != nil { - return err - } - if err := buffer.WriteByte(command); err != nil { - return err - } - if err := addrParser.WriteAddressPort(&buffer, c.Target.Address, c.Target.Port); err != nil { - return err - } - if _, err := buffer.Write(crlf); err != nil { - return err - } +func QuicLen(s int) int { + return int(quicvarint.Len(uint64(s))) +} - _, err := c.Writer.Write(buffer.Bytes()) +func (c *ConnWriter) writeHeader() error { + padding := "Jimmy Was Here" + paddingLen := len(padding) + addressAndPort := c.Target.Address.String() + ":" + c.Target.Port.String() + addressLen := len(addressAndPort) + size := QuicLen(addressLen) + addressLen + QuicLen(paddingLen) + paddingLen + + buf := make([]byte, size) + i := hysteria2.VarintPut(buf, uint64(addressLen)) + i += copy(buf[i:], addressAndPort) + i += hysteria2.VarintPut(buf[i:], uint64(paddingLen)) + copy(buf[i:], padding) + + _, err := c.Writer.Write(buf) if err == nil { c.headerSent = true } - return err } diff --git a/testing/scenarios/hysteria2_test.go b/testing/scenarios/hysteria2_test.go new file mode 100644 index 0000000000..254c82c4f2 --- /dev/null +++ b/testing/scenarios/hysteria2_test.go @@ -0,0 +1,103 @@ +package scenarios + +import ( + "testing" + "time" + + "golang.org/x/sync/errgroup" + + core "github.com/v2fly/v2ray-core/v5" + "github.com/v2fly/v2ray-core/v5/app/proxyman" + "github.com/v2fly/v2ray-core/v5/common" + "github.com/v2fly/v2ray-core/v5/common/net" + "github.com/v2fly/v2ray-core/v5/common/protocol" + "github.com/v2fly/v2ray-core/v5/common/serial" + "github.com/v2fly/v2ray-core/v5/proxy/dokodemo" + "github.com/v2fly/v2ray-core/v5/proxy/freedom" + "github.com/v2fly/v2ray-core/v5/proxy/shadowsocks" + "github.com/v2fly/v2ray-core/v5/testing/servers/tcp" +) + +func TestHysteria2(t *testing.T) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() + + account := serial.ToTypedMessage(&shadowsocks.Account{ + Password: "shadowsocks-password", + CipherType: shadowsocks.CipherType_CHACHA20_POLY1305, + }) + + serverPort := tcp.PickPort() + serverConfig := &core.Config{ + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(serverPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&shadowsocks.ServerConfig{ + User: &protocol.User{ + Account: account, + Level: 1, + }, + Network: []net.Network{net.Network_TCP}, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(clientPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + Networks: []net.Network{net.Network_TCP}, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{ + Server: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: account, + }, + }, + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + common.Must(err) + defer CloseAllServers(servers) + + var errGroup errgroup.Group + for i := 0; i < 10; i++ { + errGroup.Go(testTCPConn(clientPort, 10240*1024, time.Second*20)) + } + if err := errGroup.Wait(); err != nil { + t.Error(err) + } +} diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index 38822d1bd5..f61a97528e 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -25,9 +25,9 @@ const ( maxVarInt8 = 4611686018427387903 ) -// varintPut is like quicvarint.Append, but instead of appending to a slice, +// VarintPut is like quicvarint.Append, but instead of appending to a slice, // it writes to a fixed-size buffer. Returns the number of bytes written. -func varintPut(b []byte, i uint64) int { +func VarintPut(b []byte, i uint64) int { if i <= maxVarInt1 { b[0] = uint8(i) return 1 diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 2042df4fa3..8ab6f441cd 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -97,7 +97,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me // write frame type frameSize := int(quicvarint.Len(FrameTypeTCPRequest)) buf := make([]byte, frameSize) - varintPut(buf, FrameTypeTCPRequest) + VarintPut(buf, FrameTypeTCPRequest) stream.Write(buf) return internetConn, nil } From 750a0e300a56cee25df5364b58029cb185072b32 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Wed, 14 Feb 2024 04:02:16 +0800 Subject: [PATCH 32/81] update test --- config.pb.go | 2 +- proxy/hysteria2/config.go | 7 +- proxy/hysteria2/config.pb.go | 56 +++---- proxy/hysteria2/server.go | 188 +--------------------- testing/scenarios/hysteria2_test.go | 103 ------------ testing/scenarios/transport_test.go | 38 +++-- transport/internet/hysteria2/config.pb.go | 46 ++++-- 7 files changed, 77 insertions(+), 363 deletions(-) delete mode 100644 testing/scenarios/hysteria2_test.go diff --git a/config.pb.go b/config.pb.go index dd80bf4d55..1a1cfefcb3 100644 --- a/config.pb.go +++ b/config.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.31.0 -// protoc v4.24.4 +// protoc v4.24.3 // source: config.proto package core diff --git a/proxy/hysteria2/config.go b/proxy/hysteria2/config.go index af06745ea6..924e992529 100644 --- a/proxy/hysteria2/config.go +++ b/proxy/hysteria2/config.go @@ -17,12 +17,7 @@ type MemoryAccount struct { // AsAccount implements protocol.AsAccount. func (a *Account) AsAccount() (protocol.Account, error) { - password := a.GetPassword() - key := hexSha224(password) - return &MemoryAccount{ - Password: password, - Key: key, - }, nil + return &MemoryAccount{}, nil } // Equals implements protocol.Account.Equals(). diff --git a/proxy/hysteria2/config.pb.go b/proxy/hysteria2/config.pb.go index c28088de41..707b0b3dee 100644 --- a/proxy/hysteria2/config.pb.go +++ b/proxy/hysteria2/config.pb.go @@ -75,8 +75,7 @@ type Account struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Password string `protobuf:"bytes,1,opt,name=password,proto3" json:"password,omitempty"` - Obfs *OBFS `protobuf:"bytes,2,opt,name=obfs,proto3" json:"obfs,omitempty"` + Obfs *OBFS `protobuf:"bytes,1,opt,name=obfs,proto3" json:"obfs,omitempty"` } func (x *Account) Reset() { @@ -111,13 +110,6 @@ func (*Account) Descriptor() ([]byte, []int) { return file_proxy_hysteria2_config_proto_rawDescGZIP(), []int{1} } -func (x *Account) GetPassword() string { - if x != nil { - return x.Password - } - return "" -} - func (x *Account) GetObfs() *OBFS { if x != nil { return x.Obfs @@ -233,30 +225,28 @@ var file_proxy_hysteria2_config_proto_rawDesc = []byte{ 0x53, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x22, 0x5b, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x34, 0x0a, 0x04, 0x6f, 0x62, 0x66, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, - 0x69, 0x61, 0x32, 0x2e, 0x4f, 0x42, 0x46, 0x53, 0x52, 0x04, 0x6f, 0x62, 0x66, 0x73, 0x22, 0x52, - 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, - 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, - 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x22, 0x46, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x36, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x42, 0x6f, 0x0a, 0x1e, 0x63, 0x6f, - 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x2e, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, - 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, - 0x1a, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, - 0x79, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x64, 0x22, 0x3f, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x04, + 0x6f, 0x62, 0x66, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x32, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x68, 0x79, + 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x2e, 0x4f, 0x42, 0x46, 0x53, 0x52, 0x04, 0x6f, 0x62, + 0x66, 0x73, 0x22, 0x52, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x42, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x46, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x42, 0x6f, + 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, + 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, + 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, + 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, + 0x61, 0x32, 0xaa, 0x02, 0x1a, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, + 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index 671a33d156..536fe171cf 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -3,7 +3,6 @@ package hysteria2 import ( "context" "io" - "strconv" "time" core "github.com/v2fly/v2ray-core/v5" @@ -15,14 +14,12 @@ import ( "github.com/v2fly/v2ray-core/v5/common/net/packetaddr" "github.com/v2fly/v2ray-core/v5/common/protocol" udp_proto "github.com/v2fly/v2ray-core/v5/common/protocol/udp" - "github.com/v2fly/v2ray-core/v5/common/retry" "github.com/v2fly/v2ray-core/v5/common/session" "github.com/v2fly/v2ray-core/v5/common/signal" "github.com/v2fly/v2ray-core/v5/common/task" "github.com/v2fly/v2ray-core/v5/features/policy" "github.com/v2fly/v2ray-core/v5/features/routing" "github.com/v2fly/v2ray-core/v5/transport/internet" - "github.com/v2fly/v2ray-core/v5/transport/internet/tls" "github.com/v2fly/v2ray-core/v5/transport/internet/udp" ) @@ -36,7 +33,6 @@ func init() { type Server struct { policyManager policy.Manager validator *Validator - fallbacks map[string]map[string]*Fallback // or nil packetEncoding packetaddr.PacketAddrType } @@ -56,30 +52,8 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { v := core.MustFromContext(ctx) server := &Server{ - policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), - validator: validator, - packetEncoding: config.PacketEncoding, - } - - if config.Fallbacks != nil { - server.fallbacks = make(map[string]map[string]*Fallback) - for _, fb := range config.Fallbacks { - if server.fallbacks[fb.Alpn] == nil { - server.fallbacks[fb.Alpn] = make(map[string]*Fallback) - } - server.fallbacks[fb.Alpn][fb.Path] = fb - } - if server.fallbacks[""] != nil { - for alpn, pfb := range server.fallbacks { - if alpn != "" { // && alpn != "h2" { - for path, fb := range server.fallbacks[""] { - if pfb[path] == nil { - pfb[path] = fb - } - } - } - } - } + policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), + validator: validator, } return server, nil @@ -130,10 +104,6 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet var user *protocol.MemoryUser - apfb := s.fallbacks - isfb := apfb != nil - - shouldFallback := false if firstLen < 58 || first.Byte(56) != '\r' { // invalid protocol err = newError("not trojan protocol") @@ -144,7 +114,6 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet Reason: err, }) - shouldFallback = true } else { user = s.validator.Get(hexString(first.BytesTo(56))) if user == nil { @@ -157,16 +126,9 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet Reason: err, }) - shouldFallback = true } } - if isfb && shouldFallback { - return s.fallback(ctx, sid, err, sessionPolicy, conn, iConn, apfb, first, firstLen, bufferedReader) - } else if shouldFallback { - return newError("invalid protocol or invalid user") - } - clientReader := &ConnReader{Reader: bufferedReader} if err := clientReader.ParseHeader(); err != nil { log.Record(&log.AccessMessage{ @@ -294,149 +256,3 @@ func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Sess return nil } - -func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err error, sessionPolicy policy.Session, connection internet.Connection, iConn internet.Connection, apfb map[string]map[string]*Fallback, first *buf.Buffer, firstLen int64, reader buf.Reader) error { - if err := connection.SetReadDeadline(time.Time{}); err != nil { - newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid) - } - newError("fallback starts").Base(err).AtInfo().WriteToLog(sid) - - alpn := "" - if len(apfb) > 1 || apfb[""] == nil { - if tlsConn, ok := iConn.(*tls.Conn); ok { - alpn = tlsConn.ConnectionState().NegotiatedProtocol - newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid) - } - if apfb[alpn] == nil { - alpn = "" - } - } - pfb := apfb[alpn] - if pfb == nil { - return newError(`failed to find the default "alpn" config`).AtWarning() - } - - path := "" - if len(pfb) > 1 || pfb[""] == nil { - if firstLen >= 18 && first.Byte(4) != '*' { // not h2c - firstBytes := first.Bytes() - for i := 4; i <= 8; i++ { // 5 -> 9 - if firstBytes[i] == '/' && firstBytes[i-1] == ' ' { - search := len(firstBytes) - if search > 64 { - search = 64 // up to about 60 - } - for j := i + 1; j < search; j++ { - k := firstBytes[j] - if k == '\r' || k == '\n' { // avoid logging \r or \n - break - } - if k == ' ' { - path = string(firstBytes[i:j]) - newError("realPath = " + path).AtInfo().WriteToLog(sid) - if pfb[path] == nil { - path = "" - } - break - } - } - break - } - } - } - } - fb := pfb[path] - if fb == nil { - return newError(`failed to find the default "path" config`).AtWarning() - } - - ctx, cancel := context.WithCancel(ctx) - timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) - ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) - - var conn net.Conn - if err := retry.ExponentialBackoff(5, 100).On(func() error { - var dialer net.Dialer - conn, err = dialer.DialContext(ctx, fb.Type, fb.Dest) - if err != nil { - return err - } - return nil - }); err != nil { - return newError("failed to dial to " + fb.Dest).Base(err).AtWarning() - } - defer conn.Close() - - serverReader := buf.NewReader(conn) - serverWriter := buf.NewWriter(conn) - - postRequest := func() error { - defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) - if fb.Xver != 0 { - remoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String()) - if err != nil { - return err - } - localAddr, localPort, err := net.SplitHostPort(connection.LocalAddr().String()) - if err != nil { - return err - } - ipv4 := true - for i := 0; i < len(remoteAddr); i++ { - if remoteAddr[i] == ':' { - ipv4 = false - break - } - } - pro := buf.New() - defer pro.Release() - switch fb.Xver { - case 1: - if ipv4 { - common.Must2(pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))) - } else { - common.Must2(pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))) - } - case 2: - common.Must2(pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x21"))) // signature + v2 + PROXY - if ipv4 { - common.Must2(pro.Write([]byte("\x11\x00\x0C"))) // AF_INET + STREAM + 12 bytes - common.Must2(pro.Write(net.ParseIP(remoteAddr).To4())) - common.Must2(pro.Write(net.ParseIP(localAddr).To4())) - } else { - common.Must2(pro.Write([]byte("\x21\x00\x24"))) // AF_INET6 + STREAM + 36 bytes - common.Must2(pro.Write(net.ParseIP(remoteAddr).To16())) - common.Must2(pro.Write(net.ParseIP(localAddr).To16())) - } - p1, _ := strconv.ParseUint(remotePort, 10, 16) - p2, _ := strconv.ParseUint(localPort, 10, 16) - common.Must2(pro.Write([]byte{byte(p1 >> 8), byte(p1), byte(p2 >> 8), byte(p2)})) - } - if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil { - return newError("failed to set PROXY protocol v", fb.Xver).Base(err).AtWarning() - } - } - if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil { - return newError("failed to fallback request payload").Base(err).AtInfo() - } - return nil - } - - writer := buf.NewWriter(connection) - - getResponse := func() error { - defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) - if err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil { - return newError("failed to deliver response payload").Base(err).AtInfo() - } - return nil - } - - if err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), task.OnSuccess(getResponse, task.Close(writer))); err != nil { - common.Must(common.Interrupt(serverReader)) - common.Must(common.Interrupt(serverWriter)) - return newError("fallback ends").Base(err).AtInfo() - } - - return nil -} diff --git a/testing/scenarios/hysteria2_test.go b/testing/scenarios/hysteria2_test.go deleted file mode 100644 index 254c82c4f2..0000000000 --- a/testing/scenarios/hysteria2_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package scenarios - -import ( - "testing" - "time" - - "golang.org/x/sync/errgroup" - - core "github.com/v2fly/v2ray-core/v5" - "github.com/v2fly/v2ray-core/v5/app/proxyman" - "github.com/v2fly/v2ray-core/v5/common" - "github.com/v2fly/v2ray-core/v5/common/net" - "github.com/v2fly/v2ray-core/v5/common/protocol" - "github.com/v2fly/v2ray-core/v5/common/serial" - "github.com/v2fly/v2ray-core/v5/proxy/dokodemo" - "github.com/v2fly/v2ray-core/v5/proxy/freedom" - "github.com/v2fly/v2ray-core/v5/proxy/shadowsocks" - "github.com/v2fly/v2ray-core/v5/testing/servers/tcp" -) - -func TestHysteria2(t *testing.T) { - tcpServer := tcp.Server{ - MsgProcessor: xor, - } - dest, err := tcpServer.Start() - common.Must(err) - defer tcpServer.Close() - - account := serial.ToTypedMessage(&shadowsocks.Account{ - Password: "shadowsocks-password", - CipherType: shadowsocks.CipherType_CHACHA20_POLY1305, - }) - - serverPort := tcp.PickPort() - serverConfig := &core.Config{ - Inbound: []*core.InboundHandlerConfig{ - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: net.SinglePortRange(serverPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - }), - ProxySettings: serial.ToTypedMessage(&shadowsocks.ServerConfig{ - User: &protocol.User{ - Account: account, - Level: 1, - }, - Network: []net.Network{net.Network_TCP}, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - ProxySettings: serial.ToTypedMessage(&freedom.Config{}), - }, - }, - } - - clientPort := tcp.PickPort() - clientConfig := &core.Config{ - Inbound: []*core.InboundHandlerConfig{ - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: net.SinglePortRange(clientPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - }), - ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ - Address: net.NewIPOrDomain(dest.Address), - Port: uint32(dest.Port), - Networks: []net.Network{net.Network_TCP}, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{ - Server: []*protocol.ServerEndpoint{ - { - Address: net.NewIPOrDomain(net.LocalHostIP), - Port: uint32(serverPort), - User: []*protocol.User{ - { - Account: account, - }, - }, - }, - }, - }), - }, - }, - } - - servers, err := InitializeServerConfigs(serverConfig, clientConfig) - common.Must(err) - defer CloseAllServers(servers) - - var errGroup errgroup.Group - for i := 0; i < 10; i++ { - errGroup.Go(testTCPConn(clientPort, 10240*1024, time.Second*20)) - } - if err := errGroup.Wait(); err != nil { - t.Error(err) - } -} diff --git a/testing/scenarios/transport_test.go b/testing/scenarios/transport_test.go index 1fd104779b..a4692523f8 100644 --- a/testing/scenarios/transport_test.go +++ b/testing/scenarios/transport_test.go @@ -20,6 +20,7 @@ import ( "github.com/v2fly/v2ray-core/v5/common/uuid" "github.com/v2fly/v2ray-core/v5/proxy/dokodemo" "github.com/v2fly/v2ray-core/v5/proxy/freedom" + "github.com/v2fly/v2ray-core/v5/proxy/hysteria2" "github.com/v2fly/v2ray-core/v5/proxy/vmess" "github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound" "github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound" @@ -29,7 +30,7 @@ import ( "github.com/v2fly/v2ray-core/v5/transport/internet/domainsocket" "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http" "github.com/v2fly/v2ray-core/v5/transport/internet/headers/wechat" - "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" + hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" "github.com/v2fly/v2ray-core/v5/transport/internet/quic" tcptransport "github.com/v2fly/v2ray-core/v5/transport/internet/tcp" ) @@ -385,7 +386,13 @@ func TestVMessQuic(t *testing.T) { } } -func TestVMessHysteria2BBR(t *testing.T) { +func TestVMessHysteria2(t *testing.T) { + for _, v := range []string{"bbr", "brutal"} { + testVMessHysteria2(t, v) + } +} + +func testVMessHysteria2(t *testing.T, congestionType string) { tcpServer := tcp.Server{ MsgProcessor: xor, } @@ -411,11 +418,11 @@ func TestVMessHysteria2BBR(t *testing.T) { TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hysteria2.Config{ + Settings: serial.ToTypedMessage(&hy2_transport.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hysteria2.Congestion{Type: "bbr"}, + Congestion: &hy2_transport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, Password: "password", }), }, @@ -471,11 +478,11 @@ func TestVMessHysteria2BBR(t *testing.T) { TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hysteria2.Config{ + Settings: serial.ToTypedMessage(&hy2_transport.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hysteria2.Congestion{Type: "bbr"}, + Congestion: &hy2_transport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, Password: "password", }), }, @@ -521,7 +528,7 @@ func TestVMessHysteria2BBR(t *testing.T) { } } -func TestVMessHysteria2Brutal(t *testing.T) { +func TestHysteria2(t *testing.T) { tcpServer := tcp.Server{ MsgProcessor: xor, } @@ -547,24 +554,21 @@ func TestVMessHysteria2Brutal(t *testing.T) { TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hysteria2.Config{ + Settings: serial.ToTypedMessage(&hy2_transport.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hysteria2.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, + Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, Password: "password", }), }, }, }, }), - ProxySettings: serial.ToTypedMessage(&inbound.Config{ - User: []*protocol.User{ + ProxySettings: serial.ToTypedMessage(&hysteria2.ServerConfig{ + Users: []*protocol.User{ { - Account: serial.ToTypedMessage(&vmess.Account{ - Id: userID.String(), - AlterId: 0, - }), + Account: serial.ToTypedMessage(&hysteria2.Account{}), }, }, }), @@ -607,11 +611,11 @@ func TestVMessHysteria2Brutal(t *testing.T) { TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hysteria2.Config{ + Settings: serial.ToTypedMessage(&hy2_transport.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hysteria2.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, + Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, Password: "password", }), }, diff --git a/transport/internet/hysteria2/config.pb.go b/transport/internet/hysteria2/config.pb.go index 2692257720..292e39b968 100644 --- a/transport/internet/hysteria2/config.pb.go +++ b/transport/internet/hysteria2/config.pb.go @@ -84,10 +84,11 @@ type Config struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Security *protocol.SecurityConfig `protobuf:"bytes,2,opt,name=security,proto3" json:"security,omitempty"` - Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` - Congestion *Congestion `protobuf:"bytes,4,opt,name=congestion,proto3" json:"congestion,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Security *protocol.SecurityConfig `protobuf:"bytes,2,opt,name=security,proto3" json:"security,omitempty"` + Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` + Congestion *Congestion `protobuf:"bytes,4,opt,name=congestion,proto3" json:"congestion,omitempty"` + IgnoreClientBandwidth bool `protobuf:"varint,5,opt,name=ignore_client_bandwidth,json=ignoreClientBandwidth,proto3" json:"ignore_client_bandwidth,omitempty"` } func (x *Config) Reset() { @@ -150,6 +151,13 @@ func (x *Config) GetCongestion() *Congestion { return nil } +func (x *Config) GetIgnoreClientBandwidth() bool { + if x != nil { + return x.IgnoreClientBandwidth + } + return false +} + var File_transport_internet_hysteria2_config_proto protoreflect.FileDescriptor var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ @@ -167,7 +175,7 @@ var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x70, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x70, 0x4d, 0x62, 0x70, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xef, 0x01, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xa7, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, @@ -181,18 +189,22 @@ var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x2e, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, - 0x69, 0x6f, 0x6e, 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x16, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x70, 0x6f, 0x72, 0x74, 0x12, 0x09, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x42, - 0x96, 0x01, 0x0a, 0x2b, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, - 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, - 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, - 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, - 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x48, - 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x17, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x1a, 0x82, 0xb5, 0x18, + 0x16, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x09, 0x68, 0x79, + 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x42, 0x96, 0x01, 0x0a, 0x2b, 0x63, 0x6f, 0x6d, 0x2e, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, + 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x79, 0x73, + 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, + 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From 63159c36edcd8826db7318f871a1d35254afb986 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Wed, 14 Feb 2024 23:29:04 +0800 Subject: [PATCH 33/81] update test --- main/distro/all/all.go | 1 + proxy/hysteria2/protocol.go | 45 +------- proxy/hysteria2/server.go | 168 +++++++++++----------------- testing/scenarios/transport_test.go | 129 +++++++++++++++++++-- 4 files changed, 186 insertions(+), 157 deletions(-) diff --git a/main/distro/all/all.go b/main/distro/all/all.go index aa7748cb7f..80f13f72b9 100644 --- a/main/distro/all/all.go +++ b/main/distro/all/all.go @@ -54,6 +54,7 @@ import ( _ "github.com/v2fly/v2ray-core/v5/proxy/vlite/inbound" _ "github.com/v2fly/v2ray-core/v5/proxy/vlite/outbound" + _ "github.com/v2fly/v2ray-core/v5/proxy/hysteria2" _ "github.com/v2fly/v2ray-core/v5/proxy/shadowsocks2022" // Transports diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index 2a6cf0b078..7479da9385 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -182,54 +182,11 @@ func (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, e // ConnReader is TCP Connection Reader Wrapper for trojan protocol type ConnReader struct { io.Reader - Target net.Destination - headerParsed bool -} - -// ParseHeader parses the trojan protocol header -func (c *ConnReader) ParseHeader() error { - var crlf [2]byte - var command [1]byte - var hash [56]byte - if _, err := io.ReadFull(c.Reader, hash[:]); err != nil { - return newError("failed to read user hash").Base(err) - } - - if _, err := io.ReadFull(c.Reader, crlf[:]); err != nil { - return newError("failed to read crlf").Base(err) - } - - if _, err := io.ReadFull(c.Reader, command[:]); err != nil { - return newError("failed to read command").Base(err) - } - - network := net.Network_TCP - if command[0] == commandUDP { - network = net.Network_UDP - } - - addr, port, err := addrParser.ReadAddressPort(nil, c.Reader) - if err != nil { - return newError("failed to read address and port").Base(err) - } - c.Target = net.Destination{Network: network, Address: addr, Port: port} - - if _, err := io.ReadFull(c.Reader, crlf[:]); err != nil { - return newError("failed to read crlf").Base(err) - } - - c.headerParsed = true - return nil + Target net.Destination } // Read implements io.Reader func (c *ConnReader) Read(p []byte) (int, error) { - if !c.headerParsed { - if err := c.ParseHeader(); err != nil { - return 0, err - } - } - return c.Reader.Read(p) } diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index 536fe171cf..dc8a7a2850 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -2,9 +2,12 @@ package hysteria2 import ( "context" + "fmt" "io" + "strings" "time" + hyProtocol "github.com/apernet/hysteria/core/international/protocol" core "github.com/v2fly/v2ray-core/v5" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/buf" @@ -12,7 +15,6 @@ import ( "github.com/v2fly/v2ray-core/v5/common/log" "github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/net/packetaddr" - "github.com/v2fly/v2ray-core/v5/common/protocol" udp_proto "github.com/v2fly/v2ray-core/v5/common/protocol/udp" "github.com/v2fly/v2ray-core/v5/common/session" "github.com/v2fly/v2ray-core/v5/common/signal" @@ -55,23 +57,12 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), validator: validator, } - return server, nil } -// AddUser implements proxy.UserManager.AddUser(). -func (s *Server) AddUser(ctx context.Context, u *protocol.MemoryUser) error { - return s.validator.Add(u) -} - -// RemoveUser implements proxy.UserManager.RemoveUser(). -func (s *Server) RemoveUser(ctx context.Context, e string) error { - return s.validator.Del(e) -} - // Network implements proxy.Inbound.Network(). func (s *Server) Network() []net.Network { - return []net.Network{net.Network_TCP, net.Network_UNIX} + return []net.Network{net.Network_TCP, net.Network_UDP} } // Process implements proxy.Inbound.Process(). @@ -88,59 +79,32 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet return newError("unable to set read deadline").Base(err).AtWarning() } - first := buf.New() - defer first.Release() + var reqAddr string + var err error - firstLen, err := first.ReadFrom(conn) - if err != nil { - return newError("failed to read first request").Base(err) + if network == net.Network_TCP { + reqAddr, err = hyProtocol.ReadTCPRequest(conn) + if err != nil { + return newError("failed to parse header").Base(err) + } + err = hyProtocol.WriteTCPResponse(conn, true, "") + if err != nil { + return newError("failed to send response").Base(err) + } } - newError("firstLen = ", firstLen).AtInfo().WriteToLog(sid) - bufferedReader := &buf.BufferedReader{ Reader: buf.NewReader(conn), - Buffer: buf.MultiBuffer{first}, } - var user *protocol.MemoryUser - - if firstLen < 58 || first.Byte(56) != '\r' { - // invalid protocol - err = newError("not trojan protocol") - log.Record(&log.AccessMessage{ - From: conn.RemoteAddr(), - To: "", - Status: log.AccessRejected, - Reason: err, - }) - - } else { - user = s.validator.Get(hexString(first.BytesTo(56))) - if user == nil { - // invalid user, let's fallback - err = newError("not a valid user") - log.Record(&log.AccessMessage{ - From: conn.RemoteAddr(), - To: "", - Status: log.AccessRejected, - Reason: err, - }) - - } + address := strings.Split(reqAddr, ":") + port, err := net.PortFromString(address[1]) + if err != nil { + return err } + destination := net.Destination{Network: network, Address: net.ParseAddress(address[0]), Port: port} clientReader := &ConnReader{Reader: bufferedReader} - if err := clientReader.ParseHeader(); err != nil { - log.Record(&log.AccessMessage{ - From: conn.RemoteAddr(), - To: "", - Status: log.AccessRejected, - Reason: err, - }) - return newError("failed to create request from: ", conn.RemoteAddr()).Base(err) - } - destination := clientReader.Target if err := conn.SetReadDeadline(time.Time{}); err != nil { return newError("unable to set read deadline").Base(err).AtWarning() } @@ -149,8 +113,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet if inbound == nil { panic("no inbound metadata") } - inbound.User = user - sessionPolicy = s.policyManager.ForLevel(user.Level) + sessionPolicy = s.policyManager.ForLevel(0) if destination.Network == net.Network_UDP { // handle udp request return s.handleUDPPayload(ctx, &PacketReader{Reader: clientReader}, &PacketWriter{Writer: conn}, dispatcher) @@ -161,14 +124,55 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet To: destination, Status: log.AccessAccepted, Reason: "", - Email: user.Email, }) newError("received request for ", destination).WriteToLog(sid) return s.handleConnection(ctx, sessionPolicy, destination, clientReader, buf.NewWriter(conn), dispatcher) } -func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReader, clientWriter *PacketWriter, dispatcher routing.Dispatcher) error { +func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Session, + destination net.Destination, + clientReader buf.Reader, + clientWriter buf.Writer, dispatcher routing.Dispatcher, +) error { + ctx, cancel := context.WithCancel(ctx) + timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) + ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) + + link, err := dispatcher.Dispatch(ctx, destination) + if err != nil { + return newError("failed to dispatch request to ", destination).Base(err) + } + + requestDone := func() error { + defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) + + if err := buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer)); err != nil { + return newError("failed to transfer request").Base(err) + } + return nil + } + + responseDone := func() error { + defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) + + if err := buf.Copy(link.Reader, clientWriter, buf.UpdateActivity(timer)); err != nil { + return newError("failed to write response").Base(err) + } + return nil + } + + requestDonePost := task.OnSuccess(requestDone, task.Close(link.Writer)) + if err := task.Run(ctx, requestDonePost, responseDone); err != nil { + common.Must(common.Interrupt(link.Reader)) + common.Must(common.Interrupt(link.Writer)) + return newError("connection ends").Base(err) + } + + return nil +} + +func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReader, clientWriter *PacketWriter, dispatcher routing.Dispatcher) error { // {{{ udpDispatcherConstructor := udp.NewSplitDispatcher switch s.packetEncoding { case packetaddr.PacketAddrType_None: @@ -213,46 +217,4 @@ func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReade } } } -} - -func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Session, - destination net.Destination, - clientReader buf.Reader, - clientWriter buf.Writer, dispatcher routing.Dispatcher, -) error { - ctx, cancel := context.WithCancel(ctx) - timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) - ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) - - link, err := dispatcher.Dispatch(ctx, destination) - if err != nil { - return newError("failed to dispatch request to ", destination).Base(err) - } - - requestDone := func() error { - defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) - - if err := buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer)); err != nil { - return newError("failed to transfer request").Base(err) - } - return nil - } - - responseDone := func() error { - defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) - - if err := buf.Copy(link.Reader, clientWriter, buf.UpdateActivity(timer)); err != nil { - return newError("failed to write response").Base(err) - } - return nil - } - - requestDonePost := task.OnSuccess(requestDone, task.Close(link.Writer)) - if err := task.Run(ctx, requestDonePost, responseDone); err != nil { - common.Must(common.Interrupt(link.Reader)) - common.Must(common.Interrupt(link.Writer)) - return newError("connection ends").Base(err) - } - - return nil -} +} // }}} diff --git a/testing/scenarios/transport_test.go b/testing/scenarios/transport_test.go index a4692523f8..d2422cbd50 100644 --- a/testing/scenarios/transport_test.go +++ b/testing/scenarios/transport_test.go @@ -536,7 +536,6 @@ func TestHysteria2(t *testing.T) { common.Must(err) defer tcpServer.Close() - userID := protocol.NewID(uuid.New()) serverPort := udp.PickPort() serverConfig := &core.Config{ App: []*anypb.Any{ @@ -622,20 +621,14 @@ func TestHysteria2(t *testing.T) { }, }, }), - ProxySettings: serial.ToTypedMessage(&outbound.Config{ - Receiver: []*protocol.ServerEndpoint{ + ProxySettings: serial.ToTypedMessage(&hysteria2.ClientConfig{ + Server: []*protocol.ServerEndpoint{ { Address: net.NewIPOrDomain(net.LocalHostIP), Port: uint32(serverPort), User: []*protocol.User{ { - Account: serial.ToTypedMessage(&vmess.Account{ - Id: userID.String(), - AlterId: 0, - SecuritySettings: &protocol.SecurityConfig{ - Type: protocol.SecurityType_AES128_GCM, - }, - }), + Account: serial.ToTypedMessage(&hysteria2.Account{}), }, }, }, @@ -660,3 +653,119 @@ func TestHysteria2(t *testing.T) { t.Error(err) } } + +func TestHysteria2TCP(t *testing.T) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() + + serverPort := udp.PickPort() + serverConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(serverPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ + TransportSettings: []*internet.TransportConfig{ + { + Protocol: internet.TransportProtocol_TCP, + Settings: serial.ToTypedMessage(&tcptransport.Config{ + HeaderSettings: serial.ToTypedMessage(&http.Config{}), + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&hysteria2.ServerConfig{ + Users: []*protocol.User{ + { + Account: serial.ToTypedMessage(&hysteria2.Account{}), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(clientPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ + StreamSettings: &internet.StreamConfig{ + TransportSettings: []*internet.TransportConfig{ + { + Protocol: internet.TransportProtocol_TCP, + Settings: serial.ToTypedMessage(&tcptransport.Config{ + HeaderSettings: serial.ToTypedMessage(&http.Config{}), + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&hysteria2.ClientConfig{ + Server: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&hysteria2.Account{}), + }, + }, + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + if err != nil { + t.Fatal("Failed to initialize all servers: ", err.Error()) + } + defer CloseAllServers(servers) + + var errg errgroup.Group + for i := 0; i < 1; i++ { + errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) + } + + if err := errg.Wait(); err != nil { + t.Error(err) + } +} From 6630faf842e9a46c60c6c60f0ed60ea97c7232b2 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Thu, 15 Feb 2024 01:30:43 +0800 Subject: [PATCH 34/81] test ok --- proxy/hysteria2/server.go | 3 +-- testing/scenarios/transport_test.go | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index dc8a7a2850..bb717289a7 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -2,7 +2,6 @@ package hysteria2 import ( "context" - "fmt" "io" "strings" "time" @@ -62,7 +61,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { // Network implements proxy.Inbound.Network(). func (s *Server) Network() []net.Network { - return []net.Network{net.Network_TCP, net.Network_UDP} + return []net.Network{net.Network_TCP, net.Network_UNIX} } // Process implements proxy.Inbound.Process(). diff --git a/testing/scenarios/transport_test.go b/testing/scenarios/transport_test.go index d2422cbd50..ce06e99121 100644 --- a/testing/scenarios/transport_test.go +++ b/testing/scenarios/transport_test.go @@ -1,6 +1,7 @@ package scenarios import ( + "fmt" "os" "runtime" "testing" @@ -528,7 +529,7 @@ func testVMessHysteria2(t *testing.T, congestionType string) { } } -func TestHysteria2(t *testing.T) { +func TestHysteria2Offical(t *testing.T) { tcpServer := tcp.Server{ MsgProcessor: xor, } @@ -537,6 +538,7 @@ func TestHysteria2(t *testing.T) { defer tcpServer.Close() serverPort := udp.PickPort() + fmt.Println(serverPort) serverConfig := &core.Config{ App: []*anypb.Any{ serial.ToTypedMessage(&log.Config{ From 573ce78f091953658d64ff21193d8f157015e62c Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Thu, 15 Feb 2024 03:26:09 +0800 Subject: [PATCH 35/81] add config examples --- infra/conf/v4/hysteria2.go | 87 +++++++++++++++++++ infra/conf/v4/v2ray.go | 2 + .../config/hy2/hysteria2_offical_test_v4.json | 50 +++++++++++ release/config/{ => hy2}/hysteria2_test.json5 | 0 .../config/{ => hy2}/hysteria2_test_v4.json | 0 5 files changed, 139 insertions(+) create mode 100644 infra/conf/v4/hysteria2.go create mode 100644 release/config/hy2/hysteria2_offical_test_v4.json rename release/config/{ => hy2}/hysteria2_test.json5 (100%) rename release/config/{ => hy2}/hysteria2_test_v4.json (100%) diff --git a/infra/conf/v4/hysteria2.go b/infra/conf/v4/hysteria2.go new file mode 100644 index 0000000000..a5e08ed831 --- /dev/null +++ b/infra/conf/v4/hysteria2.go @@ -0,0 +1,87 @@ +package v4 + +import ( + "github.com/golang/protobuf/proto" + + "github.com/v2fly/v2ray-core/v5/common/protocol" + "github.com/v2fly/v2ray-core/v5/common/serial" + "github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon" + "github.com/v2fly/v2ray-core/v5/proxy/hysteria2" +) + +// Hysteria2ServerTarget is configuration of a single hysteria2 server +type Hysteria2ServerTarget struct { + Address *cfgcommon.Address `json:"address"` + Port uint16 `json:"port"` + Email string `json:"email"` + Level byte `json:"level"` +} + +// Hysteria2ClientConfig is configuration of hysteria2 servers +type Hysteria2ClientConfig struct { + Servers []*Hysteria2ServerTarget `json:"servers"` +} + +// Build implements Buildable +func (c *Hysteria2ClientConfig) Build() (proto.Message, error) { + config := new(hysteria2.ClientConfig) + + if len(c.Servers) == 0 { + return nil, newError("0 Hysteria2 server configured.") + } + + serverSpecs := make([]*protocol.ServerEndpoint, len(c.Servers)) + for idx, rec := range c.Servers { + if rec.Address == nil { + return nil, newError("Hysteria2 server address is not set.") + } + if rec.Port == 0 { + return nil, newError("Invalid Hysteria2 port.") + } + account := &hysteria2.Account{} + hysteria2 := &protocol.ServerEndpoint{ + Address: rec.Address.Build(), + Port: uint32(rec.Port), + User: []*protocol.User{ + { + Level: uint32(rec.Level), + Email: rec.Email, + Account: serial.ToTypedMessage(account), + }, + }, + } + + serverSpecs[idx] = hysteria2 + } + + config.Server = serverSpecs + + return config, nil +} + +// Hysteria2UserConfig is user configuration +type Hysteria2UserConfig struct { + Level byte `json:"level"` + Email string `json:"email"` +} + +// Hysteria2ServerConfig is Inbound configuration +type Hysteria2ServerConfig struct { + Clients []*Hysteria2UserConfig `json:"clients"` +} + +// Build implements Buildable +func (c *Hysteria2ServerConfig) Build() (proto.Message, error) { + config := new(hysteria2.ServerConfig) + config.Users = make([]*protocol.User, len(c.Clients)) + for idx, rawUser := range c.Clients { + user := new(protocol.User) + account := &hysteria2.Account{} + + user.Email = rawUser.Email + user.Level = uint32(rawUser.Level) + user.Account = serial.ToTypedMessage(account) + config.Users[idx] = user + } + return config, nil +} diff --git a/infra/conf/v4/v2ray.go b/infra/conf/v4/v2ray.go index d68fc6cc4e..cc440ccbe7 100644 --- a/infra/conf/v4/v2ray.go +++ b/infra/conf/v4/v2ray.go @@ -31,6 +31,7 @@ var ( "vless": func() interface{} { return new(VLessInboundConfig) }, "vmess": func() interface{} { return new(VMessInboundConfig) }, "trojan": func() interface{} { return new(TrojanServerConfig) }, + "hysteria2": func() interface{} { return new(Hysteria2ServerConfig) }, }, "protocol", "settings") outboundConfigLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{ @@ -42,6 +43,7 @@ var ( "vless": func() interface{} { return new(VLessOutboundConfig) }, "vmess": func() interface{} { return new(VMessOutboundConfig) }, "trojan": func() interface{} { return new(TrojanClientConfig) }, + "hysteria2": func() interface{} { return new(Hysteria2ClientConfig) }, "dns": func() interface{} { return new(DNSOutboundConfig) }, "loopback": func() interface{} { return new(LoopbackConfig) }, }, "protocol", "settings") diff --git a/release/config/hy2/hysteria2_offical_test_v4.json b/release/config/hy2/hysteria2_offical_test_v4.json new file mode 100644 index 0000000000..8e85e833e9 --- /dev/null +++ b/release/config/hy2/hysteria2_offical_test_v4.json @@ -0,0 +1,50 @@ +{ + "log": { + "loglevel": "debug" + }, + "inbounds": [{ + "port": 1080, + "listen": "127.0.0.1", + "tag": "http", + "protocol": "http" + }, { + "port": 1280, + "listen": "127.0.0.1", + "tag": "hy2_in", + "protocol": "hysteria2", + "streamSettings": { + "network": "hysteria2", + "security": "tls" + } + }], + "outbounds": [{ + "protocol": "freedom", + "tag": "direct" + }, { + "tag": "hy2_out", + "protocol": "hysteria2", + "settings": { + "servers": [{ + "address": "127.0.0.1", + "port": 1280 + }] + }, + "streamSettings": { + "network": "hysteria2", + "security": "tls" + } + }], + "routing": { + "rules": [{ + "type": "field", + "outboundTag": "direct", + "inboundTag": ["hy2_in"] + }, + { + "type": "field", + "outboundTag": "hy2_out", + "inboundTag": ["http"] + } + ] + } +} diff --git a/release/config/hysteria2_test.json5 b/release/config/hy2/hysteria2_test.json5 similarity index 100% rename from release/config/hysteria2_test.json5 rename to release/config/hy2/hysteria2_test.json5 diff --git a/release/config/hysteria2_test_v4.json b/release/config/hy2/hysteria2_test_v4.json similarity index 100% rename from release/config/hysteria2_test_v4.json rename to release/config/hy2/hysteria2_test_v4.json From c4c27825cfca45fc2380be43e07d8f41cbee1ea3 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Sat, 17 Feb 2024 13:11:05 +0800 Subject: [PATCH 36/81] try add udp --- proxy/hysteria2/protocol.go | 2 +- transport/internet/hysteria2/dialer.go | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index 7479da9385..4462df2a4c 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -62,7 +62,7 @@ func (c *ConnWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { } func (c *ConnWriter) WriteHeader() error { - if !c.headerSent { + if !c.headerSent && c.Target.Network != net.Network_TCP { if err := c.writeHeader(); err != nil { return err } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 8ab6f441cd..04528e9f16 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -8,6 +8,7 @@ import ( "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/net" + "github.com/v2fly/v2ray-core/v5/common/session" "github.com/v2fly/v2ray-core/v5/transport/internet" "github.com/v2fly/v2ray-core/v5/transport/internet/tls" ) @@ -82,6 +83,12 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me } } + outbound := session.OutboundFromContext(ctx) + network := outbound.Target.Network + if network == net.Network_TCP { + + } + stream, err := client.OpenStream() if err != nil { return nil, err From e690e4b7cc8a1e7330bd627e2bec6c9eeb993a32 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 27 Feb 2024 22:05:53 +0800 Subject: [PATCH 37/81] fix go mod --- go.mod | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 8295f768c0..6b996d8a17 100644 --- a/go.mod +++ b/go.mod @@ -44,8 +44,6 @@ require ( lukechampine.com/blake3 v1.2.1 ) -replace github.com/apernet/hysteria/core => ../hysteria/core - require ( github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 // indirect github.com/ajg/form v1.5.1 // indirect @@ -91,3 +89,6 @@ require ( ) replace github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 => github.com/xiaokangwang/struc v0.0.0-20231031203518-0e381172f248 + +//replace github.com/apernet/hysteria/core v1.3.5 => github.com/JimmyHuang454/hysteria/core v0.0.0-20240213213233-46654e2e94de +replace github.com/apernet/hysteria/core v1.3.5 => ../hysteria/core From 3c4931131a6bdbf5d4e96ea78523933fca7eb0dd Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Sat, 2 Mar 2024 23:48:00 +0800 Subject: [PATCH 38/81] fix test --- transport/internet/hysteria2/dialer.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 04528e9f16..aa6270c624 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -84,9 +84,13 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me } outbound := session.OutboundFromContext(ctx) - network := outbound.Target.Network - if network == net.Network_TCP { + network := net.Network_TCP + if outbound != nil { + network = outbound.Target.Network + } + if network == net.Network_UDP { + // TODO: <02-03-24, yourname> // } stream, err := client.OpenStream() From 1422206a12c3c2085e42e3c3f704b24885446f5d Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Sun, 3 Mar 2024 00:07:40 +0800 Subject: [PATCH 39/81] use hyProtocol --- proxy/hysteria2/protocol.go | 6 +-- transport/internet/hysteria2/conn.go | 59 +++++--------------------- transport/internet/hysteria2/dialer.go | 8 ++-- transport/internet/hysteria2/hub.go | 4 +- 4 files changed, 20 insertions(+), 57 deletions(-) diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index 4462df2a4c..e6b7d6e27f 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -5,11 +5,11 @@ import ( "io" gonet "net" + hyProtocol "github.com/apernet/hysteria/core/international/protocol" "github.com/apernet/quic-go/quicvarint" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/protocol" - "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" ) var ( @@ -82,9 +82,9 @@ func (c *ConnWriter) writeHeader() error { size := QuicLen(addressLen) + addressLen + QuicLen(paddingLen) + paddingLen buf := make([]byte, size) - i := hysteria2.VarintPut(buf, uint64(addressLen)) + i := hyProtocol.VarintPut(buf, uint64(addressLen)) i += copy(buf[i:], addressAndPort) - i += hysteria2.VarintPut(buf[i:], uint64(paddingLen)) + i += hyProtocol.VarintPut(buf[i:], uint64(paddingLen)) copy(buf[i:], padding) _, err := c.Writer.Write(buf) diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index f61a97528e..d91efaf431 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -1,7 +1,6 @@ package hysteria2 import ( - "fmt" "time" "github.com/apernet/quic-go" @@ -10,7 +9,7 @@ import ( "github.com/v2fly/v2ray-core/v5/common/net" ) -type interConn struct { +type TCPConn struct { stream quic.Stream local net.Addr remote net.Addr @@ -18,81 +17,43 @@ type interConn struct { const ( FrameTypeTCPRequest = 0x401 - - maxVarInt1 = 63 - maxVarInt2 = 16383 - maxVarInt4 = 1073741823 - maxVarInt8 = 4611686018427387903 ) -// VarintPut is like quicvarint.Append, but instead of appending to a slice, -// it writes to a fixed-size buffer. Returns the number of bytes written. -func VarintPut(b []byte, i uint64) int { - if i <= maxVarInt1 { - b[0] = uint8(i) - return 1 - } - if i <= maxVarInt2 { - b[0] = uint8(i>>8) | 0x40 - b[1] = uint8(i) - return 2 - } - if i <= maxVarInt4 { - b[0] = uint8(i>>24) | 0x80 - b[1] = uint8(i >> 16) - b[2] = uint8(i >> 8) - b[3] = uint8(i) - return 4 - } - if i <= maxVarInt8 { - b[0] = uint8(i>>56) | 0xc0 - b[1] = uint8(i >> 48) - b[2] = uint8(i >> 40) - b[3] = uint8(i >> 32) - b[4] = uint8(i >> 24) - b[5] = uint8(i >> 16) - b[6] = uint8(i >> 8) - b[7] = uint8(i) - return 8 - } - panic(fmt.Sprintf("%#x doesn't fit into 62 bits", i)) -} - -func (c *interConn) Read(b []byte) (int, error) { +func (c *TCPConn) Read(b []byte) (int, error) { return c.stream.Read(b) } -func (c *interConn) WriteMultiBuffer(mb buf.MultiBuffer) error { +func (c *TCPConn) WriteMultiBuffer(mb buf.MultiBuffer) error { mb = buf.Compact(mb) mb, err := buf.WriteMultiBuffer(c, mb) buf.ReleaseMulti(mb) return err } -func (c *interConn) Write(b []byte) (int, error) { +func (c *TCPConn) Write(b []byte) (int, error) { return c.stream.Write(b) } -func (c *interConn) Close() error { +func (c *TCPConn) Close() error { return c.stream.Close() } -func (c *interConn) LocalAddr() net.Addr { +func (c *TCPConn) LocalAddr() net.Addr { return c.local } -func (c *interConn) RemoteAddr() net.Addr { +func (c *TCPConn) RemoteAddr() net.Addr { return c.remote } -func (c *interConn) SetDeadline(t time.Time) error { +func (c *TCPConn) SetDeadline(t time.Time) error { return c.stream.SetDeadline(t) } -func (c *interConn) SetReadDeadline(t time.Time) error { +func (c *TCPConn) SetReadDeadline(t time.Time) error { return c.stream.SetReadDeadline(t) } -func (c *interConn) SetWriteDeadline(t time.Time) error { +func (c *TCPConn) SetWriteDeadline(t time.Time) error { return c.stream.SetWriteDeadline(t) } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index aa6270c624..367faf3d16 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -4,6 +4,7 @@ import ( "context" hy "github.com/apernet/hysteria/core/client" + hyProtocol "github.com/apernet/hysteria/core/international/protocol" "github.com/apernet/quic-go/quicvarint" "github.com/v2fly/v2ray-core/v5/common" @@ -91,6 +92,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me if network == net.Network_UDP { // TODO: <02-03-24, yourname> // + client.UDP() } stream, err := client.OpenStream() @@ -99,7 +101,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me } quicConn := client.GetQuicConn() - internetConn := &interConn{ + tcpConn := &TCPConn{ stream: stream, local: quicConn.LocalAddr(), remote: quicConn.RemoteAddr(), @@ -108,9 +110,9 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me // write frame type frameSize := int(quicvarint.Len(FrameTypeTCPRequest)) buf := make([]byte, frameSize) - VarintPut(buf, FrameTypeTCPRequest) + hyProtocol.VarintPut(buf, FrameTypeTCPRequest) stream.Write(buf) - return internetConn, nil + return tcpConn, nil } func init() { diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 5bea11c7b6..e2c51478ed 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -34,12 +34,12 @@ func (l *Listener) Close() error { func (l *Listener) ProxyStreamHijacker(ft http3.FrameType, conn quic.Connection, stream quic.Stream, err error) (bool, error) { // err always == nil - internetConn := &interConn{ + tcpConn := &TCPConn{ stream: stream, local: conn.LocalAddr(), remote: conn.RemoteAddr(), } - l.addConn(internetConn) + l.addConn(tcpConn) return true, nil } From c622aa989725d5ebf562f3213d690f35bb1aec0b Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Mon, 4 Mar 2024 02:54:56 +0800 Subject: [PATCH 40/81] update --- go.mod | 6 ++-- go.sum | 4 +-- transport/internet/hysteria2/config.pb.go | 37 ++++++++++++++--------- transport/internet/hysteria2/config.proto | 1 + transport/internet/hysteria2/conn.go | 4 --- transport/internet/hysteria2/dialer.go | 4 +++ transport/internet/hysteria2/hub.go | 3 +- 7 files changed, 35 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index 8295f768c0..eeb81eae29 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/adrg/xdg v0.4.0 github.com/apernet/hysteria/core v1.3.5 - github.com/apernet/quic-go v0.41.1-0.20240122005439-5bf4609c416f + github.com/apernet/quic-go v0.41.1-0.20240301003057-e18162de481d github.com/go-chi/chi/v5 v5.0.10 github.com/go-chi/render v1.0.3 github.com/go-playground/validator/v10 v10.16.0 @@ -44,8 +44,6 @@ require ( lukechampine.com/blake3 v1.2.1 ) -replace github.com/apernet/hysteria/core => ../hysteria/core - require ( github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 // indirect github.com/ajg/form v1.5.1 // indirect @@ -91,3 +89,5 @@ require ( ) replace github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 => github.com/xiaokangwang/struc v0.0.0-20231031203518-0e381172f248 + +replace github.com/apernet/hysteria/core => ../hysteria/core diff --git a/go.sum b/go.sum index c99047955f..d99ee87db2 100644 --- a/go.sum +++ b/go.sum @@ -25,8 +25,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/apernet/quic-go v0.41.1-0.20240122005439-5bf4609c416f h1:4jBGc3SlgQT8YFqHhfnK7EVFVY292CxagfNqfPiQZhY= -github.com/apernet/quic-go v0.41.1-0.20240122005439-5bf4609c416f/go.mod h1:4GInxO6ypy63J2NaO5rQx1wRp6K8YHI6zqLG+VswU6I= +github.com/apernet/quic-go v0.41.1-0.20240301003057-e18162de481d h1:K1DMSNtPcaZ/lihYmOHnjThNfUX7cD6SNuVRFnVLVmI= +github.com/apernet/quic-go v0.41.1-0.20240301003057-e18162de481d/go.mod h1:4GInxO6ypy63J2NaO5rQx1wRp6K8YHI6zqLG+VswU6I= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= diff --git a/transport/internet/hysteria2/config.pb.go b/transport/internet/hysteria2/config.pb.go index 292e39b968..50f40f2945 100644 --- a/transport/internet/hysteria2/config.pb.go +++ b/transport/internet/hysteria2/config.pb.go @@ -89,6 +89,7 @@ type Config struct { Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` Congestion *Congestion `protobuf:"bytes,4,opt,name=congestion,proto3" json:"congestion,omitempty"` IgnoreClientBandwidth bool `protobuf:"varint,5,opt,name=ignore_client_bandwidth,json=ignoreClientBandwidth,proto3" json:"ignore_client_bandwidth,omitempty"` + Udp bool `protobuf:"varint,6,opt,name=udp,proto3" json:"udp,omitempty"` } func (x *Config) Reset() { @@ -158,6 +159,13 @@ func (x *Config) GetIgnoreClientBandwidth() bool { return false } +func (x *Config) GetUdp() bool { + if x != nil { + return x.Udp + } + return false +} + var File_transport_internet_hysteria2_config_proto protoreflect.FileDescriptor var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ @@ -175,7 +183,7 @@ var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x70, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x70, 0x4d, 0x62, 0x70, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xa7, 0x02, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xb9, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, @@ -192,19 +200,20 @@ var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x17, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x1a, 0x82, 0xb5, 0x18, - 0x16, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x09, 0x68, 0x79, - 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x42, 0x96, 0x01, 0x0a, 0x2b, 0x63, 0x6f, 0x6d, 0x2e, - 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, - 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, - 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, - 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x79, 0x73, - 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, - 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x75, + 0x64, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x75, 0x64, 0x70, 0x3a, 0x1a, 0x82, + 0xb5, 0x18, 0x16, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x09, + 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x42, 0x96, 0x01, 0x0a, 0x2b, 0x63, 0x6f, + 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, + 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, + 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, + 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, + 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/transport/internet/hysteria2/config.proto b/transport/internet/hysteria2/config.proto index dc61f30286..56f2615a4d 100644 --- a/transport/internet/hysteria2/config.proto +++ b/transport/internet/hysteria2/config.proto @@ -26,4 +26,5 @@ message Config { string password = 3; Congestion congestion = 4; bool ignore_client_bandwidth = 5; + bool udp = 6; } diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index d91efaf431..aa370f3a93 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -15,10 +15,6 @@ type TCPConn struct { remote net.Addr } -const ( - FrameTypeTCPRequest = 0x401 -) - func (c *TCPConn) Read(b []byte) (int, error) { return c.stream.Read(b) } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 367faf3d16..f63ded7ddf 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -14,6 +14,10 @@ import ( "github.com/v2fly/v2ray-core/v5/transport/internet/tls" ) +const ( + FrameTypeTCPRequest = 0x401 +) + var RunningClient map[net.Destination](hy.Client) func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hy.TLSConfig, error) { diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index e2c51478ed..ee4d68429e 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -66,8 +66,9 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti hyServer, err := hy.NewServer(&hy.Config{ Conn: rawConn, TLSConfig: *GetTLSConfig(streamSettings), - IgnoreClientBandwidth: false, Authenticator: &Authenticator{Password: config.GetPassword()}, + IgnoreClientBandwidth: config.GetIgnoreClientBandwidth(), + DisableUDP: !config.GetUdp(), StreamHijacker: listener.ProxyStreamHijacker, // acceptStreams }) if err != nil { From 6a62f80e92c634377ff34c13af08c6feb0a989b8 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Fri, 8 Mar 2024 00:57:25 +0800 Subject: [PATCH 41/81] update --- transport/internet/hysteria2/conn.go | 28 ++++++++++++++------------ transport/internet/hysteria2/dialer.go | 28 ++++++++++++++++---------- transport/internet/hysteria2/hub.go | 2 +- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index aa370f3a93..6f61d34037 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -9,47 +9,49 @@ import ( "github.com/v2fly/v2ray-core/v5/common/net" ) -type TCPConn struct { - stream quic.Stream - local net.Addr - remote net.Addr +type HyConn struct { + UseUDPExtension bool + quicConn quic.Connection + stream quic.Stream + local net.Addr + remote net.Addr } -func (c *TCPConn) Read(b []byte) (int, error) { +func (c *HyConn) Read(b []byte) (int, error) { return c.stream.Read(b) } -func (c *TCPConn) WriteMultiBuffer(mb buf.MultiBuffer) error { +func (c *HyConn) WriteMultiBuffer(mb buf.MultiBuffer) error { mb = buf.Compact(mb) mb, err := buf.WriteMultiBuffer(c, mb) buf.ReleaseMulti(mb) return err } -func (c *TCPConn) Write(b []byte) (int, error) { +func (c *HyConn) Write(b []byte) (int, error) { return c.stream.Write(b) } -func (c *TCPConn) Close() error { +func (c *HyConn) Close() error { return c.stream.Close() } -func (c *TCPConn) LocalAddr() net.Addr { +func (c *HyConn) LocalAddr() net.Addr { return c.local } -func (c *TCPConn) RemoteAddr() net.Addr { +func (c *HyConn) RemoteAddr() net.Addr { return c.remote } -func (c *TCPConn) SetDeadline(t time.Time) error { +func (c *HyConn) SetDeadline(t time.Time) error { return c.stream.SetDeadline(t) } -func (c *TCPConn) SetReadDeadline(t time.Time) error { +func (c *HyConn) SetReadDeadline(t time.Time) error { return c.stream.SetReadDeadline(t) } -func (c *TCPConn) SetWriteDeadline(t time.Time) error { +func (c *HyConn) SetWriteDeadline(t time.Time) error { return c.stream.SetWriteDeadline(t) } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index f63ded7ddf..95aa07aa63 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -78,6 +78,8 @@ func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConf } func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { + config := streamSettings.ProtocolSettings.(*Config) + var client hy.Client client, found := RunningClient[dest] if !found { @@ -87,6 +89,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me return nil, err } } + quicConn := client.GetQuicConn() outbound := session.OutboundFromContext(ctx) network := net.Network_TCP @@ -94,29 +97,32 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me network = outbound.Target.Network } - if network == net.Network_UDP { - // TODO: <02-03-24, yourname> // - client.UDP() + conn := &HyConn{ + local: quicConn.LocalAddr(), + remote: quicConn.RemoteAddr(), + quicConn: quicConn, + } + + if config.GetUdp() && network == net.Network_UDP { + conn.UseUDPExtension = true + return conn, nil } stream, err := client.OpenStream() if err != nil { + delete(RunningClient, dest) + client.Close() return nil, err } - quicConn := client.GetQuicConn() - tcpConn := &TCPConn{ - stream: stream, - local: quicConn.LocalAddr(), - remote: quicConn.RemoteAddr(), - } + conn.stream = stream - // write frame type + // write TCP frame type frameSize := int(quicvarint.Len(FrameTypeTCPRequest)) buf := make([]byte, frameSize) hyProtocol.VarintPut(buf, FrameTypeTCPRequest) stream.Write(buf) - return tcpConn, nil + return conn, nil } func init() { diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index ee4d68429e..71c5137283 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -34,7 +34,7 @@ func (l *Listener) Close() error { func (l *Listener) ProxyStreamHijacker(ft http3.FrameType, conn quic.Connection, stream quic.Stream, err error) (bool, error) { // err always == nil - tcpConn := &TCPConn{ + tcpConn := &HyConn{ stream: stream, local: conn.LocalAddr(), remote: conn.RemoteAddr(), From 38ddcb104aa8b2a7bccc683a5b3bfcf46317e708 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Fri, 8 Mar 2024 01:10:32 +0800 Subject: [PATCH 42/81] remove --- transport/internet/hysteria2/conn.go | 10 ++++++++++ transport/internet/hysteria2/dialer.go | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index 6f61d34037..491edd9733 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -1,6 +1,7 @@ package hysteria2 import ( + "context" "time" "github.com/apernet/quic-go" @@ -18,6 +19,9 @@ type HyConn struct { } func (c *HyConn) Read(b []byte) (int, error) { + if c.UseUDPExtension { + c.quicConn.ReceiveDatagram(context.Background()) + } return c.stream.Read(b) } @@ -29,10 +33,16 @@ func (c *HyConn) WriteMultiBuffer(mb buf.MultiBuffer) error { } func (c *HyConn) Write(b []byte) (int, error) { + if c.UseUDPExtension { + return len(b), c.quicConn.SendDatagram(b) + } return c.stream.Write(b) } func (c *HyConn) Close() error { + if c.UseUDPExtension { + return nil + } return c.stream.Close() } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 95aa07aa63..2ae128abfc 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -103,7 +103,10 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me quicConn: quicConn, } - if config.GetUdp() && network == net.Network_UDP { + if network == net.Network_UDP { + if !config.GetUdp() { + return nil, newError("UDP extension is not enabled.") + } conn.UseUDPExtension = true return conn, nil } From 96529c610f615218cffb21a3cef586570ab38674 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Sun, 31 Mar 2024 00:46:36 +0800 Subject: [PATCH 43/81] add CloseHyClient --- proxy/hysteria2/client.go | 34 ++++++++++---------- proxy/hysteria2/protocol.go | 44 +++----------------------- proxy/hysteria2/server.go | 7 ++-- transport/internet/hysteria2/conn.go | 39 ++++++++++++++++------- transport/internet/hysteria2/dialer.go | 32 ++++++++++++------- 5 files changed, 73 insertions(+), 83 deletions(-) diff --git a/proxy/hysteria2/client.go b/proxy/hysteria2/client.go index 9f041764f5..6df25d3b20 100644 --- a/proxy/hysteria2/client.go +++ b/proxy/hysteria2/client.go @@ -92,28 +92,26 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter var bodyWriter buf.Writer bufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn)) connWriter := &ConnWriter{Writer: bufferWriter, Target: destination, Account: account} + bodyWriter = connWriter - if destination.Network == net.Network_UDP { + if network == net.Network_UDP { bodyWriter = &PacketWriter{Writer: connWriter, Target: destination} } else { - bodyWriter = connWriter - } - - // write some request payload to buffer - err = buf.CopyOnceTimeout(link.Reader, bodyWriter, proxy.FirstPayloadTimeout) - switch err { - case buf.ErrNotTimeoutReader, buf.ErrReadTimeout: - if err := connWriter.WriteHeader(); err != nil { - return newError("failed to write request header").Base(err).AtWarning() + // write some request payload to buffer + err = buf.CopyOnceTimeout(link.Reader, bodyWriter, proxy.FirstPayloadTimeout) + switch err { + case buf.ErrNotTimeoutReader, buf.ErrReadTimeout: + if err := connWriter.WriteHeader(); err != nil { + return newError("failed to write request header").Base(err).AtWarning() + } + case nil: + default: + return newError("failed to write a request payload").Base(err).AtWarning() + } + // Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer + if err = bufferWriter.SetBuffered(false); err != nil { + return newError("failed to flush payload").Base(err).AtWarning() } - case nil: - default: - return newError("failed to write a request payload").Base(err).AtWarning() - } - - // Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer - if err = bufferWriter.SetBuffered(false); err != nil { - return newError("failed to flush payload").Base(err).AtWarning() } if err = buf.Copy(link.Reader, bodyWriter, buf.UpdateActivity(timer)); err != nil { diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index e6b7d6e27f..fbe7271e7b 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -62,7 +62,7 @@ func (c *ConnWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { } func (c *ConnWriter) WriteHeader() error { - if !c.headerSent && c.Target.Network != net.Network_TCP { + if !c.headerSent { if err := c.writeHeader(); err != nil { return err } @@ -94,7 +94,7 @@ func (c *ConnWriter) writeHeader() error { return err } -// PacketWriter UDP Connection Writer Wrapper for trojan protocol +// PacketWriter UDP Connection Writer Wrapper type PacketWriter struct { io.Writer Target net.Destination @@ -137,46 +137,12 @@ func (w *PacketWriter) WriteTo(payload []byte, addr gonet.Addr) (int, error) { } func (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, error) { // nolint: unparam - var addrPortLen int32 - switch dest.Address.Family() { - case net.AddressFamilyDomain: - if protocol.IsDomainTooLong(dest.Address.Domain()) { - return 0, newError("Super long domain is not supported: ", dest.Address.Domain()) - } - addrPortLen = 1 + 1 + int32(len(dest.Address.Domain())) + 2 - case net.AddressFamilyIPv4: - addrPortLen = 1 + 4 + 2 - case net.AddressFamilyIPv6: - addrPortLen = 1 + 16 + 2 - default: - panic("Unknown address type.") - } - - length := len(payload) - lengthBuf := [2]byte{} - binary.BigEndian.PutUint16(lengthBuf[:], uint16(length)) - - buffer := buf.NewWithSize(addrPortLen + 2 + 2 + int32(length)) - defer buffer.Release() - - if err := addrParser.WriteAddressPort(buffer, dest.Address, dest.Port); err != nil { - return 0, err - } - if _, err := buffer.Write(lengthBuf[:]); err != nil { - return 0, err - } - if _, err := buffer.Write(crlf); err != nil { - return 0, err - } - if _, err := buffer.Write(payload); err != nil { - return 0, err - } - _, err := w.Write(buffer.Bytes()) + _, err := w.Write(payload) if err != nil { return 0, err } - return length, nil + return 0, nil } // ConnReader is TCP Connection Reader Wrapper for trojan protocol @@ -203,7 +169,7 @@ type PacketPayload struct { Buffer buf.MultiBuffer } -// PacketReader is UDP Connection Reader Wrapper for trojan protocol +// PacketReader is UDP Connection Reader Wrapper type PacketReader struct { io.Reader } diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index bb717289a7..4fb1842b3d 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -21,6 +21,7 @@ import ( "github.com/v2fly/v2ray-core/v5/features/policy" "github.com/v2fly/v2ray-core/v5/features/routing" "github.com/v2fly/v2ray-core/v5/transport/internet" + hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" "github.com/v2fly/v2ray-core/v5/transport/internet/udp" ) @@ -68,9 +69,9 @@ func (s *Server) Network() []net.Network { func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error { sid := session.ExportIDToError(ctx) - iConn := conn - if statConn, ok := iConn.(*internet.StatCouterConnection); ok { - iConn = statConn.Connection + hyConn, IsHy2Transport := conn.(*hy2_transport.HyConn) + if IsHy2Transport && hyConn.IsUDPExtension { + network = net.Network_UDP } sessionPolicy := s.policyManager.ForLevel(0) diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index 491edd9733..ac658a0af1 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -1,9 +1,9 @@ package hysteria2 import ( - "context" "time" + hy "github.com/apernet/hysteria/core/client" "github.com/apernet/quic-go" "github.com/v2fly/v2ray-core/v5/common/buf" @@ -11,16 +11,22 @@ import ( ) type HyConn struct { - UseUDPExtension bool - quicConn quic.Connection - stream quic.Stream - local net.Addr - remote net.Addr + IsUDPExtension bool + UDPSession hy.HyUDPConn + + stream quic.Stream + local net.Addr + remote net.Addr } func (c *HyConn) Read(b []byte) (int, error) { - if c.UseUDPExtension { - c.quicConn.ReceiveDatagram(context.Background()) + if c.IsUDPExtension { + data, address, err := c.UDPSession.Receive() + if err != nil { + return 0, err + } + b = append([]byte(address), data...) + return len(b), nil } return c.stream.Read(b) } @@ -33,15 +39,15 @@ func (c *HyConn) WriteMultiBuffer(mb buf.MultiBuffer) error { } func (c *HyConn) Write(b []byte) (int, error) { - if c.UseUDPExtension { - return len(b), c.quicConn.SendDatagram(b) + if c.IsUDPExtension { + return len(b), c.UDPSession.Send(b, "") } return c.stream.Write(b) } func (c *HyConn) Close() error { - if c.UseUDPExtension { - return nil + if c.IsUDPExtension { + return c.UDPSession.Close() } return c.stream.Close() } @@ -55,13 +61,22 @@ func (c *HyConn) RemoteAddr() net.Addr { } func (c *HyConn) SetDeadline(t time.Time) error { + if c.IsUDPExtension { + return nil + } return c.stream.SetDeadline(t) } func (c *HyConn) SetReadDeadline(t time.Time) error { + if c.IsUDPExtension { + return nil + } return c.stream.SetReadDeadline(t) } func (c *HyConn) SetWriteDeadline(t time.Time) error { + if c.IsUDPExtension { + return nil + } return c.stream.SetWriteDeadline(t) } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 2ae128abfc..493eef3857 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -77,13 +77,22 @@ func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConf return client, nil } +func CloseHyClient(dest net.Destination) error { + client, found := RunningClient[dest] + if found { + defer delete(RunningClient, dest) + return client.Close() + } + return nil +} + func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { config := streamSettings.ProtocolSettings.(*Config) var client hy.Client + var err error client, found := RunningClient[dest] if !found { - var err error client, err = NewHyClient(dest, streamSettings) if err != nil { return nil, err @@ -98,33 +107,34 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me } conn := &HyConn{ - local: quicConn.LocalAddr(), - remote: quicConn.RemoteAddr(), - quicConn: quicConn, + local: quicConn.LocalAddr(), + remote: quicConn.RemoteAddr(), } if network == net.Network_UDP { if !config.GetUdp() { return nil, newError("UDP extension is not enabled.") } - conn.UseUDPExtension = true + conn.IsUDPExtension = true + conn.UDPSession, err = client.UDP() + if err != nil { + CloseHyClient(dest) + return nil, err + } return conn, nil } - stream, err := client.OpenStream() + conn.stream, err = client.OpenStream() if err != nil { - delete(RunningClient, dest) - client.Close() + CloseHyClient(dest) return nil, err } - conn.stream = stream - // write TCP frame type frameSize := int(quicvarint.Len(FrameTypeTCPRequest)) buf := make([]byte, frameSize) hyProtocol.VarintPut(buf, FrameTypeTCPRequest) - stream.Write(buf) + conn.stream.Write(buf) return conn, nil } From 3f49529021279ff41bea4061e45972298aefb1cb Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Sun, 31 Mar 2024 01:08:24 +0800 Subject: [PATCH 44/81] add udp --- proxy/hysteria2/server.go | 3 +++ transport/internet/hysteria2/conn.go | 3 ++- transport/internet/hysteria2/dialer.go | 10 +++++----- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index 4fb1842b3d..b9ee5f9af6 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -2,6 +2,7 @@ package hysteria2 import ( "context" + "fmt" "io" "strings" "time" @@ -70,6 +71,8 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet sid := session.ExportIDToError(ctx) hyConn, IsHy2Transport := conn.(*hy2_transport.HyConn) + fmt.Println(IsHy2Transport) + fmt.Println(hyConn.IsUDPExtension) if IsHy2Transport && hyConn.IsUDPExtension { network = net.Network_UDP } diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index ac658a0af1..cdab049a56 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -13,6 +13,7 @@ import ( type HyConn struct { IsUDPExtension bool UDPSession hy.HyUDPConn + Target net.Destination stream quic.Stream local net.Addr @@ -40,7 +41,7 @@ func (c *HyConn) WriteMultiBuffer(mb buf.MultiBuffer) error { func (c *HyConn) Write(b []byte) (int, error) { if c.IsUDPExtension { - return len(b), c.UDPSession.Send(b, "") + return len(b), c.UDPSession.Send(b, c.Target.NetAddr()) } return c.stream.Write(b) } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 493eef3857..794b1a08d7 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -99,16 +99,16 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me } } quicConn := client.GetQuicConn() + conn := &HyConn{ + local: quicConn.LocalAddr(), + remote: quicConn.RemoteAddr(), + } outbound := session.OutboundFromContext(ctx) network := net.Network_TCP if outbound != nil { network = outbound.Target.Network - } - - conn := &HyConn{ - local: quicConn.LocalAddr(), - remote: quicConn.RemoteAddr(), + conn.Target = outbound.Target } if network == net.Network_UDP { From fc77e5f75eee0032ea048e66662187c6b4d40c11 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Mon, 1 Apr 2024 01:08:05 +0800 Subject: [PATCH 45/81] add UdpHijacker --- go.mod | 4 +- go.sum | 8 ++-- proxy/hysteria2/protocol.go | 16 +++---- transport/internet/hysteria2/conn.go | 61 +++++++++++++++++++++----- transport/internet/hysteria2/dialer.go | 10 ++--- transport/internet/hysteria2/hub.go | 20 ++++++--- 6 files changed, 82 insertions(+), 37 deletions(-) diff --git a/go.mod b/go.mod index daf86de378..acc737ce84 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ toolchain go1.21.4 require ( github.com/adrg/xdg v0.4.0 github.com/apernet/hysteria/core v0.0.0-00010101000000-000000000000 - github.com/apernet/quic-go v0.41.1-0.20240301003057-e18162de481d + github.com/apernet/quic-go v0.42.1-0.20240323215309-32a339817822 github.com/go-chi/chi/v5 v5.0.12 github.com/go-chi/render v1.0.3 github.com/go-playground/validator/v10 v10.19.0 @@ -83,7 +83,7 @@ require ( golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 // indirect golang.org/x/mod v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.4.0 // indirect + golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.19.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect ) diff --git a/go.sum b/go.sum index 15d96718b4..8c0010e855 100644 --- a/go.sum +++ b/go.sum @@ -25,8 +25,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/apernet/quic-go v0.41.1-0.20240301003057-e18162de481d h1:K1DMSNtPcaZ/lihYmOHnjThNfUX7cD6SNuVRFnVLVmI= -github.com/apernet/quic-go v0.41.1-0.20240301003057-e18162de481d/go.mod h1:4GInxO6ypy63J2NaO5rQx1wRp6K8YHI6zqLG+VswU6I= +github.com/apernet/quic-go v0.42.1-0.20240323215309-32a339817822 h1:+ZSzRxSMg1+fLTQKcIUvD2cCCgS+1rtyRhs+NL5oBgA= +github.com/apernet/quic-go v0.42.1-0.20240323215309-32a339817822/go.mod h1:j3QaAM7sVJqptDQyIQRWA6mASCfuxoHJszn67JQh1GE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -498,8 +498,8 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY= -golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index fbe7271e7b..4c3278d16e 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -27,17 +27,17 @@ const ( commandUDP byte = 3 ) -// ConnWriter is TCP Connection Writer Wrapper for trojan protocol +// ConnWriter is TCP Connection Writer Wrapper type ConnWriter struct { io.Writer - Target net.Destination - Account *MemoryAccount - headerSent bool + Target net.Destination + Account *MemoryAccount + TCPHeaderSent bool } // Write implements io.Writer func (c *ConnWriter) Write(p []byte) (n int, err error) { - if !c.headerSent { + if !c.TCPHeaderSent { if err := c.writeHeader(); err != nil { return 0, newError("failed to write request header").Base(err) } @@ -62,7 +62,7 @@ func (c *ConnWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { } func (c *ConnWriter) WriteHeader() error { - if !c.headerSent { + if !c.TCPHeaderSent { if err := c.writeHeader(); err != nil { return err } @@ -89,7 +89,7 @@ func (c *ConnWriter) writeHeader() error { _, err := c.Writer.Write(buf) if err == nil { - c.headerSent = true + c.TCPHeaderSent = true } return err } @@ -145,7 +145,7 @@ func (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, e return 0, nil } -// ConnReader is TCP Connection Reader Wrapper for trojan protocol +// ConnReader is TCP Connection Reader Wrapper type ConnReader struct { io.Reader Target net.Destination diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index cdab049a56..608f7d3198 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -3,17 +3,22 @@ package hysteria2 import ( "time" - hy "github.com/apernet/hysteria/core/client" + hy_client "github.com/apernet/hysteria/core/client" + hy_server "github.com/apernet/hysteria/core/server" "github.com/apernet/quic-go" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" ) +const CanNotUseUdpExtension = "Only hysteria2 proxy protocol can use udpExtension." + type HyConn struct { - IsUDPExtension bool - UDPSession hy.HyUDPConn - Target net.Destination + IsUDPExtension bool + IsServer bool + ClientUDPSession hy_client.HyUDPConn + ServerUDPSession hy_server.UDPConn + Target net.Destination stream quic.Stream local net.Addr @@ -22,12 +27,7 @@ type HyConn struct { func (c *HyConn) Read(b []byte) (int, error) { if c.IsUDPExtension { - data, address, err := c.UDPSession.Receive() - if err != nil { - return 0, err - } - b = append([]byte(address), data...) - return len(b), nil + return 0, newError(CanNotUseUdpExtension) } return c.stream.Read(b) } @@ -41,14 +41,51 @@ func (c *HyConn) WriteMultiBuffer(mb buf.MultiBuffer) error { func (c *HyConn) Write(b []byte) (int, error) { if c.IsUDPExtension { - return len(b), c.UDPSession.Send(b, c.Target.NetAddr()) + return 0, newError(CanNotUseUdpExtension) } return c.stream.Write(b) } +func (c *HyConn) WritePacket(b []byte, dest net.Destination) (int, error) { + if !c.IsUDPExtension || c.ClientUDPSession == nil { + return 0, newError(CanNotUseUdpExtension) + } + + if c.IsServer { + return c.ServerUDPSession.WriteTo(b, dest.NetAddr()) + } + return len(b), c.ClientUDPSession.Send(b, dest.NetAddr()) +} + +func (c *HyConn) ReadPacket(b []byte) (int, *net.Destination, error) { + if !c.IsUDPExtension || c.ClientUDPSession == nil { + return 0, nil, newError(CanNotUseUdpExtension) + } + + address := "" + var err error + if c.IsServer { + _, address, err = c.ServerUDPSession.ReadFrom(b) + } else { + b, address, err = c.ClientUDPSession.Receive() + } + if err != nil { + return 0, nil, err + } + dest, err := net.ParseDestination(address) + dest.Network = net.Network_UDP + if err != nil { + return 0, nil, err + } + return len(b), &dest, nil +} + func (c *HyConn) Close() error { if c.IsUDPExtension { - return c.UDPSession.Close() + if c.ClientUDPSession == nil { + return newError(CanNotUseUdpExtension) + } + return c.ClientUDPSession.Close() } return c.stream.Close() } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 794b1a08d7..b68e4ea849 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -80,7 +80,7 @@ func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConf func CloseHyClient(dest net.Destination) error { client, found := RunningClient[dest] if found { - defer delete(RunningClient, dest) + delete(RunningClient, dest) return client.Close() } return nil @@ -98,6 +98,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me return nil, err } } + quicConn := client.GetQuicConn() conn := &HyConn{ local: quicConn.LocalAddr(), @@ -111,12 +112,9 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me conn.Target = outbound.Target } - if network == net.Network_UDP { - if !config.GetUdp() { - return nil, newError("UDP extension is not enabled.") - } + if network == net.Network_UDP && config.GetUdp() { // only hysteria2 can use udpExtension conn.IsUDPExtension = true - conn.UDPSession, err = client.UDP() + conn.ClientUDPSession, err = client.UDP() if err != nil { CloseHyClient(dest) return nil, err diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 71c5137283..3169991b4d 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -3,7 +3,7 @@ package hysteria2 import ( "context" - hy "github.com/apernet/hysteria/core/server" + hy_server "github.com/apernet/hysteria/core/server" "github.com/apernet/quic-go" "github.com/apernet/quic-go/http3" @@ -16,7 +16,7 @@ import ( // Listener is an internet.Listener that listens for TCP connections. type Listener struct { - hyServer hy.Server + hyServer hy_server.Server rawConn net.PacketConn addConn internet.ConnHandler } @@ -43,6 +43,15 @@ func (l *Listener) ProxyStreamHijacker(ft http3.FrameType, conn quic.Connection, return true, nil } +func (l *Listener) UdpHijacker(entry *hy_server.UdpSessionEntry) { + udpConn := &HyConn{ + IsUDPExtension: true, + IsServer: true, + ServerUDPSession: entry.Conn, + } + l.addConn(udpConn) +} + // Listen creates a new Listener based on configurations. func Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) { if address.Family().IsDomain() { @@ -63,13 +72,14 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti addConn: handler, } - hyServer, err := hy.NewServer(&hy.Config{ + hyServer, err := hy_server.NewServer(&hy_server.Config{ Conn: rawConn, TLSConfig: *GetTLSConfig(streamSettings), Authenticator: &Authenticator{Password: config.GetPassword()}, IgnoreClientBandwidth: config.GetIgnoreClientBandwidth(), DisableUDP: !config.GetUdp(), StreamHijacker: listener.ProxyStreamHijacker, // acceptStreams + UdpSessionHijacker: listener.UdpHijacker, // acceptUDPSession }) if err != nil { return nil, err @@ -91,7 +101,7 @@ func CheckTLSConfig(streamSettings *internet.MemoryStreamConfig, isClient bool) return tlsSetting } -func GetTLSConfig(streamSettings *internet.MemoryStreamConfig) *hy.TLSConfig { +func GetTLSConfig(streamSettings *internet.MemoryStreamConfig) *hy_server.TLSConfig { tlsSetting := CheckTLSConfig(streamSettings, false) if tlsSetting == nil { tlsSetting = &tls.Config{ @@ -102,7 +112,7 @@ func GetTLSConfig(streamSettings *internet.MemoryStreamConfig) *hy.TLSConfig { }, } } - return &hy.TLSConfig{Certificates: tlsSetting.GetTLSConfig().Certificates} + return &hy_server.TLSConfig{Certificates: tlsSetting.GetTLSConfig().Certificates} } type Authenticator struct { From 7d6818fda11654d0223ccf67084ca6030f0a6245 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Mon, 1 Apr 2024 02:41:35 +0800 Subject: [PATCH 46/81] check IsServer before close --- transport/internet/hysteria2/conn.go | 5 ++++- transport/internet/hysteria2/dialer.go | 16 ++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index 608f7d3198..d1cbb380e7 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -82,9 +82,12 @@ func (c *HyConn) ReadPacket(b []byte) (int, *net.Destination, error) { func (c *HyConn) Close() error { if c.IsUDPExtension { - if c.ClientUDPSession == nil { + if !c.IsServer && c.ClientUDPSession == nil || (c.IsServer && c.ServerUDPSession == nil) { return newError(CanNotUseUdpExtension) } + if c.IsServer { + return c.ServerUDPSession.Close() + } return c.ClientUDPSession.Close() } return c.stream.Close() diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index b68e4ea849..5dadcf3a71 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -3,7 +3,7 @@ package hysteria2 import ( "context" - hy "github.com/apernet/hysteria/core/client" + hy_client "github.com/apernet/hysteria/core/client" hyProtocol "github.com/apernet/hysteria/core/international/protocol" "github.com/apernet/quic-go/quicvarint" @@ -18,9 +18,9 @@ const ( FrameTypeTCPRequest = 0x401 ) -var RunningClient map[net.Destination](hy.Client) +var RunningClient map[net.Destination](hy_client.Client) -func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hy.TLSConfig, error) { +func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hy_client.TLSConfig, error) { tlsSetting := CheckTLSConfig(streamSettings, true) if tlsSetting == nil { tlsSetting = &tls.Config{ @@ -28,7 +28,7 @@ func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hy.TLSConfig, AllowInsecure: true, } } - res := &hy.TLSConfig{ + res := &hy_client.TLSConfig{ ServerName: tlsSetting.ServerName, InsecureSkipVerify: tlsSetting.AllowInsecure, } @@ -52,7 +52,7 @@ func InitAddress(dest net.Destination) (net.Addr, error) { return destAddr, nil } -func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hy.Client, error) { +func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hy_client.Client, error) { tlsConfig, err := InitTLSConifg(streamSettings) if err != nil { return nil, err @@ -64,7 +64,7 @@ func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConf } config := streamSettings.ProtocolSettings.(*Config) - client, _, err := hy.NewClient(&hy.Config{ + client, _, err := hy_client.NewClient(&hy_client.Config{ TLSConfig: *tlsConfig, Auth: config.GetPassword(), ServerAddr: serverAddr, @@ -89,7 +89,7 @@ func CloseHyClient(dest net.Destination) error { func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { config := streamSettings.ProtocolSettings.(*Config) - var client hy.Client + var client hy_client.Client var err error client, found := RunningClient[dest] if !found { @@ -137,6 +137,6 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me } func init() { - RunningClient = make(map[net.Destination]hy.Client) + RunningClient = make(map[net.Destination]hy_client.Client) common.Must(internet.RegisterTransportDialer(protocolName, Dial)) } From 760d9b68932c33f3e5dc1bf7efbdb7eea17eb145 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 1 Apr 2024 18:02:32 +0800 Subject: [PATCH 47/81] update --- proxy/hysteria2/server.go | 2 +- transport/internet/hysteria2/dialer.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index b9ee5f9af6..f5f989d268 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -118,7 +118,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet } sessionPolicy = s.policyManager.ForLevel(0) - if destination.Network == net.Network_UDP { // handle udp request + if network == net.Network_UDP { // handle udp request return s.handleUDPPayload(ctx, &PacketReader{Reader: clientReader}, &PacketWriter{Writer: conn}, dispatcher) } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 5dadcf3a71..23010b9b84 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -114,6 +114,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me if network == net.Network_UDP && config.GetUdp() { // only hysteria2 can use udpExtension conn.IsUDPExtension = true + conn.IsServer = false conn.ClientUDPSession, err = client.UDP() if err != nil { CloseHyClient(dest) From 32902b2537d5b1bda81363e42911b78b6bfbef8d Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Mon, 1 Apr 2024 22:27:34 +0800 Subject: [PATCH 48/81] update --- proxy/hysteria2/server.go | 27 +++++++++++++------------- transport/internet/hysteria2/dialer.go | 1 + 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index f5f989d268..14ba0f102c 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -82,9 +82,21 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet return newError("unable to set read deadline").Base(err).AtWarning() } + bufferedReader := &buf.BufferedReader{ + Reader: buf.NewReader(conn), + } + clientReader := &ConnReader{Reader: bufferedReader} + + if err := conn.SetReadDeadline(time.Time{}); err != nil { + return newError("unable to set read deadline").Base(err).AtWarning() + } + + if network == net.Network_UDP { // handle udp request + return s.handleUDPPayload(ctx, &PacketReader{Reader: clientReader}, &PacketWriter{Writer: conn}, dispatcher) + } + var reqAddr string var err error - if network == net.Network_TCP { reqAddr, err = hyProtocol.ReadTCPRequest(conn) if err != nil { @@ -95,9 +107,6 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet return newError("failed to send response").Base(err) } } - bufferedReader := &buf.BufferedReader{ - Reader: buf.NewReader(conn), - } address := strings.Split(reqAddr, ":") port, err := net.PortFromString(address[1]) @@ -106,22 +115,12 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet } destination := net.Destination{Network: network, Address: net.ParseAddress(address[0]), Port: port} - clientReader := &ConnReader{Reader: bufferedReader} - - if err := conn.SetReadDeadline(time.Time{}); err != nil { - return newError("unable to set read deadline").Base(err).AtWarning() - } - inbound := session.InboundFromContext(ctx) if inbound == nil { panic("no inbound metadata") } sessionPolicy = s.policyManager.ForLevel(0) - if network == net.Network_UDP { // handle udp request - return s.handleUDPPayload(ctx, &PacketReader{Reader: clientReader}, &PacketWriter{Writer: conn}, dispatcher) - } - ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ From: conn.RemoteAddr(), To: destination, diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 23010b9b84..562a5a5ddc 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -93,6 +93,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me var err error client, found := RunningClient[dest] if !found { + // TODO: Clean idle connections client, err = NewHyClient(dest, streamSettings) if err != nil { return nil, err From 1bf4ee76903909add96194426210401f0816ac29 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Thu, 4 Apr 2024 18:12:22 +0800 Subject: [PATCH 49/81] add package into hysteria2 --- proxy/hysteria2/client.go | 10 +++++++-- proxy/hysteria2/protocol.go | 42 ++++++++----------------------------- proxy/hysteria2/server.go | 3 --- 3 files changed, 17 insertions(+), 38 deletions(-) diff --git a/proxy/hysteria2/client.go b/proxy/hysteria2/client.go index 6df25d3b20..934ee2c931 100644 --- a/proxy/hysteria2/client.go +++ b/proxy/hysteria2/client.go @@ -17,6 +17,7 @@ import ( "github.com/v2fly/v2ray-core/v5/proxy" "github.com/v2fly/v2ray-core/v5/transport" "github.com/v2fly/v2ray-core/v5/transport/internet" + hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" ) // Client is an inbound handler for trojan protocol @@ -74,6 +75,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter } newError("tunneling request to ", destination, " via ", server.Destination().NetAddr()).WriteToLog(session.ExportIDToError(ctx)) + hyConn, IsHy2Transport := conn.(*hy2_transport.HyConn) + if !IsHy2Transport || !hyConn.IsUDPExtension { + return newError(hy2_transport.CanNotUseUdpExtension) + } + defer conn.Close() user := server.PickUser() @@ -95,7 +101,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter bodyWriter = connWriter if network == net.Network_UDP { - bodyWriter = &PacketWriter{Writer: connWriter, Target: destination} + bodyWriter = &PacketWriter{Writer: connWriter, Target: destination, HyConn: hyConn} } else { // write some request payload to buffer err = buf.CopyOnceTimeout(link.Reader, bodyWriter, proxy.FirstPayloadTimeout) @@ -127,7 +133,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter var reader buf.Reader if network == net.Network_UDP { reader = &PacketReader{ - Reader: conn, + Reader: conn, HyConn: hyConn, } } else { ok, msg, err := hyProtocol.ReadTCPResponse(conn) diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index 4c3278d16e..a138d6c56d 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -10,6 +10,7 @@ import ( "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/protocol" + hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" ) var ( @@ -97,6 +98,7 @@ func (c *ConnWriter) writeHeader() error { // PacketWriter UDP Connection Writer Wrapper type PacketWriter struct { io.Writer + HyConn *hy2_transport.HyConn Target net.Destination } @@ -136,13 +138,8 @@ func (w *PacketWriter) WriteTo(payload []byte, addr gonet.Addr) (int, error) { return w.writePacket(payload, dest) } -func (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, error) { // nolint: unparam - _, err := w.Write(payload) - if err != nil { - return 0, err - } - - return 0, nil +func (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, error) { + return w.HyConn.WritePacket(payload, dest) } // ConnReader is TCP Connection Reader Wrapper @@ -172,6 +169,7 @@ type PacketPayload struct { // PacketReader is UDP Connection Reader Wrapper type PacketReader struct { io.Reader + HyConn *hy2_transport.HyConn } // ReadMultiBuffer implements buf.Reader @@ -185,32 +183,10 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) { // ReadMultiBufferWithMetadata reads udp packet with destination func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) { - addr, port, err := addrParser.ReadAddressPort(nil, r) - if err != nil { - return nil, newError("failed to read address and port").Base(err) - } - - var lengthBuf [2]byte - if _, err := io.ReadFull(r, lengthBuf[:]); err != nil { - return nil, newError("failed to read payload length").Base(err) - } - - length := binary.BigEndian.Uint16(lengthBuf[:]) - - var crlf [2]byte - if _, err := io.ReadFull(r, crlf[:]); err != nil { - return nil, newError("failed to read crlf").Base(err) - } - - dest := net.UDPDestination(addr, port) - - b := buf.NewWithSize(int32(length)) - _, err = b.ReadFullFrom(r, int32(length)) - if err != nil { - return nil, newError("failed to read payload").Base(err) - } - - return &PacketPayload{Target: dest, Buffer: buf.MultiBuffer{b}}, nil + var data []byte + _, dest, _ := r.HyConn.ReadPacket(data) + b := buf.FromBytes(data) + return &PacketPayload{Target: *dest, Buffer: buf.MultiBuffer{b}}, nil } type PacketConnectionReader struct { diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index 14ba0f102c..340789299b 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -2,7 +2,6 @@ package hysteria2 import ( "context" - "fmt" "io" "strings" "time" @@ -71,8 +70,6 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet sid := session.ExportIDToError(ctx) hyConn, IsHy2Transport := conn.(*hy2_transport.HyConn) - fmt.Println(IsHy2Transport) - fmt.Println(hyConn.IsUDPExtension) if IsHy2Transport && hyConn.IsUDPExtension { network = net.Network_UDP } From 860af00943725a070f5e9a2ec73970febead7881 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Thu, 4 Apr 2024 18:17:53 +0800 Subject: [PATCH 50/81] hysteria2 udp can not apply on others transport --- proxy/hysteria2/server.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index 340789299b..a371ccd73d 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -74,6 +74,10 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet network = net.Network_UDP } + if !IsHy2Transport && network == net.Network_UDP { + return newError(hy2_transport.CanNotUseUdpExtension) + } + sessionPolicy := s.policyManager.ForLevel(0) if err := conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil { return newError("unable to set read deadline").Base(err).AtWarning() From f5d3ba9b624dbd3b560152f5c391e564fd26bba3 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Thu, 4 Apr 2024 18:30:43 +0800 Subject: [PATCH 51/81] other proxy protocol can use udpExtension --- transport/internet/hysteria2/conn.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index d1cbb380e7..8c7d56b5e7 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -27,7 +27,8 @@ type HyConn struct { func (c *HyConn) Read(b []byte) (int, error) { if c.IsUDPExtension { - return 0, newError(CanNotUseUdpExtension) + n, _, err := c.ReadPacket(b) + return n, err } return c.stream.Read(b) } @@ -41,7 +42,8 @@ func (c *HyConn) WriteMultiBuffer(mb buf.MultiBuffer) error { func (c *HyConn) Write(b []byte) (int, error) { if c.IsUDPExtension { - return 0, newError(CanNotUseUdpExtension) + dest, _ := net.ParseDestination("v2fly.org:6666") + return c.WritePacket(b, dest) } return c.stream.Write(b) } From 3e133d1556824c77093cf21a8d47d88c6cf30a57 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Fri, 5 Apr 2024 04:06:07 +0800 Subject: [PATCH 52/81] add udp test --- transport/internet/hysteria2/conn.go | 41 ++++++++----- transport/internet/hysteria2/hub.go | 2 +- transport/internet/hysteria2/hy2_test.go | 73 +++++++++++++++++++++++- 3 files changed, 100 insertions(+), 16 deletions(-) diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index 8c7d56b5e7..7b1803b9d6 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -1,9 +1,11 @@ package hysteria2 import ( + "fmt" "time" hy_client "github.com/apernet/hysteria/core/client" + "github.com/apernet/hysteria/core/international/protocol" hy_server "github.com/apernet/hysteria/core/server" "github.com/apernet/quic-go" @@ -17,7 +19,7 @@ type HyConn struct { IsUDPExtension bool IsServer bool ClientUDPSession hy_client.HyUDPConn - ServerUDPSession hy_server.UDPConn + ServerUDPSession *hy_server.UdpSessionEntry Target net.Destination stream quic.Stream @@ -42,44 +44,54 @@ func (c *HyConn) WriteMultiBuffer(mb buf.MultiBuffer) error { func (c *HyConn) Write(b []byte) (int, error) { if c.IsUDPExtension { - dest, _ := net.ParseDestination("v2fly.org:6666") + dest, _ := net.ParseDestination("udp:v2fly.org:6666") return c.WritePacket(b, dest) } return c.stream.Write(b) } func (c *HyConn) WritePacket(b []byte, dest net.Destination) (int, error) { - if !c.IsUDPExtension || c.ClientUDPSession == nil { + if !c.IsUDPExtension { return 0, newError(CanNotUseUdpExtension) } if c.IsServer { - return c.ServerUDPSession.WriteTo(b, dest.NetAddr()) + msg := &protocol.UDPMessage{ + SessionID: c.ServerUDPSession.ID, + PacketID: 0, + FragID: 0, + FragCount: 1, + Addr: dest.NetAddr(), + Data: b, + } + c.ServerUDPSession.SendCh <- msg + return len(b), nil } return len(b), c.ClientUDPSession.Send(b, dest.NetAddr()) } func (c *HyConn) ReadPacket(b []byte) (int, *net.Destination, error) { - if !c.IsUDPExtension || c.ClientUDPSession == nil { + if !c.IsUDPExtension { return 0, nil, newError(CanNotUseUdpExtension) } - address := "" - var err error if c.IsServer { - _, address, err = c.ServerUDPSession.ReadFrom(b) - } else { - b, address, err = c.ClientUDPSession.Receive() + msg := <-c.ServerUDPSession.ReceiveCh + nBytes := copy(b, msg.Data) + dest, err := net.ParseDestination("udp:" + msg.Addr) + return nBytes, &dest, err } + fmt.Println("client waitting packet:") + data, address, err := c.ClientUDPSession.Receive() if err != nil { return 0, nil, err } - dest, err := net.ParseDestination(address) - dest.Network = net.Network_UDP + nBytes := copy(b, data) + dest, err := net.ParseDestination("udp:" + address) if err != nil { return 0, nil, err } - return len(b), &dest, nil + return nBytes, &dest, nil } func (c *HyConn) Close() error { @@ -88,7 +100,8 @@ func (c *HyConn) Close() error { return newError(CanNotUseUdpExtension) } if c.IsServer { - return c.ServerUDPSession.Close() + c.ServerUDPSession.Close() + return c.ServerUDPSession.Conn.Close() } return c.ClientUDPSession.Close() } diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 3169991b4d..a4d8702a11 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -47,7 +47,7 @@ func (l *Listener) UdpHijacker(entry *hy_server.UdpSessionEntry) { udpConn := &HyConn{ IsUDPExtension: true, IsServer: true, - ServerUDPSession: entry.Conn, + ServerUDPSession: entry, } l.addConn(udpConn) } diff --git a/transport/internet/hysteria2/hy2_test.go b/transport/internet/hysteria2/hy2_test.go index 05def44b68..bf1f9ce61b 100644 --- a/transport/internet/hysteria2/hy2_test.go +++ b/transport/internet/hysteria2/hy2_test.go @@ -13,13 +13,14 @@ import ( "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert" + "github.com/v2fly/v2ray-core/v5/common/session" "github.com/v2fly/v2ray-core/v5/testing/servers/udp" "github.com/v2fly/v2ray-core/v5/transport/internet" "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" "github.com/v2fly/v2ray-core/v5/transport/internet/tls" ) -func TestHTTP3Connection(t *testing.T) { +func TestTCP(t *testing.T) { port := udp.PickPort() listener, err := hysteria2.Listen(context.Background(), net.LocalHostIP, port, &internet.MemoryStreamConfig{ @@ -92,3 +93,73 @@ func TestHTTP3Connection(t *testing.T) { t.Error(r) } } + +func TestUDP(t *testing.T) { + port := udp.PickPort() + + listener, err := hysteria2.Listen(context.Background(), net.LocalHostIP, port, &internet.MemoryStreamConfig{ + ProtocolName: "hysteria2", + ProtocolSettings: &hysteria2.Config{Password: "123", Udp: true}, + SecurityType: "tls", + SecuritySettings: &tls.Config{ + Certificate: []*tls.Certificate{ + tls.ParseCertificate( + cert.MustGenerate(nil, + cert.DNSNames("www.v2fly.org"), + ), + ), + }, + }, + }, func(conn internet.Connection) { + fmt.Println("incoming") + go func() { + defer conn.Close() + + b := buf.New() + defer b.Release() + + for { + b.Clear() + if _, err := b.ReadFrom(conn); err != nil { + fmt.Println(err) + return + } + fmt.Println(b.Bytes()) + common.Must2(conn.Write(b.Bytes())) + } + }() + }) + common.Must(err) + + defer listener.Close() + + time.Sleep(time.Second) + + address, err := net.ParseDestination("127.0.0.1:1180") + address.Network = net.Network_UDP + dctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: address}) + + conn, err := hysteria2.Dial(dctx, net.TCPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{ + ProtocolName: "hysteria2", + ProtocolSettings: &hysteria2.Config{Password: "123", Udp: true}, + SecurityType: "tls", + SecuritySettings: &tls.Config{ + ServerName: "www.v2fly.org", + AllowInsecure: true, + }, + }) + common.Must(err) + defer conn.Close() + + const N = 10 + b1 := make([]byte, N) + common.Must2(rand.Read(b1)) + common.Must2(conn.Write(b1)) + + b2 := buf.New() + b2.Clear() + common.Must2(b2.ReadFullFrom(conn, N)) + if r := cmp.Diff(b2.Bytes(), b1); r != "" { + t.Error(r) + } +} From b3c31b6b106e76afae4032b6be9a665137cac660 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Fri, 5 Apr 2024 04:09:41 +0800 Subject: [PATCH 53/81] remove fmt --- transport/internet/hysteria2/conn.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index 7b1803b9d6..a3059297f8 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -1,7 +1,6 @@ package hysteria2 import ( - "fmt" "time" hy_client "github.com/apernet/hysteria/core/client" @@ -81,7 +80,6 @@ func (c *HyConn) ReadPacket(b []byte) (int, *net.Destination, error) { dest, err := net.ParseDestination("udp:" + msg.Addr) return nBytes, &dest, err } - fmt.Println("client waitting packet:") data, address, err := c.ClientUDPSession.Receive() if err != nil { return 0, nil, err From 76f44b69a0667085bb56949261d5511eeedff132 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Fri, 5 Apr 2024 20:37:50 +0800 Subject: [PATCH 54/81] udp test ok --- transport/internet/hysteria2/hy2_test.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/transport/internet/hysteria2/hy2_test.go b/transport/internet/hysteria2/hy2_test.go index bf1f9ce61b..1a0f8d3d20 100644 --- a/transport/internet/hysteria2/hy2_test.go +++ b/transport/internet/hysteria2/hy2_test.go @@ -84,14 +84,6 @@ func TestTCP(t *testing.T) { if r := cmp.Diff(b2.Bytes(), b1); r != "" { t.Error(r) } - - common.Must2(conn.Write(b1)) - - b2.Clear() - common.Must2(b2.ReadFullFrom(conn, N)) - if r := cmp.Diff(b2.Bytes(), b1); r != "" { - t.Error(r) - } } func TestUDP(t *testing.T) { @@ -124,7 +116,6 @@ func TestUDP(t *testing.T) { fmt.Println(err) return } - fmt.Println(b.Bytes()) common.Must2(conn.Write(b.Bytes())) } }() @@ -135,8 +126,7 @@ func TestUDP(t *testing.T) { time.Sleep(time.Second) - address, err := net.ParseDestination("127.0.0.1:1180") - address.Network = net.Network_UDP + address, err := net.ParseDestination("udp:127.0.0.1:1180") dctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: address}) conn, err := hysteria2.Dial(dctx, net.TCPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{ @@ -151,7 +141,7 @@ func TestUDP(t *testing.T) { common.Must(err) defer conn.Close() - const N = 10 + const N = 1000 b1 := make([]byte, N) common.Must2(rand.Read(b1)) common.Must2(conn.Write(b1)) From a7399cd7f4ae17ddd93fa6b0d646e2c5f6a6fbfd Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Sat, 6 Apr 2024 00:44:12 +0800 Subject: [PATCH 55/81] change test name and add udp test --- proxy/hysteria2/client.go | 2 +- proxy/hysteria2/protocol.go | 1 - testing/scenarios/hy2_test.go | 420 ++++++++++++++++++ testing/scenarios/transport_test.go | 388 ---------------- .../{hy2_test.go => hy2_transport_test.go} | 0 5 files changed, 421 insertions(+), 390 deletions(-) create mode 100644 testing/scenarios/hy2_test.go rename transport/internet/hysteria2/{hy2_test.go => hy2_transport_test.go} (100%) diff --git a/proxy/hysteria2/client.go b/proxy/hysteria2/client.go index 934ee2c931..bc11e43713 100644 --- a/proxy/hysteria2/client.go +++ b/proxy/hysteria2/client.go @@ -76,7 +76,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter newError("tunneling request to ", destination, " via ", server.Destination().NetAddr()).WriteToLog(session.ExportIDToError(ctx)) hyConn, IsHy2Transport := conn.(*hy2_transport.HyConn) - if !IsHy2Transport || !hyConn.IsUDPExtension { + if !IsHy2Transport && !hyConn.IsUDPExtension { // is not hysteria2 and proxing UDP return newError(hy2_transport.CanNotUseUdpExtension) } diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index a138d6c56d..4bb4581e27 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -1,7 +1,6 @@ package hysteria2 import ( - "encoding/binary" "io" gonet "net" diff --git a/testing/scenarios/hy2_test.go b/testing/scenarios/hy2_test.go new file mode 100644 index 0000000000..c54569ca02 --- /dev/null +++ b/testing/scenarios/hy2_test.go @@ -0,0 +1,420 @@ +package scenarios + +import ( + "fmt" + "testing" + "time" + + "golang.org/x/sync/errgroup" + "google.golang.org/protobuf/types/known/anypb" + + core "github.com/v2fly/v2ray-core/v5" + "github.com/v2fly/v2ray-core/v5/app/log" + "github.com/v2fly/v2ray-core/v5/app/proxyman" + "github.com/v2fly/v2ray-core/v5/common" + clog "github.com/v2fly/v2ray-core/v5/common/log" + "github.com/v2fly/v2ray-core/v5/common/net" + "github.com/v2fly/v2ray-core/v5/common/protocol" + "github.com/v2fly/v2ray-core/v5/common/serial" + "github.com/v2fly/v2ray-core/v5/common/uuid" + "github.com/v2fly/v2ray-core/v5/proxy/dokodemo" + "github.com/v2fly/v2ray-core/v5/proxy/freedom" + "github.com/v2fly/v2ray-core/v5/proxy/hysteria2" + "github.com/v2fly/v2ray-core/v5/proxy/vmess" + "github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound" + "github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound" + "github.com/v2fly/v2ray-core/v5/testing/servers/tcp" + "github.com/v2fly/v2ray-core/v5/testing/servers/udp" + "github.com/v2fly/v2ray-core/v5/transport/internet" + "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http" + hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" + tcptransport "github.com/v2fly/v2ray-core/v5/transport/internet/tcp" +) + +func TestVMessHysteria2Congestion(t *testing.T) { + for _, v := range []string{"bbr", "brutal"} { + testVMessHysteria2(t, v) + } +} + +func testVMessHysteria2(t *testing.T, congestionType string) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() + + userID := protocol.NewID(uuid.New()) + serverPort := udp.PickPort() + serverConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(serverPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ + ProtocolName: "hysteria2", + TransportSettings: []*internet.TransportConfig{ + { + ProtocolName: "hysteria2", + Settings: serial.ToTypedMessage(&hy2_transport.Config{ + Security: &protocol.SecurityConfig{ + Type: protocol.SecurityType_NONE, + }, + Congestion: &hy2_transport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, + Password: "password", + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&inbound.Config{ + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + AlterId: 0, + }), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(clientPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ + StreamSettings: &internet.StreamConfig{ + ProtocolName: "hysteria2", + TransportSettings: []*internet.TransportConfig{ + { + ProtocolName: "hysteria2", + Settings: serial.ToTypedMessage(&hy2_transport.Config{ + Security: &protocol.SecurityConfig{ + Type: protocol.SecurityType_NONE, + }, + Congestion: &hy2_transport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, + Password: "password", + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&outbound.Config{ + Receiver: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + AlterId: 0, + SecuritySettings: &protocol.SecurityConfig{ + Type: protocol.SecurityType_AES128_GCM, + }, + }), + }, + }, + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + if err != nil { + t.Fatal("Failed to initialize all servers: ", err.Error()) + } + defer CloseAllServers(servers) + + var errg errgroup.Group + for i := 0; i < 10; i++ { + errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) + } + + if err := errg.Wait(); err != nil { + t.Error(err) + } +} + +func TestHysteria2Offical(t *testing.T) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() + + serverPort := udp.PickPort() + fmt.Println(serverPort) + serverConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(serverPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ + ProtocolName: "hysteria2", + TransportSettings: []*internet.TransportConfig{ + { + ProtocolName: "hysteria2", + Settings: serial.ToTypedMessage(&hy2_transport.Config{ + Security: &protocol.SecurityConfig{ + Type: protocol.SecurityType_NONE, + }, + Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, + Udp: true, + Password: "password", + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&hysteria2.ServerConfig{ + Users: []*protocol.User{ + { + Account: serial.ToTypedMessage(&hysteria2.Account{}), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(clientPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP, net.Network_UDP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ + StreamSettings: &internet.StreamConfig{ + ProtocolName: "hysteria2", + TransportSettings: []*internet.TransportConfig{ + { + ProtocolName: "hysteria2", + Settings: serial.ToTypedMessage(&hy2_transport.Config{ + Security: &protocol.SecurityConfig{ + Type: protocol.SecurityType_NONE, + }, + Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, + Udp: true, + Password: "password", + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&hysteria2.ClientConfig{ + Server: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&hysteria2.Account{}), + }, + }, + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + if err != nil { + t.Fatal("Failed to initialize all servers: ", err.Error()) + } + defer CloseAllServers(servers) + + var errg errgroup.Group + for i := 0; i < 10; i++ { + errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) + errg.Go(testUDPConn(clientPort, 10240*1024, time.Second*40)) + } + + if err := errg.Wait(); err != nil { + t.Error(err) + } +} + +func TestHysteria2TCP(t *testing.T) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() + + serverPort := udp.PickPort() + serverConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(serverPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ + TransportSettings: []*internet.TransportConfig{ + { + Protocol: internet.TransportProtocol_TCP, + Settings: serial.ToTypedMessage(&tcptransport.Config{ + HeaderSettings: serial.ToTypedMessage(&http.Config{}), + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&hysteria2.ServerConfig{ + Users: []*protocol.User{ + { + Account: serial.ToTypedMessage(&hysteria2.Account{}), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + App: []*anypb.Any{ + serial.ToTypedMessage(&log.Config{ + Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(clientPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ + StreamSettings: &internet.StreamConfig{ + TransportSettings: []*internet.TransportConfig{ + { + Protocol: internet.TransportProtocol_TCP, + Settings: serial.ToTypedMessage(&tcptransport.Config{ + HeaderSettings: serial.ToTypedMessage(&http.Config{}), + }), + }, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&hysteria2.ClientConfig{ + Server: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&hysteria2.Account{}), + }, + }, + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + if err != nil { + t.Fatal("Failed to initialize all servers: ", err.Error()) + } + defer CloseAllServers(servers) + + var errg errgroup.Group + for i := 0; i < 1; i++ { + errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) + } + + if err := errg.Wait(); err != nil { + t.Error(err) + } +} diff --git a/testing/scenarios/transport_test.go b/testing/scenarios/transport_test.go index ce06e99121..20a8dca544 100644 --- a/testing/scenarios/transport_test.go +++ b/testing/scenarios/transport_test.go @@ -1,7 +1,6 @@ package scenarios import ( - "fmt" "os" "runtime" "testing" @@ -21,7 +20,6 @@ import ( "github.com/v2fly/v2ray-core/v5/common/uuid" "github.com/v2fly/v2ray-core/v5/proxy/dokodemo" "github.com/v2fly/v2ray-core/v5/proxy/freedom" - "github.com/v2fly/v2ray-core/v5/proxy/hysteria2" "github.com/v2fly/v2ray-core/v5/proxy/vmess" "github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound" "github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound" @@ -31,7 +29,6 @@ import ( "github.com/v2fly/v2ray-core/v5/transport/internet/domainsocket" "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http" "github.com/v2fly/v2ray-core/v5/transport/internet/headers/wechat" - hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" "github.com/v2fly/v2ray-core/v5/transport/internet/quic" tcptransport "github.com/v2fly/v2ray-core/v5/transport/internet/tcp" ) @@ -386,388 +383,3 @@ func TestVMessQuic(t *testing.T) { t.Error(err) } } - -func TestVMessHysteria2(t *testing.T) { - for _, v := range []string{"bbr", "brutal"} { - testVMessHysteria2(t, v) - } -} - -func testVMessHysteria2(t *testing.T, congestionType string) { - tcpServer := tcp.Server{ - MsgProcessor: xor, - } - dest, err := tcpServer.Start() - common.Must(err) - defer tcpServer.Close() - - userID := protocol.NewID(uuid.New()) - serverPort := udp.PickPort() - serverConfig := &core.Config{ - App: []*anypb.Any{ - serial.ToTypedMessage(&log.Config{ - Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, - }), - }, - Inbound: []*core.InboundHandlerConfig{ - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: net.SinglePortRange(serverPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - StreamSettings: &internet.StreamConfig{ - ProtocolName: "hysteria2", - TransportSettings: []*internet.TransportConfig{ - { - ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hy2_transport.Config{ - Security: &protocol.SecurityConfig{ - Type: protocol.SecurityType_NONE, - }, - Congestion: &hy2_transport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, - Password: "password", - }), - }, - }, - }, - }), - ProxySettings: serial.ToTypedMessage(&inbound.Config{ - User: []*protocol.User{ - { - Account: serial.ToTypedMessage(&vmess.Account{ - Id: userID.String(), - AlterId: 0, - }), - }, - }, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - ProxySettings: serial.ToTypedMessage(&freedom.Config{}), - }, - }, - } - - clientPort := tcp.PickPort() - clientConfig := &core.Config{ - App: []*anypb.Any{ - serial.ToTypedMessage(&log.Config{ - Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, - }), - }, - Inbound: []*core.InboundHandlerConfig{ - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: net.SinglePortRange(clientPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - }), - ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ - Address: net.NewIPOrDomain(dest.Address), - Port: uint32(dest.Port), - NetworkList: &net.NetworkList{ - Network: []net.Network{net.Network_TCP}, - }, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ - StreamSettings: &internet.StreamConfig{ - ProtocolName: "hysteria2", - TransportSettings: []*internet.TransportConfig{ - { - ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hy2_transport.Config{ - Security: &protocol.SecurityConfig{ - Type: protocol.SecurityType_NONE, - }, - Congestion: &hy2_transport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, - Password: "password", - }), - }, - }, - }, - }), - ProxySettings: serial.ToTypedMessage(&outbound.Config{ - Receiver: []*protocol.ServerEndpoint{ - { - Address: net.NewIPOrDomain(net.LocalHostIP), - Port: uint32(serverPort), - User: []*protocol.User{ - { - Account: serial.ToTypedMessage(&vmess.Account{ - Id: userID.String(), - AlterId: 0, - SecuritySettings: &protocol.SecurityConfig{ - Type: protocol.SecurityType_AES128_GCM, - }, - }), - }, - }, - }, - }, - }), - }, - }, - } - - servers, err := InitializeServerConfigs(serverConfig, clientConfig) - if err != nil { - t.Fatal("Failed to initialize all servers: ", err.Error()) - } - defer CloseAllServers(servers) - - var errg errgroup.Group - for i := 0; i < 10; i++ { - errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) - } - - if err := errg.Wait(); err != nil { - t.Error(err) - } -} - -func TestHysteria2Offical(t *testing.T) { - tcpServer := tcp.Server{ - MsgProcessor: xor, - } - dest, err := tcpServer.Start() - common.Must(err) - defer tcpServer.Close() - - serverPort := udp.PickPort() - fmt.Println(serverPort) - serverConfig := &core.Config{ - App: []*anypb.Any{ - serial.ToTypedMessage(&log.Config{ - Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, - }), - }, - Inbound: []*core.InboundHandlerConfig{ - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: net.SinglePortRange(serverPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - StreamSettings: &internet.StreamConfig{ - ProtocolName: "hysteria2", - TransportSettings: []*internet.TransportConfig{ - { - ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hy2_transport.Config{ - Security: &protocol.SecurityConfig{ - Type: protocol.SecurityType_NONE, - }, - Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, - Password: "password", - }), - }, - }, - }, - }), - ProxySettings: serial.ToTypedMessage(&hysteria2.ServerConfig{ - Users: []*protocol.User{ - { - Account: serial.ToTypedMessage(&hysteria2.Account{}), - }, - }, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - ProxySettings: serial.ToTypedMessage(&freedom.Config{}), - }, - }, - } - - clientPort := tcp.PickPort() - clientConfig := &core.Config{ - App: []*anypb.Any{ - serial.ToTypedMessage(&log.Config{ - Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, - }), - }, - Inbound: []*core.InboundHandlerConfig{ - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: net.SinglePortRange(clientPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - }), - ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ - Address: net.NewIPOrDomain(dest.Address), - Port: uint32(dest.Port), - NetworkList: &net.NetworkList{ - Network: []net.Network{net.Network_TCP}, - }, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ - StreamSettings: &internet.StreamConfig{ - ProtocolName: "hysteria2", - TransportSettings: []*internet.TransportConfig{ - { - ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hy2_transport.Config{ - Security: &protocol.SecurityConfig{ - Type: protocol.SecurityType_NONE, - }, - Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, - Password: "password", - }), - }, - }, - }, - }), - ProxySettings: serial.ToTypedMessage(&hysteria2.ClientConfig{ - Server: []*protocol.ServerEndpoint{ - { - Address: net.NewIPOrDomain(net.LocalHostIP), - Port: uint32(serverPort), - User: []*protocol.User{ - { - Account: serial.ToTypedMessage(&hysteria2.Account{}), - }, - }, - }, - }, - }), - }, - }, - } - - servers, err := InitializeServerConfigs(serverConfig, clientConfig) - if err != nil { - t.Fatal("Failed to initialize all servers: ", err.Error()) - } - defer CloseAllServers(servers) - - var errg errgroup.Group - for i := 0; i < 10; i++ { - errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) - } - - if err := errg.Wait(); err != nil { - t.Error(err) - } -} - -func TestHysteria2TCP(t *testing.T) { - tcpServer := tcp.Server{ - MsgProcessor: xor, - } - dest, err := tcpServer.Start() - common.Must(err) - defer tcpServer.Close() - - serverPort := udp.PickPort() - serverConfig := &core.Config{ - App: []*anypb.Any{ - serial.ToTypedMessage(&log.Config{ - Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, - }), - }, - Inbound: []*core.InboundHandlerConfig{ - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: net.SinglePortRange(serverPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - StreamSettings: &internet.StreamConfig{ - TransportSettings: []*internet.TransportConfig{ - { - Protocol: internet.TransportProtocol_TCP, - Settings: serial.ToTypedMessage(&tcptransport.Config{ - HeaderSettings: serial.ToTypedMessage(&http.Config{}), - }), - }, - }, - }, - }), - ProxySettings: serial.ToTypedMessage(&hysteria2.ServerConfig{ - Users: []*protocol.User{ - { - Account: serial.ToTypedMessage(&hysteria2.Account{}), - }, - }, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - ProxySettings: serial.ToTypedMessage(&freedom.Config{}), - }, - }, - } - - clientPort := tcp.PickPort() - clientConfig := &core.Config{ - App: []*anypb.Any{ - serial.ToTypedMessage(&log.Config{ - Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console}, - }), - }, - Inbound: []*core.InboundHandlerConfig{ - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: net.SinglePortRange(clientPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - }), - ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ - Address: net.NewIPOrDomain(dest.Address), - Port: uint32(dest.Port), - NetworkList: &net.NetworkList{ - Network: []net.Network{net.Network_TCP}, - }, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ - StreamSettings: &internet.StreamConfig{ - TransportSettings: []*internet.TransportConfig{ - { - Protocol: internet.TransportProtocol_TCP, - Settings: serial.ToTypedMessage(&tcptransport.Config{ - HeaderSettings: serial.ToTypedMessage(&http.Config{}), - }), - }, - }, - }, - }), - ProxySettings: serial.ToTypedMessage(&hysteria2.ClientConfig{ - Server: []*protocol.ServerEndpoint{ - { - Address: net.NewIPOrDomain(net.LocalHostIP), - Port: uint32(serverPort), - User: []*protocol.User{ - { - Account: serial.ToTypedMessage(&hysteria2.Account{}), - }, - }, - }, - }, - }), - }, - }, - } - - servers, err := InitializeServerConfigs(serverConfig, clientConfig) - if err != nil { - t.Fatal("Failed to initialize all servers: ", err.Error()) - } - defer CloseAllServers(servers) - - var errg errgroup.Group - for i := 0; i < 1; i++ { - errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) - } - - if err := errg.Wait(); err != nil { - t.Error(err) - } -} diff --git a/transport/internet/hysteria2/hy2_test.go b/transport/internet/hysteria2/hy2_transport_test.go similarity index 100% rename from transport/internet/hysteria2/hy2_test.go rename to transport/internet/hysteria2/hy2_transport_test.go From 70071f8f5b642973d88be4968f3970a931b0f130 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Sun, 7 Apr 2024 01:28:32 +0800 Subject: [PATCH 56/81] need to fix addr --- proxy/hysteria2/protocol.go | 3 +-- proxy/hysteria2/server.go | 19 ++++++------- testing/scenarios/hy2_test.go | 40 ++++++++++++++++++++-------- transport/internet/hysteria2/conn.go | 17 ++++++------ transport/internet/hysteria2/hub.go | 22 ++++++++++----- 5 files changed, 63 insertions(+), 38 deletions(-) diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index 4bb4581e27..7bdc495acb 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -182,8 +182,7 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) { // ReadMultiBufferWithMetadata reads udp packet with destination func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) { - var data []byte - _, dest, _ := r.HyConn.ReadPacket(data) + _, data, dest, _ := r.HyConn.ReadPacket() b := buf.FromBytes(data) return &PacketPayload{Target: *dest, Buffer: buf.MultiBuffer{b}}, nil } diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index a371ccd73d..a8ccd18f2c 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -2,6 +2,7 @@ package hysteria2 import ( "context" + "fmt" "io" "strings" "time" @@ -73,6 +74,8 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet if IsHy2Transport && hyConn.IsUDPExtension { network = net.Network_UDP } + fmt.Println("------------------------") + fmt.Println(network) if !IsHy2Transport && network == net.Network_UDP { return newError(hy2_transport.CanNotUseUdpExtension) @@ -98,15 +101,13 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet var reqAddr string var err error - if network == net.Network_TCP { - reqAddr, err = hyProtocol.ReadTCPRequest(conn) - if err != nil { - return newError("failed to parse header").Base(err) - } - err = hyProtocol.WriteTCPResponse(conn, true, "") - if err != nil { - return newError("failed to send response").Base(err) - } + reqAddr, err = hyProtocol.ReadTCPRequest(conn) + if err != nil { + return newError("failed to parse header").Base(err) + } + err = hyProtocol.WriteTCPResponse(conn, true, "") + if err != nil { + return newError("failed to send response").Base(err) } address := strings.Split(reqAddr, ":") diff --git a/testing/scenarios/hy2_test.go b/testing/scenarios/hy2_test.go index c54569ca02..1a9a9e2b71 100644 --- a/testing/scenarios/hy2_test.go +++ b/testing/scenarios/hy2_test.go @@ -1,7 +1,6 @@ package scenarios import ( - "fmt" "testing" "time" @@ -174,15 +173,31 @@ func testVMessHysteria2(t *testing.T, congestionType string) { } func TestHysteria2Offical(t *testing.T) { - tcpServer := tcp.Server{ - MsgProcessor: xor, + for _, v := range []bool{true} { + testHysteria2Offical(t, v) + } +} + +func testHysteria2Offical(t *testing.T, isUDP bool) { + var dest net.Destination + var err error + if isUDP { + udpServer := udp.Server{ + MsgProcessor: xor, + } + dest, err = udpServer.Start() + common.Must(err) + defer udpServer.Close() + } else { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err = tcpServer.Start() + common.Must(err) + defer tcpServer.Close() } - dest, err := tcpServer.Start() - common.Must(err) - defer tcpServer.Close() serverPort := udp.PickPort() - fmt.Println(serverPort) serverConfig := &core.Config{ App: []*anypb.Any{ serial.ToTypedMessage(&log.Config{ @@ -262,7 +277,7 @@ func TestHysteria2Offical(t *testing.T) { Type: protocol.SecurityType_NONE, }, Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, - Udp: true, + Udp: true, Password: "password", }), }, @@ -293,9 +308,12 @@ func TestHysteria2Offical(t *testing.T) { defer CloseAllServers(servers) var errg errgroup.Group - for i := 0; i < 10; i++ { - errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) - errg.Go(testUDPConn(clientPort, 10240*1024, time.Second*40)) + for i := 0; i < 1; i++ { + if isUDP { + errg.Go(testUDPConn(clientPort, 1024, time.Second*4)) + } else { + errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40)) + } } if err := errg.Wait(); err != nil { diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index a3059297f8..258c24c472 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -28,7 +28,8 @@ type HyConn struct { func (c *HyConn) Read(b []byte) (int, error) { if c.IsUDPExtension { - n, _, err := c.ReadPacket(b) + n, data, _, err := c.ReadPacket() + copy(b, data) return n, err } return c.stream.Read(b) @@ -69,27 +70,25 @@ func (c *HyConn) WritePacket(b []byte, dest net.Destination) (int, error) { return len(b), c.ClientUDPSession.Send(b, dest.NetAddr()) } -func (c *HyConn) ReadPacket(b []byte) (int, *net.Destination, error) { +func (c *HyConn) ReadPacket() (int, []byte, *net.Destination, error) { if !c.IsUDPExtension { - return 0, nil, newError(CanNotUseUdpExtension) + return 0, nil, nil, newError(CanNotUseUdpExtension) } if c.IsServer { msg := <-c.ServerUDPSession.ReceiveCh - nBytes := copy(b, msg.Data) dest, err := net.ParseDestination("udp:" + msg.Addr) - return nBytes, &dest, err + return len(msg.Data), msg.Data, &dest, err } data, address, err := c.ClientUDPSession.Receive() if err != nil { - return 0, nil, err + return 0, nil, nil, err } - nBytes := copy(b, data) dest, err := net.ParseDestination("udp:" + address) if err != nil { - return 0, nil, err + return 0, nil, nil, err } - return nBytes, &dest, nil + return len(data), data, &dest, nil } func (c *HyConn) Close() error { diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index a4d8702a11..8f2570fa1b 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -2,6 +2,7 @@ package hysteria2 import ( "context" + "fmt" hy_server "github.com/apernet/hysteria/core/server" "github.com/apernet/quic-go" @@ -31,7 +32,8 @@ func (l *Listener) Close() error { return l.hyServer.Close() } -func (l *Listener) ProxyStreamHijacker(ft http3.FrameType, conn quic.Connection, stream quic.Stream, err error) (bool, error) { +func (l *Listener) ProxyStreamHijacker(ft http3.FrameType, + conn quic.Connection, stream quic.Stream, err error) (bool, error) { // err always == nil tcpConn := &HyConn{ @@ -43,26 +45,32 @@ func (l *Listener) ProxyStreamHijacker(ft http3.FrameType, conn quic.Connection, return true, nil } -func (l *Listener) UdpHijacker(entry *hy_server.UdpSessionEntry) { +func (l *Listener) UdpHijacker(entry *hy_server.UdpSessionEntry, originalAddr string) { + fmt.Println(originalAddr) + addr := net.ParseAddress(originalAddr) udpConn := &HyConn{ IsUDPExtension: true, IsServer: true, ServerUDPSession: entry, + local: addr, } l.addConn(udpConn) } // Listen creates a new Listener based on configurations. -func Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) { +func Listen(ctx context.Context, address net.Address, port net.Port, + streamSettings *internet.MemoryStreamConfig, + handler internet.ConnHandler) (internet.Listener, error) { if address.Family().IsDomain() { return nil, nil } config := streamSettings.ProtocolSettings.(*Config) - rawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{ - IP: address.IP(), - Port: int(port), - }, streamSettings.SocketSettings) + rawConn, err := internet.ListenSystemPacket(context.Background(), + &net.UDPAddr{ + IP: address.IP(), + Port: int(port), + }, streamSettings.SocketSettings) if err != nil { return nil, err } From c6dc7e0f890dbcaf4b5944559467b4b4cb38e12a Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Mon, 8 Apr 2024 02:57:52 +0800 Subject: [PATCH 57/81] add address to udp --- transport/internet/hysteria2/hub.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 8f2570fa1b..6ab69379da 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -46,13 +46,16 @@ func (l *Listener) ProxyStreamHijacker(ft http3.FrameType, } func (l *Listener) UdpHijacker(entry *hy_server.UdpSessionEntry, originalAddr string) { - fmt.Println(originalAddr) - addr := net.ParseAddress(originalAddr) + addr, err := net.ResolveUDPAddr("udp", originalAddr) + if err != nil { + return + } udpConn := &HyConn{ IsUDPExtension: true, IsServer: true, ServerUDPSession: entry, - local: addr, + remote: addr, + local: l.rawConn.LocalAddr(), } l.addConn(udpConn) } From 50bc1f28717a8314a561b78c21aa6da24c51c772 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Mon, 8 Apr 2024 03:31:28 +0800 Subject: [PATCH 58/81] test udp ok --- proxy/hysteria2/server.go | 10 ++++------ testing/scenarios/hy2_test.go | 4 ++-- transport/internet/hysteria2/hub.go | 1 - 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index a8ccd18f2c..a2fe5d5bd6 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -2,7 +2,6 @@ package hysteria2 import ( "context" - "fmt" "io" "strings" "time" @@ -74,8 +73,6 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet if IsHy2Transport && hyConn.IsUDPExtension { network = net.Network_UDP } - fmt.Println("------------------------") - fmt.Println(network) if !IsHy2Transport && network == net.Network_UDP { return newError(hy2_transport.CanNotUseUdpExtension) @@ -96,7 +93,9 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet } if network == net.Network_UDP { // handle udp request - return s.handleUDPPayload(ctx, &PacketReader{Reader: clientReader}, &PacketWriter{Writer: conn}, dispatcher) + return s.handleUDPPayload(ctx, + &PacketReader{Reader: clientReader, HyConn: hyConn}, + &PacketWriter{Writer: conn, HyConn: hyConn}, dispatcher) } var reqAddr string @@ -192,7 +191,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReade }) inbound := session.InboundFromContext(ctx) - user := inbound.User + // user := inbound.User for { select { @@ -212,7 +211,6 @@ func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReade To: p.Target, Status: log.AccessAccepted, Reason: "", - Email: user.Email, }) newError("tunnelling request to ", p.Target).WriteToLog(session.ExportIDToError(ctx)) diff --git a/testing/scenarios/hy2_test.go b/testing/scenarios/hy2_test.go index 1a9a9e2b71..a61f435ec7 100644 --- a/testing/scenarios/hy2_test.go +++ b/testing/scenarios/hy2_test.go @@ -173,7 +173,7 @@ func testVMessHysteria2(t *testing.T, congestionType string) { } func TestHysteria2Offical(t *testing.T) { - for _, v := range []bool{true} { + for _, v := range []bool{true, false} { testHysteria2Offical(t, v) } } @@ -308,7 +308,7 @@ func testHysteria2Offical(t *testing.T, isUDP bool) { defer CloseAllServers(servers) var errg errgroup.Group - for i := 0; i < 1; i++ { + for i := 0; i < 10; i++ { if isUDP { errg.Go(testUDPConn(clientPort, 1024, time.Second*4)) } else { diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 6ab69379da..a23a98c100 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -2,7 +2,6 @@ package hysteria2 import ( "context" - "fmt" hy_server "github.com/apernet/hysteria/core/server" "github.com/apernet/quic-go" From cde121ff177e60f2f943a074d6d25544a3945867 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Mon, 8 Apr 2024 20:13:00 +0800 Subject: [PATCH 59/81] change config name --- app/dns/config.pb.go | 6 - app/router/config.pb.go | 235 +++++++++++----------- config.pb.go | 2 +- transport/internet/hysteria2/config.pb.go | 38 ++-- transport/internet/hysteria2/config.proto | 2 +- transport/internet/hysteria2/dialer.go | 2 +- 6 files changed, 138 insertions(+), 147 deletions(-) diff --git a/app/dns/config.pb.go b/app/dns/config.pb.go index 79754e0b2f..a2b1580a6a 100644 --- a/app/dns/config.pb.go +++ b/app/dns/config.pb.go @@ -1,9 +1,3 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.31.0 -// protoc v4.24.4 -// source: app/dns/config.proto - package dns import ( diff --git a/app/router/config.pb.go b/app/router/config.pb.go index e0ea6758c2..d3f79a83b9 100644 --- a/app/router/config.pb.go +++ b/app/router/config.pb.go @@ -1,18 +1,12 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.1 -// protoc v3.12.4 -// source: app/router/config.proto - package router import ( - any "github.com/golang/protobuf/ptypes/any" routercommon "github.com/v2fly/v2ray-core/v5/app/router/routercommon" net "github.com/v2fly/v2ray-core/v5/common/net" _ "github.com/v2fly/v2ray-core/v5/common/protoext" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" reflect "reflect" sync "sync" ) @@ -86,6 +80,7 @@ type RoutingRule struct { unknownFields protoimpl.UnknownFields // Types that are assignable to TargetTag: + // // *RoutingRule_Tag // *RoutingRule_BalancingTag TargetTag isRoutingRule_TargetTag `protobuf_oneof:"target_tag"` @@ -94,7 +89,7 @@ type RoutingRule struct { // List of CIDRs for target IP address matching. // Deprecated. Use geoip below. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/router/config.proto. Cidr []*routercommon.CIDR `protobuf:"bytes,3,rep,name=cidr,proto3" json:"cidr,omitempty"` // List of GeoIPs for target IP address matching. If this entry exists, the // cidr above will have no effect. GeoIP fields with the same country code are @@ -104,19 +99,19 @@ type RoutingRule struct { // A range of port [from, to]. If the destination port is in this range, this // rule takes effect. Deprecated. Use port_list. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/router/config.proto. PortRange *net.PortRange `protobuf:"bytes,4,opt,name=port_range,json=portRange,proto3" json:"port_range,omitempty"` // List of ports. PortList *net.PortList `protobuf:"bytes,14,opt,name=port_list,json=portList,proto3" json:"port_list,omitempty"` // List of networks. Deprecated. Use networks. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/router/config.proto. NetworkList *net.NetworkList `protobuf:"bytes,5,opt,name=network_list,json=networkList,proto3" json:"network_list,omitempty"` // List of networks for matching. Networks []net.Network `protobuf:"varint,13,rep,packed,name=networks,proto3,enum=v2ray.core.common.net.Network" json:"networks,omitempty"` // List of CIDRs for source IP address matching. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/router/config.proto. SourceCidr []*routercommon.CIDR `protobuf:"bytes,6,rep,name=source_cidr,json=sourceCidr,proto3" json:"source_cidr,omitempty"` // List of GeoIPs for source IP address matching. If this entry exists, the // source_cidr above will have no effect. @@ -192,7 +187,7 @@ func (x *RoutingRule) GetDomain() []*routercommon.Domain { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/router/config.proto. func (x *RoutingRule) GetCidr() []*routercommon.CIDR { if x != nil { return x.Cidr @@ -207,7 +202,7 @@ func (x *RoutingRule) GetGeoip() []*routercommon.GeoIP { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/router/config.proto. func (x *RoutingRule) GetPortRange() *net.PortRange { if x != nil { return x.PortRange @@ -222,7 +217,7 @@ func (x *RoutingRule) GetPortList() *net.PortList { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/router/config.proto. func (x *RoutingRule) GetNetworkList() *net.NetworkList { if x != nil { return x.NetworkList @@ -237,7 +232,7 @@ func (x *RoutingRule) GetNetworks() []net.Network { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/router/config.proto. func (x *RoutingRule) GetSourceCidr() []*routercommon.CIDR { if x != nil { return x.SourceCidr @@ -324,11 +319,11 @@ type BalancingRule struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` - OutboundSelector []string `protobuf:"bytes,2,rep,name=outbound_selector,json=outboundSelector,proto3" json:"outbound_selector,omitempty"` - Strategy string `protobuf:"bytes,3,opt,name=strategy,proto3" json:"strategy,omitempty"` - StrategySettings *any.Any `protobuf:"bytes,4,opt,name=strategy_settings,json=strategySettings,proto3" json:"strategy_settings,omitempty"` - FallbackTag string `protobuf:"bytes,5,opt,name=fallback_tag,json=fallbackTag,proto3" json:"fallback_tag,omitempty"` + Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + OutboundSelector []string `protobuf:"bytes,2,rep,name=outbound_selector,json=outboundSelector,proto3" json:"outbound_selector,omitempty"` + Strategy string `protobuf:"bytes,3,opt,name=strategy,proto3" json:"strategy,omitempty"` + StrategySettings *anypb.Any `protobuf:"bytes,4,opt,name=strategy_settings,json=strategySettings,proto3" json:"strategy_settings,omitempty"` + FallbackTag string `protobuf:"bytes,5,opt,name=fallback_tag,json=fallbackTag,proto3" json:"fallback_tag,omitempty"` } func (x *BalancingRule) Reset() { @@ -384,7 +379,7 @@ func (x *BalancingRule) GetStrategy() string { return "" } -func (x *BalancingRule) GetStrategySettings() *any.Any { +func (x *BalancingRule) GetStrategySettings() *anypb.Any { if x != nil { return x.StrategySettings } @@ -724,6 +719,7 @@ type SimplifiedRoutingRule struct { unknownFields protoimpl.UnknownFields // Types that are assignable to TargetTag: + // // *SimplifiedRoutingRule_Tag // *SimplifiedRoutingRule_BalancingTag TargetTag isSimplifiedRoutingRule_TargetTag `protobuf_oneof:"target_tag"` @@ -1068,110 +1064,109 @@ var file_app_router_config_proto_rawDesc = []byte{ 0x67, 0x65, 0x78, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0x74, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x61, 0x6e, 0x64, + 0x22, 0x70, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x61, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x0a, - 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x82, 0xb5, 0x18, 0x08, 0x12, 0x06, - 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x22, 0x5b, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, - 0x67, 0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x61, - 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x54, 0x61, 0x67, 0x3a, 0x1d, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x65, 0x72, 0x82, 0xb5, 0x18, 0x0b, 0x12, 0x09, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x70, - 0x69, 0x6e, 0x67, 0x22, 0x88, 0x02, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, - 0x4c, 0x65, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x3b, 0x0a, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, - 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, - 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x57, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09, - 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, - 0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, - 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, - 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x12, 0x1c, - 0x0a, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x02, 0x52, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, - 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x61, 0x67, 0x3a, - 0x1d, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x82, - 0xb5, 0x18, 0x0b, 0x12, 0x09, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xdd, - 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, - 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x36, 0x0a, 0x04, 0x72, 0x75, 0x6c, - 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, - 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, - 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, - 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, - 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22, 0xab, - 0x05, 0x0a, 0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x6f, 0x75, - 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x25, 0x0a, 0x0d, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, - 0x54, 0x61, 0x67, 0x12, 0x42, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, - 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, - 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, - 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x72, 0x74, - 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x72, - 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, - 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x08, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x4c, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, + 0x09, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x3a, 0x16, 0x82, 0xb5, 0x18, 0x12, + 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x06, 0x72, 0x61, 0x6e, 0x64, + 0x6f, 0x6d, 0x22, 0x57, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x4c, 0x65, + 0x61, 0x73, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, + 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x61, 0x67, + 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x15, 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, + 0x12, 0x09, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x70, 0x69, 0x6e, 0x67, 0x22, 0x84, 0x02, 0x0a, 0x17, + 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x61, + 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, + 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x05, 0x63, + 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x16, + 0x0a, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, + 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, + 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, + 0x61, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x5f, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x54, 0x61, 0x67, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x15, 0x0a, 0x08, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x09, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x6c, 0x6f, + 0x61, 0x64, 0x22, 0xdd, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, + 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x36, 0x0a, + 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x65, - 0x6f, 0x69, 0x70, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x0a, - 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, - 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x08, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x6f, 0x6d, - 0x61, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, - 0x12, 0x4c, 0x0a, 0x0a, 0x67, 0x65, 0x6f, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0xa1, - 0x93, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x53, - 0x69, 0x74, 0x65, 0x52, 0x09, 0x67, 0x65, 0x6f, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x42, 0x0c, - 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x8c, 0x02, 0x0a, - 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, - 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, + 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, + 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x22, 0xab, 0x05, 0x0a, 0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, + 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x03, + 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, + 0x12, 0x25, 0x0a, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, + 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x67, 0x12, 0x42, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, + 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, + 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, - 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, - 0x79, 0x12, 0x40, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, - 0x75, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, - 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, - 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, - 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, - 0xb5, 0x18, 0x08, 0x12, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2a, 0x47, 0x0a, 0x0e, 0x44, + 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x1b, 0x0a, 0x09, + 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x08, 0x6e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x4c, 0x0a, 0x0c, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x47, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, + 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, + 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, + 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, + 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, + 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x72, 0x12, 0x4c, 0x0a, 0x0a, 0x67, 0x65, 0x6f, 0x5f, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x18, 0xa1, 0x93, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x32, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x52, 0x09, 0x67, 0x65, 0x6f, 0x44, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, + 0x22, 0x88, 0x02, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, + 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, + 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, + 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x40, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, + 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2a, 0x47, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x49, 0x70, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66, 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, @@ -1218,7 +1213,7 @@ var file_app_router_config_proto_goTypes = []interface{}{ (*net.NetworkList)(nil), // 15: v2ray.core.common.net.NetworkList (net.Network)(0), // 16: v2ray.core.common.net.Network (*routercommon.GeoSite)(nil), // 17: v2ray.core.app.router.routercommon.GeoSite - (*any.Any)(nil), // 18: google.protobuf.Any + (*anypb.Any)(nil), // 18: google.protobuf.Any } var file_app_router_config_proto_depIdxs = []int32{ 10, // 0: v2ray.core.app.router.RoutingRule.domain:type_name -> v2ray.core.app.router.routercommon.Domain diff --git a/config.pb.go b/config.pb.go index 1a1cfefcb3..dd80bf4d55 100644 --- a/config.pb.go +++ b/config.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.31.0 -// protoc v4.24.3 +// protoc v4.24.4 // source: config.proto package core diff --git a/transport/internet/hysteria2/config.pb.go b/transport/internet/hysteria2/config.pb.go index 50f40f2945..61d3da1879 100644 --- a/transport/internet/hysteria2/config.pb.go +++ b/transport/internet/hysteria2/config.pb.go @@ -89,7 +89,7 @@ type Config struct { Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` Congestion *Congestion `protobuf:"bytes,4,opt,name=congestion,proto3" json:"congestion,omitempty"` IgnoreClientBandwidth bool `protobuf:"varint,5,opt,name=ignore_client_bandwidth,json=ignoreClientBandwidth,proto3" json:"ignore_client_bandwidth,omitempty"` - Udp bool `protobuf:"varint,6,opt,name=udp,proto3" json:"udp,omitempty"` + UseUdpExtension bool `protobuf:"varint,6,opt,name=use_udp_extension,json=useUdpExtension,proto3" json:"use_udp_extension,omitempty"` } func (x *Config) Reset() { @@ -159,9 +159,9 @@ func (x *Config) GetIgnoreClientBandwidth() bool { return false } -func (x *Config) GetUdp() bool { +func (x *Config) GetUseUdpExtension() bool { if x != nil { - return x.Udp + return x.UseUdpExtension } return false } @@ -183,7 +183,7 @@ var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x70, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x70, 0x4d, 0x62, 0x70, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xb9, 0x02, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xd3, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, @@ -200,20 +200,22 @@ var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x17, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x75, - 0x64, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x75, 0x64, 0x70, 0x3a, 0x1a, 0x82, - 0xb5, 0x18, 0x16, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x09, - 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x42, 0x96, 0x01, 0x0a, 0x2b, 0x63, 0x6f, - 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, - 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, - 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, - 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, - 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x11, 0x75, + 0x73, 0x65, 0x5f, 0x75, 0x64, 0x70, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x75, 0x73, 0x65, 0x55, 0x64, 0x70, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x16, 0x0a, 0x09, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x09, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, + 0x69, 0x61, 0x32, 0x42, 0x96, 0x01, 0x0a, 0x2b, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, + 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, + 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, + 0x61, 0x32, 0xaa, 0x02, 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/transport/internet/hysteria2/config.proto b/transport/internet/hysteria2/config.proto index 56f2615a4d..ac5f278445 100644 --- a/transport/internet/hysteria2/config.proto +++ b/transport/internet/hysteria2/config.proto @@ -26,5 +26,5 @@ message Config { string password = 3; Congestion congestion = 4; bool ignore_client_bandwidth = 5; - bool udp = 6; + bool use_udp_extension = 6; } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 562a5a5ddc..2cd7cfd330 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -113,7 +113,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me conn.Target = outbound.Target } - if network == net.Network_UDP && config.GetUdp() { // only hysteria2 can use udpExtension + if network == net.Network_UDP && config.GetUseUdpExtension() { // only hysteria2 can use udpExtension conn.IsUDPExtension = true conn.IsServer = false conn.ClientUDPSession, err = client.UDP() From 6b0b561756e32cc312a4c3102708714ccd76dcbe Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Mon, 8 Apr 2024 20:13:00 +0800 Subject: [PATCH 60/81] change config name --- app/dns/config.pb.go | 6 - app/router/config.pb.go | 235 +++++++++++----------- config.pb.go | 2 +- transport/internet/hysteria2/config.pb.go | 38 ++-- transport/internet/hysteria2/config.proto | 2 +- transport/internet/hysteria2/dialer.go | 2 +- transport/internet/hysteria2/hub.go | 2 +- 7 files changed, 139 insertions(+), 148 deletions(-) diff --git a/app/dns/config.pb.go b/app/dns/config.pb.go index 79754e0b2f..a2b1580a6a 100644 --- a/app/dns/config.pb.go +++ b/app/dns/config.pb.go @@ -1,9 +1,3 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.31.0 -// protoc v4.24.4 -// source: app/dns/config.proto - package dns import ( diff --git a/app/router/config.pb.go b/app/router/config.pb.go index e0ea6758c2..d3f79a83b9 100644 --- a/app/router/config.pb.go +++ b/app/router/config.pb.go @@ -1,18 +1,12 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.1 -// protoc v3.12.4 -// source: app/router/config.proto - package router import ( - any "github.com/golang/protobuf/ptypes/any" routercommon "github.com/v2fly/v2ray-core/v5/app/router/routercommon" net "github.com/v2fly/v2ray-core/v5/common/net" _ "github.com/v2fly/v2ray-core/v5/common/protoext" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" reflect "reflect" sync "sync" ) @@ -86,6 +80,7 @@ type RoutingRule struct { unknownFields protoimpl.UnknownFields // Types that are assignable to TargetTag: + // // *RoutingRule_Tag // *RoutingRule_BalancingTag TargetTag isRoutingRule_TargetTag `protobuf_oneof:"target_tag"` @@ -94,7 +89,7 @@ type RoutingRule struct { // List of CIDRs for target IP address matching. // Deprecated. Use geoip below. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/router/config.proto. Cidr []*routercommon.CIDR `protobuf:"bytes,3,rep,name=cidr,proto3" json:"cidr,omitempty"` // List of GeoIPs for target IP address matching. If this entry exists, the // cidr above will have no effect. GeoIP fields with the same country code are @@ -104,19 +99,19 @@ type RoutingRule struct { // A range of port [from, to]. If the destination port is in this range, this // rule takes effect. Deprecated. Use port_list. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/router/config.proto. PortRange *net.PortRange `protobuf:"bytes,4,opt,name=port_range,json=portRange,proto3" json:"port_range,omitempty"` // List of ports. PortList *net.PortList `protobuf:"bytes,14,opt,name=port_list,json=portList,proto3" json:"port_list,omitempty"` // List of networks. Deprecated. Use networks. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/router/config.proto. NetworkList *net.NetworkList `protobuf:"bytes,5,opt,name=network_list,json=networkList,proto3" json:"network_list,omitempty"` // List of networks for matching. Networks []net.Network `protobuf:"varint,13,rep,packed,name=networks,proto3,enum=v2ray.core.common.net.Network" json:"networks,omitempty"` // List of CIDRs for source IP address matching. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in app/router/config.proto. SourceCidr []*routercommon.CIDR `protobuf:"bytes,6,rep,name=source_cidr,json=sourceCidr,proto3" json:"source_cidr,omitempty"` // List of GeoIPs for source IP address matching. If this entry exists, the // source_cidr above will have no effect. @@ -192,7 +187,7 @@ func (x *RoutingRule) GetDomain() []*routercommon.Domain { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/router/config.proto. func (x *RoutingRule) GetCidr() []*routercommon.CIDR { if x != nil { return x.Cidr @@ -207,7 +202,7 @@ func (x *RoutingRule) GetGeoip() []*routercommon.GeoIP { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/router/config.proto. func (x *RoutingRule) GetPortRange() *net.PortRange { if x != nil { return x.PortRange @@ -222,7 +217,7 @@ func (x *RoutingRule) GetPortList() *net.PortList { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/router/config.proto. func (x *RoutingRule) GetNetworkList() *net.NetworkList { if x != nil { return x.NetworkList @@ -237,7 +232,7 @@ func (x *RoutingRule) GetNetworks() []net.Network { return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in app/router/config.proto. func (x *RoutingRule) GetSourceCidr() []*routercommon.CIDR { if x != nil { return x.SourceCidr @@ -324,11 +319,11 @@ type BalancingRule struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` - OutboundSelector []string `protobuf:"bytes,2,rep,name=outbound_selector,json=outboundSelector,proto3" json:"outbound_selector,omitempty"` - Strategy string `protobuf:"bytes,3,opt,name=strategy,proto3" json:"strategy,omitempty"` - StrategySettings *any.Any `protobuf:"bytes,4,opt,name=strategy_settings,json=strategySettings,proto3" json:"strategy_settings,omitempty"` - FallbackTag string `protobuf:"bytes,5,opt,name=fallback_tag,json=fallbackTag,proto3" json:"fallback_tag,omitempty"` + Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + OutboundSelector []string `protobuf:"bytes,2,rep,name=outbound_selector,json=outboundSelector,proto3" json:"outbound_selector,omitempty"` + Strategy string `protobuf:"bytes,3,opt,name=strategy,proto3" json:"strategy,omitempty"` + StrategySettings *anypb.Any `protobuf:"bytes,4,opt,name=strategy_settings,json=strategySettings,proto3" json:"strategy_settings,omitempty"` + FallbackTag string `protobuf:"bytes,5,opt,name=fallback_tag,json=fallbackTag,proto3" json:"fallback_tag,omitempty"` } func (x *BalancingRule) Reset() { @@ -384,7 +379,7 @@ func (x *BalancingRule) GetStrategy() string { return "" } -func (x *BalancingRule) GetStrategySettings() *any.Any { +func (x *BalancingRule) GetStrategySettings() *anypb.Any { if x != nil { return x.StrategySettings } @@ -724,6 +719,7 @@ type SimplifiedRoutingRule struct { unknownFields protoimpl.UnknownFields // Types that are assignable to TargetTag: + // // *SimplifiedRoutingRule_Tag // *SimplifiedRoutingRule_BalancingTag TargetTag isSimplifiedRoutingRule_TargetTag `protobuf_oneof:"target_tag"` @@ -1068,110 +1064,109 @@ var file_app_router_config_proto_rawDesc = []byte{ 0x67, 0x65, 0x78, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0x74, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x61, 0x6e, 0x64, + 0x22, 0x70, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x61, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x0a, - 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x82, 0xb5, 0x18, 0x08, 0x12, 0x06, - 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x22, 0x5b, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, - 0x67, 0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x61, - 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x54, 0x61, 0x67, 0x3a, 0x1d, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x65, 0x72, 0x82, 0xb5, 0x18, 0x0b, 0x12, 0x09, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x70, - 0x69, 0x6e, 0x67, 0x22, 0x88, 0x02, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, - 0x4c, 0x65, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x3b, 0x0a, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, - 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, - 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x57, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09, - 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, - 0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, - 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, - 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x12, 0x1c, - 0x0a, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x02, 0x52, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, - 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x61, 0x67, 0x3a, - 0x1d, 0x82, 0xb5, 0x18, 0x0a, 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x82, - 0xb5, 0x18, 0x0b, 0x12, 0x09, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xdd, - 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, - 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x36, 0x0a, 0x04, 0x72, 0x75, 0x6c, - 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, - 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, - 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, - 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, - 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22, 0xab, - 0x05, 0x0a, 0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x6f, 0x75, - 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x25, 0x0a, 0x0d, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, - 0x54, 0x61, 0x67, 0x12, 0x42, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, - 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, - 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, - 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x72, 0x74, - 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x72, - 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, - 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x08, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x4c, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, + 0x09, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x3a, 0x16, 0x82, 0xb5, 0x18, 0x12, + 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x06, 0x72, 0x61, 0x6e, 0x64, + 0x6f, 0x6d, 0x22, 0x57, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x4c, 0x65, + 0x61, 0x73, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, + 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x61, 0x67, + 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x15, 0x0a, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, + 0x12, 0x09, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x70, 0x69, 0x6e, 0x67, 0x22, 0x84, 0x02, 0x0a, 0x17, + 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x61, + 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, + 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x05, 0x63, + 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x09, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x16, + 0x0a, 0x06, 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, + 0x6d, 0x61, 0x78, 0x52, 0x54, 0x54, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, 0x61, + 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x74, 0x6f, 0x6c, 0x65, 0x72, + 0x61, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x5f, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x54, 0x61, 0x67, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x15, 0x0a, 0x08, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x09, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x6c, 0x6f, + 0x61, 0x64, 0x22, 0xdd, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, + 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x36, 0x0a, + 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x65, - 0x6f, 0x69, 0x70, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x0a, - 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, - 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x08, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x6f, 0x6d, - 0x61, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, - 0x12, 0x4c, 0x0a, 0x0a, 0x67, 0x65, 0x6f, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0xa1, - 0x93, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x53, - 0x69, 0x74, 0x65, 0x52, 0x09, 0x67, 0x65, 0x6f, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x42, 0x0c, - 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x8c, 0x02, 0x0a, - 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, - 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, + 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, + 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x22, 0xab, 0x05, 0x0a, 0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, + 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x03, + 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, + 0x12, 0x25, 0x0a, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, + 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x67, 0x12, 0x42, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, + 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, + 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, - 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, - 0x79, 0x12, 0x40, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, - 0x75, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, - 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, - 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, - 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, - 0xb5, 0x18, 0x08, 0x12, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2a, 0x47, 0x0a, 0x0e, 0x44, + 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x1b, 0x0a, 0x09, + 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x08, 0x6e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x4c, 0x0a, 0x0c, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x47, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, + 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, + 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, + 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, + 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, + 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x72, 0x12, 0x4c, 0x0a, 0x0a, 0x67, 0x65, 0x6f, 0x5f, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x18, 0xa1, 0x93, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x32, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x52, 0x09, 0x67, 0x65, 0x6f, 0x44, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, + 0x22, 0x88, 0x02, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, + 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, + 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, + 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x40, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, + 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x3a, 0x15, 0x82, 0xb5, 0x18, 0x11, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2a, 0x47, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x49, 0x70, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66, 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, @@ -1218,7 +1213,7 @@ var file_app_router_config_proto_goTypes = []interface{}{ (*net.NetworkList)(nil), // 15: v2ray.core.common.net.NetworkList (net.Network)(0), // 16: v2ray.core.common.net.Network (*routercommon.GeoSite)(nil), // 17: v2ray.core.app.router.routercommon.GeoSite - (*any.Any)(nil), // 18: google.protobuf.Any + (*anypb.Any)(nil), // 18: google.protobuf.Any } var file_app_router_config_proto_depIdxs = []int32{ 10, // 0: v2ray.core.app.router.RoutingRule.domain:type_name -> v2ray.core.app.router.routercommon.Domain diff --git a/config.pb.go b/config.pb.go index 1a1cfefcb3..dd80bf4d55 100644 --- a/config.pb.go +++ b/config.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.31.0 -// protoc v4.24.3 +// protoc v4.24.4 // source: config.proto package core diff --git a/transport/internet/hysteria2/config.pb.go b/transport/internet/hysteria2/config.pb.go index 50f40f2945..61d3da1879 100644 --- a/transport/internet/hysteria2/config.pb.go +++ b/transport/internet/hysteria2/config.pb.go @@ -89,7 +89,7 @@ type Config struct { Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` Congestion *Congestion `protobuf:"bytes,4,opt,name=congestion,proto3" json:"congestion,omitempty"` IgnoreClientBandwidth bool `protobuf:"varint,5,opt,name=ignore_client_bandwidth,json=ignoreClientBandwidth,proto3" json:"ignore_client_bandwidth,omitempty"` - Udp bool `protobuf:"varint,6,opt,name=udp,proto3" json:"udp,omitempty"` + UseUdpExtension bool `protobuf:"varint,6,opt,name=use_udp_extension,json=useUdpExtension,proto3" json:"use_udp_extension,omitempty"` } func (x *Config) Reset() { @@ -159,9 +159,9 @@ func (x *Config) GetIgnoreClientBandwidth() bool { return false } -func (x *Config) GetUdp() bool { +func (x *Config) GetUseUdpExtension() bool { if x != nil { - return x.Udp + return x.UseUdpExtension } return false } @@ -183,7 +183,7 @@ var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x70, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x70, 0x4d, 0x62, 0x70, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xb9, 0x02, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xd3, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, @@ -200,20 +200,22 @@ var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x17, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x75, - 0x64, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x75, 0x64, 0x70, 0x3a, 0x1a, 0x82, - 0xb5, 0x18, 0x16, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x09, - 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x42, 0x96, 0x01, 0x0a, 0x2b, 0x63, 0x6f, - 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, - 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, - 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, - 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, - 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x11, 0x75, + 0x73, 0x65, 0x5f, 0x75, 0x64, 0x70, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x75, 0x73, 0x65, 0x55, 0x64, 0x70, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x1a, 0x82, 0xb5, 0x18, 0x16, 0x0a, 0x09, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x09, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, + 0x69, 0x61, 0x32, 0x42, 0x96, 0x01, 0x0a, 0x2b, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, + 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, + 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, + 0x61, 0x32, 0xaa, 0x02, 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/transport/internet/hysteria2/config.proto b/transport/internet/hysteria2/config.proto index 56f2615a4d..ac5f278445 100644 --- a/transport/internet/hysteria2/config.proto +++ b/transport/internet/hysteria2/config.proto @@ -26,5 +26,5 @@ message Config { string password = 3; Congestion congestion = 4; bool ignore_client_bandwidth = 5; - bool udp = 6; + bool use_udp_extension = 6; } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 562a5a5ddc..2cd7cfd330 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -113,7 +113,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me conn.Target = outbound.Target } - if network == net.Network_UDP && config.GetUdp() { // only hysteria2 can use udpExtension + if network == net.Network_UDP && config.GetUseUdpExtension() { // only hysteria2 can use udpExtension conn.IsUDPExtension = true conn.IsServer = false conn.ClientUDPSession, err = client.UDP() diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index a23a98c100..75219e35d0 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -87,7 +87,7 @@ func Listen(ctx context.Context, address net.Address, port net.Port, TLSConfig: *GetTLSConfig(streamSettings), Authenticator: &Authenticator{Password: config.GetPassword()}, IgnoreClientBandwidth: config.GetIgnoreClientBandwidth(), - DisableUDP: !config.GetUdp(), + DisableUDP: !config.GetUseUdpExtension(), StreamHijacker: listener.ProxyStreamHijacker, // acceptStreams UdpSessionHijacker: listener.UdpHijacker, // acceptUDPSession }) From 49ab4eb6449ffabe984bff53af7cde731d3f1635 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Tue, 9 Apr 2024 00:20:20 +0800 Subject: [PATCH 61/81] add example config --- infra/conf/v4/transport_internet.go | 8 +- proxy/hysteria2/client.go | 4 +- proxy/hysteria2/config.pb.go | 56 +++++++------ proxy/hysteria2/config.proto | 7 ++ proxy/hysteria2/server.go | 6 +- ...test_v4.json => hysteria2_offical_v4.json} | 0 release/config/hy2/hysteria2_official.json5 | 78 +++++++++++++++++++ ...eria2_test.json5 => hysteria2_vmess.json5} | 27 ++++++- ...2_test_v4.json => hysteria2_vmess_v4.json} | 0 9 files changed, 150 insertions(+), 36 deletions(-) rename release/config/hy2/{hysteria2_offical_test_v4.json => hysteria2_offical_v4.json} (100%) create mode 100644 release/config/hy2/hysteria2_official.json5 rename release/config/hy2/{hysteria2_test.json5 => hysteria2_vmess.json5} (66%) rename release/config/hy2/{hysteria2_test_v4.json => hysteria2_vmess_v4.json} (100%) diff --git a/infra/conf/v4/transport_internet.go b/infra/conf/v4/transport_internet.go index 09d1562ba3..9584205dee 100644 --- a/infra/conf/v4/transport_internet.go +++ b/infra/conf/v4/transport_internet.go @@ -145,8 +145,9 @@ type Hy2ConfigCongestion struct { } type Hy2Config struct { - Password string `json:"password"` - Congestion Hy2ConfigCongestion `json:"congestion"` + Password string `json:"password"` + Congestion Hy2ConfigCongestion `json:"congestion"` + UseUdpExtension bool `json:"use_udp_extension"` } // Build implements Buildable. @@ -156,7 +157,8 @@ func (c *Hy2Config) Build() (proto.Message, error) { Type: c.Congestion.Type, DownMbps: c.Congestion.DownMbps, UpMbps: c.Congestion.UpMbps, - }}, nil + }, + UseUdpExtension: c.UseUdpExtension}, nil } type WebSocketConfig struct { diff --git a/proxy/hysteria2/client.go b/proxy/hysteria2/client.go index bc11e43713..cf1322ce74 100644 --- a/proxy/hysteria2/client.go +++ b/proxy/hysteria2/client.go @@ -20,13 +20,13 @@ import ( hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" ) -// Client is an inbound handler for trojan protocol +// Client is an inbound handler type Client struct { serverPicker protocol.ServerPicker policyManager policy.Manager } -// NewClient create a new trojan client. +// NewClient create a new client. func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) { serverList := protocol.NewServerList() for _, rec := range config.Server { diff --git a/proxy/hysteria2/config.pb.go b/proxy/hysteria2/config.pb.go index 707b0b3dee..e7c913a1d8 100644 --- a/proxy/hysteria2/config.pb.go +++ b/proxy/hysteria2/config.pb.go @@ -2,6 +2,7 @@ package hysteria2 import ( protocol "github.com/v2fly/v2ray-core/v5/common/protocol" + _ "github.com/v2fly/v2ray-core/v5/common/protoext" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -221,32 +222,37 @@ var file_proxy_hysteria2_config_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, - 0x70, 0x65, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x36, 0x0a, 0x04, 0x4f, 0x42, 0x46, - 0x53, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x22, 0x3f, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x04, - 0x6f, 0x62, 0x66, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x32, 0x72, - 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x68, 0x79, - 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x2e, 0x4f, 0x42, 0x46, 0x53, 0x52, 0x04, 0x6f, 0x62, - 0x66, 0x73, 0x22, 0x52, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x42, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, + 0x70, 0x65, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x36, 0x0a, 0x04, 0x4f, + 0x42, 0x46, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x22, 0x3f, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34, + 0x0a, 0x04, 0x6f, 0x62, 0x66, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, + 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x2e, 0x4f, 0x42, 0x46, 0x53, 0x52, 0x04, + 0x6f, 0x62, 0x66, 0x73, 0x22, 0x6d, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x15, 0x0a, 0x08, + 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x09, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, + 0x69, 0x61, 0x32, 0x22, 0x60, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x46, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x42, 0x6f, - 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, - 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, - 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, - 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, - 0x61, 0x32, 0xaa, 0x02, 0x1a, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, - 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x3a, 0x18, 0x82, 0xb5, 0x18, + 0x14, 0x0a, 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x09, 0x68, 0x79, 0x73, 0x74, + 0x65, 0x72, 0x69, 0x61, 0x32, 0x42, 0x6f, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x68, 0x79, + 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, + 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, 0x1a, 0x56, 0x32, 0x52, 0x61, + 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x48, 0x79, 0x73, + 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/hysteria2/config.proto b/proxy/hysteria2/config.proto index 2ef7824687..822d414731 100644 --- a/proxy/hysteria2/config.proto +++ b/proxy/hysteria2/config.proto @@ -8,6 +8,7 @@ option java_multiple_files = true; import "common/protocol/user.proto"; import "common/protocol/server_spec.proto"; +import "common/protoext/extensions.proto"; message OBFS { string type = 1; @@ -19,9 +20,15 @@ message Account { } message ClientConfig { + option (v2ray.core.common.protoext.message_opt).type = "outbound"; + option (v2ray.core.common.protoext.message_opt).short_name = "hysteria2"; + repeated v2ray.core.common.protocol.ServerEndpoint server = 1; } message ServerConfig { + option (v2ray.core.common.protoext.message_opt).type = "inbound"; + option (v2ray.core.common.protoext.message_opt).short_name = "hysteria2"; + repeated v2ray.core.common.protocol.User users = 1; } diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index a2fe5d5bd6..f20159ca55 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -31,20 +31,20 @@ func init() { })) } -// Server is an inbound connection handler that handles messages in trojan protocol. +// Server is an inbound connection handler that handles messages in protocol. type Server struct { policyManager policy.Manager validator *Validator packetEncoding packetaddr.PacketAddrType } -// NewServer creates a new trojan inbound handler. +// NewServer creates a new inbound handler. func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { validator := new(Validator) for _, user := range config.Users { u, err := user.ToMemoryUser() if err != nil { - return nil, newError("failed to get trojan user").Base(err).AtError() + return nil, newError("failed to get user").Base(err).AtError() } if err := validator.Add(u); err != nil { diff --git a/release/config/hy2/hysteria2_offical_test_v4.json b/release/config/hy2/hysteria2_offical_v4.json similarity index 100% rename from release/config/hy2/hysteria2_offical_test_v4.json rename to release/config/hy2/hysteria2_offical_v4.json diff --git a/release/config/hy2/hysteria2_official.json5 b/release/config/hy2/hysteria2_official.json5 new file mode 100644 index 0000000000..6be1013aae --- /dev/null +++ b/release/config/hy2/hysteria2_official.json5 @@ -0,0 +1,78 @@ +{ + "log": { + "access":{"level": "Debug"} + }, + "inbounds": [{ + "port": 1080, + "listen": "127.0.0.1", + "tag": "http", + "protocol": "http" + }, { + "port": 1280, + "listen": "127.0.0.1", + "tag": "hy2_in_bbr", + "protocol": "hysteria2", + "streamSettings": { + "transport": "hysteria2", + "transportSettings": { + "congestion": { + "type": "bbr" + }, + "use_udp_extension": true + }, + "security": "tls" + } + },{ + "port": 1281, + "listen": "127.0.0.1", + "tag": "hy2_in_brutal", + "protocol": "hysteria2", + "streamSettings": { + "transport": "hysteria2", + "transportSettings": { + "congestion": { + "type": "brutal", + "up_mbps":20, + "down_mbps": 100 + }, + "use_udp_extension": true + }, + "security": "tls" + } + }], + "outbounds": [{ + "protocol": "freedom", + "tag": "direct" + }, { + "tag": "hy2_out", + "protocol": "hysteria2", + "settings": { + "server": [{ + "address": "127.0.0.1", + "port": 1280 + }] + }, + "streamSettings": { + "transport": "hysteria2", + "transportSettings": { + "congestion": { + "type": "bbr" + } + }, + "security": "tls" + } + }], + "routing": { + "rules": [{ + "type": "field", + "outboundTag": "direct", + "inboundTag": ["hy2_in_bbr", "hy2_in_brutal"] + }, + { + "type": "field", + "outboundTag": "hy2_out", + "inboundTag": ["http"] + } + ] + } +} diff --git a/release/config/hy2/hysteria2_test.json5 b/release/config/hy2/hysteria2_vmess.json5 similarity index 66% rename from release/config/hy2/hysteria2_test.json5 rename to release/config/hy2/hysteria2_vmess.json5 index ca1cf243ad..386ae616b7 100644 --- a/release/config/hy2/hysteria2_test.json5 +++ b/release/config/hy2/hysteria2_vmess.json5 @@ -10,7 +10,7 @@ }, { "port": 1280, "listen": "127.0.0.1", - "tag": "hy2_in", + "tag": "hy2_in_bbr", "protocol": "vmess", "settings": { "users": ["23ad6b10-8d1a-40f7-8ad0-e3e35cd38297"] @@ -20,7 +20,28 @@ "transportSettings": { "congestion": { "type": "bbr" - } + }, + "use_udp_extension": true + }, + "security": "tls" + } + },{ + "port": 1281, + "listen": "127.0.0.1", + "tag": "hy2_in_brutal", + "protocol": "vmess", + "settings": { + "users": ["23ad6b10-8d1a-40f7-8ad0-e3e35cd38297"] + }, + "streamSettings": { + "transport": "hysteria2", + "transportSettings": { + "congestion": { + "type": "brutal", + "up_mbps":20, + "down_mbps": 100 + }, + "use_udp_extension": true }, "security": "tls" } @@ -50,7 +71,7 @@ "rules": [{ "type": "field", "outboundTag": "direct", - "inboundTag": ["hy2_in"] + "inboundTag": ["hy2_in_bbr", "hy2_in_brutal"] }, { "type": "field", diff --git a/release/config/hy2/hysteria2_test_v4.json b/release/config/hy2/hysteria2_vmess_v4.json similarity index 100% rename from release/config/hy2/hysteria2_test_v4.json rename to release/config/hy2/hysteria2_vmess_v4.json From ab0f81be40bd93822597e410d74f7be9a2ce1f5d Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Tue, 9 Apr 2024 00:49:44 +0800 Subject: [PATCH 62/81] update go mod --- go.mod | 4 ++-- go.sum | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index acc737ce84..928a0fa11b 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.21.4 require ( github.com/adrg/xdg v0.4.0 - github.com/apernet/hysteria/core v0.0.0-00010101000000-000000000000 + github.com/apernet/hysteria/core v1.3.5 github.com/apernet/quic-go v0.42.1-0.20240323215309-32a339817822 github.com/go-chi/chi/v5 v5.0.12 github.com/go-chi/render v1.0.3 @@ -90,4 +90,4 @@ require ( replace github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 => github.com/xiaokangwang/struc v0.0.0-20231031203518-0e381172f248 -replace github.com/apernet/hysteria/core => ../hysteria/core +replace github.com/apernet/hysteria/core v1.3.5 => github.com/JimmyHuang454/hysteria/core v0.0.0-20240408143247-3a6a6d41fbe2 diff --git a/go.sum b/go.sum index 8c0010e855..478036c495 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/FlowerWrong/water v0.0.0-20180301012659-01a4eaa1f6f2/go.mod h1:xrG5L7lq7T2DLnPr2frMnL906CNEoKRwLB+VYFhPq2w= +github.com/JimmyHuang454/hysteria/core v0.0.0-20240408143247-3a6a6d41fbe2 h1:/lKOEeohwnaQO+CCPLM+o0NPRZ43Ceznq7CZbl3C14w= +github.com/JimmyHuang454/hysteria/core v0.0.0-20240408143247-3a6a6d41fbe2/go.mod h1:RBDIw+EbNr0o9pLON6P4J6Uhesmc9OSczAgH8QN5R74= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= From 78f563ad4d3f654f5d9bce349b164268aa16d870 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Tue, 9 Apr 2024 01:06:59 +0800 Subject: [PATCH 63/81] fix test --- testing/scenarios/hy2_test.go | 8 ++++---- transport/internet/hysteria2/hy2_transport_test.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/testing/scenarios/hy2_test.go b/testing/scenarios/hy2_test.go index a61f435ec7..324937dd72 100644 --- a/testing/scenarios/hy2_test.go +++ b/testing/scenarios/hy2_test.go @@ -218,9 +218,9 @@ func testHysteria2Offical(t *testing.T, isUDP bool) { Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, - Udp: true, - Password: "password", + Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, + UseUdpExtension: true, + Password: "password", }), }, }, @@ -277,7 +277,7 @@ func testHysteria2Offical(t *testing.T, isUDP bool) { Type: protocol.SecurityType_NONE, }, Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, - Udp: true, + UseUdpExtension: true, Password: "password", }), }, diff --git a/transport/internet/hysteria2/hy2_transport_test.go b/transport/internet/hysteria2/hy2_transport_test.go index 1a0f8d3d20..e4a5c1fde8 100644 --- a/transport/internet/hysteria2/hy2_transport_test.go +++ b/transport/internet/hysteria2/hy2_transport_test.go @@ -91,7 +91,7 @@ func TestUDP(t *testing.T) { listener, err := hysteria2.Listen(context.Background(), net.LocalHostIP, port, &internet.MemoryStreamConfig{ ProtocolName: "hysteria2", - ProtocolSettings: &hysteria2.Config{Password: "123", Udp: true}, + ProtocolSettings: &hysteria2.Config{Password: "123", UseUdpExtension: true}, SecurityType: "tls", SecuritySettings: &tls.Config{ Certificate: []*tls.Certificate{ @@ -131,7 +131,7 @@ func TestUDP(t *testing.T) { conn, err := hysteria2.Dial(dctx, net.TCPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{ ProtocolName: "hysteria2", - ProtocolSettings: &hysteria2.Config{Password: "123", Udp: true}, + ProtocolSettings: &hysteria2.Config{Password: "123", UseUdpExtension: true}, SecurityType: "tls", SecuritySettings: &tls.Config{ ServerName: "www.v2fly.org", From cdbd68de9b241de01921eb3279b28ae84f958e46 Mon Sep 17 00:00:00 2001 From: JimmyHuang Date: Thu, 11 Apr 2024 02:02:18 +0800 Subject: [PATCH 64/81] remove legacy code, add traffic counter(Only TCP), add err checker --- proxy/hysteria2/client.go | 9 +++++++-- proxy/hysteria2/protocol.go | 29 ++++++++--------------------- proxy/hysteria2/server.go | 7 ++++++- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/proxy/hysteria2/client.go b/proxy/hysteria2/client.go index cf1322ce74..35fe4d767d 100644 --- a/proxy/hysteria2/client.go +++ b/proxy/hysteria2/client.go @@ -75,7 +75,12 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter } newError("tunneling request to ", destination, " via ", server.Destination().NetAddr()).WriteToLog(session.ExportIDToError(ctx)) - hyConn, IsHy2Transport := conn.(*hy2_transport.HyConn) + iConn := conn + if statConn, ok := conn.(*internet.StatCouterConnection); ok { + iConn = statConn.Connection // will not count the UDP traffic. + } + hyConn, IsHy2Transport := iConn.(*hy2_transport.HyConn) + if !IsHy2Transport && !hyConn.IsUDPExtension { // is not hysteria2 and proxing UDP return newError(hy2_transport.CanNotUseUdpExtension) } @@ -107,7 +112,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter err = buf.CopyOnceTimeout(link.Reader, bodyWriter, proxy.FirstPayloadTimeout) switch err { case buf.ErrNotTimeoutReader, buf.ErrReadTimeout: - if err := connWriter.WriteHeader(); err != nil { + if err := connWriter.WriteTcpHeader(); err != nil { return newError("failed to write request header").Base(err).AtWarning() } case nil: diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index 7bdc495acb..864cf98cbb 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -8,25 +8,9 @@ import ( "github.com/apernet/quic-go/quicvarint" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" - "github.com/v2fly/v2ray-core/v5/common/protocol" hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" ) -var ( - crlf = []byte{'\r', '\n'} - - addrParser = protocol.NewAddressParser( - protocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4), - protocol.AddressFamilyByte(0x04, net.AddressFamilyIPv6), - protocol.AddressFamilyByte(0x03, net.AddressFamilyDomain), - ) -) - -const ( - commandTCP byte = 1 - commandUDP byte = 3 -) - // ConnWriter is TCP Connection Writer Wrapper type ConnWriter struct { io.Writer @@ -38,7 +22,7 @@ type ConnWriter struct { // Write implements io.Writer func (c *ConnWriter) Write(p []byte) (n int, err error) { if !c.TCPHeaderSent { - if err := c.writeHeader(); err != nil { + if err := c.writeTcpHeader(); err != nil { return 0, newError("failed to write request header").Base(err) } } @@ -61,9 +45,9 @@ func (c *ConnWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { return nil } -func (c *ConnWriter) WriteHeader() error { +func (c *ConnWriter) WriteTcpHeader() error { if !c.TCPHeaderSent { - if err := c.writeHeader(); err != nil { + if err := c.writeTcpHeader(); err != nil { return err } } @@ -74,7 +58,7 @@ func QuicLen(s int) int { return int(quicvarint.Len(uint64(s))) } -func (c *ConnWriter) writeHeader() error { +func (c *ConnWriter) writeTcpHeader() error { padding := "Jimmy Was Here" paddingLen := len(padding) addressAndPort := c.Target.Address.String() + ":" + c.Target.Port.String() @@ -182,7 +166,10 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) { // ReadMultiBufferWithMetadata reads udp packet with destination func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) { - _, data, dest, _ := r.HyConn.ReadPacket() + _, data, dest, err := r.HyConn.ReadPacket() + if err != nil { + return nil, err + } b := buf.FromBytes(data) return &PacketPayload{Target: *dest, Buffer: buf.MultiBuffer{b}}, nil } diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index f20159ca55..60f6bb7890 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -69,7 +69,12 @@ func (s *Server) Network() []net.Network { func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error { sid := session.ExportIDToError(ctx) - hyConn, IsHy2Transport := conn.(*hy2_transport.HyConn) + iConn := conn + if statConn, ok := conn.(*internet.StatCouterConnection); ok { + iConn = statConn.Connection // will not count the UDP traffic. + } + hyConn, IsHy2Transport := iConn.(*hy2_transport.HyConn) + if IsHy2Transport && hyConn.IsUDPExtension { network = net.Network_UDP } From 91c2d87b16244d0c00832e2e11e76580bad6ef91 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 May 2024 10:45:55 +0800 Subject: [PATCH 65/81] update example --- release/config/hy2/hysteria2_offical_v4.json | 17 +++++++++++++---- release/config/hy2/hysteria2_official.json5 | 13 +++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/release/config/hy2/hysteria2_offical_v4.json b/release/config/hy2/hysteria2_offical_v4.json index 8e85e833e9..2046c31d17 100644 --- a/release/config/hy2/hysteria2_offical_v4.json +++ b/release/config/hy2/hysteria2_offical_v4.json @@ -8,13 +8,16 @@ "tag": "http", "protocol": "http" }, { - "port": 1280, + "port": 1443, "listen": "127.0.0.1", "tag": "hy2_in", "protocol": "hysteria2", "streamSettings": { "network": "hysteria2", - "security": "tls" + "security": "tls", + "hy2Settings": { + "password": "your-password" + } } }], "outbounds": [{ @@ -26,12 +29,18 @@ "settings": { "servers": [{ "address": "127.0.0.1", - "port": 1280 + "port": 1443 }] }, "streamSettings": { "network": "hysteria2", - "security": "tls" + "security": "tls", + "tlsSettings": { + "allowInsecure": true + }, + "hy2Settings": { + "password": "your-password" + } } }], "routing": { diff --git a/release/config/hy2/hysteria2_official.json5 b/release/config/hy2/hysteria2_official.json5 index 6be1013aae..d1db1dfe51 100644 --- a/release/config/hy2/hysteria2_official.json5 +++ b/release/config/hy2/hysteria2_official.json5 @@ -8,7 +8,7 @@ "tag": "http", "protocol": "http" }, { - "port": 1280, + "port": 1443, "listen": "127.0.0.1", "tag": "hy2_in_bbr", "protocol": "hysteria2", @@ -18,6 +18,7 @@ "congestion": { "type": "bbr" }, + "password": "your-password" "use_udp_extension": true }, "security": "tls" @@ -49,7 +50,7 @@ "settings": { "server": [{ "address": "127.0.0.1", - "port": 1280 + "port": 1443 }] }, "streamSettings": { @@ -57,9 +58,13 @@ "transportSettings": { "congestion": { "type": "bbr" - } + }, + "password": "your-password" }, - "security": "tls" + "security": "tls", + "securitySettings": { + "allowInsecure": true + } } }], "routing": { From 08ea4ef3044c87bf06f22cce1b5f582ba044d410 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 May 2024 17:13:02 +0800 Subject: [PATCH 66/81] fix hysteria2OnTCP and use ListenSystemPacket --- proxy/hysteria2/client.go | 3 ++- testing/scenarios/hy2_test.go | 8 ++++---- transport/internet/hysteria2/dialer.go | 22 ++++++++++++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/proxy/hysteria2/client.go b/proxy/hysteria2/client.go index 35fe4d767d..6f897152d9 100644 --- a/proxy/hysteria2/client.go +++ b/proxy/hysteria2/client.go @@ -81,7 +81,8 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter } hyConn, IsHy2Transport := iConn.(*hy2_transport.HyConn) - if !IsHy2Transport && !hyConn.IsUDPExtension { // is not hysteria2 and proxing UDP + if !IsHy2Transport && network == net.Network_UDP { + // hysteria2 need to use udp extension to proxy UDP. return newError(hy2_transport.CanNotUseUdpExtension) } diff --git a/testing/scenarios/hy2_test.go b/testing/scenarios/hy2_test.go index 324937dd72..1e7f5244ca 100644 --- a/testing/scenarios/hy2_test.go +++ b/testing/scenarios/hy2_test.go @@ -276,9 +276,9 @@ func testHysteria2Offical(t *testing.T, isUDP bool) { Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, - UseUdpExtension: true, - Password: "password", + Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, + UseUdpExtension: true, + Password: "password", }), }, }, @@ -321,7 +321,7 @@ func testHysteria2Offical(t *testing.T, isUDP bool) { } } -func TestHysteria2TCP(t *testing.T) { +func TestHysteria2OnTCP(t *testing.T) { tcpServer := tcp.Server{ MsgProcessor: xor, } diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 2cd7cfd330..10bd67858b 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -52,6 +52,16 @@ func InitAddress(dest net.Destination) (net.Addr, error) { return destAddr, nil } +type connFactory struct { + hy_client.ConnFactory + + NewFunc func(addr net.Addr) (net.PacketConn, error) +} + +func (f *connFactory) New(addr net.Addr) (net.PacketConn, error) { + return f.NewFunc(addr) +} + func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hy_client.Client, error) { tlsConfig, err := InitTLSConifg(streamSettings) if err != nil { @@ -68,6 +78,18 @@ func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConf TLSConfig: *tlsConfig, Auth: config.GetPassword(), ServerAddr: serverAddr, + ConnFactory: &connFactory{ + NewFunc: func(addr net.Addr) (net.PacketConn, error) { + rawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{ + IP: []byte{0, 0, 0, 0}, + Port: 0, + }, streamSettings.SocketSettings) + if err != nil { + return nil, err + } + return rawConn.(*net.UDPConn), nil + }, + }, }) if err != nil { return nil, err From 09e177610f6d693718b9f4e066c5fef9a18bd354 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 May 2024 19:55:33 +0800 Subject: [PATCH 67/81] rename --- transport/internet/hysteria2/conn.go | 8 ++++---- transport/internet/hysteria2/dialer.go | 26 +++++++++++--------------- transport/internet/hysteria2/hub.go | 12 ++++++------ 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index 258c24c472..02c41faa4d 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -3,9 +3,9 @@ package hysteria2 import ( "time" - hy_client "github.com/apernet/hysteria/core/client" + hyClient "github.com/apernet/hysteria/core/client" "github.com/apernet/hysteria/core/international/protocol" - hy_server "github.com/apernet/hysteria/core/server" + hyServer "github.com/apernet/hysteria/core/server" "github.com/apernet/quic-go" "github.com/v2fly/v2ray-core/v5/common/buf" @@ -17,8 +17,8 @@ const CanNotUseUdpExtension = "Only hysteria2 proxy protocol can use udpExtensio type HyConn struct { IsUDPExtension bool IsServer bool - ClientUDPSession hy_client.HyUDPConn - ServerUDPSession *hy_server.UdpSessionEntry + ClientUDPSession hyClient.HyUDPConn + ServerUDPSession *hyServer.UdpSessionEntry Target net.Destination stream quic.Stream diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 10bd67858b..efdcf4b70c 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -3,7 +3,7 @@ package hysteria2 import ( "context" - hy_client "github.com/apernet/hysteria/core/client" + hyClient "github.com/apernet/hysteria/core/client" hyProtocol "github.com/apernet/hysteria/core/international/protocol" "github.com/apernet/quic-go/quicvarint" @@ -14,13 +14,9 @@ import ( "github.com/v2fly/v2ray-core/v5/transport/internet/tls" ) -const ( - FrameTypeTCPRequest = 0x401 -) - -var RunningClient map[net.Destination](hy_client.Client) +var RunningClient map[net.Destination](hyClient.Client) -func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hy_client.TLSConfig, error) { +func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hyClient.TLSConfig, error) { tlsSetting := CheckTLSConfig(streamSettings, true) if tlsSetting == nil { tlsSetting = &tls.Config{ @@ -28,7 +24,7 @@ func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hy_client.TLSC AllowInsecure: true, } } - res := &hy_client.TLSConfig{ + res := &hyClient.TLSConfig{ ServerName: tlsSetting.ServerName, InsecureSkipVerify: tlsSetting.AllowInsecure, } @@ -53,7 +49,7 @@ func InitAddress(dest net.Destination) (net.Addr, error) { } type connFactory struct { - hy_client.ConnFactory + hyClient.ConnFactory NewFunc func(addr net.Addr) (net.PacketConn, error) } @@ -62,7 +58,7 @@ func (f *connFactory) New(addr net.Addr) (net.PacketConn, error) { return f.NewFunc(addr) } -func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hy_client.Client, error) { +func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hyClient.Client, error) { tlsConfig, err := InitTLSConifg(streamSettings) if err != nil { return nil, err @@ -74,7 +70,7 @@ func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConf } config := streamSettings.ProtocolSettings.(*Config) - client, _, err := hy_client.NewClient(&hy_client.Config{ + client, _, err := hyClient.NewClient(&hyClient.Config{ TLSConfig: *tlsConfig, Auth: config.GetPassword(), ServerAddr: serverAddr, @@ -111,7 +107,7 @@ func CloseHyClient(dest net.Destination) error { func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { config := streamSettings.ProtocolSettings.(*Config) - var client hy_client.Client + var client hyClient.Client var err error client, found := RunningClient[dest] if !found { @@ -153,14 +149,14 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me } // write TCP frame type - frameSize := int(quicvarint.Len(FrameTypeTCPRequest)) + frameSize := int(quicvarint.Len(hyProtocol.FrameTypeTCPRequest)) buf := make([]byte, frameSize) - hyProtocol.VarintPut(buf, FrameTypeTCPRequest) + hyProtocol.VarintPut(buf, hyProtocol.FrameTypeTCPRequest) conn.stream.Write(buf) return conn, nil } func init() { - RunningClient = make(map[net.Destination]hy_client.Client) + RunningClient = make(map[net.Destination]hyClient.Client) common.Must(internet.RegisterTransportDialer(protocolName, Dial)) } diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 75219e35d0..0394512977 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -3,7 +3,7 @@ package hysteria2 import ( "context" - hy_server "github.com/apernet/hysteria/core/server" + hyServer "github.com/apernet/hysteria/core/server" "github.com/apernet/quic-go" "github.com/apernet/quic-go/http3" @@ -16,7 +16,7 @@ import ( // Listener is an internet.Listener that listens for TCP connections. type Listener struct { - hyServer hy_server.Server + hyServer hyServer.Server rawConn net.PacketConn addConn internet.ConnHandler } @@ -44,7 +44,7 @@ func (l *Listener) ProxyStreamHijacker(ft http3.FrameType, return true, nil } -func (l *Listener) UdpHijacker(entry *hy_server.UdpSessionEntry, originalAddr string) { +func (l *Listener) UdpHijacker(entry *hyServer.UdpSessionEntry, originalAddr string) { addr, err := net.ResolveUDPAddr("udp", originalAddr) if err != nil { return @@ -82,7 +82,7 @@ func Listen(ctx context.Context, address net.Address, port net.Port, addConn: handler, } - hyServer, err := hy_server.NewServer(&hy_server.Config{ + hyServer, err := hyServer.NewServer(&hyServer.Config{ Conn: rawConn, TLSConfig: *GetTLSConfig(streamSettings), Authenticator: &Authenticator{Password: config.GetPassword()}, @@ -111,7 +111,7 @@ func CheckTLSConfig(streamSettings *internet.MemoryStreamConfig, isClient bool) return tlsSetting } -func GetTLSConfig(streamSettings *internet.MemoryStreamConfig) *hy_server.TLSConfig { +func GetTLSConfig(streamSettings *internet.MemoryStreamConfig) *hyServer.TLSConfig { tlsSetting := CheckTLSConfig(streamSettings, false) if tlsSetting == nil { tlsSetting = &tls.Config{ @@ -122,7 +122,7 @@ func GetTLSConfig(streamSettings *internet.MemoryStreamConfig) *hy_server.TLSCon }, } } - return &hy_server.TLSConfig{Certificates: tlsSetting.GetTLSConfig().Certificates} + return &hyServer.TLSConfig{Certificates: tlsSetting.GetTLSConfig().Certificates} } type Authenticator struct { From fe0c3aa9dcab53dd80ca6ffc3c0aba27a94ec853 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 May 2024 14:45:22 +0800 Subject: [PATCH 68/81] rename and fix address parsing --- proxy/hysteria2/client.go | 8 ++++---- proxy/hysteria2/protocol.go | 14 +++++++------- proxy/hysteria2/server.go | 15 +++++++++------ testing/scenarios/hy2_test.go | 24 ++++++++++++------------ 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/proxy/hysteria2/client.go b/proxy/hysteria2/client.go index 6f897152d9..edd8c4d785 100644 --- a/proxy/hysteria2/client.go +++ b/proxy/hysteria2/client.go @@ -17,7 +17,7 @@ import ( "github.com/v2fly/v2ray-core/v5/proxy" "github.com/v2fly/v2ray-core/v5/transport" "github.com/v2fly/v2ray-core/v5/transport/internet" - hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" + hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" ) // Client is an inbound handler @@ -79,11 +79,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter if statConn, ok := conn.(*internet.StatCouterConnection); ok { iConn = statConn.Connection // will not count the UDP traffic. } - hyConn, IsHy2Transport := iConn.(*hy2_transport.HyConn) + hyConn, IsHy2Transport := iConn.(*hyTransport.HyConn) if !IsHy2Transport && network == net.Network_UDP { // hysteria2 need to use udp extension to proxy UDP. - return newError(hy2_transport.CanNotUseUdpExtension) + return newError(hyTransport.CanNotUseUdpExtension) } defer conn.Close() @@ -113,7 +113,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter err = buf.CopyOnceTimeout(link.Reader, bodyWriter, proxy.FirstPayloadTimeout) switch err { case buf.ErrNotTimeoutReader, buf.ErrReadTimeout: - if err := connWriter.WriteTcpHeader(); err != nil { + if err := connWriter.WriteTCPHeader(); err != nil { return newError("failed to write request header").Base(err).AtWarning() } case nil: diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index 864cf98cbb..84baa3e8cc 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -8,7 +8,7 @@ import ( "github.com/apernet/quic-go/quicvarint" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" - hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" + hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" ) // ConnWriter is TCP Connection Writer Wrapper @@ -22,7 +22,7 @@ type ConnWriter struct { // Write implements io.Writer func (c *ConnWriter) Write(p []byte) (n int, err error) { if !c.TCPHeaderSent { - if err := c.writeTcpHeader(); err != nil { + if err := c.writeTCPHeader(); err != nil { return 0, newError("failed to write request header").Base(err) } } @@ -45,9 +45,9 @@ func (c *ConnWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { return nil } -func (c *ConnWriter) WriteTcpHeader() error { +func (c *ConnWriter) WriteTCPHeader() error { if !c.TCPHeaderSent { - if err := c.writeTcpHeader(); err != nil { + if err := c.writeTCPHeader(); err != nil { return err } } @@ -58,7 +58,7 @@ func QuicLen(s int) int { return int(quicvarint.Len(uint64(s))) } -func (c *ConnWriter) writeTcpHeader() error { +func (c *ConnWriter) writeTCPHeader() error { padding := "Jimmy Was Here" paddingLen := len(padding) addressAndPort := c.Target.Address.String() + ":" + c.Target.Port.String() @@ -81,7 +81,7 @@ func (c *ConnWriter) writeTcpHeader() error { // PacketWriter UDP Connection Writer Wrapper type PacketWriter struct { io.Writer - HyConn *hy2_transport.HyConn + HyConn *hyTransport.HyConn Target net.Destination } @@ -152,7 +152,7 @@ type PacketPayload struct { // PacketReader is UDP Connection Reader Wrapper type PacketReader struct { io.Reader - HyConn *hy2_transport.HyConn + HyConn *hyTransport.HyConn } // ReadMultiBuffer implements buf.Reader diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index 60f6bb7890..30c366e891 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -21,7 +21,7 @@ import ( "github.com/v2fly/v2ray-core/v5/features/policy" "github.com/v2fly/v2ray-core/v5/features/routing" "github.com/v2fly/v2ray-core/v5/transport/internet" - hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" + hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" "github.com/v2fly/v2ray-core/v5/transport/internet/udp" ) @@ -73,14 +73,14 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet if statConn, ok := conn.(*internet.StatCouterConnection); ok { iConn = statConn.Connection // will not count the UDP traffic. } - hyConn, IsHy2Transport := iConn.(*hy2_transport.HyConn) + hyConn, IsHy2Transport := iConn.(*hyTransport.HyConn) if IsHy2Transport && hyConn.IsUDPExtension { network = net.Network_UDP } if !IsHy2Transport && network == net.Network_UDP { - return newError(hy2_transport.CanNotUseUdpExtension) + return newError(hyTransport.CanNotUseUdpExtension) } sessionPolicy := s.policyManager.ForLevel(0) @@ -114,12 +114,15 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet return newError("failed to send response").Base(err) } - address := strings.Split(reqAddr, ":") - port, err := net.PortFromString(address[1]) + address, stringPort, err := net.SplitHostPort(reqAddr) if err != nil { return err } - destination := net.Destination{Network: network, Address: net.ParseAddress(address[0]), Port: port} + port, err := net.PortFromString(stringPort) + if err != nil { + return err + } + destination := net.Destination{Network: network, Address: net.ParseAddress(address), Port: port} inbound := session.InboundFromContext(ctx) if inbound == nil { diff --git a/testing/scenarios/hy2_test.go b/testing/scenarios/hy2_test.go index 1e7f5244ca..e973320592 100644 --- a/testing/scenarios/hy2_test.go +++ b/testing/scenarios/hy2_test.go @@ -26,8 +26,8 @@ import ( "github.com/v2fly/v2ray-core/v5/testing/servers/udp" "github.com/v2fly/v2ray-core/v5/transport/internet" "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http" - hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" - tcptransport "github.com/v2fly/v2ray-core/v5/transport/internet/tcp" + hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" + tcpTransport "github.com/v2fly/v2ray-core/v5/transport/internet/tcp" ) func TestVMessHysteria2Congestion(t *testing.T) { @@ -62,11 +62,11 @@ func testVMessHysteria2(t *testing.T, congestionType string) { TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hy2_transport.Config{ + Settings: serial.ToTypedMessage(&hyTransport.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hy2_transport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, + Congestion: &hyTransport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, Password: "password", }), }, @@ -122,11 +122,11 @@ func testVMessHysteria2(t *testing.T, congestionType string) { TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hy2_transport.Config{ + Settings: serial.ToTypedMessage(&hyTransport.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hy2_transport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, + Congestion: &hyTransport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, Password: "password", }), }, @@ -214,11 +214,11 @@ func testHysteria2Offical(t *testing.T, isUDP bool) { TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hy2_transport.Config{ + Settings: serial.ToTypedMessage(&hyTransport.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, + Congestion: &hyTransport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, UseUdpExtension: true, Password: "password", }), @@ -272,11 +272,11 @@ func testHysteria2Offical(t *testing.T, isUDP bool) { TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hy2_transport.Config{ + Settings: serial.ToTypedMessage(&hyTransport.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, + Congestion: &hyTransport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, UseUdpExtension: true, Password: "password", }), @@ -345,7 +345,7 @@ func TestHysteria2OnTCP(t *testing.T) { TransportSettings: []*internet.TransportConfig{ { Protocol: internet.TransportProtocol_TCP, - Settings: serial.ToTypedMessage(&tcptransport.Config{ + Settings: serial.ToTypedMessage(&tcpTransport.Config{ HeaderSettings: serial.ToTypedMessage(&http.Config{}), }), }, @@ -397,7 +397,7 @@ func TestHysteria2OnTCP(t *testing.T) { TransportSettings: []*internet.TransportConfig{ { Protocol: internet.TransportProtocol_TCP, - Settings: serial.ToTypedMessage(&tcptransport.Config{ + Settings: serial.ToTypedMessage(&tcpTransport.Config{ HeaderSettings: serial.ToTypedMessage(&http.Config{}), }), }, From 74593e097337024fc92020747916157b21280611 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 May 2024 14:45:22 +0800 Subject: [PATCH 69/81] rename and fix address parsing --- proxy/hysteria2/client.go | 8 ++++---- proxy/hysteria2/protocol.go | 14 +++++++------- proxy/hysteria2/server.go | 16 +++++++++------- testing/scenarios/hy2_test.go | 24 ++++++++++++------------ 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/proxy/hysteria2/client.go b/proxy/hysteria2/client.go index 6f897152d9..edd8c4d785 100644 --- a/proxy/hysteria2/client.go +++ b/proxy/hysteria2/client.go @@ -17,7 +17,7 @@ import ( "github.com/v2fly/v2ray-core/v5/proxy" "github.com/v2fly/v2ray-core/v5/transport" "github.com/v2fly/v2ray-core/v5/transport/internet" - hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" + hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" ) // Client is an inbound handler @@ -79,11 +79,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter if statConn, ok := conn.(*internet.StatCouterConnection); ok { iConn = statConn.Connection // will not count the UDP traffic. } - hyConn, IsHy2Transport := iConn.(*hy2_transport.HyConn) + hyConn, IsHy2Transport := iConn.(*hyTransport.HyConn) if !IsHy2Transport && network == net.Network_UDP { // hysteria2 need to use udp extension to proxy UDP. - return newError(hy2_transport.CanNotUseUdpExtension) + return newError(hyTransport.CanNotUseUdpExtension) } defer conn.Close() @@ -113,7 +113,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter err = buf.CopyOnceTimeout(link.Reader, bodyWriter, proxy.FirstPayloadTimeout) switch err { case buf.ErrNotTimeoutReader, buf.ErrReadTimeout: - if err := connWriter.WriteTcpHeader(); err != nil { + if err := connWriter.WriteTCPHeader(); err != nil { return newError("failed to write request header").Base(err).AtWarning() } case nil: diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index 864cf98cbb..84baa3e8cc 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -8,7 +8,7 @@ import ( "github.com/apernet/quic-go/quicvarint" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" - hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" + hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" ) // ConnWriter is TCP Connection Writer Wrapper @@ -22,7 +22,7 @@ type ConnWriter struct { // Write implements io.Writer func (c *ConnWriter) Write(p []byte) (n int, err error) { if !c.TCPHeaderSent { - if err := c.writeTcpHeader(); err != nil { + if err := c.writeTCPHeader(); err != nil { return 0, newError("failed to write request header").Base(err) } } @@ -45,9 +45,9 @@ func (c *ConnWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { return nil } -func (c *ConnWriter) WriteTcpHeader() error { +func (c *ConnWriter) WriteTCPHeader() error { if !c.TCPHeaderSent { - if err := c.writeTcpHeader(); err != nil { + if err := c.writeTCPHeader(); err != nil { return err } } @@ -58,7 +58,7 @@ func QuicLen(s int) int { return int(quicvarint.Len(uint64(s))) } -func (c *ConnWriter) writeTcpHeader() error { +func (c *ConnWriter) writeTCPHeader() error { padding := "Jimmy Was Here" paddingLen := len(padding) addressAndPort := c.Target.Address.String() + ":" + c.Target.Port.String() @@ -81,7 +81,7 @@ func (c *ConnWriter) writeTcpHeader() error { // PacketWriter UDP Connection Writer Wrapper type PacketWriter struct { io.Writer - HyConn *hy2_transport.HyConn + HyConn *hyTransport.HyConn Target net.Destination } @@ -152,7 +152,7 @@ type PacketPayload struct { // PacketReader is UDP Connection Reader Wrapper type PacketReader struct { io.Reader - HyConn *hy2_transport.HyConn + HyConn *hyTransport.HyConn } // ReadMultiBuffer implements buf.Reader diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index 60f6bb7890..a18daa3558 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -3,7 +3,6 @@ package hysteria2 import ( "context" "io" - "strings" "time" hyProtocol "github.com/apernet/hysteria/core/international/protocol" @@ -21,7 +20,7 @@ import ( "github.com/v2fly/v2ray-core/v5/features/policy" "github.com/v2fly/v2ray-core/v5/features/routing" "github.com/v2fly/v2ray-core/v5/transport/internet" - hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" + hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" "github.com/v2fly/v2ray-core/v5/transport/internet/udp" ) @@ -73,14 +72,14 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet if statConn, ok := conn.(*internet.StatCouterConnection); ok { iConn = statConn.Connection // will not count the UDP traffic. } - hyConn, IsHy2Transport := iConn.(*hy2_transport.HyConn) + hyConn, IsHy2Transport := iConn.(*hyTransport.HyConn) if IsHy2Transport && hyConn.IsUDPExtension { network = net.Network_UDP } if !IsHy2Transport && network == net.Network_UDP { - return newError(hy2_transport.CanNotUseUdpExtension) + return newError(hyTransport.CanNotUseUdpExtension) } sessionPolicy := s.policyManager.ForLevel(0) @@ -114,12 +113,15 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet return newError("failed to send response").Base(err) } - address := strings.Split(reqAddr, ":") - port, err := net.PortFromString(address[1]) + address, stringPort, err := net.SplitHostPort(reqAddr) if err != nil { return err } - destination := net.Destination{Network: network, Address: net.ParseAddress(address[0]), Port: port} + port, err := net.PortFromString(stringPort) + if err != nil { + return err + } + destination := net.Destination{Network: network, Address: net.ParseAddress(address), Port: port} inbound := session.InboundFromContext(ctx) if inbound == nil { diff --git a/testing/scenarios/hy2_test.go b/testing/scenarios/hy2_test.go index 1e7f5244ca..e973320592 100644 --- a/testing/scenarios/hy2_test.go +++ b/testing/scenarios/hy2_test.go @@ -26,8 +26,8 @@ import ( "github.com/v2fly/v2ray-core/v5/testing/servers/udp" "github.com/v2fly/v2ray-core/v5/transport/internet" "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http" - hy2_transport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" - tcptransport "github.com/v2fly/v2ray-core/v5/transport/internet/tcp" + hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" + tcpTransport "github.com/v2fly/v2ray-core/v5/transport/internet/tcp" ) func TestVMessHysteria2Congestion(t *testing.T) { @@ -62,11 +62,11 @@ func testVMessHysteria2(t *testing.T, congestionType string) { TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hy2_transport.Config{ + Settings: serial.ToTypedMessage(&hyTransport.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hy2_transport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, + Congestion: &hyTransport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, Password: "password", }), }, @@ -122,11 +122,11 @@ func testVMessHysteria2(t *testing.T, congestionType string) { TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hy2_transport.Config{ + Settings: serial.ToTypedMessage(&hyTransport.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hy2_transport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, + Congestion: &hyTransport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, Password: "password", }), }, @@ -214,11 +214,11 @@ func testHysteria2Offical(t *testing.T, isUDP bool) { TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hy2_transport.Config{ + Settings: serial.ToTypedMessage(&hyTransport.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, + Congestion: &hyTransport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, UseUdpExtension: true, Password: "password", }), @@ -272,11 +272,11 @@ func testHysteria2Offical(t *testing.T, isUDP bool) { TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", - Settings: serial.ToTypedMessage(&hy2_transport.Config{ + Settings: serial.ToTypedMessage(&hyTransport.Config{ Security: &protocol.SecurityConfig{ Type: protocol.SecurityType_NONE, }, - Congestion: &hy2_transport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, + Congestion: &hyTransport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, UseUdpExtension: true, Password: "password", }), @@ -345,7 +345,7 @@ func TestHysteria2OnTCP(t *testing.T) { TransportSettings: []*internet.TransportConfig{ { Protocol: internet.TransportProtocol_TCP, - Settings: serial.ToTypedMessage(&tcptransport.Config{ + Settings: serial.ToTypedMessage(&tcpTransport.Config{ HeaderSettings: serial.ToTypedMessage(&http.Config{}), }), }, @@ -397,7 +397,7 @@ func TestHysteria2OnTCP(t *testing.T) { TransportSettings: []*internet.TransportConfig{ { Protocol: internet.TransportProtocol_TCP, - Settings: serial.ToTypedMessage(&tcptransport.Config{ + Settings: serial.ToTypedMessage(&tcpTransport.Config{ HeaderSettings: serial.ToTypedMessage(&http.Config{}), }), }, From b2cb9594cfd07cf956577d41abc1901a2467ab26 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 May 2024 15:19:33 +0800 Subject: [PATCH 70/81] update core version --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 20f2fcbe97..5212d272d4 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ toolchain go1.21.4 require ( github.com/adrg/xdg v0.4.0 github.com/apernet/hysteria/core v1.3.5 - github.com/apernet/quic-go v0.42.1-0.20240323215309-32a339817822 + github.com/apernet/quic-go v0.43.1-0.20240429030958-51a0843014d6 github.com/go-chi/chi/v5 v5.0.12 github.com/go-chi/render v1.0.3 github.com/go-playground/validator/v10 v10.20.0 @@ -90,4 +90,4 @@ require ( replace github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 => github.com/xiaokangwang/struc v0.0.0-20231031203518-0e381172f248 -replace github.com/apernet/hysteria/core v1.3.5 => github.com/JimmyHuang454/hysteria/core v0.0.0-20240408143247-3a6a6d41fbe2 +replace github.com/apernet/hysteria/core v1.3.5 => github.com/JimmyHuang454/hysteria/core v0.0.0-20240510071018-cee008247828 diff --git a/go.sum b/go.sum index d12d9b54ea..3e757b5f36 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/FlowerWrong/water v0.0.0-20180301012659-01a4eaa1f6f2/go.mod h1:xrG5L7lq7T2DLnPr2frMnL906CNEoKRwLB+VYFhPq2w= -github.com/JimmyHuang454/hysteria/core v0.0.0-20240408143247-3a6a6d41fbe2 h1:/lKOEeohwnaQO+CCPLM+o0NPRZ43Ceznq7CZbl3C14w= -github.com/JimmyHuang454/hysteria/core v0.0.0-20240408143247-3a6a6d41fbe2/go.mod h1:RBDIw+EbNr0o9pLON6P4J6Uhesmc9OSczAgH8QN5R74= +github.com/JimmyHuang454/hysteria/core v0.0.0-20240510071018-cee008247828 h1:VjGcFN8xkTFDdHH/6oLtyYvJ8biz3Y7bBSP4ldZnKok= +github.com/JimmyHuang454/hysteria/core v0.0.0-20240510071018-cee008247828/go.mod h1:M90Ik/hn3JaHS/oXmncvnEiIatdIhMNLvKHOqp9ap/M= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= @@ -27,8 +27,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/apernet/quic-go v0.42.1-0.20240323215309-32a339817822 h1:+ZSzRxSMg1+fLTQKcIUvD2cCCgS+1rtyRhs+NL5oBgA= -github.com/apernet/quic-go v0.42.1-0.20240323215309-32a339817822/go.mod h1:j3QaAM7sVJqptDQyIQRWA6mASCfuxoHJszn67JQh1GE= +github.com/apernet/quic-go v0.43.1-0.20240429030958-51a0843014d6 h1:ZfaQo52EyyhNCxfMNk64W1YHcIh+0rCkp3e0gR7BO5E= +github.com/apernet/quic-go v0.43.1-0.20240429030958-51a0843014d6/go.mod h1:j3QaAM7sVJqptDQyIQRWA6mASCfuxoHJszn67JQh1GE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= From dfb42e1cf11d835cfa7dcb31b877bed97319eecf Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 May 2024 16:05:45 +0800 Subject: [PATCH 71/81] update hysteria2 --- go.mod | 3 ++- go.sum | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5212d272d4..d2adfc65df 100644 --- a/go.mod +++ b/go.mod @@ -90,4 +90,5 @@ require ( replace github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 => github.com/xiaokangwang/struc v0.0.0-20231031203518-0e381172f248 -replace github.com/apernet/hysteria/core v1.3.5 => github.com/JimmyHuang454/hysteria/core v0.0.0-20240510071018-cee008247828 +replace github.com/apernet/hysteria/core v1.3.5 => github.com/JimmyHuang454/hysteria/core v0.0.0-20240511074602-b0840e28099e +//replace github.com/apernet/hysteria/core => ../hysteria/core/ diff --git a/go.sum b/go.sum index 3e757b5f36..a1aade9848 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/FlowerWrong/water v0.0.0-20180301012659-01a4eaa1f6f2/go.mod h1:xrG5L7lq7T2DLnPr2frMnL906CNEoKRwLB+VYFhPq2w= -github.com/JimmyHuang454/hysteria/core v0.0.0-20240510071018-cee008247828 h1:VjGcFN8xkTFDdHH/6oLtyYvJ8biz3Y7bBSP4ldZnKok= -github.com/JimmyHuang454/hysteria/core v0.0.0-20240510071018-cee008247828/go.mod h1:M90Ik/hn3JaHS/oXmncvnEiIatdIhMNLvKHOqp9ap/M= +github.com/JimmyHuang454/hysteria/core v0.0.0-20240511074602-b0840e28099e h1:inRDfo93TKP2xYXtSKIVMErrnUm8UuHFMyHXTxfvsBQ= +github.com/JimmyHuang454/hysteria/core v0.0.0-20240511074602-b0840e28099e/go.mod h1:nzkbgafcTmrehm47Ncx1u/Ts0dfg4MuTKSeCVmFvLyk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= From 2d0ba37be64e2837a070b87032a5122aff21eff5 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 May 2024 16:11:15 +0800 Subject: [PATCH 72/81] mod tidy --- go.mod | 1 + 1 file changed, 1 insertion(+) diff --git a/go.mod b/go.mod index d2adfc65df..b4cf20134c 100644 --- a/go.mod +++ b/go.mod @@ -91,4 +91,5 @@ require ( replace github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 => github.com/xiaokangwang/struc v0.0.0-20231031203518-0e381172f248 replace github.com/apernet/hysteria/core v1.3.5 => github.com/JimmyHuang454/hysteria/core v0.0.0-20240511074602-b0840e28099e + //replace github.com/apernet/hysteria/core => ../hysteria/core/ From 0653961ad87dfb0905f08d2b77a0639890a43162 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 May 2024 16:55:34 +0800 Subject: [PATCH 73/81] optimize GetTLSConfig() --- testing/scenarios/hy2_test.go | 68 +++++++++++++++++++++----- transport/internet/hysteria2/dialer.go | 19 ++++++- transport/internet/hysteria2/hub.go | 30 ++++++------ 3 files changed, 86 insertions(+), 31 deletions(-) diff --git a/testing/scenarios/hy2_test.go b/testing/scenarios/hy2_test.go index e973320592..39c1d0688a 100644 --- a/testing/scenarios/hy2_test.go +++ b/testing/scenarios/hy2_test.go @@ -14,6 +14,7 @@ import ( clog "github.com/v2fly/v2ray-core/v5/common/log" "github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/protocol" + "github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert" "github.com/v2fly/v2ray-core/v5/common/serial" "github.com/v2fly/v2ray-core/v5/common/uuid" "github.com/v2fly/v2ray-core/v5/proxy/dokodemo" @@ -28,6 +29,7 @@ import ( "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http" hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2" tcpTransport "github.com/v2fly/v2ray-core/v5/transport/internet/tcp" + "github.com/v2fly/v2ray-core/v5/transport/internet/tls" ) func TestVMessHysteria2Congestion(t *testing.T) { @@ -57,15 +59,21 @@ func testVMessHysteria2(t *testing.T, congestionType string) { ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ PortRange: net.SinglePortRange(serverPort), Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ ProtocolName: "hysteria2", + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*anypb.Any{ + serial.ToTypedMessage( + &tls.Config{ + Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))}, + }, + ), + }, TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", Settings: serial.ToTypedMessage(&hyTransport.Config{ - Security: &protocol.SecurityConfig{ - Type: protocol.SecurityType_NONE, - }, Congestion: &hyTransport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, Password: "password", }), @@ -119,13 +127,19 @@ func testVMessHysteria2(t *testing.T, congestionType string) { SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ StreamSettings: &internet.StreamConfig{ ProtocolName: "hysteria2", + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*anypb.Any{ + serial.ToTypedMessage( + &tls.Config{ + ServerName: "www.v2fly.org", + AllowInsecure: true, + }, + ), + }, TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", Settings: serial.ToTypedMessage(&hyTransport.Config{ - Security: &protocol.SecurityConfig{ - Type: protocol.SecurityType_NONE, - }, Congestion: &hyTransport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100}, Password: "password", }), @@ -144,7 +158,7 @@ func testVMessHysteria2(t *testing.T, congestionType string) { Id: userID.String(), AlterId: 0, SecuritySettings: &protocol.SecurityConfig{ - Type: protocol.SecurityType_AES128_GCM, + Type: protocol.SecurityType_NONE, }, }), }, @@ -211,13 +225,18 @@ func testHysteria2Offical(t *testing.T, isUDP bool) { Listen: net.NewIPOrDomain(net.LocalHostIP), StreamSettings: &internet.StreamConfig{ ProtocolName: "hysteria2", + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*anypb.Any{ + serial.ToTypedMessage( + &tls.Config{ + Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))}, + }, + ), + }, TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", Settings: serial.ToTypedMessage(&hyTransport.Config{ - Security: &protocol.SecurityConfig{ - Type: protocol.SecurityType_NONE, - }, Congestion: &hyTransport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, UseUdpExtension: true, Password: "password", @@ -269,13 +288,19 @@ func testHysteria2Offical(t *testing.T, isUDP bool) { SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ StreamSettings: &internet.StreamConfig{ ProtocolName: "hysteria2", + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*anypb.Any{ + serial.ToTypedMessage( + &tls.Config{ + ServerName: "www.v2fly.org", + AllowInsecure: true, + }, + ), + }, TransportSettings: []*internet.TransportConfig{ { ProtocolName: "hysteria2", Settings: serial.ToTypedMessage(&hyTransport.Config{ - Security: &protocol.SecurityConfig{ - Type: protocol.SecurityType_NONE, - }, Congestion: &hyTransport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100}, UseUdpExtension: true, Password: "password", @@ -342,6 +367,14 @@ func TestHysteria2OnTCP(t *testing.T) { PortRange: net.SinglePortRange(serverPort), Listen: net.NewIPOrDomain(net.LocalHostIP), StreamSettings: &internet.StreamConfig{ + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*anypb.Any{ + serial.ToTypedMessage( + &tls.Config{ + Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))}, + }, + ), + }, TransportSettings: []*internet.TransportConfig{ { Protocol: internet.TransportProtocol_TCP, @@ -394,6 +427,15 @@ func TestHysteria2OnTCP(t *testing.T) { { SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ StreamSettings: &internet.StreamConfig{ + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*anypb.Any{ + serial.ToTypedMessage( + &tls.Config{ + ServerName: "www.v2fly.org", + AllowInsecure: true, + }, + ), + }, TransportSettings: []*internet.TransportConfig{ { Protocol: internet.TransportProtocol_TCP, diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index efdcf4b70c..773591a17f 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -16,7 +16,7 @@ import ( var RunningClient map[net.Destination](hyClient.Client) -func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hyClient.TLSConfig, error) { +func InitTLSConifg2(streamSettings *internet.MemoryStreamConfig) (*hyClient.TLSConfig, error) { tlsSetting := CheckTLSConfig(streamSettings, true) if tlsSetting == nil { tlsSetting = &tls.Config{ @@ -31,6 +31,21 @@ func InitTLSConifg(streamSettings *internet.MemoryStreamConfig) (*hyClient.TLSCo return res, nil } +func GetClientTLSConfig(streamSettings *internet.MemoryStreamConfig) (*hyClient.TLSConfig, error) { + config := tls.ConfigFromStreamSettings(streamSettings) + if config == nil { + return nil, newError("need tls") + } + tlsConfig := config.GetTLSConfig() + + return &hyClient.TLSConfig{ + RootCAs: tlsConfig.RootCAs, + ServerName: tlsConfig.ServerName, + InsecureSkipVerify: tlsConfig.InsecureSkipVerify, + VerifyPeerCertificate: tlsConfig.VerifyPeerCertificate, + }, nil +} + func InitAddress(dest net.Destination) (net.Addr, error) { var destAddr *net.UDPAddr if dest.Address.Family().IsIP() { @@ -59,7 +74,7 @@ func (f *connFactory) New(addr net.Addr) (net.PacketConn, error) { } func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hyClient.Client, error) { - tlsConfig, err := InitTLSConifg(streamSettings) + tlsConfig, err := GetClientTLSConfig(streamSettings) if err != nil { return nil, err } diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 0394512977..2ff73f149b 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -9,7 +9,6 @@ import ( "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/net" - "github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert" "github.com/v2fly/v2ray-core/v5/transport/internet" "github.com/v2fly/v2ray-core/v5/transport/internet/tls" ) @@ -60,9 +59,12 @@ func (l *Listener) UdpHijacker(entry *hyServer.UdpSessionEntry, originalAddr str } // Listen creates a new Listener based on configurations. -func Listen(ctx context.Context, address net.Address, port net.Port, - streamSettings *internet.MemoryStreamConfig, - handler internet.ConnHandler) (internet.Listener, error) { +func Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) { + tlsConfig, err := GetServerTLSConfig(streamSettings) + if err != nil { + return nil, err + } + if address.Family().IsDomain() { return nil, nil } @@ -84,7 +86,7 @@ func Listen(ctx context.Context, address net.Address, port net.Port, hyServer, err := hyServer.NewServer(&hyServer.Config{ Conn: rawConn, - TLSConfig: *GetTLSConfig(streamSettings), + TLSConfig: *tlsConfig, Authenticator: &Authenticator{Password: config.GetPassword()}, IgnoreClientBandwidth: config.GetIgnoreClientBandwidth(), DisableUDP: !config.GetUseUdpExtension(), @@ -111,18 +113,14 @@ func CheckTLSConfig(streamSettings *internet.MemoryStreamConfig, isClient bool) return tlsSetting } -func GetTLSConfig(streamSettings *internet.MemoryStreamConfig) *hyServer.TLSConfig { - tlsSetting := CheckTLSConfig(streamSettings, false) - if tlsSetting == nil { - tlsSetting = &tls.Config{ - Certificate: []*tls.Certificate{ - tls.ParseCertificate( - cert.MustGenerate(nil, cert.DNSNames(internalDomain), cert.CommonName(internalDomain)), - ), - }, - } +func GetServerTLSConfig(streamSettings *internet.MemoryStreamConfig) (*hyServer.TLSConfig, error) { + config := tls.ConfigFromStreamSettings(streamSettings) + if config == nil { + return nil, newError("need tls") } - return &hyServer.TLSConfig{Certificates: tlsSetting.GetTLSConfig().Certificates} + tlsConfig := config.GetTLSConfig() + + return &hyServer.TLSConfig{Certificates: tlsConfig.Certificates, GetCertificate: tlsConfig.GetCertificate}, nil } type Authenticator struct { From 8e323bf39ce720922cf77fc9b420950957aba37f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 May 2024 17:17:21 +0800 Subject: [PATCH 74/81] update --- transport/internet/hysteria2/conn.go | 1 + transport/internet/hysteria2/dialer.go | 17 +---------------- transport/internet/hysteria2/hub.go | 2 +- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index 02c41faa4d..b8e390d4e0 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -13,6 +13,7 @@ import ( ) const CanNotUseUdpExtension = "Only hysteria2 proxy protocol can use udpExtension." +const Hy2MustNeedTLS = "Hysteria2 based on QUIC that requires TLS." type HyConn struct { IsUDPExtension bool diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 773591a17f..7b186677a9 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -16,25 +16,10 @@ import ( var RunningClient map[net.Destination](hyClient.Client) -func InitTLSConifg2(streamSettings *internet.MemoryStreamConfig) (*hyClient.TLSConfig, error) { - tlsSetting := CheckTLSConfig(streamSettings, true) - if tlsSetting == nil { - tlsSetting = &tls.Config{ - ServerName: internalDomain, - AllowInsecure: true, - } - } - res := &hyClient.TLSConfig{ - ServerName: tlsSetting.ServerName, - InsecureSkipVerify: tlsSetting.AllowInsecure, - } - return res, nil -} - func GetClientTLSConfig(streamSettings *internet.MemoryStreamConfig) (*hyClient.TLSConfig, error) { config := tls.ConfigFromStreamSettings(streamSettings) if config == nil { - return nil, newError("need tls") + return nil, newError(Hy2MustNeedTLS) } tlsConfig := config.GetTLSConfig() diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 2ff73f149b..3a12aec104 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -116,7 +116,7 @@ func CheckTLSConfig(streamSettings *internet.MemoryStreamConfig, isClient bool) func GetServerTLSConfig(streamSettings *internet.MemoryStreamConfig) (*hyServer.TLSConfig, error) { config := tls.ConfigFromStreamSettings(streamSettings) if config == nil { - return nil, newError("need tls") + return nil, newError(Hy2MustNeedTLS) } tlsConfig := config.GetTLSConfig() From 52c00074e89c9760da63ac09f595cc3cf0c0b092 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 23 May 2024 14:42:27 +0800 Subject: [PATCH 75/81] remove and format legacy code --- transport/internet/hysteria2/hub.go | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 3a12aec104..8d2b3d9cd3 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -30,8 +30,7 @@ func (l *Listener) Close() error { return l.hyServer.Close() } -func (l *Listener) ProxyStreamHijacker(ft http3.FrameType, - conn quic.Connection, stream quic.Stream, err error) (bool, error) { +func (l *Listener) StreamHijacker(ft http3.FrameType, conn quic.Connection, stream quic.Stream, err error) (bool, error) { // err always == nil tcpConn := &HyConn{ @@ -90,8 +89,8 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti Authenticator: &Authenticator{Password: config.GetPassword()}, IgnoreClientBandwidth: config.GetIgnoreClientBandwidth(), DisableUDP: !config.GetUseUdpExtension(), - StreamHijacker: listener.ProxyStreamHijacker, // acceptStreams - UdpSessionHijacker: listener.UdpHijacker, // acceptUDPSession + StreamHijacker: listener.StreamHijacker, // acceptStreams + UdpSessionHijacker: listener.UdpHijacker, // acceptUDPSession }) if err != nil { return nil, err @@ -102,17 +101,6 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti return listener, nil } -func CheckTLSConfig(streamSettings *internet.MemoryStreamConfig, isClient bool) *tls.Config { - if streamSettings == nil || streamSettings.SecuritySettings == nil { - return nil - } - tlsSetting := streamSettings.SecuritySettings.(*tls.Config) - if tlsSetting.ServerName == "" || (len(tlsSetting.Certificate) == 0 && !isClient) { - return nil - } - return tlsSetting -} - func GetServerTLSConfig(streamSettings *internet.MemoryStreamConfig) (*hyServer.TLSConfig, error) { config := tls.ConfigFromStreamSettings(streamSettings) if config == nil { From 221a25ad5e1f0130f2e385f72cb8a0d8bb7884e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 23 May 2024 15:46:54 +0800 Subject: [PATCH 76/81] update hysteria2 --- go.mod | 22 ++++++++-------- go.sum | 36 +++++++++++++------------- proxy/hysteria2/client.go | 2 +- proxy/hysteria2/protocol.go | 2 +- proxy/hysteria2/server.go | 2 +- transport/internet/hysteria2/conn.go | 6 ++--- transport/internet/hysteria2/dialer.go | 4 +-- transport/internet/hysteria2/hub.go | 2 +- 8 files changed, 38 insertions(+), 38 deletions(-) diff --git a/go.mod b/go.mod index b4cf20134c..faa8700ec5 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ toolchain go1.21.4 require ( github.com/adrg/xdg v0.4.0 - github.com/apernet/hysteria/core v1.3.5 - github.com/apernet/quic-go v0.43.1-0.20240429030958-51a0843014d6 + github.com/apernet/hysteria/core/v2 v2.0.0-20240523014710-44f4ddacfedf + github.com/apernet/quic-go v0.44.1-0.20240520215222-bb2e53664023 github.com/go-chi/chi/v5 v5.0.12 github.com/go-chi/render v1.0.3 github.com/go-playground/validator/v10 v10.20.0 @@ -34,10 +34,10 @@ require ( github.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432 go.starlark.net v0.0.0-20230612165344-9532f5667272 go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 - golang.org/x/crypto v0.22.0 - golang.org/x/net v0.24.0 + golang.org/x/crypto v0.23.0 + golang.org/x/net v0.25.0 golang.org/x/sync v0.7.0 - golang.org/x/sys v0.19.0 + golang.org/x/sys v0.20.0 google.golang.org/grpc v1.63.2 google.golang.org/protobuf v1.34.0 gopkg.in/yaml.v3 v3.0.1 @@ -80,16 +80,16 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/xtaci/smux v1.5.24 // indirect go.uber.org/mock v0.4.0 // indirect - golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect - golang.org/x/mod v0.16.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.19.0 // indirect + golang.org/x/tools v0.21.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect ) replace github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 => github.com/xiaokangwang/struc v0.0.0-20231031203518-0e381172f248 -replace github.com/apernet/hysteria/core v1.3.5 => github.com/JimmyHuang454/hysteria/core v0.0.0-20240511074602-b0840e28099e +replace github.com/apernet/hysteria/core/v2 v2.0.0-20240523014710-44f4ddacfedf => github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240523073322-ddfdce403cba -//replace github.com/apernet/hysteria/core => ../hysteria/core/ +//replace github.com/apernet/hysteria/core/v2 => ../hysteria/core/ diff --git a/go.sum b/go.sum index a1aade9848..a24643919e 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/FlowerWrong/water v0.0.0-20180301012659-01a4eaa1f6f2/go.mod h1:xrG5L7lq7T2DLnPr2frMnL906CNEoKRwLB+VYFhPq2w= -github.com/JimmyHuang454/hysteria/core v0.0.0-20240511074602-b0840e28099e h1:inRDfo93TKP2xYXtSKIVMErrnUm8UuHFMyHXTxfvsBQ= -github.com/JimmyHuang454/hysteria/core v0.0.0-20240511074602-b0840e28099e/go.mod h1:nzkbgafcTmrehm47Ncx1u/Ts0dfg4MuTKSeCVmFvLyk= +github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240523073322-ddfdce403cba h1:6oIShG5oQgUSFo3tr+ZhN+o3X+FWMV5cb2DZX5V1nuE= +github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240523073322-ddfdce403cba/go.mod h1:5fTtdKIoVb8sarjYpQWqkoKM/1vyyC5QXf89KLDObd0= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= @@ -27,8 +27,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/apernet/quic-go v0.43.1-0.20240429030958-51a0843014d6 h1:ZfaQo52EyyhNCxfMNk64W1YHcIh+0rCkp3e0gR7BO5E= -github.com/apernet/quic-go v0.43.1-0.20240429030958-51a0843014d6/go.mod h1:j3QaAM7sVJqptDQyIQRWA6mASCfuxoHJszn67JQh1GE= +github.com/apernet/quic-go v0.44.1-0.20240520215222-bb2e53664023 h1:UTrvVPt+GfeOeli9/3gvpCDz2Jd5UEn3YotfP0u/pok= +github.com/apernet/quic-go v0.44.1-0.20240520215222-bb2e53664023/go.mod h1:UkcG7+34BM+bbH2RFVKtHQp3mR7h8yJHx4z95lZ7sx4= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -376,15 +376,15 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 h1:Di6/M8l0O2lCLc6VVRWhgCiApHV8MnQurBnFSHsQtNY= -golang.org/x/exp v0.0.0-20230725093048-515e97ebf090/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -404,8 +404,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= -golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -430,8 +430,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -479,8 +479,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -498,8 +498,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -528,8 +528,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= -golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/proxy/hysteria2/client.go b/proxy/hysteria2/client.go index edd8c4d785..b47b090ddc 100644 --- a/proxy/hysteria2/client.go +++ b/proxy/hysteria2/client.go @@ -3,7 +3,7 @@ package hysteria2 import ( "context" - hyProtocol "github.com/apernet/hysteria/core/international/protocol" + hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol" core "github.com/v2fly/v2ray-core/v5" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/buf" diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index 84baa3e8cc..49b76d0f2a 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -4,7 +4,7 @@ import ( "io" gonet "net" - hyProtocol "github.com/apernet/hysteria/core/international/protocol" + hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol" "github.com/apernet/quic-go/quicvarint" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index a18daa3558..3bb48676c0 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -5,7 +5,7 @@ import ( "io" "time" - hyProtocol "github.com/apernet/hysteria/core/international/protocol" + hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol" core "github.com/v2fly/v2ray-core/v5" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/buf" diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index b8e390d4e0..351ff7001c 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -3,9 +3,9 @@ package hysteria2 import ( "time" - hyClient "github.com/apernet/hysteria/core/client" - "github.com/apernet/hysteria/core/international/protocol" - hyServer "github.com/apernet/hysteria/core/server" + hyClient "github.com/apernet/hysteria/core/v2/client" + "github.com/apernet/hysteria/core/v2/international/protocol" + hyServer "github.com/apernet/hysteria/core/v2/server" "github.com/apernet/quic-go" "github.com/v2fly/v2ray-core/v5/common/buf" diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 7b186677a9..45d40c37b9 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -3,8 +3,8 @@ package hysteria2 import ( "context" - hyClient "github.com/apernet/hysteria/core/client" - hyProtocol "github.com/apernet/hysteria/core/international/protocol" + hyClient "github.com/apernet/hysteria/core/v2/client" + hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol" "github.com/apernet/quic-go/quicvarint" "github.com/v2fly/v2ray-core/v5/common" diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 8d2b3d9cd3..f493d6efdd 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -3,7 +3,7 @@ package hysteria2 import ( "context" - hyServer "github.com/apernet/hysteria/core/server" + hyServer "github.com/apernet/hysteria/core/v2/server" "github.com/apernet/quic-go" "github.com/apernet/quic-go/http3" From fb415bdbbfb3e555aa9d976add6403d798371475 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Tue, 11 Jun 2024 07:37:57 +0800 Subject: [PATCH 77/81] update hysteria2 core --- go.mod | 22 ++++++++-------- go.sum | 36 +++++++++++++------------- proxy/hysteria2/client.go | 2 +- proxy/hysteria2/protocol.go | 2 +- proxy/hysteria2/server.go | 2 +- transport/internet/hysteria2/conn.go | 6 ++--- transport/internet/hysteria2/dialer.go | 4 +-- transport/internet/hysteria2/hub.go | 2 +- 8 files changed, 38 insertions(+), 38 deletions(-) diff --git a/go.mod b/go.mod index b4cf20134c..926efa1c2f 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ toolchain go1.21.4 require ( github.com/adrg/xdg v0.4.0 - github.com/apernet/hysteria/core v1.3.5 - github.com/apernet/quic-go v0.43.1-0.20240429030958-51a0843014d6 + github.com/apernet/hysteria/core/v2 v2.4.5 + github.com/apernet/quic-go v0.44.1-0.20240520215222-bb2e53664023 github.com/go-chi/chi/v5 v5.0.12 github.com/go-chi/render v1.0.3 github.com/go-playground/validator/v10 v10.20.0 @@ -34,10 +34,10 @@ require ( github.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432 go.starlark.net v0.0.0-20230612165344-9532f5667272 go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 - golang.org/x/crypto v0.22.0 - golang.org/x/net v0.24.0 + golang.org/x/crypto v0.23.0 + golang.org/x/net v0.25.0 golang.org/x/sync v0.7.0 - golang.org/x/sys v0.19.0 + golang.org/x/sys v0.20.0 google.golang.org/grpc v1.63.2 google.golang.org/protobuf v1.34.0 gopkg.in/yaml.v3 v3.0.1 @@ -80,16 +80,16 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/xtaci/smux v1.5.24 // indirect go.uber.org/mock v0.4.0 // indirect - golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect - golang.org/x/mod v0.16.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.19.0 // indirect + golang.org/x/tools v0.21.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect ) replace github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 => github.com/xiaokangwang/struc v0.0.0-20231031203518-0e381172f248 -replace github.com/apernet/hysteria/core v1.3.5 => github.com/JimmyHuang454/hysteria/core v0.0.0-20240511074602-b0840e28099e +replace github.com/apernet/hysteria/core/v2 v2.4.5 => github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240605063419-3717f44ca98d -//replace github.com/apernet/hysteria/core => ../hysteria/core/ +//replace github.com/apernet/hysteria/core/v2 => ../hysteria/core/ diff --git a/go.sum b/go.sum index a1aade9848..3d4a8690d3 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/FlowerWrong/water v0.0.0-20180301012659-01a4eaa1f6f2/go.mod h1:xrG5L7lq7T2DLnPr2frMnL906CNEoKRwLB+VYFhPq2w= -github.com/JimmyHuang454/hysteria/core v0.0.0-20240511074602-b0840e28099e h1:inRDfo93TKP2xYXtSKIVMErrnUm8UuHFMyHXTxfvsBQ= -github.com/JimmyHuang454/hysteria/core v0.0.0-20240511074602-b0840e28099e/go.mod h1:nzkbgafcTmrehm47Ncx1u/Ts0dfg4MuTKSeCVmFvLyk= +github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240605063419-3717f44ca98d h1:E7Z+FenkyU7IbmEgm6mwh0xlCgdPndUkaDEgriP3rro= +github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240605063419-3717f44ca98d/go.mod h1:5fTtdKIoVb8sarjYpQWqkoKM/1vyyC5QXf89KLDObd0= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= @@ -27,8 +27,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/apernet/quic-go v0.43.1-0.20240429030958-51a0843014d6 h1:ZfaQo52EyyhNCxfMNk64W1YHcIh+0rCkp3e0gR7BO5E= -github.com/apernet/quic-go v0.43.1-0.20240429030958-51a0843014d6/go.mod h1:j3QaAM7sVJqptDQyIQRWA6mASCfuxoHJszn67JQh1GE= +github.com/apernet/quic-go v0.44.1-0.20240520215222-bb2e53664023 h1:UTrvVPt+GfeOeli9/3gvpCDz2Jd5UEn3YotfP0u/pok= +github.com/apernet/quic-go v0.44.1-0.20240520215222-bb2e53664023/go.mod h1:UkcG7+34BM+bbH2RFVKtHQp3mR7h8yJHx4z95lZ7sx4= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -376,15 +376,15 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 h1:Di6/M8l0O2lCLc6VVRWhgCiApHV8MnQurBnFSHsQtNY= -golang.org/x/exp v0.0.0-20230725093048-515e97ebf090/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -404,8 +404,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= -golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -430,8 +430,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -479,8 +479,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -498,8 +498,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -528,8 +528,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= -golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/proxy/hysteria2/client.go b/proxy/hysteria2/client.go index edd8c4d785..b47b090ddc 100644 --- a/proxy/hysteria2/client.go +++ b/proxy/hysteria2/client.go @@ -3,7 +3,7 @@ package hysteria2 import ( "context" - hyProtocol "github.com/apernet/hysteria/core/international/protocol" + hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol" core "github.com/v2fly/v2ray-core/v5" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/buf" diff --git a/proxy/hysteria2/protocol.go b/proxy/hysteria2/protocol.go index 84baa3e8cc..49b76d0f2a 100644 --- a/proxy/hysteria2/protocol.go +++ b/proxy/hysteria2/protocol.go @@ -4,7 +4,7 @@ import ( "io" gonet "net" - hyProtocol "github.com/apernet/hysteria/core/international/protocol" + hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol" "github.com/apernet/quic-go/quicvarint" "github.com/v2fly/v2ray-core/v5/common/buf" "github.com/v2fly/v2ray-core/v5/common/net" diff --git a/proxy/hysteria2/server.go b/proxy/hysteria2/server.go index a18daa3558..3bb48676c0 100644 --- a/proxy/hysteria2/server.go +++ b/proxy/hysteria2/server.go @@ -5,7 +5,7 @@ import ( "io" "time" - hyProtocol "github.com/apernet/hysteria/core/international/protocol" + hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol" core "github.com/v2fly/v2ray-core/v5" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/buf" diff --git a/transport/internet/hysteria2/conn.go b/transport/internet/hysteria2/conn.go index b8e390d4e0..351ff7001c 100644 --- a/transport/internet/hysteria2/conn.go +++ b/transport/internet/hysteria2/conn.go @@ -3,9 +3,9 @@ package hysteria2 import ( "time" - hyClient "github.com/apernet/hysteria/core/client" - "github.com/apernet/hysteria/core/international/protocol" - hyServer "github.com/apernet/hysteria/core/server" + hyClient "github.com/apernet/hysteria/core/v2/client" + "github.com/apernet/hysteria/core/v2/international/protocol" + hyServer "github.com/apernet/hysteria/core/v2/server" "github.com/apernet/quic-go" "github.com/v2fly/v2ray-core/v5/common/buf" diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 7b186677a9..45d40c37b9 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -3,8 +3,8 @@ package hysteria2 import ( "context" - hyClient "github.com/apernet/hysteria/core/client" - hyProtocol "github.com/apernet/hysteria/core/international/protocol" + hyClient "github.com/apernet/hysteria/core/v2/client" + hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol" "github.com/apernet/quic-go/quicvarint" "github.com/v2fly/v2ray-core/v5/common" diff --git a/transport/internet/hysteria2/hub.go b/transport/internet/hysteria2/hub.go index 3a12aec104..f69508da61 100644 --- a/transport/internet/hysteria2/hub.go +++ b/transport/internet/hysteria2/hub.go @@ -3,7 +3,7 @@ package hysteria2 import ( "context" - hyServer "github.com/apernet/hysteria/core/server" + hyServer "github.com/apernet/hysteria/core/v2/server" "github.com/apernet/quic-go" "github.com/apernet/quic-go/http3" From f2487ec8d8513ac7c7f4d23cac5d9b609c4dc588 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Fri, 21 Jun 2024 14:39:32 +0800 Subject: [PATCH 78/81] add ClientMutex --- transport/internet/hysteria2/dialer.go | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 45d40c37b9..63cb7b34a3 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -2,6 +2,7 @@ package hysteria2 import ( "context" + "sync" hyClient "github.com/apernet/hysteria/core/v2/client" hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol" @@ -15,6 +16,7 @@ import ( ) var RunningClient map[net.Destination](hyClient.Client) +var ClientMutex sync.Mutex func GetClientTLSConfig(streamSettings *internet.MemoryStreamConfig) (*hyClient.TLSConfig, error) { config := tls.ConfigFromStreamSettings(streamSettings) @@ -91,11 +93,13 @@ func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConf return nil, err } - RunningClient[dest] = client return client, nil } func CloseHyClient(dest net.Destination) error { + ClientMutex.Lock() + defer ClientMutex.Unlock() + client, found := RunningClient[dest] if found { delete(RunningClient, dest) @@ -104,8 +108,9 @@ func CloseHyClient(dest net.Destination) error { return nil } -func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { - config := streamSettings.ProtocolSettings.(*Config) +func GetHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hyClient.Client, error) { + ClientMutex.Lock() + defer ClientMutex.Unlock() var client hyClient.Client var err error @@ -116,6 +121,18 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me if err != nil { return nil, err } + RunningClient[dest] = client + } + return client, nil +} + +func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { + config := streamSettings.ProtocolSettings.(*Config) + + client, err := GetHyClient(dest, streamSettings) + if err != nil { + CloseHyClient(dest) + return nil, err } quicConn := client.GetQuicConn() From 945b8ef0ee5b768c45305f34478bd15d3c0a93f3 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Sat, 22 Jun 2024 01:29:44 +0800 Subject: [PATCH 79/81] use net.Addr and add client retry --- transport/internet/hysteria2/dialer.go | 68 ++++++++++++++++---------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 63cb7b34a3..0f3743a0d5 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -15,7 +15,7 @@ import ( "github.com/v2fly/v2ray-core/v5/transport/internet/tls" ) -var RunningClient map[net.Destination](hyClient.Client) +var RunningClient map[net.Addr](hyClient.Client) var ClientMutex sync.Mutex func GetClientTLSConfig(streamSettings *internet.MemoryStreamConfig) (*hyClient.TLSConfig, error) { @@ -33,7 +33,7 @@ func GetClientTLSConfig(streamSettings *internet.MemoryStreamConfig) (*hyClient. }, nil } -func InitAddress(dest net.Destination) (net.Addr, error) { +func ResolveAdress(dest net.Destination) (net.Addr, error) { var destAddr *net.UDPAddr if dest.Address.Family().IsIP() { destAddr = &net.UDPAddr{ @@ -60,17 +60,12 @@ func (f *connFactory) New(addr net.Addr) (net.PacketConn, error) { return f.NewFunc(addr) } -func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hyClient.Client, error) { +func NewHyClient(serverAddr net.Addr, streamSettings *internet.MemoryStreamConfig) (hyClient.Client, error) { tlsConfig, err := GetClientTLSConfig(streamSettings) if err != nil { return nil, err } - serverAddr, err := InitAddress(dest) - if err != nil { - return nil, err - } - config := streamSettings.ProtocolSettings.(*Config) client, _, err := hyClient.NewClient(&hyClient.Config{ TLSConfig: *tlsConfig, @@ -96,42 +91,63 @@ func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConf return client, nil } -func CloseHyClient(dest net.Destination) error { +func CloseHyClient(serverAddr net.Addr) error { ClientMutex.Lock() defer ClientMutex.Unlock() - client, found := RunningClient[dest] + client, found := RunningClient[serverAddr] if found { - delete(RunningClient, dest) + delete(RunningClient, serverAddr) return client.Close() } return nil } -func GetHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hyClient.Client, error) { - ClientMutex.Lock() - defer ClientMutex.Unlock() - - var client hyClient.Client +func GetHyClient(serverAddr net.Addr, streamSettings *internet.MemoryStreamConfig) (hyClient.Client, error) { var err error - client, found := RunningClient[dest] - if !found { - // TODO: Clean idle connections - client, err = NewHyClient(dest, streamSettings) + var client hyClient.Client + + ClientMutex.Lock() + client, found := RunningClient[serverAddr] + ClientMutex.Unlock() + if !found || !CheckHyClentHealthy(client) { + if found { + // retry + CloseHyClient(serverAddr) + } + client, err = NewHyClient(serverAddr, streamSettings) if err != nil { return nil, err } - RunningClient[dest] = client + ClientMutex.Lock() + RunningClient[serverAddr] = client + ClientMutex.Unlock() } return client, nil } +func CheckHyClentHealthy(client hyClient.Client) bool { + // TODO: Clean idle connections + quicConn := client.GetQuicConn() + select { + case <-quicConn.Context().Done(): + return false + default: + } + return true +} + func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { config := streamSettings.ProtocolSettings.(*Config) - client, err := GetHyClient(dest, streamSettings) + serverAddr, err := ResolveAdress(dest) + if err != nil { + return nil, err + } + + client, err := GetHyClient(serverAddr, streamSettings) if err != nil { - CloseHyClient(dest) + CloseHyClient(serverAddr) return nil, err } @@ -153,7 +169,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me conn.IsServer = false conn.ClientUDPSession, err = client.UDP() if err != nil { - CloseHyClient(dest) + CloseHyClient(serverAddr) return nil, err } return conn, nil @@ -161,7 +177,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me conn.stream, err = client.OpenStream() if err != nil { - CloseHyClient(dest) + CloseHyClient(serverAddr) return nil, err } @@ -174,6 +190,6 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me } func init() { - RunningClient = make(map[net.Destination]hyClient.Client) + RunningClient = make(map[net.Addr]hyClient.Client) common.Must(internet.RegisterTransportDialer(protocolName, Dial)) } From 0e5b29d69bc86bf73ad6665f4464066878f7ca6d Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Sat, 22 Jun 2024 01:37:48 +0800 Subject: [PATCH 80/81] fix typo and check nil --- transport/internet/hysteria2/dialer.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/transport/internet/hysteria2/dialer.go b/transport/internet/hysteria2/dialer.go index 0f3743a0d5..d5b0648302 100644 --- a/transport/internet/hysteria2/dialer.go +++ b/transport/internet/hysteria2/dialer.go @@ -33,7 +33,7 @@ func GetClientTLSConfig(streamSettings *internet.MemoryStreamConfig) (*hyClient. }, nil } -func ResolveAdress(dest net.Destination) (net.Addr, error) { +func ResolveAddress(dest net.Destination) (net.Addr, error) { var destAddr *net.UDPAddr if dest.Address.Family().IsIP() { destAddr = &net.UDPAddr{ @@ -129,6 +129,9 @@ func GetHyClient(serverAddr net.Addr, streamSettings *internet.MemoryStreamConfi func CheckHyClentHealthy(client hyClient.Client) bool { // TODO: Clean idle connections quicConn := client.GetQuicConn() + if quicConn == nil { + return false + } select { case <-quicConn.Context().Done(): return false @@ -140,7 +143,7 @@ func CheckHyClentHealthy(client hyClient.Client) bool { func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { config := streamSettings.ProtocolSettings.(*Config) - serverAddr, err := ResolveAdress(dest) + serverAddr, err := ResolveAddress(dest) if err != nil { return nil, err } From 9d89366ae81d66f4db20673293a260714cacb7b2 Mon Sep 17 00:00:00 2001 From: Jimmy Huang Date: Sat, 22 Jun 2024 01:53:15 +0800 Subject: [PATCH 81/81] update hysteria2 core --- go.mod | 4 ++-- go.sum | 21 +++++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 926efa1c2f..07ddf2ee50 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( golang.org/x/sync v0.7.0 golang.org/x/sys v0.20.0 google.golang.org/grpc v1.63.2 - google.golang.org/protobuf v1.34.0 + google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v3 v3.0.1 gvisor.dev/gvisor v0.0.0-20231020174304-b8a429915ff1 h12.io/socks v1.0.3 @@ -90,6 +90,6 @@ require ( replace github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 => github.com/xiaokangwang/struc v0.0.0-20231031203518-0e381172f248 -replace github.com/apernet/hysteria/core/v2 v2.4.5 => github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240605063419-3717f44ca98d +replace github.com/apernet/hysteria/core/v2 v2.4.5 => github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240621174944-4c4ba8b7f163 //replace github.com/apernet/hysteria/core/v2 => ../hysteria/core/ diff --git a/go.sum b/go.sum index 3d4a8690d3..2ec6514b4d 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/FlowerWrong/water v0.0.0-20180301012659-01a4eaa1f6f2/go.mod h1:xrG5L7lq7T2DLnPr2frMnL906CNEoKRwLB+VYFhPq2w= -github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240605063419-3717f44ca98d h1:E7Z+FenkyU7IbmEgm6mwh0xlCgdPndUkaDEgriP3rro= -github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240605063419-3717f44ca98d/go.mod h1:5fTtdKIoVb8sarjYpQWqkoKM/1vyyC5QXf89KLDObd0= +github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240621174944-4c4ba8b7f163 h1:yc0h7bAT4P6yfF7yO5GQGaWFF8ZJbctzUT7NtkY1vPE= +github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240621174944-4c4ba8b7f163/go.mod h1:RskXoU8aQ3EcpwxWK8tK0kWNNJveve7RG23Us+1GoHI= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= @@ -191,10 +191,11 @@ github.com/klauspost/reedsolomon v1.11.7/go.mod h1:4bXRN+cVzMdml6ti7qLouuYi32KHJ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lunixbochs/struc v0.0.0-20190916212049-a5c72983bc42/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg= @@ -223,8 +224,6 @@ github.com/mustafaturan/monoton v1.0.0/go.mod h1:FOnE7NV3s3EWPXb8/7+/OSdiMBbdlkV github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo/v2 v2.17.0 h1:kdnunFXpBjbzN56hcJHrXZ8M+LOkenKA7NnBzTNigTI= github.com/onsi/ginkgo/v2 v2.17.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= @@ -281,6 +280,8 @@ github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -570,14 +571,14 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= -google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=