diff --git a/app/commander/outbound.go b/app/commander/outbound.go index 907497059..0a849ddd1 100644 --- a/app/commander/outbound.go +++ b/app/commander/outbound.go @@ -22,9 +22,9 @@ func (l *OutboundListener) add(conn net.Conn) { select { case l.buffer <- conn: case <-l.done.Wait(): - conn.Close() // nolint: errcheck + conn.Close() default: - conn.Close() // nolint: errcheck + conn.Close() } } @@ -45,7 +45,7 @@ L: for { select { case c := <-l.buffer: - c.Close() // nolint: errcheck + c.Close() default: break L } diff --git a/app/dns/dnscommon_test.go b/app/dns/dnscommon_test.go index 7d81190af..24cc69270 100644 --- a/app/dns/dnscommon_test.go +++ b/app/dns/dnscommon_test.go @@ -89,7 +89,6 @@ func Test_parseResponse(t *testing.T) { } func Test_buildReqMsgs(t *testing.T) { - stubID := func() uint16 { return uint16(rand.Uint32()) } diff --git a/app/dns/dohdns.go b/app/dns/dohdns.go index 257023ff8..1bb61dee5 100644 --- a/app/dns/dohdns.go +++ b/app/dns/dohdns.go @@ -43,7 +43,6 @@ type DoHNameServer struct { // NewDoHNameServer creates DOH client object for remote resolving func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, clientIP net.IP) (*DoHNameServer, error) { - newError("DNS: created Remote DOH client for ", url.String()).AtInfo().WriteToLog() s := baseDOHNameServer(url, "DOH", clientIP) @@ -112,7 +111,6 @@ func NewDoHLocalNameServer(url *url.URL, clientIP net.IP) *DoHNameServer { } func baseDOHNameServer(url *url.URL, prefix string, clientIP net.IP) *DoHNameServer { - s := &DoHNameServer{ ips: make(map[string]record), clientIP: clientIP, diff --git a/app/dns/hosts.go b/app/dns/hosts.go index f47a32fef..21dc30ba8 100644 --- a/app/dns/hosts.go +++ b/app/dns/hosts.go @@ -66,7 +66,8 @@ func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDoma } id := g.Add(matcher) ips := make([]net.Address, 0, len(mapping.Ip)+1) - if len(mapping.Ip) > 0 { + switch { + case len(mapping.Ip) > 0: for _, ip := range mapping.Ip { addr := net.IPAddress(ip) if addr == nil { @@ -74,9 +75,11 @@ func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDoma } ips = append(ips, addr) } - } else if len(mapping.ProxiedDomain) > 0 { + + case len(mapping.ProxiedDomain) > 0: ips = append(ips, net.DomainAddress(mapping.ProxiedDomain)) - } else { + + default: return nil, newError("neither IP address nor proxied domain specified for domain: ", mapping.Domain).AtWarning() } diff --git a/app/dns/nameserver.go b/app/dns/nameserver.go index c002e2e99..c55f901cf 100644 --- a/app/dns/nameserver.go +++ b/app/dns/nameserver.go @@ -24,11 +24,11 @@ type Client interface { QueryIP(ctx context.Context, domain string, option IPOption) ([]net.IP, error) } -type localNameServer struct { +type LocalNameServer struct { client *localdns.Client } -func (s *localNameServer) QueryIP(ctx context.Context, domain string, option IPOption) ([]net.IP, error) { +func (s *LocalNameServer) QueryIP(ctx context.Context, domain string, option IPOption) ([]net.IP, error) { if option.IPv4Enable && option.IPv6Enable { return s.client.LookupIP(domain) } @@ -44,13 +44,13 @@ func (s *localNameServer) QueryIP(ctx context.Context, domain string, option IPO return nil, newError("neither IPv4 nor IPv6 is enabled") } -func (s *localNameServer) Name() string { +func (s *LocalNameServer) Name() string { return "localhost" } -func NewLocalNameServer() *localNameServer { +func NewLocalNameServer() *LocalNameServer { newError("DNS: created localhost client").AtInfo().WriteToLog() - return &localNameServer{ + return &LocalNameServer{ client: localdns.New(), } } diff --git a/app/dns/server.go b/app/dns/server.go index 0693fa1e0..ecf4d2153 100644 --- a/app/dns/server.go +++ b/app/dns/server.go @@ -97,7 +97,9 @@ func New(ctx context.Context, config *Config) (*Server, error) { addNameServer := func(ns *NameServer) int { endpoint := ns.Address address := endpoint.Address.AsAddress() - if address.Family().IsDomain() && address.Domain() == "localhost" { + + switch { + case address.Family().IsDomain() && address.Domain() == "localhost": server.clients = append(server.clients, NewLocalNameServer()) // Priotize local domains with specific TLDs or without any dot to local DNS // References: @@ -115,7 +117,8 @@ func New(ctx context.Context, config *Config) (*Server, error) { {Type: DomainMatchingType_Subdomain, Domain: "test"}, } ns.PrioritizedDomain = append(ns.PrioritizedDomain, localTLDsAndDotlessDomains...) - } else if address.Family().IsDomain() && strings.HasPrefix(address.Domain(), "https+local://") { + + case address.Family().IsDomain() && strings.HasPrefix(address.Domain(), "https+local://"): // URI schemed string treated as domain // DOH Local mode u, err := url.Parse(address.Domain()) @@ -123,7 +126,8 @@ func New(ctx context.Context, config *Config) (*Server, error) { log.Fatalln(newError("DNS config error").Base(err)) } server.clients = append(server.clients, NewDoHLocalNameServer(u, server.clientIP)) - } else if address.Family().IsDomain() && strings.HasPrefix(address.Domain(), "https://") { + + case address.Family().IsDomain() && strings.HasPrefix(address.Domain(), "https://"): // DOH Remote mode u, err := url.Parse(address.Domain()) if err != nil { @@ -140,7 +144,8 @@ func New(ctx context.Context, config *Config) (*Server, error) { } server.clients[idx] = c })) - } else { + + default: // UDP classic DNS mode dest := endpoint.AsDestination() if dest.Network == net.Network_Unknown { diff --git a/app/dns/server_test.go b/app/dns/server_test.go index de3f8caf7..f988ad4a0 100644 --- a/app/dns/server_test.go +++ b/app/dns/server_test.go @@ -42,7 +42,8 @@ func (*staticHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) { } for _, q := range r.Question { - if q.Name == "google.com." && q.Qtype == dns.TypeA { + switch { + case q.Name == "google.com." && q.Qtype == dns.TypeA: if clientIP == nil { rr, _ := dns.NewRR("google.com. IN A 8.8.8.8") ans.Answer = append(ans.Answer, rr) @@ -50,44 +51,57 @@ func (*staticHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) { rr, _ := dns.NewRR("google.com. IN A 8.8.4.4") ans.Answer = append(ans.Answer, rr) } - } else if q.Name == "api.google.com." && q.Qtype == dns.TypeA { + + case q.Name == "api.google.com." && q.Qtype == dns.TypeA: rr, _ := dns.NewRR("api.google.com. IN A 8.8.7.7") ans.Answer = append(ans.Answer, rr) - } else if q.Name == "v2.api.google.com." && q.Qtype == dns.TypeA { + + case q.Name == "v2.api.google.com." && q.Qtype == dns.TypeA: rr, _ := dns.NewRR("v2.api.google.com. IN A 8.8.7.8") ans.Answer = append(ans.Answer, rr) - } else if q.Name == "facebook.com." && q.Qtype == dns.TypeA { + + case q.Name == "facebook.com." && q.Qtype == dns.TypeA: rr, _ := dns.NewRR("facebook.com. IN A 9.9.9.9") ans.Answer = append(ans.Answer, rr) - } else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeA { + + case q.Name == "ipv6.google.com." && q.Qtype == dns.TypeA: rr, err := dns.NewRR("ipv6.google.com. IN A 8.8.8.7") common.Must(err) ans.Answer = append(ans.Answer, rr) - } else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeAAAA { + + case q.Name == "ipv6.google.com." && q.Qtype == dns.TypeAAAA: rr, err := dns.NewRR("ipv6.google.com. IN AAAA 2001:4860:4860::8888") common.Must(err) ans.Answer = append(ans.Answer, rr) - } else if q.Name == "notexist.google.com." && q.Qtype == dns.TypeAAAA { + + case q.Name == "notexist.google.com." && q.Qtype == dns.TypeAAAA: ans.MsgHdr.Rcode = dns.RcodeNameError - } else if q.Name == "hostname." && q.Qtype == dns.TypeA { + + case q.Name == "hostname." && q.Qtype == dns.TypeA: rr, _ := dns.NewRR("hostname. IN A 127.0.0.1") ans.Answer = append(ans.Answer, rr) - } else if q.Name == "hostname.local." && q.Qtype == dns.TypeA { + + case q.Name == "hostname.local." && q.Qtype == dns.TypeA: rr, _ := dns.NewRR("hostname.local. IN A 127.0.0.1") ans.Answer = append(ans.Answer, rr) - } else if q.Name == "hostname.localdomain." && q.Qtype == dns.TypeA { + + case q.Name == "hostname.localdomain." && q.Qtype == dns.TypeA: rr, _ := dns.NewRR("hostname.localdomain. IN A 127.0.0.1") ans.Answer = append(ans.Answer, rr) - } else if q.Name == "localhost." && q.Qtype == dns.TypeA { + + case q.Name == "localhost." && q.Qtype == dns.TypeA: rr, _ := dns.NewRR("localhost. IN A 127.0.0.2") ans.Answer = append(ans.Answer, rr) - } else if q.Name == "localhost-a." && q.Qtype == dns.TypeA { + + case q.Name == "localhost-a." && q.Qtype == dns.TypeA: rr, _ := dns.NewRR("localhost-a. IN A 127.0.0.3") ans.Answer = append(ans.Answer, rr) - } else if q.Name == "localhost-b." && q.Qtype == dns.TypeA { + + case q.Name == "localhost-b." && q.Qtype == dns.TypeA: rr, _ := dns.NewRR("localhost-b. IN A 127.0.0.4") ans.Answer = append(ans.Answer, rr) - } else if q.Name == "Mijia\\ Cloud." && q.Qtype == dns.TypeA { + + case q.Name == "Mijia\\ Cloud." && q.Qtype == dns.TypeA: rr, _ := dns.NewRR("Mijia\\ Cloud. IN A 127.0.0.1") ans.Answer = append(ans.Answer, rr) } diff --git a/app/dns/udpns.go b/app/dns/udpns.go index a362c1dff..267f15e96 100644 --- a/app/dns/udpns.go +++ b/app/dns/udpns.go @@ -36,7 +36,6 @@ type ClassicNameServer struct { } func NewClassicNameServer(address net.Destination, dispatcher routing.Dispatcher, clientIP net.IP) *ClassicNameServer { - // default to 53 if unspecific if address.Port == 0 { address.Port = net.Port(53) @@ -105,7 +104,6 @@ func (s *ClassicNameServer) Cleanup() error { } func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_proto.Packet) { - ipRec, err := parseResponse(packet.Payload.Bytes()) if err != nil { newError(s.name, " fail to parse responded DNS udp").AtError().WriteToLog() @@ -240,7 +238,6 @@ func (s *ClassicNameServer) findIPsForDomain(domain string, option IPOption) ([] } func (s *ClassicNameServer) QueryIP(ctx context.Context, domain string, option IPOption) ([]net.IP, error) { - fqdn := Fqdn(domain) ips, err := s.findIPsForDomain(fqdn, option) diff --git a/app/log/log.go b/app/log/log.go index bf95a4ce6..ae78be3b3 100644 --- a/app/log/log.go +++ b/app/log/log.go @@ -127,10 +127,10 @@ func (g *Instance) Close() error { g.active = false - common.Close(g.accessLogger) // nolint: errcheck + common.Close(g.accessLogger) g.accessLogger = nil - common.Close(g.errorLogger) // nolint: errcheck + common.Close(g.errorLogger) g.errorLogger = nil return nil diff --git a/app/proxyman/inbound/worker.go b/app/proxyman/inbound/worker.go index b10a5867b..dc0677612 100644 --- a/app/proxyman/inbound/worker.go +++ b/app/proxyman/inbound/worker.go @@ -280,7 +280,7 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest conn, existing := w.getConnection(id) // payload will be discarded in pipe is full. - conn.writer.WriteMultiBuffer(buf.MultiBuffer{b}) // nolint: errcheck + conn.writer.WriteMultiBuffer(buf.MultiBuffer{b}) if !existing { common.Must(w.checker.Start()) @@ -303,7 +303,7 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest if err := w.proxy.Process(ctx, net.Network_UDP, conn, w.dispatcher); err != nil { newError("connection ends").Base(err).WriteToLog(session.ExportIDToError(ctx)) } - conn.Close() // nolint: errcheck + conn.Close() w.removeConn(id) }() } @@ -332,9 +332,9 @@ func (w *udpWorker) clean() error { } for addr, conn := range w.activeConn { - if nowSec-atomic.LoadInt64(&conn.lastActivityTime) > 8 { //TODO Timeout too small + if nowSec-atomic.LoadInt64(&conn.lastActivityTime) > 8 { // TODO Timeout too small delete(w.activeConn, addr) - conn.Close() // nolint: errcheck + conn.Close() } } diff --git a/app/router/command/command.go b/app/router/command/command.go index f1720f871..fc467fa76 100644 --- a/app/router/command/command.go +++ b/app/router/command/command.go @@ -39,7 +39,7 @@ func (s *routingServer) TestRoute(ctx context.Context, request *TestRouteRequest return nil, err } if request.PublishResult && s.routingStats != nil { - ctx, _ := context.WithTimeout(context.Background(), 4*time.Second) // nolint: govet + ctx, _ := context.WithTimeout(context.Background(), 4*time.Second) s.routingStats.Publish(ctx, route) } return AsProtobufMessage(request.FieldSelectors)(route), nil @@ -54,7 +54,7 @@ func (s *routingServer) SubscribeRoutingStats(request *SubscribeRoutingStatsRequ if err != nil { return err } - defer stats.UnsubscribeClosableChannel(s.routingStats, subscriber) // nolint: errcheck + defer stats.UnsubscribeClosableChannel(s.routingStats, subscriber) for { select { case value, ok := <-subscriber: diff --git a/app/router/router_test.go b/app/router/router_test.go index 8c1aec0aa..080534d6d 100644 --- a/app/router/router_test.go +++ b/app/router/router_test.go @@ -34,12 +34,12 @@ func TestSimpleRouter(t *testing.T) { mockCtl := gomock.NewController(t) defer mockCtl.Finish() - mockDns := mocks.NewDNSClient(mockCtl) + mockDNS := mocks.NewDNSClient(mockCtl) mockOhm := mocks.NewOutboundManager(mockCtl) mockHs := mocks.NewOutboundHandlerSelector(mockCtl) r := new(Router) - common.Must(r.Init(config, mockDns, &mockOutboundManager{ + common.Must(r.Init(config, mockDNS, &mockOutboundManager{ Manager: mockOhm, HandlerSelector: mockHs, })) @@ -73,14 +73,14 @@ func TestSimpleBalancer(t *testing.T) { mockCtl := gomock.NewController(t) defer mockCtl.Finish() - mockDns := mocks.NewDNSClient(mockCtl) + mockDNS := mocks.NewDNSClient(mockCtl) mockOhm := mocks.NewOutboundManager(mockCtl) mockHs := mocks.NewOutboundHandlerSelector(mockCtl) mockHs.EXPECT().Select(gomock.Eq([]string{"test-"})).Return([]string{"test"}) r := new(Router) - common.Must(r.Init(config, mockDns, &mockOutboundManager{ + common.Must(r.Init(config, mockDNS, &mockOutboundManager{ Manager: mockOhm, HandlerSelector: mockHs, })) @@ -114,11 +114,11 @@ func TestIPOnDemand(t *testing.T) { mockCtl := gomock.NewController(t) defer mockCtl.Finish() - mockDns := mocks.NewDNSClient(mockCtl) - mockDns.EXPECT().LookupIP(gomock.Eq("v2ray.com")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes() + mockDNS := mocks.NewDNSClient(mockCtl) + mockDNS.EXPECT().LookupIP(gomock.Eq("v2ray.com")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes() r := new(Router) - common.Must(r.Init(config, mockDns, nil)) + common.Must(r.Init(config, mockDNS, nil)) ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2ray.com"), 80)}) route, err := r.PickRoute(routing_session.AsRoutingContext(ctx)) @@ -149,11 +149,11 @@ func TestIPIfNonMatchDomain(t *testing.T) { mockCtl := gomock.NewController(t) defer mockCtl.Finish() - mockDns := mocks.NewDNSClient(mockCtl) - mockDns.EXPECT().LookupIP(gomock.Eq("v2ray.com")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes() + mockDNS := mocks.NewDNSClient(mockCtl) + mockDNS.EXPECT().LookupIP(gomock.Eq("v2ray.com")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes() r := new(Router) - common.Must(r.Init(config, mockDns, nil)) + common.Must(r.Init(config, mockDNS, nil)) ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2ray.com"), 80)}) route, err := r.PickRoute(routing_session.AsRoutingContext(ctx)) @@ -184,10 +184,10 @@ func TestIPIfNonMatchIP(t *testing.T) { mockCtl := gomock.NewController(t) defer mockCtl.Finish() - mockDns := mocks.NewDNSClient(mockCtl) + mockDNS := mocks.NewDNSClient(mockCtl) r := new(Router) - common.Must(r.Init(config, mockDns, nil)) + common.Must(r.Init(config, mockDNS, nil)) ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 80)}) route, err := r.PickRoute(routing_session.AsRoutingContext(ctx)) diff --git a/app/stats/channel_test.go b/app/stats/channel_test.go index b2a1c174c..09184bf57 100644 --- a/app/stats/channel_test.go +++ b/app/stats/channel_test.go @@ -388,7 +388,7 @@ func TestStatsChannelConcurrency(t *testing.T) { if ok { errCh <- fmt.Sprint("unexpected receiving: ", v) } else { - errCh <- fmt.Sprint("unexpected closing of channel") + errCh <- "unexpected closing of channel" } default: } diff --git a/common/antireplay/antireplay.go b/common/antireplay/antireplay.go index bdf22f266..9ac4300fd 100644 --- a/common/antireplay/antireplay.go +++ b/common/antireplay/antireplay.go @@ -1,14 +1,15 @@ package antireplay import ( - cuckoo "github.com/seiflotfy/cuckoofilter" "sync" "time" + + cuckoo "github.com/seiflotfy/cuckoofilter" ) -func NewAntiReplayWindow(AntiReplayTime int64) *AntiReplayWindow { +func NewAntiReplayWindow(antiReplayTime int64) *AntiReplayWindow { arw := &AntiReplayWindow{} - arw.AntiReplayTime = AntiReplayTime + arw.AntiReplayTime = antiReplayTime return arw } diff --git a/common/buf/multi_buffer_test.go b/common/buf/multi_buffer_test.go index add7a1e19..f0d2776b6 100644 --- a/common/buf/multi_buffer_test.go +++ b/common/buf/multi_buffer_test.go @@ -4,12 +4,11 @@ import ( "bytes" "crypto/rand" "io" + "io/ioutil" + "os" "testing" "github.com/google/go-cmp/cmp" - "io/ioutil" - "os" - "v2ray.com/core/common" . "v2ray.com/core/common/buf" ) @@ -110,7 +109,6 @@ func TestMultiBufferReadAllToByte(t *testing.T) { if l := len(b); l != 8*1024 { t.Error("unexpceted length from ReadAllToBytes", l) } - } { const dat = "data/test_MultiBufferReadAllToByte.dat" diff --git a/common/buf/reader_test.go b/common/buf/reader_test.go index 95622eefe..910851094 100644 --- a/common/buf/reader_test.go +++ b/common/buf/reader_test.go @@ -88,7 +88,6 @@ func TestReadBuffer(t *testing.T) { } buf.Release() } - } func TestReadAtMost(t *testing.T) { diff --git a/common/buf/readv_test.go b/common/buf/readv_test.go index 190e83d0e..b2a3627d2 100644 --- a/common/buf/readv_test.go +++ b/common/buf/readv_test.go @@ -23,11 +23,11 @@ func TestReadvReader(t *testing.T) { } dest, err := tcpServer.Start() common.Must(err) - defer tcpServer.Close() // nolint: errcheck + defer tcpServer.Close() conn, err := net.Dial("tcp", dest.NetAddr()) common.Must(err) - defer conn.Close() // nolint: errcheck + defer conn.Close() const size = 8192 data := make([]byte, 8192) diff --git a/common/bytespool/pool.go b/common/bytespool/pool.go index 24542ffa8..9b0e710e5 100644 --- a/common/bytespool/pool.go +++ b/common/bytespool/pool.go @@ -65,7 +65,7 @@ func Free(b []byte) { b = b[0:cap(b)] for i := numPools - 1; i >= 0; i-- { if size >= poolSize[i] { - pool[i].Put(b) // nolint: megacheck + pool[i].Put(b) return } } diff --git a/common/dice/dice.go b/common/dice/dice.go index f5a625592..150a76134 100644 --- a/common/dice/dice.go +++ b/common/dice/dice.go @@ -32,15 +32,15 @@ func RollUint64() uint64 { return rand.Uint64() } -func NewDeterministicDice(seed int64) *deterministicDice { - return &deterministicDice{rand.New(rand.NewSource(seed))} +func NewDeterministicDice(seed int64) *DeterministicDice { + return &DeterministicDice{rand.New(rand.NewSource(seed))} } -type deterministicDice struct { +type DeterministicDice struct { *rand.Rand } -func (dd *deterministicDice) Roll(n int) int { +func (dd *DeterministicDice) Roll(n int) int { if n == 1 { return 0 } diff --git a/common/log/logger.go b/common/log/logger.go index a6b8316b1..7360c6498 100644 --- a/common/log/logger.go +++ b/common/log/logger.go @@ -48,14 +48,14 @@ func (l *generalLogger) run() { if logger == nil { return } - defer logger.Close() // nolint: errcheck + defer logger.Close() for { select { case <-l.done.Wait(): return case msg := <-l.buffer: - logger.Write(msg.String() + platform.LineSeparator()) // nolint: errcheck + logger.Write(msg.String() + platform.LineSeparator()) dataWritten = true case <-ticker.C: if !dataWritten { diff --git a/common/log/logger_test.go b/common/log/logger_test.go index b41f41dfd..9ce8ca3c6 100644 --- a/common/log/logger_test.go +++ b/common/log/logger_test.go @@ -29,7 +29,7 @@ func TestFileLogger(t *testing.T) { f, err = os.Open(path) common.Must(err) - defer f.Close() // nolint: errcheck + defer f.Close() b, err := buf.ReadAllToBytes(f) common.Must(err) diff --git a/common/mux/client.go b/common/mux/client.go index 9e651bbe5..90ea1cfd5 100644 --- a/common/mux/client.go +++ b/common/mux/client.go @@ -214,8 +214,8 @@ func (m *ClientWorker) monitor() { select { case <-m.done.Wait(): m.sessionManager.Close() - common.Close(m.link.Writer) // nolint: errcheck - common.Interrupt(m.link.Reader) // nolint: errcheck + common.Close(m.link.Writer) + common.Interrupt(m.link.Reader) return case <-timer.C: size := m.sessionManager.Size() @@ -247,8 +247,8 @@ func fetchInput(ctx context.Context, s *Session, output buf.Writer) { } s.transferType = transferType writer := NewWriter(s.ID, dest, output, transferType) - defer s.Close() // nolint: errcheck - defer writer.Close() // nolint: errcheck + defer s.Close() + defer writer.Close() newError("dispatching request to ", dest).WriteToLog(session.ExportIDToError(ctx)) if err := writeFirstPayload(s.input, writer); err != nil { diff --git a/common/mux/server.go b/common/mux/server.go index 8985bdd73..c4f9ca920 100644 --- a/common/mux/server.go +++ b/common/mux/server.go @@ -232,7 +232,7 @@ func (w *ServerWorker) run(ctx context.Context) { input := w.link.Reader reader := &buf.BufferedReader{Reader: input} - defer w.sessionManager.Close() // nolint: errcheck + defer w.sessionManager.Close() for { select { diff --git a/common/mux/session.go b/common/mux/session.go index c0759f96f..84764babe 100644 --- a/common/mux/session.go +++ b/common/mux/session.go @@ -126,8 +126,8 @@ func (m *SessionManager) Close() error { m.closed = true for _, s := range m.sessions { - common.Close(s.input) // nolint: errcheck - common.Close(s.output) // nolint: errcheck + common.Close(s.input) + common.Close(s.output) } m.sessions = nil @@ -145,8 +145,8 @@ type Session struct { // Close closes all resources associated with this session. func (s *Session) Close() error { - common.Close(s.output) // nolint: errcheck - common.Close(s.input) // nolint: errcheck + common.Close(s.output) + common.Close(s.input) s.parent.Remove(s.ID) return nil } diff --git a/common/mux/writer.go b/common/mux/writer.go index f3b3c1d35..21850ac60 100644 --- a/common/mux/writer.go +++ b/common/mux/writer.go @@ -121,6 +121,6 @@ func (w *Writer) Close() error { frame := buf.New() common.Must(meta.WriteTo(frame)) - w.writer.WriteMultiBuffer(buf.MultiBuffer{frame}) // nolint: errcheck + w.writer.WriteMultiBuffer(buf.MultiBuffer{frame}) return nil } diff --git a/common/net/destination_test.go b/common/net/destination_test.go index 3cfe915b9..1e160511d 100644 --- a/common/net/destination_test.go +++ b/common/net/destination_test.go @@ -90,10 +90,8 @@ func TestDestinationParse(t *testing.T) { if d != testcase.Output { t.Error("for test case: ", testcase.Input, " expected output: ", testcase.Output.String(), " but got ", d.String()) } - } else { - if err == nil { - t.Error("for test case: ", testcase.Input, " expected error, but got nil") - } + } else if err == nil { + t.Error("for test case: ", testcase.Input, " expected error, but got nil") } } } diff --git a/common/platform/platform.go b/common/platform/platform.go index c0bf8c20b..6da185cff 100644 --- a/common/platform/platform.go +++ b/common/platform/platform.go @@ -49,7 +49,7 @@ func (f EnvFlag) GetValueAsInt(defaultValue int) int { } func NormalizeEnvName(name string) string { - return strings.Replace(strings.ToUpper(strings.TrimSpace(name)), ".", "_", -1) + return strings.ReplaceAll(strings.ToUpper(strings.TrimSpace(name)), ".", "_") } func getExecutableDir() string { diff --git a/common/protocol/tls/cert/cert_test.go b/common/protocol/tls/cert/cert_test.go index 20ad6239b..830387966 100644 --- a/common/protocol/tls/cert/cert_test.go +++ b/common/protocol/tls/cert/cert_test.go @@ -8,6 +8,7 @@ import ( "strings" "testing" "time" + "v2ray.com/core/common" "v2ray.com/core/common/task" ) diff --git a/common/retry/retry_test.go b/common/retry/retry_test.go index ef278423d..9d5ae9042 100644 --- a/common/retry/retry_test.go +++ b/common/retry/retry_test.go @@ -10,7 +10,7 @@ import ( ) var ( - errorTestOnly = errors.New("This is a fake error.") + errorTestOnly = errors.New("this is a fake error") ) func TestNoRetry(t *testing.T) { diff --git a/common/signal/timer.go b/common/signal/timer.go index 4182d4b2d..afda17754 100644 --- a/common/signal/timer.go +++ b/common/signal/timer.go @@ -45,7 +45,7 @@ func (t *ActivityTimer) finish() { t.onTimeout = nil } if t.checkTask != nil { - t.checkTask.Close() // nolint: errcheck + t.checkTask.Close() t.checkTask = nil } } @@ -64,7 +64,7 @@ func (t *ActivityTimer) SetTimeout(timeout time.Duration) { t.Lock() if t.checkTask != nil { - t.checkTask.Close() // nolint: errcheck + t.checkTask.Close() } t.checkTask = checkTask t.Unlock() diff --git a/common/task/periodic.go b/common/task/periodic.go index a646300f8..6abe41ae0 100644 --- a/common/task/periodic.go +++ b/common/task/periodic.go @@ -44,7 +44,7 @@ func (t *Periodic) checkedExecute() error { } t.timer = time.AfterFunc(t.Interval, func() { - t.checkedExecute() // nolint: errcheck + t.checkedExecute() }) return nil diff --git a/features/policy/policy.go b/features/policy/policy.go index b00ffeb78..64f556984 100644 --- a/features/policy/policy.go +++ b/features/policy/policy.go @@ -117,8 +117,8 @@ func defaultBufferPolicy() Buffer { func SessionDefault() Session { return Session{ Timeouts: Timeout{ - //Align Handshake timeout with nginx client_header_timeout - //So that this value will not indicate server identity + // Align Handshake timeout with nginx client_header_timeout + // So that this value will not indicate server identity Handshake: time.Second * 60, ConnectionIdle: time.Second * 300, UplinkOnly: time.Second * 1, diff --git a/infra/conf/api.go b/infra/conf/api.go index 4ddfe37b6..0e165c2c4 100644 --- a/infra/conf/api.go +++ b/infra/conf/api.go @@ -10,14 +10,14 @@ import ( "v2ray.com/core/common/serial" ) -type ApiConfig struct { +type APIConfig struct { Tag string `json:"tag"` Services []string `json:"services"` } -func (c *ApiConfig) Build() (*commander.Config, error) { +func (c *APIConfig) Build() (*commander.Config, error) { if c.Tag == "" { - return nil, newError("Api tag can't be empty.") + return nil, newError("API tag can't be empty.") } services := make([]*serial.TypedMessage, 0, 16) diff --git a/infra/conf/blackhole.go b/infra/conf/blackhole.go index bd0ebf02c..a0eeec430 100644 --- a/infra/conf/blackhole.go +++ b/infra/conf/blackhole.go @@ -15,9 +15,9 @@ func (*NoneResponse) Build() (proto.Message, error) { return new(blackhole.NoneResponse), nil } -type HttpResponse struct{} +type HTTPResponse struct{} -func (*HttpResponse) Build() (proto.Message, error) { +func (*HTTPResponse) Build() (proto.Message, error) { return new(blackhole.HTTPResponse), nil } @@ -46,7 +46,7 @@ var ( configLoader = NewJSONConfigLoader( ConfigCreatorCache{ "none": func() interface{} { return new(NoneResponse) }, - "http": func() interface{} { return new(HttpResponse) }, + "http": func() interface{} { return new(HTTPResponse) }, }, "type", "") diff --git a/infra/conf/common.go b/infra/conf/common.go index b97a200ac..03ec6749a 100644 --- a/infra/conf/common.go +++ b/infra/conf/common.go @@ -221,7 +221,7 @@ func (list *PortList) UnmarshalJSON(data []byte) error { } } if number != 0 { - list.Range = append(list.Range, PortRange{From: uint32(number), To: uint32(number)}) + list.Range = append(list.Range, PortRange{From: number, To: number}) } return nil } diff --git a/infra/conf/common_test.go b/infra/conf/common_test.go index b73dcbf47..e50c165ca 100644 --- a/infra/conf/common_test.go +++ b/infra/conf/common_test.go @@ -2,31 +2,31 @@ package conf_test import ( "encoding/json" - "github.com/google/go-cmp/cmp/cmpopts" "os" "testing" "github.com/google/go-cmp/cmp" - "v2ray.com/core/common/protocol" + "github.com/google/go-cmp/cmp/cmpopts" "v2ray.com/core/common" "v2ray.com/core/common/net" + "v2ray.com/core/common/protocol" . "v2ray.com/core/infra/conf" ) func TestStringListUnmarshalError(t *testing.T) { - rawJson := `1234` + rawJSON := `1234` list := new(StringList) - err := json.Unmarshal([]byte(rawJson), list) + err := json.Unmarshal([]byte(rawJSON), list) if err == nil { t.Error("expected error, but got nil") } } func TestStringListLen(t *testing.T) { - rawJson := `"a, b, c, d"` + rawJSON := `"a, b, c, d"` var list StringList - err := json.Unmarshal([]byte(rawJson), &list) + err := json.Unmarshal([]byte(rawJSON), &list) common.Must(err) if r := cmp.Diff([]string(list), []string{"a", " b", " c", " d"}); r != "" { t.Error(r) @@ -34,9 +34,9 @@ func TestStringListLen(t *testing.T) { } func TestIPParsing(t *testing.T) { - rawJson := "\"8.8.8.8\"" + rawJSON := "\"8.8.8.8\"" var address Address - err := json.Unmarshal([]byte(rawJson), &address) + err := json.Unmarshal([]byte(rawJSON), &address) common.Must(err) if r := cmp.Diff(address.IP(), net.IP{8, 8, 8, 8}); r != "" { t.Error(r) @@ -44,9 +44,9 @@ func TestIPParsing(t *testing.T) { } func TestDomainParsing(t *testing.T) { - rawJson := "\"v2ray.com\"" + rawJSON := "\"v2ray.com\"" var address Address - common.Must(json.Unmarshal([]byte(rawJson), &address)) + common.Must(json.Unmarshal([]byte(rawJSON), &address)) if address.Domain() != "v2ray.com" { t.Error("domain: ", address.Domain()) } @@ -54,17 +54,17 @@ func TestDomainParsing(t *testing.T) { func TestURLParsing(t *testing.T) { { - rawJson := "\"https://dns.google/dns-query\"" + rawJSON := "\"https://dns.google/dns-query\"" var address Address - common.Must(json.Unmarshal([]byte(rawJson), &address)) + common.Must(json.Unmarshal([]byte(rawJSON), &address)) if address.Domain() != "https://dns.google/dns-query" { t.Error("URL: ", address.Domain()) } } { - rawJson := "\"https+local://dns.google/dns-query\"" + rawJSON := "\"https+local://dns.google/dns-query\"" var address Address - common.Must(json.Unmarshal([]byte(rawJson), &address)) + common.Must(json.Unmarshal([]byte(rawJSON), &address)) if address.Domain() != "https+local://dns.google/dns-query" { t.Error("URL: ", address.Domain()) } @@ -72,9 +72,9 @@ func TestURLParsing(t *testing.T) { } func TestInvalidAddressJson(t *testing.T) { - rawJson := "1234" + rawJSON := "1234" var address Address - err := json.Unmarshal([]byte(rawJson), &address) + err := json.Unmarshal([]byte(rawJSON), &address) if err == nil { t.Error("nil error") } diff --git a/infra/conf/dns.go b/infra/conf/dns.go index e9222a4c0..1487f3fd7 100644 --- a/infra/conf/dns.go +++ b/infra/conf/dns.go @@ -106,8 +106,8 @@ var typeMap = map[router.Domain_Type]dns.DomainMatchingType{ router.Domain_Regex: dns.DomainMatchingType_Regex, } -// DnsConfig is a JSON serializable object for dns.Config. -type DnsConfig struct { +// DNSConfig is a JSON serializable object for dns.Config. +type DNSConfig struct { Servers []*NameServerConfig `json:"servers"` Hosts map[string]*Address `json:"hosts"` ClientIP *Address `json:"clientIp"` @@ -127,7 +127,7 @@ func getHostMapping(addr *Address) *dns.Config_HostMapping { } // Build implements Buildable -func (c *DnsConfig) Build() (*dns.Config, error) { +func (c *DNSConfig) Build() (*dns.Config, error) { config := &dns.Config{ Tag: c.Tag, } @@ -153,16 +153,18 @@ func (c *DnsConfig) Build() (*dns.Config, error) { domains = append(domains, domain) } sort.Strings(domains) + for _, domain := range domains { addr := c.Hosts[domain] var mappings []*dns.Config_HostMapping - if strings.HasPrefix(domain, "domain:") { + switch { + case strings.HasPrefix(domain, "domain:"): mapping := getHostMapping(addr) mapping.Type = dns.DomainMatchingType_Subdomain mapping.Domain = domain[7:] - mappings = append(mappings, mapping) - } else if strings.HasPrefix(domain, "geosite:") { + + case strings.HasPrefix(domain, "geosite:"): domains, err := loadGeositeWithAttr("geosite.dat", strings.ToUpper(domain[8:])) if err != nil { return nil, newError("invalid geosite settings: ", domain).Base(err) @@ -171,28 +173,28 @@ func (c *DnsConfig) Build() (*dns.Config, error) { mapping := getHostMapping(addr) mapping.Type = typeMap[d.Type] mapping.Domain = d.Value - mappings = append(mappings, mapping) } - } else if strings.HasPrefix(domain, "regexp:") { + + case strings.HasPrefix(domain, "regexp:"): mapping := getHostMapping(addr) mapping.Type = dns.DomainMatchingType_Regex mapping.Domain = domain[7:] - mappings = append(mappings, mapping) - } else if strings.HasPrefix(domain, "keyword:") { + + case strings.HasPrefix(domain, "keyword:"): mapping := getHostMapping(addr) mapping.Type = dns.DomainMatchingType_Keyword mapping.Domain = domain[8:] - mappings = append(mappings, mapping) - } else if strings.HasPrefix(domain, "full:") { + + case strings.HasPrefix(domain, "full:"): mapping := getHostMapping(addr) mapping.Type = dns.DomainMatchingType_Full mapping.Domain = domain[5:] - mappings = append(mappings, mapping) - } else if strings.HasPrefix(domain, "dotless:") { + + case strings.HasPrefix(domain, "dotless:"): mapping := getHostMapping(addr) mapping.Type = dns.DomainMatchingType_Regex switch substr := domain[8:]; { @@ -203,9 +205,9 @@ func (c *DnsConfig) Build() (*dns.Config, error) { default: return nil, newError("substr in dotless rule should not contain a dot: ", substr) } - mappings = append(mappings, mapping) - } else if strings.HasPrefix(domain, "ext:") { + + case strings.HasPrefix(domain, "ext:"): kv := strings.Split(domain[4:], ":") if len(kv) != 2 { return nil, newError("invalid external resource: ", domain) @@ -220,14 +222,13 @@ func (c *DnsConfig) Build() (*dns.Config, error) { mapping := getHostMapping(addr) mapping.Type = typeMap[d.Type] mapping.Domain = d.Value - mappings = append(mappings, mapping) } - } else { + + default: mapping := getHostMapping(addr) mapping.Type = dns.DomainMatchingType_Full mapping.Domain = domain - mappings = append(mappings, mapping) } diff --git a/infra/conf/dns_proxy.go b/infra/conf/dns_proxy.go index 4617ead5e..2333892f3 100644 --- a/infra/conf/dns_proxy.go +++ b/infra/conf/dns_proxy.go @@ -6,13 +6,13 @@ import ( "v2ray.com/core/proxy/dns" ) -type DnsOutboundConfig struct { +type DNSOutboundConfig struct { Network Network `json:"network"` Address *Address `json:"address"` Port uint16 `json:"port"` } -func (c *DnsOutboundConfig) Build() (proto.Message, error) { +func (c *DNSOutboundConfig) Build() (proto.Message, error) { config := &dns.Config{ Server: &net.Endpoint{ Network: c.Network.Build(), diff --git a/infra/conf/dns_proxy_test.go b/infra/conf/dns_proxy_test.go index 1ecc22626..64351929f 100644 --- a/infra/conf/dns_proxy_test.go +++ b/infra/conf/dns_proxy_test.go @@ -10,7 +10,7 @@ import ( func TestDnsProxyConfig(t *testing.T) { creator := func() Buildable { - return new(DnsOutboundConfig) + return new(DNSOutboundConfig) } runMultiTestCase(t, []TestCase{ diff --git a/infra/conf/dns_test.go b/infra/conf/dns_test.go index ca5a037ff..5afd33b73 100644 --- a/infra/conf/dns_test.go +++ b/infra/conf/dns_test.go @@ -45,7 +45,7 @@ func init() { common.Must(err) common.Must2(geositeFile.Write(listBytes)) } -func TestDnsConfigParsing(t *testing.T) { +func TestDNSConfigParsing(t *testing.T) { geositePath := platform.GetAssetLocation("geosite.dat") defer func() { os.Remove(geositePath) @@ -54,7 +54,7 @@ func TestDnsConfigParsing(t *testing.T) { parserCreator := func() func(string) (proto.Message, error) { return func(s string) (proto.Message, error) { - config := new(DnsConfig) + config := new(DNSConfig) if err := json.Unmarshal([]byte(s), config); err != nil { return nil, err } diff --git a/infra/conf/http.go b/infra/conf/http.go index d17537244..e3e2b8f8d 100644 --- a/infra/conf/http.go +++ b/infra/conf/http.go @@ -9,26 +9,26 @@ import ( "v2ray.com/core/proxy/http" ) -type HttpAccount struct { +type HTTPAccount struct { Username string `json:"user"` Password string `json:"pass"` } -func (v *HttpAccount) Build() *http.Account { +func (v *HTTPAccount) Build() *http.Account { return &http.Account{ Username: v.Username, Password: v.Password, } } -type HttpServerConfig struct { +type HTTPServerConfig struct { Timeout uint32 `json:"timeout"` - Accounts []*HttpAccount `json:"accounts"` + Accounts []*HTTPAccount `json:"accounts"` Transparent bool `json:"allowTransparent"` UserLevel uint32 `json:"userLevel"` } -func (c *HttpServerConfig) Build() (proto.Message, error) { +func (c *HTTPServerConfig) Build() (proto.Message, error) { config := &http.ServerConfig{ Timeout: c.Timeout, AllowTransparent: c.Transparent, @@ -45,16 +45,16 @@ func (c *HttpServerConfig) Build() (proto.Message, error) { return config, nil } -type HttpRemoteConfig struct { +type HTTPRemoteConfig struct { Address *Address `json:"address"` Port uint16 `json:"port"` Users []json.RawMessage `json:"users"` } -type HttpClientConfig struct { - Servers []*HttpRemoteConfig `json:"servers"` +type HTTPClientConfig struct { + Servers []*HTTPRemoteConfig `json:"servers"` } -func (v *HttpClientConfig) Build() (proto.Message, error) { +func (v *HTTPClientConfig) Build() (proto.Message, error) { config := new(http.ClientConfig) config.Server = make([]*protocol.ServerEndpoint, len(v.Servers)) for idx, serverConfig := range v.Servers { @@ -67,7 +67,7 @@ func (v *HttpClientConfig) Build() (proto.Message, error) { if err := json.Unmarshal(rawUser, user); err != nil { return nil, newError("failed to parse HTTP user").Base(err).AtError() } - account := new(HttpAccount) + account := new(HTTPAccount) if err := json.Unmarshal(rawUser, account); err != nil { return nil, newError("failed to parse HTTP account").Base(err).AtError() } diff --git a/infra/conf/http_test.go b/infra/conf/http_test.go index 87dd4f097..2780f92d1 100644 --- a/infra/conf/http_test.go +++ b/infra/conf/http_test.go @@ -7,9 +7,9 @@ import ( "v2ray.com/core/proxy/http" ) -func TestHttpServerConfig(t *testing.T) { +func TestHTTPServerConfig(t *testing.T) { creator := func() Buildable { - return new(HttpServerConfig) + return new(HTTPServerConfig) } runMultiTestCase(t, []TestCase{ diff --git a/infra/conf/json/reader_test.go b/infra/conf/json/reader_test.go index 900abcb20..44d8623e2 100644 --- a/infra/conf/json/reader_test.go +++ b/infra/conf/json/reader_test.go @@ -93,5 +93,4 @@ func TestReader1(t *testing.T) { t.Error("got ", string(target), " want ", testCase.output) } } - } diff --git a/infra/conf/policy_test.go b/infra/conf/policy_test.go index ce6d4daf2..097181052 100644 --- a/infra/conf/policy_test.go +++ b/infra/conf/policy_test.go @@ -27,7 +27,7 @@ func TestBufferSize(t *testing.T) { } for _, c := range cases { - bs := int32(c.Input) + bs := c.Input pConf := Policy{ BufferSize: &bs, } diff --git a/infra/conf/router.go b/infra/conf/router.go index 10b51993f..80afcde33 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -5,11 +5,11 @@ import ( "strconv" "strings" + "github.com/golang/protobuf/proto" + "v2ray.com/core/app/router" "v2ray.com/core/common/net" "v2ray.com/core/common/platform/filesystem" - - "github.com/golang/protobuf/proto" ) type RouterRulesConfig struct { @@ -67,10 +67,15 @@ func (c *RouterConfig) Build() (*router.Config, error) { config := new(router.Config) config.DomainStrategy = c.getDomainStrategy() - rawRuleList := c.RuleList - if c.Settings != nil { - rawRuleList = append(c.RuleList, c.Settings.RuleList...) + var rawRuleList []json.RawMessage + if c != nil { + rawRuleList = c.RuleList + if c.Settings != nil { + c.RuleList = append(c.RuleList, c.Settings.RuleList...) + rawRuleList = c.RuleList + } } + for _, rawRule := range rawRuleList { rule, err := ParseRule(rawRule) if err != nil { @@ -290,15 +295,19 @@ func parseDomainRule(domain string) ([]*router.Domain, error) { case strings.HasPrefix(domain, "regexp:"): domainRule.Type = router.Domain_Regex domainRule.Value = domain[7:] + case strings.HasPrefix(domain, "domain:"): domainRule.Type = router.Domain_Domain domainRule.Value = domain[7:] + case strings.HasPrefix(domain, "full:"): domainRule.Type = router.Domain_Full domainRule.Value = domain[5:] + case strings.HasPrefix(domain, "keyword:"): domainRule.Type = router.Domain_Plain domainRule.Value = domain[8:] + case strings.HasPrefix(domain, "dotless:"): domainRule.Type = router.Domain_Regex switch substr := domain[8:]; { @@ -309,6 +318,7 @@ func parseDomainRule(domain string) ([]*router.Domain, error) { default: return nil, newError("substr in dotless rule should not contain a dot: ", substr) } + default: domainRule.Type = router.Domain_Plain domainRule.Value = domain @@ -403,15 +413,16 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { } rule := new(router.RoutingRule) - if len(rawFieldRule.OutboundTag) > 0 { + switch { + case len(rawFieldRule.OutboundTag) > 0: rule.TargetTag = &router.RoutingRule_Tag{ Tag: rawFieldRule.OutboundTag, } - } else if len(rawFieldRule.BalancerTag) > 0 { + case len(rawFieldRule.BalancerTag) > 0: rule.TargetTag = &router.RoutingRule_BalancingTag{ BalancingTag: rawFieldRule.BalancerTag, } - } else { + default: return nil, newError("neither outboundTag nor balancerTag is specified in routing rule") } diff --git a/infra/conf/socks.go b/infra/conf/socks.go index cba5989a6..1d382788b 100644 --- a/infra/conf/socks.go +++ b/infra/conf/socks.go @@ -43,7 +43,7 @@ func (v *SocksServerConfig) Build() (proto.Message, error) { case AuthMethodUserPass: config.AuthType = socks.AuthType_PASSWORD default: - //newError("unknown socks auth method: ", v.AuthMethod, ". Default to noauth.").AtWarning().WriteToLog() + // newError("unknown socks auth method: ", v.AuthMethod, ". Default to noauth.").AtWarning().WriteToLog() config.AuthType = socks.AuthType_NO_AUTH } diff --git a/infra/conf/transport_authenticators.go b/infra/conf/transport_authenticators.go index 29092d3a4..989060fdb 100644 --- a/infra/conf/transport_authenticators.go +++ b/infra/conf/transport_authenticators.go @@ -56,7 +56,7 @@ func (DTLSAuthenticator) Build() (proto.Message, error) { return new(tls.PacketConfig), nil } -type HTTPAuthenticatorRequest struct { +type AuthenticatorRequest struct { Version string `json:"version"` Method string `json:"method"` Path StringList `json:"path"` @@ -72,7 +72,7 @@ func sortMapKeys(m map[string]*StringList) []string { return keys } -func (v *HTTPAuthenticatorRequest) Build() (*http.RequestConfig, error) { +func (v *AuthenticatorRequest) Build() (*http.RequestConfig, error) { config := &http.RequestConfig{ Uri: []string{"/"}, Header: []*http.Header{ @@ -132,14 +132,14 @@ func (v *HTTPAuthenticatorRequest) Build() (*http.RequestConfig, error) { return config, nil } -type HTTPAuthenticatorResponse struct { +type AuthenticatorResponse struct { Version string `json:"version"` Status string `json:"status"` Reason string `json:"reason"` Headers map[string]*StringList `json:"headers"` } -func (v *HTTPAuthenticatorResponse) Build() (*http.ResponseConfig, error) { +func (v *AuthenticatorResponse) Build() (*http.ResponseConfig, error) { config := &http.ResponseConfig{ Header: []*http.Header{ { @@ -200,12 +200,12 @@ func (v *HTTPAuthenticatorResponse) Build() (*http.ResponseConfig, error) { return config, nil } -type HTTPAuthenticator struct { - Request HTTPAuthenticatorRequest `json:"request"` - Response HTTPAuthenticatorResponse `json:"response"` +type Authenticator struct { + Request AuthenticatorRequest `json:"request"` + Response AuthenticatorResponse `json:"response"` } -func (v *HTTPAuthenticator) Build() (proto.Message, error) { +func (v *Authenticator) Build() (proto.Message, error) { config := new(http.Config) requestConfig, err := v.Request.Build() if err != nil { diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index 3906badda..38d16d203 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -31,7 +31,7 @@ var ( tcpHeaderLoader = NewJSONConfigLoader(ConfigCreatorCache{ "none": func() interface{} { return new(NoOpConnectionAuthenticator) }, - "http": func() interface{} { return new(HTTPAuthenticator) }, + "http": func() interface{} { return new(Authenticator) }, }, "type", "") ) @@ -473,7 +473,7 @@ func (c *StreamConfig) Build() (*internet.StreamConfig, error) { ProtocolName: "tcp", } if c.Network != nil { - protocol, err := (*c.Network).Build() + protocol, err := c.Network.Build() if err != nil { return nil, err } diff --git a/infra/conf/trojan.go b/infra/conf/trojan.go index 88fd605d9..baaf337ec 100644 --- a/infra/conf/trojan.go +++ b/infra/conf/trojan.go @@ -6,7 +6,7 @@ import ( "strconv" "syscall" - "github.com/golang/protobuf/proto" // nolint: staticcheck + "github.com/golang/protobuf/proto" "v2ray.com/core/common/net" "v2ray.com/core/common/protocol" diff --git a/infra/conf/v2ray.go b/infra/conf/v2ray.go index 8625f1f53..92137b3c8 100644 --- a/infra/conf/v2ray.go +++ b/infra/conf/v2ray.go @@ -17,7 +17,7 @@ import ( var ( inboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{ "dokodemo-door": func() interface{} { return new(DokodemoConfig) }, - "http": func() interface{} { return new(HttpServerConfig) }, + "http": func() interface{} { return new(HTTPServerConfig) }, "shadowsocks": func() interface{} { return new(ShadowsocksServerConfig) }, "socks": func() interface{} { return new(SocksServerConfig) }, "vless": func() interface{} { return new(VLessInboundConfig) }, @@ -29,14 +29,14 @@ var ( outboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{ "blackhole": func() interface{} { return new(BlackholeConfig) }, "freedom": func() interface{} { return new(FreedomConfig) }, - "http": func() interface{} { return new(HttpClientConfig) }, + "http": func() interface{} { return new(HTTPClientConfig) }, "shadowsocks": func() interface{} { return new(ShadowsocksClientConfig) }, "socks": func() interface{} { return new(SocksClientConfig) }, "vless": func() interface{} { return new(VLessOutboundConfig) }, "vmess": func() interface{} { return new(VMessOutboundConfig) }, "trojan": func() interface{} { return new(TrojanClientConfig) }, "mtproto": func() interface{} { return new(MTProtoClientConfig) }, - "dns": func() interface{} { return new(DnsOutboundConfig) }, + "dns": func() interface{} { return new(DNSOutboundConfig) }, }, "protocol", "settings") ctllog = log.New(os.Stderr, "v2ctl> ", 0) @@ -315,7 +315,7 @@ type Config struct { Port uint16 `json:"port"` // Port of this Point server. Deprecated. LogConfig *LogConfig `json:"log"` RouterConfig *RouterConfig `json:"routing"` - DNSConfig *DnsConfig `json:"dns"` + DNSConfig *DNSConfig `json:"dns"` InboundConfigs []InboundDetourConfig `json:"inbounds"` OutboundConfigs []OutboundDetourConfig `json:"outbounds"` InboundConfig *InboundDetourConfig `json:"inbound"` // Deprecated. @@ -324,7 +324,7 @@ type Config struct { OutboundDetours []OutboundDetourConfig `json:"outboundDetour"` // Deprecated. Transport *TransportConfig `json:"transport"` Policy *PolicyConfig `json:"policy"` - Api *ApiConfig `json:"api"` + API *APIConfig `json:"api"` Stats *StatsConfig `json:"stats"` Reverse *ReverseConfig `json:"reverse"` } @@ -353,7 +353,6 @@ func (c *Config) findOutboundTag(tag string) int { // Override method accepts another Config overrides the current attribute func (c *Config) Override(o *Config, fn string) { - // only process the non-deprecated members if o.LogConfig != nil { @@ -371,8 +370,8 @@ func (c *Config) Override(o *Config, fn string) { if o.Policy != nil { c.Policy = o.Policy } - if o.Api != nil { - c.Api = o.Api + if o.API != nil { + c.API = o.API } if o.Stats != nil { c.Stats = o.Stats @@ -460,8 +459,8 @@ func (c *Config) Build() (*core.Config, error) { }, } - if c.Api != nil { - apiConf, err := c.Api.Build() + if c.API != nil { + apiConf, err := c.API.Build() if err != nil { return nil, err } diff --git a/infra/conf/v2ray_test.go b/infra/conf/v2ray_test.go index e51a42c58..a26af25ee 100644 --- a/infra/conf/v2ray_test.go +++ b/infra/conf/v2ray_test.go @@ -384,10 +384,10 @@ func TestConfig_Override(t *testing.T) { &Config{ LogConfig: &LogConfig{}, RouterConfig: &RouterConfig{}, - DNSConfig: &DnsConfig{}, + DNSConfig: &DNSConfig{}, Transport: &TransportConfig{}, Policy: &PolicyConfig{}, - Api: &ApiConfig{}, + API: &APIConfig{}, Stats: &StatsConfig{}, Reverse: &ReverseConfig{}, }, @@ -395,10 +395,10 @@ func TestConfig_Override(t *testing.T) { &Config{ LogConfig: &LogConfig{}, RouterConfig: &RouterConfig{}, - DNSConfig: &DnsConfig{}, + DNSConfig: &DNSConfig{}, Transport: &TransportConfig{}, Policy: &PolicyConfig{}, - Api: &ApiConfig{}, + API: &APIConfig{}, Stats: &StatsConfig{}, Reverse: &ReverseConfig{}, }, diff --git a/infra/conf/vless.go b/infra/conf/vless.go index 4939696e6..21fc0ae34 100644 --- a/infra/conf/vless.go +++ b/infra/conf/vless.go @@ -33,12 +33,7 @@ type VLessInboundConfig struct { // Build implements Buildable func (c *VLessInboundConfig) Build() (proto.Message, error) { - config := new(inbound.Config) - - if len(c.Clients) == 0 { - //return nil, newError(`VLESS settings: "clients" is empty`) - } config.Clients = make([]*protocol.User, len(c.Clients)) for idx, rawUser := range c.Clients { user := new(protocol.User) @@ -142,7 +137,6 @@ type VLessOutboundConfig struct { // Build implements Buildable func (c *VLessOutboundConfig) Build() (proto.Message, error) { - config := new(outbound.Config) if len(c.Vnext) == 0 { diff --git a/infra/control/api.go b/infra/control/api.go index 823d49450..8954eb6f9 100644 --- a/infra/control/api.go +++ b/infra/control/api.go @@ -16,13 +16,13 @@ import ( "v2ray.com/core/common" ) -type ApiCommand struct{} +type APICommand struct{} -func (c *ApiCommand) Name() string { +func (c *APICommand) Name() string { return "api" } -func (c *ApiCommand) Description() Description { +func (c *APICommand) Description() Description { return Description{ Short: "Call V2Ray API", Usage: []string{ @@ -42,7 +42,7 @@ func (c *ApiCommand) Description() Description { } } -func (c *ApiCommand) Execute(args []string) error { +func (c *APICommand) Execute(args []string) error { fs := flag.NewFlagSet(c.Name(), flag.ContinueOnError) serverAddrPtr := fs.String("server", "127.0.0.1:8080", "Server address") @@ -154,5 +154,5 @@ func callStatsService(ctx context.Context, conn *grpc.ClientConn, method string, } func init() { - common.Must(RegisterCommand(&ApiCommand{})) + common.Must(RegisterCommand(&APICommand{})) } diff --git a/infra/control/cert.go b/infra/control/cert.go index 1cdfd2eed..e39f28696 100644 --- a/infra/control/cert.go +++ b/infra/control/cert.go @@ -53,7 +53,7 @@ func (c *CertificateCommand) Description() Description { } } -func (c *CertificateCommand) printJson(certificate *cert.Certificate) { +func (c *CertificateCommand) printJSON(certificate *cert.Certificate) { certPEM, keyPEM := certificate.ToPEM() jCert := &jsonCert{ Certificate: strings.Split(strings.TrimSpace(string(certPEM)), "\n"), @@ -122,7 +122,7 @@ func (c *CertificateCommand) Execute(args []string) error { } if *jsonOutput { - c.printJson(cert) + c.printJSON(cert) } if len(*fileOutput) > 0 { diff --git a/infra/control/config.go b/infra/control/config.go index 504975a8c..5738cc9dd 100644 --- a/infra/control/config.go +++ b/infra/control/config.go @@ -66,13 +66,15 @@ func (c *ConfigCommand) Execute(args []string) error { // LoadArg loads one arg, maybe an remote url, or local file path func (c *ConfigCommand) LoadArg(arg string) (out io.Reader, err error) { - var data []byte - if strings.HasPrefix(arg, "http://") || strings.HasPrefix(arg, "https://") { + switch { + case strings.HasPrefix(arg, "http://"), strings.HasPrefix(arg, "https://"): data, err = FetchHTTPContent(arg) - } else if arg == "stdin:" { + + case arg == "stdin:": data, err = ioutil.ReadAll(os.Stdin) - } else { + + default: data, err = ioutil.ReadFile(arg) } diff --git a/infra/control/fetch.go b/infra/control/fetch.go index a9deef25f..30830ae2f 100644 --- a/infra/control/fetch.go +++ b/infra/control/fetch.go @@ -39,7 +39,6 @@ func (c *FetchCommand) Execute(args []string) error { // FetchHTTPContent dials https for remote content func FetchHTTPContent(target string) ([]byte, error) { - parsedTarget, err := url.Parse(target) if err != nil { return nil, newError("invalid URL: ", target).Base(err) diff --git a/infra/control/tlsping.go b/infra/control/tlsping.go index 2bd20b0d8..de57a5d28 100644 --- a/infra/control/tlsping.go +++ b/infra/control/tlsping.go @@ -10,13 +10,13 @@ import ( "v2ray.com/core/common" ) -type TlsPingCommand struct{} +type TLSPingCommand struct{} -func (c *TlsPingCommand) Name() string { +func (c *TLSPingCommand) Name() string { return "tlsping" } -func (c *TlsPingCommand) Description() Description { +func (c *TLSPingCommand) Description() Description { return Description{ Short: "Ping the domain with TLS handshake", Usage: []string{"v2ctl tlsping --ip "}, @@ -32,7 +32,7 @@ func printCertificates(certs []*x509.Certificate) { } } -func (c *TlsPingCommand) Execute(args []string) error { +func (c *TLSPingCommand) Execute(args []string) error { fs := flag.NewFlagSet(c.Name(), flag.ContinueOnError) ipStr := fs.String("ip", "", "IP address of the domain") @@ -115,5 +115,5 @@ func (c *TlsPingCommand) Execute(args []string) error { } func init() { - common.Must(RegisterCommand(&TlsPingCommand{})) + common.Must(RegisterCommand(&TLSPingCommand{})) } diff --git a/infra/control/verify.go b/infra/control/verify.go index 1a4ee2818..5c7064b52 100644 --- a/infra/control/verify.go +++ b/infra/control/verify.go @@ -2,8 +2,9 @@ package control import ( "flag" - "github.com/xiaokangwang/VSign/signerVerify" "os" + + "github.com/xiaokangwang/VSign/signerVerify" "v2ray.com/core/common" ) diff --git a/main/confloader/external/external.go b/main/confloader/external/external.go index f6bcf7d5b..84c00cbe9 100644 --- a/main/confloader/external/external.go +++ b/main/confloader/external/external.go @@ -18,13 +18,15 @@ import ( ) func ConfigLoader(arg string) (out io.Reader, err error) { - var data []byte - if strings.HasPrefix(arg, "http://") || strings.HasPrefix(arg, "https://") { + switch { + case strings.HasPrefix(arg, "http://"), strings.HasPrefix(arg, "https://"): data, err = FetchHTTPContent(arg) - } else if arg == "stdin:" { + + case arg == "stdin:": data, err = ioutil.ReadAll(os.Stdin) - } else { + + default: data, err = ioutil.ReadFile(arg) } @@ -36,7 +38,6 @@ func ConfigLoader(arg string) (out io.Reader, err error) { } func FetchHTTPContent(target string) ([]byte, error) { - parsedTarget, err := url.Parse(target) if err != nil { return nil, newError("invalid URL: ", target).Base(err) diff --git a/main/distro/debug/debug.go b/main/distro/debug/debug.go index f005c5b37..7448ecdfe 100644 --- a/main/distro/debug/debug.go +++ b/main/distro/debug/debug.go @@ -1,7 +1,8 @@ package debug -import _ "net/http/pprof" -import "net/http" +import ( + "net/http" +) func init() { go func() { diff --git a/main/main.go b/main/main.go index 8390af3e7..de6f3890d 100644 --- a/main/main.go +++ b/main/main.go @@ -70,11 +70,9 @@ func getConfigFilePath() (cmdarg.Arg, error) { if dirExists(configDir) { log.Println("Using confdir from arg:", configDir) readConfDir(configDir) - } else { - if envConfDir := platform.GetConfDirPath(); dirExists(envConfDir) { - log.Println("Using confdir from env:", envConfDir) - readConfDir(envConfDir) - } + } else if envConfDir := platform.GetConfDirPath(); dirExists(envConfDir) { + log.Println("Using confdir from env:", envConfDir) + readConfDir(envConfDir) } if len(configFiles) > 0 { @@ -134,7 +132,6 @@ func printVersion() { } func main() { - flag.Parse() printVersion() diff --git a/proxy/blackhole/blackhole.go b/proxy/blackhole/blackhole.go index d2213390b..00b12a222 100644 --- a/proxy/blackhole/blackhole.go +++ b/proxy/blackhole/blackhole.go @@ -1,7 +1,6 @@ // +build !confonly // Package blackhole is an outbound handler that blocks all connections. - package blackhole //go:generate go run v2ray.com/core/common/errors/errorgen diff --git a/proxy/blackhole/config_test.go b/proxy/blackhole/config_test.go index 340ddcc27..d67ac87fe 100644 --- a/proxy/blackhole/config_test.go +++ b/proxy/blackhole/config_test.go @@ -19,6 +19,7 @@ func TestHTTPResponse(t *testing.T) { reader := bufio.NewReader(buffer) response, err := http.ReadResponse(reader, nil) common.Must(err) + if response.StatusCode != 403 { t.Error("expected status code 403, but got ", response.StatusCode) } diff --git a/proxy/dns/dns_test.go b/proxy/dns/dns_test.go index 7ac7d520d..95833d681 100644 --- a/proxy/dns/dns_test.go +++ b/proxy/dns/dns_test.go @@ -44,7 +44,8 @@ func (*staticHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) { } for _, q := range r.Question { - if q.Name == "google.com." && q.Qtype == dns.TypeA { + switch { + case q.Name == "google.com." && q.Qtype == dns.TypeA: if clientIP == nil { rr, _ := dns.NewRR("google.com. IN A 8.8.8.8") ans.Answer = append(ans.Answer, rr) @@ -52,18 +53,22 @@ func (*staticHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) { rr, _ := dns.NewRR("google.com. IN A 8.8.4.4") ans.Answer = append(ans.Answer, rr) } - } else if q.Name == "facebook.com." && q.Qtype == dns.TypeA { + + case q.Name == "facebook.com." && q.Qtype == dns.TypeA: rr, _ := dns.NewRR("facebook.com. IN A 9.9.9.9") ans.Answer = append(ans.Answer, rr) - } else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeA { + + case q.Name == "ipv6.google.com." && q.Qtype == dns.TypeA: rr, err := dns.NewRR("ipv6.google.com. IN A 8.8.8.7") common.Must(err) ans.Answer = append(ans.Answer, rr) - } else if q.Name == "ipv6.google.com." && q.Qtype == dns.TypeAAAA { + + case q.Name == "ipv6.google.com." && q.Qtype == dns.TypeAAAA: rr, err := dns.NewRR("ipv6.google.com. IN AAAA 2001:4860:4860::8888") common.Must(err) ans.Answer = append(ans.Answer, rr) - } else if q.Name == "notexist.google.com." && q.Qtype == dns.TypeAAAA { + + case q.Name == "notexist.google.com." && q.Qtype == dns.TypeAAAA: ans.MsgHdr.Rcode = dns.RcodeNameError } } diff --git a/proxy/dokodemo/dokodemo.go b/proxy/dokodemo/dokodemo.go index 0333eb28c..9185a597f 100644 --- a/proxy/dokodemo/dokodemo.go +++ b/proxy/dokodemo/dokodemo.go @@ -156,7 +156,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in if network == net.Network_TCP { writer = buf.NewWriter(conn) } else { - //if we are in TPROXY mode, use linux's udp forging functionality + // if we are in TPROXY mode, use linux's udp forging functionality if !destinationOverridden { writer = &buf.SequentialWriter{Writer: conn} } else { diff --git a/proxy/freedom/freedom.go b/proxy/freedom/freedom.go index 0ac95466c..9a55a71b2 100644 --- a/proxy/freedom/freedom.go +++ b/proxy/freedom/freedom.go @@ -137,7 +137,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte if err != nil { return newError("failed to open connection to ", destination).Base(err) } - defer conn.Close() // nolint: errcheck + defer conn.Close() plcy := h.policy() ctx, cancel := context.WithCancel(ctx) diff --git a/proxy/http/server.go b/proxy/http/server.go index f956438c4..059ea310a 100644 --- a/proxy/http/server.go +++ b/proxy/http/server.go @@ -103,7 +103,7 @@ Start: if err != nil { trace := newError("failed to read http request").Base(err) if errors.Cause(err) != io.EOF && !isTimeout(errors.Cause(err)) { - trace.AtWarning() // nolint: errcheck + trace.AtWarning() } return trace } @@ -159,7 +159,7 @@ Start: return err } -func (s *Server) handleConnect(ctx context.Context, request *http.Request, reader *bufio.Reader, conn internet.Connection, dest net.Destination, dispatcher routing.Dispatcher) error { +func (s *Server) handleConnect(ctx context.Context, _ *http.Request, reader *bufio.Reader, conn internet.Connection, dest net.Destination, dispatcher routing.Dispatcher) error { _, err := conn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n")) if err != nil { return newError("failed to write back OK response").Base(err) @@ -263,7 +263,7 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, wri } // Plain HTTP request is not a stream. The request always finishes before response. Hense request has to be closed later. - defer common.Close(link.Writer) // nolint: errcheck + defer common.Close(link.Writer) var result error = errWaitAnother requestDone := func() error { diff --git a/proxy/mtproto/client.go b/proxy/mtproto/client.go index 6db10e048..115b668b2 100644 --- a/proxy/mtproto/client.go +++ b/proxy/mtproto/client.go @@ -34,7 +34,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter if err != nil { return newError("failed to dial to ", dest).Base(err).AtWarning() } - defer conn.Close() // nolint: errcheck + defer conn.Close() sc := SessionContextFromContext(ctx) auth := NewAuthentication(sc) diff --git a/proxy/shadowsocks/client.go b/proxy/shadowsocks/client.go index 012e595f1..04b7c723d 100644 --- a/proxy/shadowsocks/client.go +++ b/proxy/shadowsocks/client.go @@ -136,7 +136,6 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter } if request.Command == protocol.RequestCommandUDP { - writer := &buf.SequentialWriter{Writer: &UDPWriter{ Writer: conn, Request: request, diff --git a/proxy/shadowsocks/protocol.go b/proxy/shadowsocks/protocol.go index 4d4fc414d..63f807605 100644 --- a/proxy/shadowsocks/protocol.go +++ b/proxy/shadowsocks/protocol.go @@ -6,14 +6,13 @@ import ( "crypto/hmac" "crypto/rand" "crypto/sha256" - "hash" "hash/crc32" "io" "io/ioutil" - "v2ray.com/core/common/dice" "v2ray.com/core/common" "v2ray.com/core/common/buf" + "v2ray.com/core/common/dice" "v2ray.com/core/common/net" "v2ray.com/core/common/protocol" ) @@ -35,7 +34,7 @@ var addrParser = protocol.NewAddressParser( func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) { account := user.Account.(*MemoryAccount) - hashkdf := hmac.New(func() hash.Hash { return sha256.New() }, []byte("SSBSKDF")) + hashkdf := hmac.New(sha256.New, []byte("SSBSKDF")) hashkdf.Write(account.Key) behaviorSeed := crc32.ChecksumIEEE(hashkdf.Sum(nil)) diff --git a/proxy/shadowsocks/protocol_test.go b/proxy/shadowsocks/protocol_test.go index 60630e29c..10080bfff 100644 --- a/proxy/shadowsocks/protocol_test.go +++ b/proxy/shadowsocks/protocol_test.go @@ -133,7 +133,6 @@ func TestTCPRequest(t *testing.T) { for _, test := range cases { runTest(test.request, test.payload) } - } func TestUDPReaderWriter(t *testing.T) { diff --git a/proxy/socks/client.go b/proxy/socks/client.go index a6a345b27..836caf205 100644 --- a/proxy/socks/client.go +++ b/proxy/socks/client.go @@ -127,7 +127,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter if err != nil { return newError("failed to create UDP connection").Base(err) } - defer udpConn.Close() // nolint: errcheck + defer udpConn.Close() requestFunc = func() error { defer timer.SetTimeout(p.Timeouts.DownlinkOnly) return buf.Copy(link.Reader, &buf.SequentialWriter{Writer: NewUDPWriter(request, udpConn)}, buf.UpdateActivity(timer)) diff --git a/proxy/socks/protocol.go b/proxy/socks/protocol.go index 6542600e7..47ad3f30f 100644 --- a/proxy/socks/protocol.go +++ b/proxy/socks/protocol.go @@ -26,7 +26,7 @@ const ( socks4RequestRejected = 91 authNotRequired = 0x00 - //authGssAPI = 0x01 + // authGssAPI = 0x01 authPassword = 0x02 authNoMatchingMethod = 0xFF @@ -47,7 +47,7 @@ type ServerSession struct { func (s *ServerSession) handshake4(cmd byte, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) { if s.config.AuthType == AuthType_PASSWORD { - writeSocks4Response(writer, socks4RequestRejected, net.AnyIP, net.Port(0)) // nolint: errcheck + writeSocks4Response(writer, socks4RequestRejected, net.AnyIP, net.Port(0)) return nil, newError("socks 4 is not allowed when auth is required.") } @@ -89,7 +89,7 @@ func (s *ServerSession) handshake4(cmd byte, reader io.Reader, writer io.Writer) } return request, nil default: - writeSocks4Response(writer, socks4RequestRejected, net.AnyIP, net.Port(0)) // nolint: errcheck + writeSocks4Response(writer, socks4RequestRejected, net.AnyIP, net.Port(0)) return nil, newError("unsupported command: ", cmd) } } @@ -108,7 +108,7 @@ func (s *ServerSession) auth5(nMethod byte, reader io.Reader, writer io.Writer) } if !hasAuthMethod(expectedAuth, buffer.BytesRange(0, int32(nMethod))) { - writeSocks5AuthenticationResponse(writer, socks5Version, authNoMatchingMethod) // nolint: errcheck + writeSocks5AuthenticationResponse(writer, socks5Version, authNoMatchingMethod) return "", newError("no matching auth method") } @@ -123,7 +123,7 @@ func (s *ServerSession) auth5(nMethod byte, reader io.Reader, writer io.Writer) } if !s.config.HasAccount(username, password) { - writeSocks5AuthenticationResponse(writer, 0x01, 0xFF) // nolint: errcheck + writeSocks5AuthenticationResponse(writer, 0x01, 0xFF) return "", newError("invalid username or password") } @@ -166,15 +166,15 @@ func (s *ServerSession) handshake5(nMethod byte, reader io.Reader, writer io.Wri request.Command = protocol.RequestCommandTCP case cmdUDPPort: if !s.config.UdpEnabled { - writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0)) // nolint: errcheck + writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0)) return nil, newError("UDP is not enabled.") } request.Command = protocol.RequestCommandUDP case cmdTCPBind: - writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0)) // nolint: errcheck + writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0)) return nil, newError("TCP bind is not supported.") default: - writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0)) // nolint: errcheck + writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0)) return nil, newError("unknown command ", cmd) } diff --git a/proxy/socks/server.go b/proxy/socks/server.go index b91020fff..3f421bb78 100644 --- a/proxy/socks/server.go +++ b/proxy/socks/server.go @@ -202,7 +202,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection, newError("failed to write UDP response").AtWarning().Base(err).WriteToLog(session.ExportIDToError(ctx)) } - conn.Write(udpMessage.Bytes()) // nolint: errcheck + conn.Write(udpMessage.Bytes()) }) if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() { diff --git a/proxy/trojan/client.go b/proxy/trojan/client.go index bd2758b15..20392c8d1 100644 --- a/proxy/trojan/client.go +++ b/proxy/trojan/client.go @@ -49,7 +49,7 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) { } // Process implements OutboundHandler.Process(). -func (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error { // nolint: funlen +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") @@ -60,7 +60,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter var server *protocol.ServerSpec var conn internet.Connection - err := retry.ExponentialBackoff(5, 100).On(func() error { // nolint: gomnd + err := retry.ExponentialBackoff(5, 100).On(func() error { server = c.serverPicker.PickServer() rawConn, err := dialer.Dial(ctx, server.Destination()) if err != nil { @@ -101,7 +101,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter } // write some request payload to buffer - if err = buf.CopyOnceTimeout(link.Reader, bodyWriter, time.Millisecond*100); err != nil && err != buf.ErrNotTimeoutReader && err != buf.ErrReadTimeout { // nolint: lll,gomnd + if err = buf.CopyOnceTimeout(link.Reader, bodyWriter, time.Millisecond*100); err != nil && err != buf.ErrNotTimeoutReader && err != buf.ErrReadTimeout { return newError("failed to write A reqeust payload").Base(err).AtWarning() } @@ -140,7 +140,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter } func init() { - common.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { // nolint: lll + common.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { return NewClient(ctx, config.(*ClientConfig)) })) } diff --git a/proxy/trojan/protocol.go b/proxy/trojan/protocol.go index d8007563d..4c13964dc 100644 --- a/proxy/trojan/protocol.go +++ b/proxy/trojan/protocol.go @@ -13,9 +13,9 @@ var ( crlf = []byte{'\r', '\n'} addrParser = protocol.NewAddressParser( - protocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4), // nolint: gomnd - protocol.AddressFamilyByte(0x04, net.AddressFamilyIPv6), // nolint: gomnd - protocol.AddressFamilyByte(0x03, net.AddressFamilyDomain), // nolint: gomnd + protocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4), + protocol.AddressFamilyByte(0x04, net.AddressFamilyIPv6), + protocol.AddressFamilyByte(0x03, net.AddressFamilyDomain), ) ) @@ -129,7 +129,7 @@ func (w *PacketWriter) WriteMultiBufferWithMetadata(mb buf.MultiBuffer, dest net return nil } -func (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, error) { // nolint: unparam +func (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, error) { buffer := buf.StackNew() defer buffer.Release() diff --git a/proxy/trojan/server.go b/proxy/trojan/server.go index d1248d6f2..ecacdeb68 100644 --- a/proxy/trojan/server.go +++ b/proxy/trojan/server.go @@ -29,7 +29,7 @@ import ( ) func init() { - common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { // nolint: lll + common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { return NewServer(ctx, config.(*ServerConfig)) })) } @@ -91,8 +91,7 @@ func (s *Server) Network() []net.Network { } // Process implements proxy.Inbound.Process(). -func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error { // nolint: funlen,lll - +func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error { sid := session.ExportIDToError(ctx) iConn := conn @@ -125,7 +124,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet isfb := apfb != nil shouldFallback := false - if firstLen < 58 || first.Byte(56) != '\r' { // nolint: gomnd + if firstLen < 58 || first.Byte(56) != '\r' { // invalid protocol err = newError("not trojan protocol") log.Record(&log.AccessMessage{ @@ -137,7 +136,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet shouldFallback = true } else { - user = s.validator.Get(hexString(first.BytesTo(56))) // nolint: gomnd + user = s.validator.Get(hexString(first.BytesTo(56))) if user == nil { // invalid user, let's fallback err = newError("not a valid user") @@ -199,7 +198,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet 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 { // nolint: lll +func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReader, clientWriter *PacketWriter, dispatcher routing.Dispatcher) error { udpServer := udp.NewDispatcher(dispatcher, func(ctx context.Context, packet *udp_proto.Packet) { common.Must(clientWriter.WriteMultiBufferWithMetadata(buf.MultiBuffer{packet.Payload}, packet.Source)) }) @@ -277,7 +276,7 @@ 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 { // nolint: lll +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) } diff --git a/proxy/vless/encoding/addons.go b/proxy/vless/encoding/addons.go index 459cabf8c..c847f0079 100644 --- a/proxy/vless/encoding/addons.go +++ b/proxy/vless/encoding/addons.go @@ -13,10 +13,8 @@ import ( ) func EncodeHeaderAddons(buffer *buf.Buffer, addons *Addons) error { - switch addons.Flow { case vless.XRO, vless.XRD: - bytes, err := proto.Marshal(addons) if err != nil { return newError("failed to marshal addons protobuf value").Base(err) @@ -27,30 +25,23 @@ func EncodeHeaderAddons(buffer *buf.Buffer, addons *Addons) error { if _, err := buffer.Write(bytes); err != nil { return newError("failed to write addons protobuf value").Base(err) } - default: - if err := buffer.WriteByte(0); err != nil { return newError("failed to write addons protobuf length").Base(err) } - } return nil - } func DecodeHeaderAddons(buffer *buf.Buffer, reader io.Reader) (*Addons, error) { - addons := new(Addons) - buffer.Clear() if _, err := buffer.ReadFullFrom(reader, 1); err != nil { return nil, newError("failed to read addons protobuf length").Base(err) } if length := int32(buffer.Byte(0)); length != 0 { - buffer.Clear() if _, err := buffer.ReadFullFrom(reader, length); err != nil { return nil, newError("failed to read addons protobuf value").Base(err) @@ -63,45 +54,32 @@ func DecodeHeaderAddons(buffer *buf.Buffer, reader io.Reader) (*Addons, error) { // Verification. switch addons.Flow { default: - } - } return addons, nil - } // EncodeBodyAddons returns a Writer that auto-encrypt content written by caller. func EncodeBodyAddons(writer io.Writer, request *protocol.RequestHeader, addons *Addons) buf.Writer { - switch addons.Flow { default: - if request.Command == protocol.RequestCommandUDP { return NewMultiLengthPacketWriter(writer.(buf.Writer)) } - } - return buf.NewWriter(writer) - } // DecodeBodyAddons returns a Reader from which caller can fetch decrypted body. func DecodeBodyAddons(reader io.Reader, request *protocol.RequestHeader, addons *Addons) buf.Reader { - switch addons.Flow { default: - if request.Command == protocol.RequestCommandUDP { return NewLengthPacketReader(reader) } - } - return buf.NewReader(reader) - } func NewMultiLengthPacketWriter(writer buf.Writer) *MultiLengthPacketWriter { @@ -157,7 +135,7 @@ type LengthPacketWriter struct { func (w *LengthPacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { length := mb.Len() // none of mb is nil - //fmt.Println("Write", length) + // fmt.Println("Write", length) if length == 0 { return nil } @@ -193,7 +171,7 @@ func (r *LengthPacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) { return nil, newError("failed to read packet length").Base(err) } length := int32(r.cache[0])<<8 | int32(r.cache[1]) - //fmt.Println("Read", length) + // fmt.Println("Read", length) mb := make(buf.MultiBuffer, 0, length/buf.Size+1) for length > 0 { size := length diff --git a/proxy/vless/encoding/encoding.go b/proxy/vless/encoding/encoding.go index ec6ecff6c..81a8d512a 100644 --- a/proxy/vless/encoding/encoding.go +++ b/proxy/vless/encoding/encoding.go @@ -26,7 +26,6 @@ var addrParser = protocol.NewAddressParser( // EncodeRequestHeader writes encoded request header into the given writer. func EncodeRequestHeader(writer io.Writer, request *protocol.RequestHeader, requestAddons *Addons) error { - buffer := buf.StackNew() defer buffer.Release() @@ -60,8 +59,7 @@ func EncodeRequestHeader(writer io.Writer, request *protocol.RequestHeader, requ } // DecodeRequestHeader decodes and returns (if successful) a RequestHeader from an input stream. -func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validator *vless.Validator) (*protocol.RequestHeader, *Addons, error, bool) { - +func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validator *vless.Validator) (*protocol.RequestHeader, *Addons, bool, error) { buffer := buf.StackNew() defer buffer.Release() @@ -71,7 +69,7 @@ func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validat request.Version = first.Byte(0) } else { if _, err := buffer.ReadFullFrom(reader, 1); err != nil { - return nil, nil, newError("failed to read request version").Base(err), false + return nil, nil, false, newError("failed to read request version").Base(err) } request.Version = buffer.Byte(0) } @@ -86,13 +84,13 @@ func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validat } else { buffer.Clear() if _, err := buffer.ReadFullFrom(reader, 16); err != nil { - return nil, nil, newError("failed to read request user id").Base(err), false + return nil, nil, false, newError("failed to read request user id").Base(err) } copy(id[:], buffer.Bytes()) } if request.User = validator.Get(id); request.User == nil { - return nil, nil, newError("invalid request user id"), isfb + return nil, nil, isfb, newError("invalid request user id") } if isfb { @@ -101,12 +99,12 @@ func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validat requestAddons, err := DecodeHeaderAddons(&buffer, reader) if err != nil { - return nil, nil, newError("failed to decode request header addons").Base(err), false + return nil, nil, false, newError("failed to decode request header addons").Base(err) } buffer.Clear() if _, err := buffer.ReadFullFrom(reader, 1); err != nil { - return nil, nil, newError("failed to read request command").Base(err), false + return nil, nil, false, newError("failed to read request command").Base(err) } request.Command = protocol.RequestCommand(buffer.Byte(0)) @@ -120,24 +118,17 @@ func DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validat request.Port = port } } - if request.Address == nil { - return nil, nil, newError("invalid request address"), false + return nil, nil, false, newError("invalid request address") } - - return request, requestAddons, nil, false - + return request, requestAddons, false, nil default: - - return nil, nil, newError("invalid request version"), isfb - + return nil, nil, isfb, newError("invalid request version") } - } // EncodeResponseHeader writes encoded response header into the given writer. func EncodeResponseHeader(writer io.Writer, request *protocol.RequestHeader, responseAddons *Addons) error { - buffer := buf.StackNew() defer buffer.Release() @@ -158,7 +149,6 @@ func EncodeResponseHeader(writer io.Writer, request *protocol.RequestHeader, res // DecodeResponseHeader decodes and returns (if successful) a ResponseHeader from an input stream. func DecodeResponseHeader(reader io.Reader, request *protocol.RequestHeader) (*Addons, error) { - buffer := buf.StackNew() defer buffer.Release() diff --git a/proxy/vless/encoding/encoding_test.go b/proxy/vless/encoding/encoding_test.go index 12c9e2b57..5366b84d2 100644 --- a/proxy/vless/encoding/encoding_test.go +++ b/proxy/vless/encoding/encoding_test.go @@ -46,7 +46,7 @@ func TestRequestSerialization(t *testing.T) { Validator := new(vless.Validator) Validator.Add(user) - actualRequest, actualAddons, err, _ := DecodeRequestHeader(false, nil, &buffer, Validator) + actualRequest, actualAddons, _, err := DecodeRequestHeader(false, nil, &buffer, Validator) common.Must(err) if r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != "" { @@ -83,7 +83,7 @@ func TestInvalidRequest(t *testing.T) { Validator := new(vless.Validator) Validator.Add(user) - _, _, err, _ := DecodeRequestHeader(false, nil, &buffer, Validator) + _, _, _, err := DecodeRequestHeader(false, nil, &buffer, Validator) if err == nil { t.Error("nil error") } @@ -114,7 +114,7 @@ func TestMuxRequest(t *testing.T) { Validator := new(vless.Validator) Validator.Add(user) - actualRequest, actualAddons, err, _ := DecodeRequestHeader(false, nil, &buffer, Validator) + actualRequest, actualAddons, _, err := DecodeRequestHeader(false, nil, &buffer, Validator) common.Must(err) if r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != "" { diff --git a/proxy/vless/inbound/inbound.go b/proxy/vless/inbound/inbound.go index db5a599f2..b2e736d49 100644 --- a/proxy/vless/inbound/inbound.go +++ b/proxy/vless/inbound/inbound.go @@ -64,12 +64,11 @@ type Handler struct { validator *vless.Validator dns dns.Client fallbacks map[string]map[string]*Fallback // or nil - //regexps map[string]*regexp.Regexp // or nil + // regexps map[string]*regexp.Regexp // or nil } // New creates a new VLess inbound handler. func New(ctx context.Context, config *Config, dc dns.Client) (*Handler, error) { - v := core.MustFromContext(ctx) handler := &Handler{ inboundHandlerManager: v.GetFeature(feature_inbound.ManagerType()).(feature_inbound.Manager), @@ -90,7 +89,7 @@ func New(ctx context.Context, config *Config, dc dns.Client) (*Handler, error) { if config.Fallbacks != nil { handler.fallbacks = make(map[string]map[string]*Fallback) - //handler.regexps = make(map[string]*regexp.Regexp) + // handler.regexps = make(map[string]*regexp.Regexp) for _, fb := range config.Fallbacks { if handler.fallbacks[fb.Alpn] == nil { handler.fallbacks[fb.Alpn] = make(map[string]*Fallback) @@ -144,9 +143,7 @@ func (*Handler) Network() []net.Network { // Process implements proxy.Inbound.Process(). func (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher routing.Dispatcher) error { - sid := session.ExportIDToError(ctx) - iConn := connection if statConn, ok := iConn.(*internet.StatCouterConnection); ok { iConn = statConn.Connection @@ -178,11 +175,10 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i if isfb && firstLen < 18 { err = newError("fallback directly") } else { - request, requestAddons, err, isfb = encoding.DecodeRequestHeader(isfb, first, reader, h.validator) + request, requestAddons, isfb, err = encoding.DecodeRequestHeader(isfb, first, reader, h.validator) } if err != nil { - if isfb { if err := connection.SetReadDeadline(time.Time{}); err != nil { newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid) @@ -271,7 +267,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i }); err != nil { return newError("failed to dial to " + fb.Dest).Base(err).AtWarning() } - defer conn.Close() // nolint: errcheck + defer conn.Close() serverReader := buf.NewReader(conn) serverWriter := buf.NewWriter(conn) @@ -303,6 +299,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i } else { pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n")) } + case 2: pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x21")) // signature + v2 + PROXY if ipv4 { @@ -372,7 +369,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i account := request.User.Account.(*vless.MemoryAccount) responseAddons := &encoding.Addons{ - //Flow: requestAddons.Flow, + // Flow: requestAddons.Flow, } switch requestAddons.Flow { @@ -473,7 +470,6 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i // Indicates the end of response payload. switch responseAddons.Flow { default: - } return nil diff --git a/proxy/vless/outbound/outbound.go b/proxy/vless/outbound/outbound.go index b7d7d65df..d052ef2ad 100644 --- a/proxy/vless/outbound/outbound.go +++ b/proxy/vless/outbound/outbound.go @@ -52,7 +52,6 @@ type Handler struct { // New creates a new VLess outbound handler. func New(ctx context.Context, config *Config) (*Handler, error) { - serverList := protocol.NewServerList() for _, rec := range config.Vnext { s, err := protocol.NewServerSpecFromPB(rec) @@ -74,7 +73,6 @@ func New(ctx context.Context, config *Config) (*Handler, error) { // Process implements proxy.Outbound.Process(). func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error { - var rec *protocol.ServerSpec var conn internet.Connection @@ -89,7 +87,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte }); err != nil { return newError("failed to find an available destination").Base(err).AtWarning() } - defer conn.Close() // nolint: errcheck + defer conn.Close() iConn := conn if statConn, ok := iConn.(*internet.StatCouterConnection); ok { @@ -193,9 +191,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte // Indicates the end of request payload. switch requestAddons.Flow { default: - } - return nil } diff --git a/proxy/vmess/aead/authid.go b/proxy/vmess/aead/authid.go index 5ba2db1fa..adde14a75 100644 --- a/proxy/vmess/aead/authid.go +++ b/proxy/vmess/aead/authid.go @@ -11,10 +11,16 @@ import ( "io" "math" "time" + "v2ray.com/core/common" antiReplayWindow "v2ray.com/core/common/antireplay" ) +var ( + ErrNotFound = errors.New("user do not exist") + ErrReplay = errors.New("replayed request") +) + func CreateAuthID(cmdKey []byte, time int64) [16]byte { buf := bytes.NewBuffer(nil) common.Must(binary.Write(buf, binary.BigEndian, time)) @@ -32,7 +38,7 @@ func CreateAuthID(cmdKey []byte, time int64) [16]byte { } func NewCipherFromKey(cmdKey []byte) cipher.Block { - aesBlock, err := aes.NewCipher(KDF16(cmdKey, KDFSaltConst_AuthIDEncryptionKey)) + aesBlock, err := aes.NewCipher(KDF16(cmdKey, KDFSaltConstAuthIDEncryptionKey)) if err != nil { panic(err) } @@ -88,10 +94,9 @@ func (a *AuthIDDecoderHolder) RemoveUser(key [16]byte) { delete(a.aidhi, string(key[:])) } -func (a *AuthIDDecoderHolder) Match(AuthID [16]byte) (interface{}, error) { +func (a *AuthIDDecoderHolder) Match(authID [16]byte) (interface{}, error) { for _, v := range a.aidhi { - - t, z, r, d := v.dec.Decode(AuthID) + t, z, r, d := v.dec.Decode(authID) if z != crc32.ChecksumIEEE(d[:12]) { continue } @@ -104,18 +109,13 @@ func (a *AuthIDDecoderHolder) Match(AuthID [16]byte) (interface{}, error) { continue } - if !a.apw.Check(AuthID[:]) { + if !a.apw.Check(authID[:]) { return nil, ErrReplay } _ = r return v.ticket, nil - } return nil, ErrNotFound } - -var ErrNotFound = errors.New("user do not exist") - -var ErrReplay = errors.New("replayed request") diff --git a/proxy/vmess/aead/authid_test.go b/proxy/vmess/aead/authid_test.go index c1f923c53..837d3372b 100644 --- a/proxy/vmess/aead/authid_test.go +++ b/proxy/vmess/aead/authid_test.go @@ -2,10 +2,11 @@ package aead import ( "fmt" - "github.com/stretchr/testify/assert" "strconv" "testing" "time" + + "github.com/stretchr/testify/assert" ) func TestCreateAuthID(t *testing.T) { @@ -57,7 +58,6 @@ func TestCreateAuthIDAndDecode2(t *testing.T) { res2, err2 := AuthDecoder.Match(authid2) assert.EqualError(t, err2, "user do not exist") assert.Nil(t, res2) - } func TestCreateAuthIDAndDecodeMassive(t *testing.T) { @@ -89,7 +89,6 @@ func TestCreateAuthIDAndDecodeMassive(t *testing.T) { res2, err2 := AuthDecoder.Match(authid3) assert.Equal(t, "Demo User", res2) assert.Nil(t, err2) - } func TestCreateAuthIDAndDecodeSuperMassive(t *testing.T) { @@ -125,5 +124,4 @@ func TestCreateAuthIDAndDecodeSuperMassive(t *testing.T) { assert.Nil(t, err2) fmt.Println(after.Sub(before).Seconds()) - } diff --git a/proxy/vmess/aead/consts.go b/proxy/vmess/aead/consts.go index 7a62fc53b..ef13977db 100644 --- a/proxy/vmess/aead/consts.go +++ b/proxy/vmess/aead/consts.go @@ -1,21 +1,14 @@ package aead -const KDFSaltConst_AuthIDEncryptionKey = "AES Auth ID Encryption" - -const KDFSaltConst_AEADRespHeaderLenKey = "AEAD Resp Header Len Key" - -const KDFSaltConst_AEADRespHeaderLenIV = "AEAD Resp Header Len IV" - -const KDFSaltConst_AEADRespHeaderPayloadKey = "AEAD Resp Header Key" - -const KDFSaltConst_AEADRespHeaderPayloadIV = "AEAD Resp Header IV" - -const KDFSaltConst_VMessAEADKDF = "VMess AEAD KDF" - -const KDFSaltConst_VMessHeaderPayloadAEADKey = "VMess Header AEAD Key" - -const KDFSaltConst_VMessHeaderPayloadAEADIV = "VMess Header AEAD Nonce" - -const KDFSaltConst_VMessHeaderPayloadLengthAEADKey = "VMess Header AEAD Key_Length" - -const KDFSaltConst_VMessHeaderPayloadLengthAEADIV = "VMess Header AEAD Nonce_Length" +const ( + KDFSaltConstAuthIDEncryptionKey = "AES Auth ID Encryption" + KDFSaltConstAEADRespHeaderLenKey = "AEAD Resp Header Len Key" + KDFSaltConstAEADRespHeaderLenIV = "AEAD Resp Header Len IV" + KDFSaltConstAEADRespHeaderPayloadKey = "AEAD Resp Header Key" + KDFSaltConstAEADRespHeaderPayloadIV = "AEAD Resp Header IV" + KDFSaltConstVMessAEADKDF = "VMess AEAD KDF" + KDFSaltConstVMessHeaderPayloadAEADKey = "VMess Header AEAD Key" + KDFSaltConstVMessHeaderPayloadAEADIV = "VMess Header AEAD Nonce" + KDFSaltConstVMessHeaderPayloadLengthAEADKey = "VMess Header AEAD Key_Length" + KDFSaltConstVMessHeaderPayloadLengthAEADIV = "VMess Header AEAD Nonce_Length" +) diff --git a/proxy/vmess/aead/encrypt.go b/proxy/vmess/aead/encrypt.go index d2d0b1dea..073a4ac2e 100644 --- a/proxy/vmess/aead/encrypt.go +++ b/proxy/vmess/aead/encrypt.go @@ -30,9 +30,9 @@ func SealVMessAEADHeader(key [16]byte, data []byte) []byte { var payloadHeaderLengthAEADEncrypted []byte { - payloadHeaderLengthAEADKey := KDF16(key[:], KDFSaltConst_VMessHeaderPayloadLengthAEADKey, string(generatedAuthID[:]), string(connectionNonce)) + payloadHeaderLengthAEADKey := KDF16(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADKey, string(generatedAuthID[:]), string(connectionNonce)) - payloadHeaderLengthAEADNonce := KDF(key[:], KDFSaltConst_VMessHeaderPayloadLengthAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12] + payloadHeaderLengthAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12] payloadHeaderLengthAEADAESBlock, err := aes.NewCipher(payloadHeaderLengthAEADKey) if err != nil { @@ -51,9 +51,9 @@ func SealVMessAEADHeader(key [16]byte, data []byte) []byte { var payloadHeaderAEADEncrypted []byte { - payloadHeaderAEADKey := KDF16(key[:], KDFSaltConst_VMessHeaderPayloadAEADKey, string(generatedAuthID[:]), string(connectionNonce)) + payloadHeaderAEADKey := KDF16(key[:], KDFSaltConstVMessHeaderPayloadAEADKey, string(generatedAuthID[:]), string(connectionNonce)) - payloadHeaderAEADNonce := KDF(key[:], KDFSaltConst_VMessHeaderPayloadAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12] + payloadHeaderAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12] payloadHeaderAEADAESBlock, err := aes.NewCipher(payloadHeaderAEADKey) if err != nil { @@ -71,18 +71,15 @@ func SealVMessAEADHeader(key [16]byte, data []byte) []byte { var outputBuffer = bytes.NewBuffer(nil) - common.Must2(outputBuffer.Write(generatedAuthID[:])) //16 - - common.Must2(outputBuffer.Write(payloadHeaderLengthAEADEncrypted)) //2+16 - - common.Must2(outputBuffer.Write(connectionNonce)) //8 - + common.Must2(outputBuffer.Write(generatedAuthID[:])) // 16 + common.Must2(outputBuffer.Write(payloadHeaderLengthAEADEncrypted)) // 2+16 + common.Must2(outputBuffer.Write(connectionNonce)) // 8 common.Must2(outputBuffer.Write(payloadHeaderAEADEncrypted)) return outputBuffer.Bytes() } -func OpenVMessAEADHeader(key [16]byte, authid [16]byte, data io.Reader) ([]byte, bool, error, int) { +func OpenVMessAEADHeader(key [16]byte, authid [16]byte, data io.Reader) ([]byte, bool, int, error) { var payloadHeaderLengthAEADEncrypted [18]byte var nonce [8]byte @@ -91,23 +88,23 @@ func OpenVMessAEADHeader(key [16]byte, authid [16]byte, data io.Reader) ([]byte, authidCheckValueReadBytesCounts, err := io.ReadFull(data, payloadHeaderLengthAEADEncrypted[:]) bytesRead += authidCheckValueReadBytesCounts if err != nil { - return nil, false, err, bytesRead + return nil, false, bytesRead, err } nonceReadBytesCounts, err := io.ReadFull(data, nonce[:]) bytesRead += nonceReadBytesCounts if err != nil { - return nil, false, err, bytesRead + return nil, false, bytesRead, err } - //Decrypt Length + // Decrypt Length var decryptedAEADHeaderLengthPayloadResult []byte { - payloadHeaderLengthAEADKey := KDF16(key[:], KDFSaltConst_VMessHeaderPayloadLengthAEADKey, string(authid[:]), string(nonce[:])) + payloadHeaderLengthAEADKey := KDF16(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADKey, string(authid[:]), string(nonce[:])) - payloadHeaderLengthAEADNonce := KDF(key[:], KDFSaltConst_VMessHeaderPayloadLengthAEADIV, string(authid[:]), string(nonce[:]))[:12] + payloadHeaderLengthAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADIV, string(authid[:]), string(nonce[:]))[:12] payloadHeaderAEADAESBlock, err := aes.NewCipher(payloadHeaderLengthAEADKey) if err != nil { @@ -123,7 +120,7 @@ func OpenVMessAEADHeader(key [16]byte, authid [16]byte, data io.Reader) ([]byte, decryptedAEADHeaderLengthPayload, erropenAEAD := payloadHeaderLengthAEAD.Open(nil, payloadHeaderLengthAEADNonce, payloadHeaderLengthAEADEncrypted[:], authid[:]) if erropenAEAD != nil { - return nil, true, erropenAEAD, bytesRead + return nil, true, bytesRead, erropenAEAD } decryptedAEADHeaderLengthPayloadResult = decryptedAEADHeaderLengthPayload @@ -131,24 +128,24 @@ func OpenVMessAEADHeader(key [16]byte, authid [16]byte, data io.Reader) ([]byte, var length uint16 - common.Must(binary.Read(bytes.NewReader(decryptedAEADHeaderLengthPayloadResult[:]), binary.BigEndian, &length)) + common.Must(binary.Read(bytes.NewReader(decryptedAEADHeaderLengthPayloadResult), binary.BigEndian, &length)) var decryptedAEADHeaderPayloadR []byte var payloadHeaderAEADEncryptedReadedBytesCounts int { - payloadHeaderAEADKey := KDF16(key[:], KDFSaltConst_VMessHeaderPayloadAEADKey, string(authid[:]), string(nonce[:])) + payloadHeaderAEADKey := KDF16(key[:], KDFSaltConstVMessHeaderPayloadAEADKey, string(authid[:]), string(nonce[:])) - payloadHeaderAEADNonce := KDF(key[:], KDFSaltConst_VMessHeaderPayloadAEADIV, string(authid[:]), string(nonce[:]))[:12] + payloadHeaderAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadAEADIV, string(authid[:]), string(nonce[:]))[:12] - //16 == AEAD Tag size + // 16 == AEAD Tag size payloadHeaderAEADEncrypted := make([]byte, length+16) payloadHeaderAEADEncryptedReadedBytesCounts, err = io.ReadFull(data, payloadHeaderAEADEncrypted) bytesRead += payloadHeaderAEADEncryptedReadedBytesCounts if err != nil { - return nil, false, err, bytesRead + return nil, false, bytesRead, err } payloadHeaderAEADAESBlock, err := aes.NewCipher(payloadHeaderAEADKey) @@ -165,11 +162,11 @@ func OpenVMessAEADHeader(key [16]byte, authid [16]byte, data io.Reader) ([]byte, decryptedAEADHeaderPayload, erropenAEAD := payloadHeaderAEAD.Open(nil, payloadHeaderAEADNonce, payloadHeaderAEADEncrypted, authid[:]) if erropenAEAD != nil { - return nil, true, erropenAEAD, bytesRead + return nil, true, bytesRead, erropenAEAD } decryptedAEADHeaderPayloadR = decryptedAEADHeaderPayload } - return decryptedAEADHeaderPayloadR, false, nil, bytesRead + return decryptedAEADHeaderPayloadR, false, bytesRead, nil } diff --git a/proxy/vmess/aead/encrypt_test.go b/proxy/vmess/aead/encrypt_test.go index 9e5f7af94..b18cfcce2 100644 --- a/proxy/vmess/aead/encrypt_test.go +++ b/proxy/vmess/aead/encrypt_test.go @@ -22,7 +22,7 @@ func TestOpenVMessAEADHeader(t *testing.T) { io.ReadFull(AEADR, authid[:]) - out, _, err, _ := OpenVMessAEADHeader(keyw, authid, AEADR) + out, _, _, err := OpenVMessAEADHeader(keyw, authid, AEADR) fmt.Println(string(out)) fmt.Println(err) @@ -41,7 +41,7 @@ func TestOpenVMessAEADHeader2(t *testing.T) { io.ReadFull(AEADR, authid[:]) - out, _, err, readen := OpenVMessAEADHeader(keyw, authid, AEADR) + out, _, readen, err := OpenVMessAEADHeader(keyw, authid, AEADR) assert.Equal(t, len(sealed)-16-AEADR.Len(), readen) assert.Equal(t, string(TestHeader), string(out)) assert.Nil(t, err) @@ -63,7 +63,7 @@ func TestOpenVMessAEADHeader4(t *testing.T) { io.ReadFull(AEADR, authid[:]) - out, drain, err, readen := OpenVMessAEADHeader(keyw, authid, AEADR) + out, drain, readen, err := OpenVMessAEADHeader(keyw, authid, AEADR) assert.Equal(t, len(sealed)-16-AEADR.Len(), readen) assert.Equal(t, true, drain) assert.NotNil(t, err) @@ -72,12 +72,10 @@ func TestOpenVMessAEADHeader4(t *testing.T) { } assert.Nil(t, out) } - } func TestOpenVMessAEADHeader4Massive(t *testing.T) { for j := 0; j < 1000; j++ { - for i := 0; i <= 60; i++ { TestHeader := []byte("Test Header") key := KDF16([]byte("Demo Key for Auth ID Test"), "Demo Path for Auth ID Test") @@ -93,7 +91,7 @@ func TestOpenVMessAEADHeader4Massive(t *testing.T) { io.ReadFull(AEADR, authid[:]) - out, drain, err, readen := OpenVMessAEADHeader(keyw, authid, AEADR) + out, drain, readen, err := OpenVMessAEADHeader(keyw, authid, AEADR) assert.Equal(t, len(sealed)-16-AEADR.Len(), readen) assert.Equal(t, true, drain) assert.NotNil(t, err) diff --git a/proxy/vmess/aead/kdf.go b/proxy/vmess/aead/kdf.go index 26b9540c3..ebcea0a30 100644 --- a/proxy/vmess/aead/kdf.go +++ b/proxy/vmess/aead/kdf.go @@ -7,9 +7,7 @@ import ( ) func KDF(key []byte, path ...string) []byte { - hmacf := hmac.New(func() hash.Hash { - return sha256.New() - }, []byte(KDFSaltConst_VMessAEADKDF)) + hmacf := hmac.New(sha256.New, []byte(KDFSaltConstVMessAEADKDF)) for _, v := range path { hmacf = hmac.New(func() hash.Hash { diff --git a/proxy/vmess/encoding/client.go b/proxy/vmess/encoding/client.go index 78945532d..564ba51e0 100644 --- a/proxy/vmess/encoding/client.go +++ b/proxy/vmess/encoding/client.go @@ -47,8 +47,7 @@ type ClientSession struct { } // NewClientSession creates a new ClientSession. -func NewClientSession(isAEAD bool, idHash protocol.IDHash, ctx context.Context) *ClientSession { - +func NewClientSession(ctx context.Context, isAEAD bool, idHash protocol.IDHash) *ClientSession { session := &ClientSession{ isAEAD: isAEAD, idHash: idHash, @@ -114,7 +113,7 @@ func (c *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writ if !c.isAEAD { iv := hashTimestamp(md5.New(), timestamp) - aesStream := crypto.NewAesEncryptionStream(account.ID.CmdKey(), iv[:]) + aesStream := crypto.NewAesEncryptionStream(account.ID.CmdKey(), iv) aesStream.XORKeyStream(buffer.Bytes(), buffer.Bytes()) common.Must2(writer.Write(buffer.Bytes())) } else { @@ -193,8 +192,8 @@ func (c *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.Respon aesStream := crypto.NewAesDecryptionStream(c.responseBodyKey[:], c.responseBodyIV[:]) c.responseReader = crypto.NewCryptionReader(aesStream, reader) } else { - aeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConst_AEADRespHeaderLenKey) - aeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConst_AEADRespHeaderLenIV)[:12] + aeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderLenKey) + aeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderLenIV)[:12] aeadResponseHeaderLengthEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderLengthEncryptionKey)).(cipher.Block) aeadResponseHeaderLengthEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderLengthEncryptionKeyAESBlock)).(cipher.AEAD) @@ -213,8 +212,8 @@ func (c *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.Respon decryptedResponseHeaderLength = int(decryptedResponseHeaderLengthBinaryDeserializeBuffer) } - aeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConst_AEADRespHeaderPayloadKey) - aeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConst_AEADRespHeaderPayloadIV)[:12] + aeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadKey) + aeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadIV)[:12] aeadResponseHeaderPayloadEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderPayloadEncryptionKey)).(cipher.Block) aeadResponseHeaderPayloadEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderPayloadEncryptionKeyAESBlock)).(cipher.AEAD) diff --git a/proxy/vmess/encoding/encoding_test.go b/proxy/vmess/encoding/encoding_test.go index c0f938b7d..5abcee9dc 100644 --- a/proxy/vmess/encoding/encoding_test.go +++ b/proxy/vmess/encoding/encoding_test.go @@ -43,7 +43,7 @@ func TestRequestSerialization(t *testing.T) { } buffer := buf.New() - client := NewClientSession(true, protocol.DefaultIDHash, context.TODO()) + client := NewClientSession(context.TODO(), true, protocol.DefaultIDHash) common.Must(client.EncodeRequestHeader(expectedRequest, buffer)) buffer2 := buf.New() @@ -93,7 +93,7 @@ func TestInvalidRequest(t *testing.T) { } buffer := buf.New() - client := NewClientSession(true, protocol.DefaultIDHash, context.TODO()) + client := NewClientSession(context.TODO(), true, protocol.DefaultIDHash) common.Must(client.EncodeRequestHeader(expectedRequest, buffer)) buffer2 := buf.New() @@ -134,7 +134,7 @@ func TestMuxRequest(t *testing.T) { } buffer := buf.New() - client := NewClientSession(true, protocol.DefaultIDHash, context.TODO()) + client := NewClientSession(context.TODO(), true, protocol.DefaultIDHash) common.Must(client.EncodeRequestHeader(expectedRequest, buffer)) buffer2 := buf.New() diff --git a/proxy/vmess/encoding/server.go b/proxy/vmess/encoding/server.go index 680f35ef9..6dbc2d696 100644 --- a/proxy/vmess/encoding/server.go +++ b/proxy/vmess/encoding/server.go @@ -26,7 +26,7 @@ import ( vmessaead "v2ray.com/core/proxy/vmess/aead" ) -type sessionId struct { +type sessionID struct { user [16]byte key [16]byte nonce [16]byte @@ -35,14 +35,14 @@ type sessionId struct { // SessionHistory keeps track of historical session ids, to prevent replay attacks. type SessionHistory struct { sync.RWMutex - cache map[sessionId]time.Time + cache map[sessionID]time.Time task *task.Periodic } // NewSessionHistory creates a new SessionHistory object. func NewSessionHistory() *SessionHistory { h := &SessionHistory{ - cache: make(map[sessionId]time.Time, 128), + cache: make(map[sessionID]time.Time, 128), } h.task = &task.Periodic{ Interval: time.Second * 30, @@ -56,7 +56,7 @@ func (h *SessionHistory) Close() error { return h.task.Close() } -func (h *SessionHistory) addIfNotExits(session sessionId) bool { +func (h *SessionHistory) addIfNotExits(session sessionID) bool { h.Lock() if expire, found := h.cache[session]; found && expire.After(time.Now()) { @@ -87,7 +87,7 @@ func (h *SessionHistory) removeExpiredEntries() error { } if len(h.cache) == 0 { - h.cache = make(map[sessionId]time.Time, 128) + h.cache = make(map[sessionID]time.Time, 128) } return nil @@ -141,7 +141,7 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request readSizeRemain := DrainSize drainConnection := func(e error) error { - //We read a deterministic generated length of data before closing the connection to offset padding read pattern + // We read a deterministic generated length of data before closing the connection to offset padding read pattern readSizeRemain -= int(buffer.Len()) if readSizeRemain > 0 { err := s.DrainConnN(reader, readSizeRemain) @@ -169,22 +169,24 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request var fixedSizeAuthID [16]byte copy(fixedSizeAuthID[:], buffer.Bytes()) - if foundAEAD { + switch { + case foundAEAD: vmessAccount = user.Account.(*vmess.MemoryAccount) var fixedSizeCmdKey [16]byte copy(fixedSizeCmdKey[:], vmessAccount.ID.CmdKey()) - aeadData, shouldDrain, errorReason, bytesRead := vmessaead.OpenVMessAEADHeader(fixedSizeCmdKey, fixedSizeAuthID, reader) + aeadData, shouldDrain, bytesRead, errorReason := vmessaead.OpenVMessAEADHeader(fixedSizeCmdKey, fixedSizeAuthID, reader) if errorReason != nil { if shouldDrain { readSizeRemain -= bytesRead return nil, drainConnection(newError("AEAD read failed").Base(errorReason)) } else { - return nil, drainConnection(newError("AEAD read failed, drain skiped").Base(errorReason)) + return nil, drainConnection(newError("AEAD read failed, drain skipped").Base(errorReason)) } } decryptor = bytes.NewReader(aeadData) s.isAEADRequest = true - } else if !s.isAEADForced && errorAEAD == vmessaead.ErrNotFound { + + case !s.isAEADForced && errorAEAD == vmessaead.ErrNotFound: userLegacy, timestamp, valid, userValidationError := s.userValidator.Get(buffer.Bytes()) if !valid || userValidationError != nil { return nil, drainConnection(newError("invalid user").Base(userValidationError)) @@ -193,9 +195,10 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request iv := hashTimestamp(md5.New(), timestamp) vmessAccount = userLegacy.Account.(*vmess.MemoryAccount) - aesStream := crypto.NewAesDecryptionStream(vmessAccount.ID.CmdKey(), iv[:]) + aesStream := crypto.NewAesDecryptionStream(vmessAccount.ID.CmdKey(), iv) decryptor = crypto.NewCryptionReader(aesStream, reader) - } else { + + default: return nil, drainConnection(newError("invalid user").Base(errorAEAD)) } @@ -212,7 +215,7 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request copy(s.requestBodyIV[:], buffer.BytesRange(1, 17)) // 16 bytes copy(s.requestBodyKey[:], buffer.BytesRange(17, 33)) // 16 bytes - var sid sessionId + var sid sessionID copy(sid.user[:], vmessAccount.ID.Bytes()) sid.key = s.requestBodyKey sid.nonce = s.requestBodyIV @@ -226,7 +229,6 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request } else { return nil, newError("duplicated session id, possibly under replay attack, but this is a AEAD request") } - } s.responseHeader = buffer.Byte(33) // 1 byte @@ -240,6 +242,7 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request case protocol.RequestCommandMux: request.Address = net.DomainAddress("v1.mux.cool") request.Port = 0 + case protocol.RequestCommandTCP, protocol.RequestCommandUDP: if addr, port, err := addrParser.ReadAddressPort(buffer, decryptor); err == nil { request.Address = addr @@ -283,12 +286,11 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request if burnErr != nil { Autherr = newError("invalid auth, can't taint legacy userHash").Base(burnErr) } - //It is possible that we are under attack described in https://github.com/v2ray/v2ray-core/issues/2523 + // It is possible that we are under attack described in https://github.com/v2ray/v2ray-core/issues/2523 return nil, drainConnection(Autherr) } else { return nil, newError("invalid auth, but this is a AEAD request") } - } if request.Address == nil { @@ -327,8 +329,8 @@ func (s *ServerSession) DecodeRequestBody(request *protocol.RequestHeader, reade } return crypto.NewAuthenticationReader(auth, sizeParser, reader, protocol.TransferTypePacket, padding) } - return buf.NewReader(reader) + case protocol.SecurityType_LEGACY: aesStream := crypto.NewAesDecryptionStream(s.requestBodyKey[:], s.requestBodyIV[:]) cryptionReader := crypto.NewCryptionReader(aesStream, reader) @@ -340,17 +342,17 @@ func (s *ServerSession) DecodeRequestBody(request *protocol.RequestHeader, reade } return crypto.NewAuthenticationReader(auth, sizeParser, cryptionReader, request.Command.TransferType(), padding) } - return buf.NewReader(cryptionReader) + case protocol.SecurityType_AES128_GCM: aead := crypto.NewAesGcm(s.requestBodyKey[:]) - auth := &crypto.AEADAuthenticator{ AEAD: aead, NonceGenerator: GenerateChunkNonce(s.requestBodyIV[:], uint32(aead.NonceSize())), AdditionalDataGenerator: crypto.GenerateEmptyBytes(), } return crypto.NewAuthenticationReader(auth, sizeParser, reader, request.Command.TransferType(), padding) + case protocol.SecurityType_CHACHA20_POLY1305: aead, _ := chacha20poly1305.New(GenerateChacha20Poly1305Key(s.requestBodyKey[:])) @@ -360,6 +362,7 @@ func (s *ServerSession) DecodeRequestBody(request *protocol.RequestHeader, reade AdditionalDataGenerator: crypto.GenerateEmptyBytes(), } return crypto.NewAuthenticationReader(auth, sizeParser, reader, request.Command.TransferType(), padding) + default: panic("Unknown security type.") } @@ -395,9 +398,8 @@ func (s *ServerSession) EncodeResponseHeader(header *protocol.ResponseHeader, wr } if s.isAEADRequest { - - aeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConst_AEADRespHeaderLenKey) - aeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConst_AEADRespHeaderLenIV)[:12] + aeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderLenKey) + aeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderLenIV)[:12] aeadResponseHeaderLengthEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderLengthEncryptionKey)).(cipher.Block) aeadResponseHeaderLengthEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderLengthEncryptionKeyAESBlock)).(cipher.AEAD) @@ -411,8 +413,8 @@ func (s *ServerSession) EncodeResponseHeader(header *protocol.ResponseHeader, wr AEADEncryptedLength := aeadResponseHeaderLengthEncryptionAEAD.Seal(nil, aeadResponseHeaderLengthEncryptionIV, aeadResponseHeaderLengthEncryptionBuffer.Bytes(), nil) common.Must2(io.Copy(writer, bytes.NewReader(AEADEncryptedLength))) - aeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConst_AEADRespHeaderPayloadKey) - aeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConst_AEADRespHeaderPayloadIV)[:12] + aeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadKey) + aeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadIV)[:12] aeadResponseHeaderPayloadEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderPayloadEncryptionKey)).(cipher.Block) aeadResponseHeaderPayloadEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderPayloadEncryptionKeyAESBlock)).(cipher.AEAD) @@ -447,8 +449,8 @@ func (s *ServerSession) EncodeResponseBody(request *protocol.RequestHeader, writ } return crypto.NewAuthenticationWriter(auth, sizeParser, writer, protocol.TransferTypePacket, padding) } - return buf.NewWriter(writer) + case protocol.SecurityType_LEGACY: if request.Option.Has(protocol.RequestOptionChunkStream) { auth := &crypto.AEADAuthenticator{ @@ -458,17 +460,17 @@ func (s *ServerSession) EncodeResponseBody(request *protocol.RequestHeader, writ } return crypto.NewAuthenticationWriter(auth, sizeParser, s.responseWriter, request.Command.TransferType(), padding) } - return &buf.SequentialWriter{Writer: s.responseWriter} + case protocol.SecurityType_AES128_GCM: aead := crypto.NewAesGcm(s.responseBodyKey[:]) - auth := &crypto.AEADAuthenticator{ AEAD: aead, NonceGenerator: GenerateChunkNonce(s.responseBodyIV[:], uint32(aead.NonceSize())), AdditionalDataGenerator: crypto.GenerateEmptyBytes(), } return crypto.NewAuthenticationWriter(auth, sizeParser, writer, request.Command.TransferType(), padding) + case protocol.SecurityType_CHACHA20_POLY1305: aead, _ := chacha20poly1305.New(GenerateChacha20Poly1305Key(s.responseBodyKey[:])) @@ -478,6 +480,7 @@ func (s *ServerSession) EncodeResponseBody(request *protocol.RequestHeader, writ AdditionalDataGenerator: crypto.GenerateEmptyBytes(), } return crypto.NewAuthenticationWriter(auth, sizeParser, writer, request.Command.TransferType(), padding) + default: panic("Unknown security type.") } diff --git a/proxy/vmess/outbound/outbound.go b/proxy/vmess/outbound/outbound.go index 852552397..bb31ad758 100644 --- a/proxy/vmess/outbound/outbound.go +++ b/proxy/vmess/outbound/outbound.go @@ -71,7 +71,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte if err != nil { return newError("failed to find an available destination").Base(err).AtWarning() } - defer conn.Close() //nolint: errcheck + defer conn.Close() outbound := session.OutboundFromContext(ctx) if outbound == nil || !outbound.Target.IsValid() { @@ -114,11 +114,11 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte output := link.Writer isAEAD := false - if !aead_disabled && len(account.AlterIDs) == 0 { + if !aeadDisabled && len(account.AlterIDs) == 0 { isAEAD = true } - session := encoding.NewClientSession(isAEAD, protocol.DefaultIDHash, ctx) + session := encoding.NewClientSession(ctx, isAEAD, protocol.DefaultIDHash) sessionPolicy := h.policyManager.ForLevel(request.User.Level) ctx, cancel := context.WithCancel(ctx) @@ -179,7 +179,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte var ( enablePadding = false - aead_disabled = false + aeadDisabled = false ) func shouldEnablePadding(s protocol.SecurityType) bool { @@ -198,8 +198,8 @@ func init() { enablePadding = true } - aeadDisabled := platform.NewEnvFlag("v2ray.vmess.aead.disabled").GetValue(func() string { return defaultFlagValue }) - if aeadDisabled == "true" { - aead_disabled = true + isAeadDisabled := platform.NewEnvFlag("v2ray.vmess.aead.disabled").GetValue(func() string { return defaultFlagValue }) + if isAeadDisabled == "true" { + aeadDisabled = true } } diff --git a/proxy/vmess/validator.go b/proxy/vmess/validator.go index e308255bf..512337448 100644 --- a/proxy/vmess/validator.go +++ b/proxy/vmess/validator.go @@ -5,7 +5,6 @@ package vmess import ( "crypto/hmac" "crypto/sha256" - "hash" "hash/crc64" "strings" "sync" @@ -142,7 +141,7 @@ func (v *TimedUserValidator) Add(u *protocol.MemoryUser) error { account := uu.user.Account.(*MemoryAccount) if !v.behaviorFused { - hashkdf := hmac.New(func() hash.Hash { return sha256.New() }, []byte("VMESSBSKDF")) + hashkdf := hmac.New(sha256.New, []byte("VMESSBSKDF")) hashkdf.Write(account.ID.Bytes()) v.behaviorSeed = crc64.Update(v.behaviorSeed, crc64.MakeTable(crc64.ECMA), hashkdf.Sum(nil)) } diff --git a/testing/scenarios/command_test.go b/testing/scenarios/command_test.go index 4f9ab9749..daf48244c 100644 --- a/testing/scenarios/command_test.go +++ b/testing/scenarios/command_test.go @@ -3,13 +3,13 @@ package scenarios import ( "context" "fmt" - "github.com/google/go-cmp/cmp/cmpopts" "io" "strings" "testing" "time" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "google.golang.org/grpc" "v2ray.com/core" diff --git a/testing/scenarios/common.go b/testing/scenarios/common.go index fe105922f..d3ba1e863 100644 --- a/testing/scenarios/common.go +++ b/testing/scenarios/common.go @@ -203,6 +203,5 @@ func testTCPConn2(conn net.Conn, payloadSize int, timeout time.Duration) func() } return nil - } } diff --git a/testing/scenarios/http_test.go b/testing/scenarios/http_test.go index 9516ca6ab..aca61c41f 100644 --- a/testing/scenarios/http_test.go +++ b/testing/scenarios/http_test.go @@ -2,6 +2,7 @@ package scenarios import ( "bytes" + "context" "crypto/rand" "io" "io/ioutil" @@ -136,7 +137,7 @@ func TestHttpError(t *testing.T) { } } -func TestHttpConnectMethod(t *testing.T) { +func TestHTTPConnectMethod(t *testing.T) { tcpServer := tcp.Server{ MsgProcessor: xor, } @@ -179,7 +180,9 @@ func TestHttpConnectMethod(t *testing.T) { payload := make([]byte, 1024*64) common.Must2(rand.Read(payload)) - req, err := http.NewRequest("Connect", "http://"+dest.NetAddr()+"/", bytes.NewReader(payload)) + + ctx := context.Background() + req, err := http.NewRequestWithContext(ctx, "Connect", "http://"+dest.NetAddr()+"/", bytes.NewReader(payload)) req.Header.Set("X-a", "b") req.Header.Set("X-b", "d") common.Must(err) @@ -334,7 +337,8 @@ func TestHttpBasicAuth(t *testing.T) { } { - req, err := http.NewRequest("GET", "http://127.0.0.1:"+httpServerPort.String(), nil) + ctx := context.Background() + req, err := http.NewRequestWithContext(ctx, "GET", "http://127.0.0.1:"+httpServerPort.String(), nil) common.Must(err) setProxyBasicAuth(req, "a", "c") @@ -346,7 +350,8 @@ func TestHttpBasicAuth(t *testing.T) { } { - req, err := http.NewRequest("GET", "http://127.0.0.1:"+httpServerPort.String(), nil) + ctx := context.Background() + req, err := http.NewRequestWithContext(ctx, "GET", "http://127.0.0.1:"+httpServerPort.String(), nil) common.Must(err) setProxyBasicAuth(req, "a", "b") diff --git a/testing/scenarios/shadowsocks_test.go b/testing/scenarios/shadowsocks_test.go index 368a67d47..322c2a3d3 100644 --- a/testing/scenarios/shadowsocks_test.go +++ b/testing/scenarios/shadowsocks_test.go @@ -226,7 +226,7 @@ func TestShadowsocksAES128UDP(t *testing.T) { payload := make([]byte, 1024) common.Must2(rand.Read(payload)) - nBytes, err := conn.Write([]byte(payload)) + nBytes, err := conn.Write(payload) if err != nil { return err } diff --git a/testing/scenarios/transport_test.go b/testing/scenarios/transport_test.go index 65ba87606..b61db43d1 100644 --- a/testing/scenarios/transport_test.go +++ b/testing/scenarios/transport_test.go @@ -31,7 +31,7 @@ import ( tcptransport "v2ray.com/core/transport/internet/tcp" ) -func TestHttpConnectionHeader(t *testing.T) { +func TestHTTPConnectionHeader(t *testing.T) { tcpServer := tcp.Server{ MsgProcessor: xor, } diff --git a/testing/servers/http/http.go b/testing/servers/http/http.go index 379da590e..8ba591a7f 100644 --- a/testing/servers/http/http.go +++ b/testing/servers/http/http.go @@ -32,7 +32,7 @@ func (s *Server) Start() (net.Destination, error) { Handler: s, } go s.server.ListenAndServe() - return net.TCPDestination(net.LocalHostIP, net.Port(s.Port)), nil + return net.TCPDestination(net.LocalHostIP, s.Port), nil } func (s *Server) Close() error { diff --git a/testing/servers/tcp/tcp.go b/testing/servers/tcp/tcp.go index 3e0d46db2..ef366f388 100644 --- a/testing/servers/tcp/tcp.go +++ b/testing/servers/tcp/tcp.go @@ -65,7 +65,7 @@ func (server *Server) handleConnection(conn net.Conn) { pReader, pWriter := pipe.New(pipe.WithoutSizeLimit()) err := task.Run(context.Background(), func() error { - defer pWriter.Close() // nolint: errcheck + defer pWriter.Close() for { b := buf.New() @@ -102,7 +102,7 @@ func (server *Server) handleConnection(conn net.Conn) { fmt.Println("failed to transfer data: ", err.Error()) } - conn.Close() // nolint: errcheck + conn.Close() } func (server *Server) Close() error { diff --git a/transport/internet/domainsocket/config.go b/transport/internet/domainsocket/config.go index 652162126..f51879476 100644 --- a/transport/internet/domainsocket/config.go +++ b/transport/internet/domainsocket/config.go @@ -22,9 +22,7 @@ func (c *Config) GetUnixAddr() (*net.UnixAddr, error) { if c.Abstract && c.Padding { raw := []byte(path) addr := make([]byte, sizeofSunPath) - for i, c := range raw { - addr[i] = c - } + copy(addr, raw) path = string(addr) } return &net.UnixAddr{ diff --git a/transport/internet/headers/http/config.go b/transport/internet/headers/http/config.go index 32a068eb8..0f4c2b172 100644 --- a/transport/internet/headers/http/config.go +++ b/transport/internet/headers/http/config.go @@ -18,7 +18,7 @@ func pickString(arr []string) string { } } -func (v *RequestConfig) PickUri() string { +func (v *RequestConfig) PickURI() string { return pickString(v.Uri) } diff --git a/transport/internet/headers/http/http.go b/transport/internet/headers/http/http.go index c12d5b035..f00e11b94 100644 --- a/transport/internet/headers/http/http.go +++ b/transport/internet/headers/http/http.go @@ -109,24 +109,23 @@ func (h *HeaderReader) Read(reader io.Reader) (*buf.Buffer, error) { return buffer, nil } - //Parse the request - + // Parse the request if req, err := readRequest(bufio.NewReader(bytes.NewReader(headerBuf.Bytes())), false); err != nil { return nil, err } else { h.req = req } - //Check req + // Check req path := h.req.URL.Path - hasThisUri := false + hasThisURI := false for _, u := range h.expectedHeader.Uri { if u == path { - hasThisUri = true + hasThisURI = true } } - if !hasThisUri { + if !hasThisURI { return nil, ErrHeaderMisMatch } @@ -158,7 +157,7 @@ func (w *HeaderWriter) Write(writer io.Writer) error { return err } -type HttpConn struct { +type Conn struct { net.Conn readBuffer *buf.Buffer @@ -167,12 +166,11 @@ type HttpConn struct { errorWriter Writer errorMismatchWriter Writer errorTooLongWriter Writer - - errReason error + errReason error } -func NewHttpConn(conn net.Conn, reader Reader, writer Writer, errorWriter Writer, errorMismatchWriter Writer, errorTooLongWriter Writer) *HttpConn { - return &HttpConn{ +func NewConn(conn net.Conn, reader Reader, writer Writer, errorWriter Writer, errorMismatchWriter Writer, errorTooLongWriter Writer) *Conn { + return &Conn{ Conn: conn, oneTimeReader: reader, oneTimeWriter: writer, @@ -182,7 +180,7 @@ func NewHttpConn(conn net.Conn, reader Reader, writer Writer, errorWriter Writer } } -func (c *HttpConn) Read(b []byte) (int, error) { +func (c *Conn) Read(b []byte) (int, error) { if c.oneTimeReader != nil { buffer, err := c.oneTimeReader.Read(c.Conn) if err != nil { @@ -206,7 +204,7 @@ func (c *HttpConn) Read(b []byte) (int, error) { } // Write implements io.Writer. -func (c *HttpConn) Write(b []byte) (int, error) { +func (c *Conn) Write(b []byte) (int, error) { if c.oneTimeWriter != nil { err := c.oneTimeWriter.Write(c.Conn) c.oneTimeWriter = nil @@ -219,18 +217,18 @@ func (c *HttpConn) Write(b []byte) (int, error) { } // Close implements net.Conn.Close(). -func (c *HttpConn) Close() error { +func (c *Conn) Close() error { if c.oneTimeWriter != nil && c.errorWriter != nil { // Connection is being closed but header wasn't sent. This means the client request // is probably not valid. Sending back a server error header in this case. - //Write response based on error reason - - if c.errReason == ErrHeaderMisMatch { + // Write response based on error reason + switch c.errReason { + case ErrHeaderMisMatch: c.errorMismatchWriter.Write(c.Conn) - } else if c.errReason == ErrHeaderToLong { + case ErrHeaderToLong: c.errorTooLongWriter.Write(c.Conn) - } else { + default: c.errorWriter.Write(c.Conn) } } @@ -259,14 +257,14 @@ func formResponseHeader(config *ResponseConfig) *HeaderWriter { } } -type HttpAuthenticator struct { +type Authenticator struct { config *Config } -func (a HttpAuthenticator) GetClientWriter() *HeaderWriter { +func (a Authenticator) GetClientWriter() *HeaderWriter { header := buf.New() config := a.config.Request - common.Must2(header.WriteString(strings.Join([]string{config.GetMethodValue(), config.PickUri(), config.GetFullVersion()}, " "))) + common.Must2(header.WriteString(strings.Join([]string{config.GetMethodValue(), config.PickURI(), config.GetFullVersion()}, " "))) common.Must2(header.WriteString(CRLF)) headers := config.PickHeaders() @@ -280,11 +278,11 @@ func (a HttpAuthenticator) GetClientWriter() *HeaderWriter { } } -func (a HttpAuthenticator) GetServerWriter() *HeaderWriter { +func (a Authenticator) GetServerWriter() *HeaderWriter { return formResponseHeader(a.config.Response) } -func (a HttpAuthenticator) Client(conn net.Conn) net.Conn { +func (a Authenticator) Client(conn net.Conn) net.Conn { if a.config.Request == nil && a.config.Response == nil { return conn } @@ -297,27 +295,27 @@ func (a HttpAuthenticator) Client(conn net.Conn) net.Conn { if a.config.Response != nil { writer = a.GetClientWriter() } - return NewHttpConn(conn, reader, writer, NoOpWriter{}, NoOpWriter{}, NoOpWriter{}) + return NewConn(conn, reader, writer, NoOpWriter{}, NoOpWriter{}, NoOpWriter{}) } -func (a HttpAuthenticator) Server(conn net.Conn) net.Conn { +func (a Authenticator) Server(conn net.Conn) net.Conn { if a.config.Request == nil && a.config.Response == nil { return conn } - return NewHttpConn(conn, new(HeaderReader).ExpectThisRequest(a.config.Request), a.GetServerWriter(), + return NewConn(conn, new(HeaderReader).ExpectThisRequest(a.config.Request), a.GetServerWriter(), formResponseHeader(resp400), formResponseHeader(resp404), formResponseHeader(resp400)) } -func NewHttpAuthenticator(ctx context.Context, config *Config) (HttpAuthenticator, error) { - return HttpAuthenticator{ +func NewAuthenticator(ctx context.Context, config *Config) (Authenticator, error) { + return Authenticator{ config: config, }, nil } func init() { common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { - return NewHttpAuthenticator(ctx, config.(*Config)) + return NewAuthenticator(ctx, config.(*Config)) })) } diff --git a/transport/internet/headers/http/http_test.go b/transport/internet/headers/http/http_test.go index 54fcaf664..95b180bfb 100644 --- a/transport/internet/headers/http/http_test.go +++ b/transport/internet/headers/http/http_test.go @@ -41,7 +41,7 @@ func TestReaderWriter(t *testing.T) { } func TestRequestHeader(t *testing.T) { - auth, err := NewHttpAuthenticator(context.Background(), &Config{ + auth, err := NewAuthenticator(context.Background(), &Config{ Request: &RequestConfig{ Uri: []string{"/"}, Header: []*Header{ @@ -66,7 +66,7 @@ func TestRequestHeader(t *testing.T) { func TestLongRequestHeader(t *testing.T) { payload := make([]byte, buf.Size+2) common.Must2(rand.Read(payload[:buf.Size-2])) - copy(payload[buf.Size-2:], []byte(ENDING)) + copy(payload[buf.Size-2:], ENDING) payload = append(payload, []byte("abcd")...) reader := HeaderReader{} @@ -84,7 +84,7 @@ func TestLongRequestHeader(t *testing.T) { } func TestConnection(t *testing.T) { - auth, err := NewHttpAuthenticator(context.Background(), &Config{ + auth, err := NewAuthenticator(context.Background(), &Config{ Request: &RequestConfig{ Method: &Method{Value: "Post"}, Uri: []string{"/testpath"}, @@ -157,7 +157,7 @@ func TestConnection(t *testing.T) { } func TestConnectionInvPath(t *testing.T) { - auth, err := NewHttpAuthenticator(context.Background(), &Config{ + auth, err := NewAuthenticator(context.Background(), &Config{ Request: &RequestConfig{ Method: &Method{Value: "Post"}, Uri: []string{"/testpath"}, @@ -184,7 +184,7 @@ func TestConnectionInvPath(t *testing.T) { }) common.Must(err) - authR, err := NewHttpAuthenticator(context.Background(), &Config{ + authR, err := NewAuthenticator(context.Background(), &Config{ Request: &RequestConfig{ Method: &Method{Value: "Post"}, Uri: []string{"/testpathErr"}, @@ -258,7 +258,7 @@ func TestConnectionInvPath(t *testing.T) { } func TestConnectionInvReq(t *testing.T) { - auth, err := NewHttpAuthenticator(context.Background(), &Config{ + auth, err := NewAuthenticator(context.Background(), &Config{ Request: &RequestConfig{ Method: &Method{Value: "Post"}, Uri: []string{"/testpath"}, diff --git a/transport/internet/headers/utp/utp.go b/transport/internet/headers/utp/utp.go index 0ed164ca9..e210cc3bd 100644 --- a/transport/internet/headers/utp/utp.go +++ b/transport/internet/headers/utp/utp.go @@ -11,7 +11,7 @@ import ( type UTP struct { header byte extension byte - connectionId uint16 + connectionID uint16 } func (*UTP) Size() int32 { @@ -20,7 +20,7 @@ func (*UTP) Size() int32 { // Serialize implements PacketHeader. func (u *UTP) Serialize(b []byte) { - binary.BigEndian.PutUint16(b, u.connectionId) + binary.BigEndian.PutUint16(b, u.connectionID) b[2] = u.header b[3] = u.extension } @@ -30,7 +30,7 @@ func New(ctx context.Context, config interface{}) (interface{}, error) { return &UTP{ header: 1, extension: 0, - connectionId: dice.RollUint16(), + connectionID: dice.RollUint16(), }, nil } diff --git a/transport/internet/http/dialer.go b/transport/internet/http/dialer.go index ffa727417..4a32b9fe3 100644 --- a/transport/internet/http/dialer.go +++ b/transport/internet/http/dialer.go @@ -23,7 +23,7 @@ var ( globalDialerAccess sync.Mutex ) -func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.Config) (*http.Client, error) { +func getHTTPClient(_ context.Context, dest net.Destination, tlsSettings *tls.Config) (*http.Client, error) { globalDialerAccess.Lock() defer globalDialerAccess.Unlock() diff --git a/transport/internet/kcp/config.go b/transport/internet/kcp/config.go index f60161858..3179e9c7e 100644 --- a/transport/internet/kcp/config.go +++ b/transport/internet/kcp/config.go @@ -4,6 +4,7 @@ package kcp import ( "crypto/cipher" + "v2ray.com/core/common" "v2ray.com/core/transport/internet" ) diff --git a/transport/internet/kcp/connection.go b/transport/internet/kcp/connection.go index e5227ecd5..b89e1da69 100644 --- a/transport/internet/kcp/connection.go +++ b/transport/internet/kcp/connection.go @@ -532,7 +532,7 @@ func (c *Connection) Terminate() { } newError("#", c.meta.Conversation, " terminating connection to ", c.RemoteAddr()).WriteToLog() - //v.SetState(StateTerminated) + // v.SetState(StateTerminated) c.dataInput.Signal() c.dataOutput.Signal() diff --git a/transport/internet/kcp/cryptreal.go b/transport/internet/kcp/cryptreal.go index 124ec4133..aca8e6fe6 100644 --- a/transport/internet/kcp/cryptreal.go +++ b/transport/internet/kcp/cryptreal.go @@ -4,6 +4,7 @@ import ( "crypto/aes" "crypto/cipher" "crypto/sha256" + "v2ray.com/core/common" ) diff --git a/transport/internet/kcp/dialer.go b/transport/internet/kcp/dialer.go index bc481ae3d..83050edc0 100644 --- a/transport/internet/kcp/dialer.go +++ b/transport/internet/kcp/dialer.go @@ -20,7 +20,7 @@ var ( globalConv = uint32(dice.RollUint16()) ) -func fetchInput(ctx context.Context, input io.Reader, reader PacketReader, conn *Connection) { +func fetchInput(_ context.Context, input io.Reader, reader PacketReader, conn *Connection) { cache := make(chan *buf.Buffer, 1024) go func() { for { diff --git a/transport/internet/kcp/io_test.go b/transport/internet/kcp/io_test.go index 68838fc81..9a4b6e2c1 100644 --- a/transport/internet/kcp/io_test.go +++ b/transport/internet/kcp/io_test.go @@ -33,5 +33,4 @@ func TestKCPPacketReader(t *testing.T) { t.Errorf("Expect some output, but got nil") } } - } diff --git a/transport/internet/quic/hub.go b/transport/internet/quic/hub.go index 372d96e8d..9e4947595 100644 --- a/transport/internet/quic/hub.go +++ b/transport/internet/quic/hub.go @@ -50,7 +50,6 @@ func (l *Listener) acceptStreams(session quic.Session) { l.addConn(conn) } - } func (l *Listener) keepAccepting() { diff --git a/transport/internet/tls/config.go b/transport/internet/tls/config.go index 32035c47a..2d55998b6 100644 --- a/transport/internet/tls/config.go +++ b/transport/internet/tls/config.go @@ -22,11 +22,14 @@ const exp8357 = "experiment:8357" // ParseCertificate converts a cert.Certificate to Certificate. func ParseCertificate(c *cert.Certificate) *Certificate { - certPEM, keyPEM := c.ToPEM() - return &Certificate{ - Certificate: certPEM, - Key: keyPEM, + if c != nil { + certPEM, keyPEM := c.ToPEM() + return &Certificate{ + Certificate: certPEM, + Key: keyPEM, + } } + return nil } func (c *Config) loadSelfCertPool() (*x509.CertPool, error) { @@ -173,6 +176,16 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config { newError("failed to load system root certificate").AtError().Base(err).WriteToLog() } + if c == nil { + return &tls.Config{ + ClientSessionCache: globalSessionCache, + RootCAs: root, + InsecureSkipVerify: false, + NextProtos: nil, + SessionTicketsDisabled: false, + } + } + config := &tls.Config{ ClientSessionCache: globalSessionCache, RootCAs: root, @@ -180,9 +193,6 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config { NextProtos: c.NextProtocol, SessionTicketsDisabled: c.DisableSessionResumption, } - if c == nil { - return config - } for _, opt := range opts { opt(config) diff --git a/transport/internet/udp/hub.go b/transport/internet/udp/hub.go index d1c7992cd..d9a00b1b9 100644 --- a/transport/internet/udp/hub.go +++ b/transport/internet/udp/hub.go @@ -119,7 +119,6 @@ func (h *Hub) start() { buffer.Release() payload.Payload = nil } - } } diff --git a/transport/internet/websocket/ws_test.go b/transport/internet/websocket/ws_test.go index db919b342..0cfb3697a 100644 --- a/transport/internet/websocket/ws_test.go +++ b/transport/internet/websocket/ws_test.go @@ -81,7 +81,7 @@ func TestDialWithRemoteAddr(t *testing.T) { var b [1024]byte _, err := c.Read(b[:]) - //common.Must(err) + // common.Must(err) if err != nil { return } diff --git a/transport/internet/xtls/config.go b/transport/internet/xtls/config.go index 580d1cead..0fc2708f6 100644 --- a/transport/internet/xtls/config.go +++ b/transport/internet/xtls/config.go @@ -20,11 +20,14 @@ var ( // ParseCertificate converts a cert.Certificate to Certificate. func ParseCertificate(c *cert.Certificate) *Certificate { - certPEM, keyPEM := c.ToPEM() - return &Certificate{ - Certificate: certPEM, - Key: keyPEM, + if c != nil { + certPEM, keyPEM := c.ToPEM() + return &Certificate{ + Certificate: certPEM, + Key: keyPEM, + } } + return nil } func (c *Config) loadSelfCertPool() (*x509.CertPool, error) { @@ -163,6 +166,16 @@ func (c *Config) GetXTLSConfig(opts ...Option) *xtls.Config { newError("failed to load system root certificate").AtError().Base(err).WriteToLog() } + if c == nil { + return &xtls.Config{ + ClientSessionCache: globalSessionCache, + RootCAs: root, + InsecureSkipVerify: false, + NextProtos: nil, + SessionTicketsDisabled: false, + } + } + config := &xtls.Config{ ClientSessionCache: globalSessionCache, RootCAs: root, @@ -170,9 +183,6 @@ func (c *Config) GetXTLSConfig(opts ...Option) *xtls.Config { NextProtos: c.NextProtocol, SessionTicketsDisabled: c.DisableSessionResumption, } - if c == nil { - return config - } for _, opt := range opts { opt(config) diff --git a/v2ray.go b/v2ray.go index b9e868d9a..0dfd8b5a5 100644 --- a/v2ray.go +++ b/v2ray.go @@ -161,7 +161,7 @@ func RequireFeatures(ctx context.Context, callback interface{}) error { func New(config *Config) (*Instance, error) { var server = &Instance{ctx: context.Background()} - err, done := initInstanceWithConfig(config, server) + done, err := initInstanceWithConfig(config, server) if done { return nil, err } @@ -169,10 +169,10 @@ func New(config *Config) (*Instance, error) { return server, nil } -func NewWithContext(config *Config, ctx context.Context) (*Instance, error) { +func NewWithContext(ctx context.Context, config *Config) (*Instance, error) { var server = &Instance{ctx: ctx} - err, done := initInstanceWithConfig(config, server) + done, err := initInstanceWithConfig(config, server) if done { return nil, err } @@ -180,26 +180,26 @@ func NewWithContext(config *Config, ctx context.Context) (*Instance, error) { return server, nil } -func initInstanceWithConfig(config *Config, server *Instance) (error, bool) { +func initInstanceWithConfig(config *Config, server *Instance) (bool, error) { if config.Transport != nil { features.PrintDeprecatedFeatureWarning("global transport settings") } if err := config.Transport.Apply(); err != nil { - return err, true + return true, err } for _, appSettings := range config.App { settings, err := appSettings.GetInstance() if err != nil { - return err, true + return true, err } obj, err := CreateObject(server, settings) if err != nil { - return err, true + return true, err } if feature, ok := obj.(features.Feature); ok { if err := server.AddFeature(feature); err != nil { - return err, true + return true, err } } } @@ -217,23 +217,23 @@ func initInstanceWithConfig(config *Config, server *Instance) (error, bool) { for _, f := range essentialFeatures { if server.GetFeature(f.Type) == nil { if err := server.AddFeature(f.Instance); err != nil { - return err, true + return true, err } } } if server.featureResolutions != nil { - return newError("not all dependency are resolved."), true + return true, newError("not all dependency are resolved.") } if err := addInboundHandlers(server, config.Inbound); err != nil { - return err, true + return true, err } if err := addOutboundHandlers(server, config.Outbound); err != nil { - return err, true + return true, err } - return nil, false + return false, nil } // Type implements common.HasType. diff --git a/v2ray_test.go b/v2ray_test.go index 8b93d5c5f..982f44ed5 100644 --- a/v2ray_test.go +++ b/v2ray_test.go @@ -38,7 +38,7 @@ func TestV2RayDependency(t *testing.T) { func TestV2RayClose(t *testing.T) { port := tcp.PickPort() - userId := uuid.New() + userID := uuid.New() config := &Config{ App: []*serial.TypedMessage{ serial.ToTypedMessage(&dispatcher.Config{}), @@ -70,7 +70,7 @@ func TestV2RayClose(t *testing.T) { User: []*protocol.User{ { Account: serial.ToTypedMessage(&vmess.Account{ - Id: userId.String(), + Id: userID.String(), }), }, },