Compare commits

...

30 Commits

Author SHA1 Message Date
RPRX
0203190a98 v1.1.5 2020-12-25 15:25:10 +00:00
RPRX
a78db47571 Adjust OCSP Stapling 2020-12-25 15:10:12 +00:00
RPRX
ffd8fd1d8a Adjust JSON & TOML & YAML 2020-12-25 18:53:17 +08:00
eMeab
3d7e86efba Add OCSP Stapling for TLS & XTLS (#92) 2020-12-25 08:01:20 +00:00
Arthur Morgan
6f25191822 Changes from v2ray-core (#93) 2020-12-24 19:45:35 +00:00
Monsoon
85619b5a29 Add YAML Support (#86) 2020-12-24 19:30:26 +00:00
秋のかえで
f073456ac0 Add TOML Support (#98) 2020-12-24 19:11:32 +00:00
RPRX
09f9d03fb6 Add Homebrew 2020-12-24 12:43:19 +00:00
RPRX
8f8f7dd66f Refactor: Shadowsocks & Trojan UDP FullCone NAT
https://t.me/projectXray/95704
2020-12-23 13:06:21 +00:00
RPRX
4140ed7ab0 v1.1.4 2020-12-18 13:12:41 +00:00
RPRX
f390047b37 Disable VMess drain when not pure connection 2020-12-18 12:45:47 +00:00
RPRX
ff9bb2d8df Optimize cipherSuites setting loader 2020-12-17 09:25:30 +00:00
RPRX
38faac5ffc Adjust config loader of TLS & XTLS 2020-12-16 15:59:04 +00:00
eMeab
88dfed931b Add cipherSuites setting for TLS & XTLS (#78) 2020-12-16 12:53:55 +00:00
Jim Han
19ce0e99a5 Config loader returns error instead of directly panic (#80) 2020-12-16 12:35:27 +00:00
Jim Han
fe445f8e1a Fix: HTTP dialer uses ctx instead of context.Background() (#79) 2020-12-16 11:52:45 +00:00
RPRX
6a5618bc54 Outbound Splice supports Inbound XTLS 2020-12-16 10:35:28 +00:00
RPRX
ed0e9b12dc Adjust ProtoBuf of TLS & XTLS 2020-12-16 08:50:18 +00:00
eMeab
dab978749c Add minVersion setting for TLS & XTLS (#77) 2020-12-16 05:20:24 +00:00
RPRX
45f44c401a Refactor: Optimize Memory Usage At Startup
https://github.com/XTLS/Xray-core/issues/68#issuecomment-745231528
2020-12-15 20:27:18 +08:00
RPRX
2e942e0303 Fix Trojan XTLS 2020-12-14 17:05:15 +08:00
RPRX
decb012f9d Add Qv2ray and Kitsunebi 2020-12-13 06:21:50 +00:00
RPRX
574446f942 Add Hello World and ShadowSocksR Plus+ 2020-12-13 05:55:38 +00:00
RPRX
d71fa16e64 v1.1.3 2020-12-11 09:32:13 +00:00
RPRX
f8faf3c8b8 Removal: confonly 2020-12-11 13:05:29 +08:00
RPRX
b4e84603a2 Add XTLS Splice to Trojan Outbound 2020-12-11 03:05:39 +00:00
RPRX
ee19bcc08c Add comments for additional code 2020-12-10 07:38:59 +00:00
JimhHan
9c0f0a0cd5 Fix: Code generator & API (#52) 2020-12-10 03:52:05 +00:00
RPRX
f1eb5e3d08 Refactor: Support TCP/IPv6 in REDIRECT mode
十分感谢 @badO1a5A90 @LGA1150 协助测试

https://github.com/XTLS/Xray-core/issues/48#issuecomment-741509789

https://github.com/v2ray/v2ray-core/issues/1309#issuecomment-447432696
2020-12-09 12:16:38 +00:00
RPRX
b3f3c5be81 Use runtime.Gosched() instead 2020-12-07 16:08:35 +00:00
152 changed files with 1390 additions and 706 deletions

View File

@@ -13,13 +13,16 @@
- [Xray-script](https://github.com/kirin10000/Xray-script)
- Docker
- [teddysun/xray](https://hub.docker.com/r/teddysun/xray)
- [charlieethan](https://github.com/users/charlieethan/packages/container/package/xray)
- Xray-docker
- One Click
- [ProxySU](https://github.com/proxysu/ProxySU)
- [v2ray-agent](https://github.com/mack-a/v2ray-agent)
- Magisk
- [Xray4Magisk](https://github.com/CerteKim/Xray4Magisk)
- [Xray_For_Magisk](https://github.com/E7KMbb/Xray_For_Magisk)
- Homebrew
- [Repository 0](https://github.com/N4FA/homebrew-xray)
- [Repository 1](https://github.com/xiruizhao/homebrew-xray)
## Usage
@@ -29,10 +32,14 @@
- OpenWrt
- [PassWall](https://github.com/xiaorouji/openwrt-passwall)
- [Hello World](https://github.com/jerrykuku/luci-app-vssr)
- [ShadowSocksR Plus+](https://github.com/fw876/helloworld)
- Windows
- [v2rayN](https://github.com/2dust/v2rayN)
- [Qv2ray](https://github.com/Qv2ray/Qv2ray)
- Android
- [v2rayNG](https://github.com/2dust/v2rayNG)
- [Kitsunebi](https://github.com/rurirei/Kitsunebi/tree/release_xtls)
- iOS / Mac
- [Shadowrocket](https://apps.apple.com/app/shadowrocket/id932747118)

View File

@@ -1,5 +1,3 @@
// +build !confonly
package commander
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@@ -1,5 +1,3 @@
// +build !confonly
package commander
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package commander
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dispatcher
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dispatcher
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dispatcher
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dispatcher
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dns
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dns
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dns
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dns
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dns
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dns
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dns
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package command
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
@@ -40,9 +38,15 @@ type service struct {
}
func (s *service) Register(server *grpc.Server) {
RegisterLoggerServiceServer(server, &LoggerServer{
ls := &LoggerServer{
V: s.v,
})
}
RegisterLoggerServiceServer(server, ls)
// For compatibility purposes
vCoreDesc := _LoggerService_serviceDesc
vCoreDesc.ServiceName = "v2ray.core.app.log.command.LoggerService"
server.RegisterService(&vCoreDesc, ls)
}
func init() {

View File

@@ -63,7 +63,6 @@ type UnsafeLoggerServiceServer interface {
func RegisterLoggerServiceServer(s grpc.ServiceRegistrar, srv LoggerServiceServer) {
s.RegisterService(&_LoggerService_serviceDesc, srv)
s.RegisterService(&_LoggerService_serviceDesc2, srv)
}
func _LoggerService_RestartLogger_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
@@ -96,16 +95,3 @@ var _LoggerService_serviceDesc = grpc.ServiceDesc{
Streams: []grpc.StreamDesc{},
Metadata: "app/log/command/config.proto",
}
var _LoggerService_serviceDesc2 = grpc.ServiceDesc{
ServiceName: "v2ray.core.app.log.command.LoggerService",
HandlerType: (*LoggerServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "RestartLogger",
Handler: _LoggerService_RestartLogger_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "app/log/command/config.proto",
}

View File

@@ -1,5 +1,3 @@
// +build !confonly
package log
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@@ -1,5 +1,3 @@
// +build !confonly
package log
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package command
import (
@@ -140,6 +138,11 @@ func (s *service) Register(server *grpc.Server) {
hs.ohm = om
}))
RegisterHandlerServiceServer(server, hs)
// For compatibility purposes
vCoreDesc := _HandlerService_serviceDesc
vCoreDesc.ServiceName = "v2ray.core.app.proxyman.command.HandlerService"
server.RegisterService(&vCoreDesc, hs)
}
func init() {

View File

@@ -133,7 +133,6 @@ type UnsafeHandlerServiceServer interface {
func RegisterHandlerServiceServer(s grpc.ServiceRegistrar, srv HandlerServiceServer) {
s.RegisterService(&_HandlerService_serviceDesc, srv)
s.RegisterService(&_HandlerService_serviceDesc2, srv)
}
func _HandlerService_AddInbound_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
@@ -276,36 +275,3 @@ var _HandlerService_serviceDesc = grpc.ServiceDesc{
Streams: []grpc.StreamDesc{},
Metadata: "app/proxyman/command/command.proto",
}
var _HandlerService_serviceDesc2 = grpc.ServiceDesc{
ServiceName: "v2ray.core.app.proxyman.command.HandlerService",
HandlerType: (*HandlerServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "AddInbound",
Handler: _HandlerService_AddInbound_Handler,
},
{
MethodName: "RemoveInbound",
Handler: _HandlerService_RemoveInbound_Handler,
},
{
MethodName: "AlterInbound",
Handler: _HandlerService_AlterInbound_Handler,
},
{
MethodName: "AddOutbound",
Handler: _HandlerService_AddOutbound_Handler,
},
{
MethodName: "RemoveOutbound",
Handler: _HandlerService_RemoveOutbound_Handler,
},
{
MethodName: "AlterOutbound",
Handler: _HandlerService_AlterOutbound_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "app/proxyman/command/command.proto",
}

View File

@@ -1,5 +1,3 @@
// +build !confonly
package reverse
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package reverse
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package reverse
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package reverse
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@@ -1,5 +1,3 @@
// +build !confonly
package router
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package command
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
@@ -83,7 +81,13 @@ type service struct {
func (s *service) Register(server *grpc.Server) {
common.Must(s.v.RequireFeatures(func(router routing.Router, stats stats.Manager) {
RegisterRoutingServiceServer(server, NewRoutingServer(router, nil))
rs := NewRoutingServer(router, nil)
RegisterRoutingServiceServer(server, rs)
// For compatibility purposes
vCoreDesc := _RoutingService_serviceDesc
vCoreDesc.ServiceName = "v2ray.core.app.router.command.RoutingService"
server.RegisterService(&vCoreDesc, rs)
}))
}

View File

@@ -100,7 +100,6 @@ type UnsafeRoutingServiceServer interface {
func RegisterRoutingServiceServer(s grpc.ServiceRegistrar, srv RoutingServiceServer) {
s.RegisterService(&_RoutingService_serviceDesc, srv)
s.RegisterService(&_RoutingService_serviceDesc2, srv)
}
func _RoutingService_SubscribeRoutingStats_Handler(srv interface{}, stream grpc.ServerStream) error {
@@ -160,22 +159,3 @@ var _RoutingService_serviceDesc = grpc.ServiceDesc{
},
Metadata: "app/router/command/command.proto",
}
var _RoutingService_serviceDesc2 = grpc.ServiceDesc{
ServiceName: "v2ray.core.app.router.command.RoutingService",
HandlerType: (*RoutingServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "TestRoute",
Handler: _RoutingService_TestRoute_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "SubscribeRoutingStats",
Handler: _RoutingService_SubscribeRoutingStats_Handler,
ServerStreams: true,
},
},
Metadata: "app/router/command/command.proto",
}

View File

@@ -1,5 +1,3 @@
// +build !confonly
package router
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package router
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package router
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package router
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@@ -1,5 +1,3 @@
// +build !confonly
package stats
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package command
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
@@ -111,7 +109,13 @@ type service struct {
}
func (s *service) Register(server *grpc.Server) {
RegisterStatsServiceServer(server, NewStatsServer(s.statsManager))
ss := NewStatsServer(s.statsManager)
RegisterStatsServiceServer(server, ss)
// For compatibility purposes
vCoreDesc := _StatsService_serviceDesc
vCoreDesc.ServiceName = "v2ray.core.app.stats.command.StatsService"
server.RegisterService(&vCoreDesc, ss)
}
func init() {

View File

@@ -91,7 +91,6 @@ type UnsafeStatsServiceServer interface {
func RegisterStatsServiceServer(s grpc.ServiceRegistrar, srv StatsServiceServer) {
s.RegisterService(&_StatsService_serviceDesc, srv)
s.RegisterService(&_StatsService_serviceDesc2, srv)
}
func _StatsService_GetStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
@@ -168,24 +167,3 @@ var _StatsService_serviceDesc = grpc.ServiceDesc{
Streams: []grpc.StreamDesc{},
Metadata: "app/stats/command/command.proto",
}
var _StatsService_serviceDesc2 = grpc.ServiceDesc{
ServiceName: "v2ray.core.app.stats.command.StatsService",
HandlerType: (*StatsServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetStats",
Handler: _StatsService_GetStats_Handler,
},
{
MethodName: "QueryStats",
Handler: _StatsService_QueryStats_Handler,
},
{
MethodName: "GetSysStats",
Handler: _StatsService_GetSysStats_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "app/stats/command/command.proto",
}

View File

@@ -1,5 +1,3 @@
// +build !confonly
package stats
import "sync/atomic"

View File

@@ -1,5 +1,3 @@
// +build !confonly
package stats
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@@ -2,6 +2,7 @@ package buf
import (
"io"
"net"
"github.com/xtls/xray-core/common/bytespool"
)
@@ -20,6 +21,7 @@ type Buffer struct {
v []byte
start int32
end int32
UDP *net.UDPAddr
}
// New creates a Buffer with 0 length and 2K capacity.

View File

@@ -36,19 +36,23 @@ func (m *AccessMessage) String() string {
builder.WriteString(string(m.Status))
builder.WriteByte(' ')
builder.WriteString(serial.ToString(m.To))
builder.WriteByte(' ')
if len(m.Detour) > 0 {
builder.WriteByte('[')
builder.WriteString(" [")
builder.WriteString(m.Detour)
builder.WriteString("] ")
builder.WriteByte(']')
}
if reason := serial.ToString(m.Reason); len(reason) > 0 {
builder.WriteString(" ")
builder.WriteString(reason)
}
builder.WriteString(serial.ToString(m.Reason))
if len(m.Email) > 0 {
builder.WriteString("email:")
builder.WriteString(" email: ")
builder.WriteString(m.Email)
builder.WriteByte(' ')
}
return builder.String()
}

View File

@@ -1,5 +1,3 @@
// +build !confonly
package net
import (

View File

@@ -1,4 +1,4 @@
package jsonem
package ocsp
import "github.com/xtls/xray-core/common/errors"

136
common/ocsp/ocsp.go Normal file
View File

@@ -0,0 +1,136 @@
package ocsp
import (
"bytes"
"crypto/x509"
"encoding/pem"
"io/ioutil"
"net/http"
"os"
"golang.org/x/crypto/ocsp"
"github.com/xtls/xray-core/common/platform/filesystem"
)
func GetOCSPForFile(path string) ([]byte, error) {
return filesystem.ReadFile(path)
}
func CheckOCSPFileIsNotExist(path string) bool {
_, err := os.Stat(path)
if err != nil {
return os.IsNotExist(err)
}
return false
}
func GetOCSPStapling(cert [][]byte, path string) ([]byte, error) {
ocspData, err := GetOCSPForFile(path)
if err != nil {
ocspData, err = GetOCSPForCert(cert)
if !CheckOCSPFileIsNotExist(path) {
err = os.Remove(path)
if err != nil {
return nil, err
}
}
newFile, err := os.Create(path)
if err != nil {
return nil, err
}
newFile.Write(ocspData)
defer newFile.Close()
}
return ocspData, nil
}
func GetOCSPForCert(cert [][]byte) ([]byte, error) {
bundle := new(bytes.Buffer)
for _, derBytes := range cert {
err := pem.Encode(bundle, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
if err != nil {
return nil, err
}
}
pemBundle := bundle.Bytes()
certificates, err := parsePEMBundle(pemBundle)
if err != nil {
return nil, err
}
issuedCert := certificates[0]
if len(issuedCert.OCSPServer) == 0 {
return nil, newError("no OCSP server specified in cert")
}
if len(certificates) == 1 {
if len(issuedCert.IssuingCertificateURL) == 0 {
return nil, newError("no issuing certificate URL")
}
resp, errC := http.Get(issuedCert.IssuingCertificateURL[0])
if errC != nil {
return nil, newError("no issuing certificate URL")
}
defer resp.Body.Close()
issuerBytes, errC := ioutil.ReadAll(resp.Body)
if errC != nil {
return nil, newError(errC)
}
issuerCert, errC := x509.ParseCertificate(issuerBytes)
if errC != nil {
return nil, newError(errC)
}
certificates = append(certificates, issuerCert)
}
issuerCert := certificates[1]
ocspReq, err := ocsp.CreateRequest(issuedCert, issuerCert, nil)
if err != nil {
return nil, err
}
reader := bytes.NewReader(ocspReq)
req, err := http.Post(issuedCert.OCSPServer[0], "application/ocsp-request", reader)
if err != nil {
return nil, newError(err)
}
defer req.Body.Close()
ocspResBytes, err := ioutil.ReadAll(req.Body)
if err != nil {
return nil, newError(err)
}
return ocspResBytes, nil
}
// parsePEMBundle parses a certificate bundle from top to bottom and returns
// a slice of x509 certificates. This function will error if no certificates are found.
func parsePEMBundle(bundle []byte) ([]*x509.Certificate, error) {
var certificates []*x509.Certificate
var certDERBlock *pem.Block
for {
certDERBlock, bundle = pem.Decode(bundle)
if certDERBlock == nil {
break
}
if certDERBlock.Type == "CERTIFICATE" {
cert, err := x509.ParseCertificate(certDERBlock.Bytes)
if err != nil {
return nil, err
}
certificates = append(certificates, cert)
}
}
if len(certificates) == 0 {
return nil, newError("no certificates were found while parsing the bundle")
}
return certificates, nil
}

View File

@@ -8,7 +8,7 @@ import (
// ToString serialize an arbitrary value into string.
func ToString(v interface{}) string {
if v == nil {
return " "
return ""
}
switch value := v.(type) {

View File

@@ -1,5 +1,3 @@
// +build !confonly
package core
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package core
import (

View File

@@ -18,7 +18,7 @@ import (
)
var (
version = "1.1.2"
version = "1.1.5"
build = "Custom"
codename = "Xray, Penetrates Everything."
intro = "A unified platform for anti-censorship."

View File

@@ -1,5 +1,3 @@
// +build !confonly
package core
import (

View File

@@ -1,8 +1,8 @@
package core
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination testing/mocks/io.go -mock_names Reader=Reader,Writer=Writer io Reader,Writer
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination testing/mocks/log.go -mock_names Handler=LogHandler github.com/xtls/xray-core/common/log Handler
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination testing/mocks/mux.go -mock_names ClientWorkerFactory=MuxClientWorkerFactory github.com/xtls/xray-core/common/mux ClientWorkerFactory
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination testing/mocks/dns.go -mock_names Client=DNSClient github.com/xtls/xray-core/features/dns Client
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination testing/mocks/outbound.go -mock_names Manager=OutboundManager,HandlerSelector=OutboundHandlerSelector github.com/xtls/xray-core/features/outbound Manager,HandlerSelector
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination testing/mocks/proxy.go -mock_names Inbound=ProxyInbound,Outbound=ProxyOutbound github.com/xtls/xray-core/proxy Inbound,Outbound
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination ../testing/mocks/io.go -mock_names Reader=Reader,Writer=Writer io Reader,Writer
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination ../testing/mocks/log.go -mock_names Handler=LogHandler github.com/xtls/xray-core/common/log Handler
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination ../testing/mocks/mux.go -mock_names ClientWorkerFactory=MuxClientWorkerFactory github.com/xtls/xray-core/common/mux ClientWorkerFactory
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination ../testing/mocks/dns.go -mock_names Client=DNSClient github.com/xtls/xray-core/features/dns Client
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination ../testing/mocks/outbound.go -mock_names Manager=OutboundManager,HandlerSelector=OutboundHandlerSelector github.com/xtls/xray-core/features/outbound Manager,HandlerSelector
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination ../testing/mocks/proxy.go -mock_names Inbound=ProxyInbound,Outbound=ProxyOutbound github.com/xtls/xray-core/proxy Inbound,Outbound

View File

@@ -4,8 +4,9 @@ import "path/filepath"
//go:generate go install -v google.golang.org/protobuf/cmd/protoc-gen-go
//go:generate go install -v google.golang.org/grpc/cmd/protoc-gen-go-grpc
//go:generate go get -v -u github.com/gogo/protobuf/protoc-gen-gofast
//go:generate go install -v github.com/gogo/protobuf/protoc-gen-gofast
//go:generate go run ../infra/vprotogen/main.go
//go:generate go run ../infra/vprotogen/main.go -pwd ./..
// ProtoFilesUsingProtocGenGoFast is the map of Proto files
// that use `protoc-gen-gofast` to generate pb.go files

View File

@@ -1,5 +1,3 @@
// +build !confonly
package core
import (

19
go.mod
View File

@@ -3,23 +3,24 @@ module github.com/xtls/xray-core
go 1.15
require (
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 // indirect
github.com/BurntSushi/toml v0.3.1
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
github.com/golang/mock v1.4.4
github.com/golang/protobuf v1.4.3
github.com/google/go-cmp v0.5.4
github.com/gorilla/websocket v1.4.2
github.com/lucas-clemente/quic-go v0.19.3
github.com/miekg/dns v1.1.35
github.com/pires/go-proxyproto v0.3.2
github.com/seiflotfy/cuckoofilter v0.0.0-20201009151232-afb285a456ab
github.com/pires/go-proxyproto v0.3.3
github.com/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c
github.com/stretchr/testify v1.6.1
github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499
go.starlark.net v0.0.0-20201204201740-42d4f566359b
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
golang.org/x/sys v0.0.0-20201204225414-ed752295db88
go.starlark.net v0.0.0-20201210151846-e81fc95f7bd5
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/net v0.0.0-20201224014010-6772e930b67b
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
golang.org/x/sys v0.0.0-20201223074533-0d417f636930
google.golang.org/grpc v1.34.0
google.golang.org/protobuf v1.25.0
h12.io/socks v1.0.1
h12.io/socks v1.0.2
)

57
go.sum
View File

@@ -7,6 +7,7 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -22,6 +23,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 h1:BS21ZUJ/B5X2UVUbczfmdWH7GapPWAhxcMsDnjJTU1E=
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
@@ -33,8 +35,11 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew=
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -45,6 +50,7 @@ github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200j
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -64,6 +70,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
@@ -77,42 +84,52 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364 h1:5XxdakFhqd9dnXoAZy1Mb2R/DZ6D1e+0bGC/JhucGYI=
github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364/go.mod h1:eDJQioIyy4Yn3MVivT7rv/39gAJTrA7lgmYr8EW950c=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4=
github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
github.com/marten-seemann/qtls v0.10.0 h1:ECsuYUKalRL240rRD4Ri33ISb7kAQ3qGDlrrl55b2pc=
github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs=
github.com/marten-seemann/qtls-go1-15 v0.1.1 h1:LIH6K34bPVttyXnUWixk0bzH6/N07VxbSabxn5A5gZQ=
github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/miekg/dns v1.1.35 h1:oTfOaDH+mZkdcgdIjH6yBajRGtIwcwcaR+rt23ZSrJs=
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/pires/go-proxyproto v0.3.2 h1:E5ig1h9SFGne7IWVY6yRu3UCzyAFkQIukXHMkdFUOCA=
github.com/pires/go-proxyproto v0.3.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
github.com/pires/go-proxyproto v0.3.3 h1:jOXGrsAfSQVFiD1hWg1aiHpLYsd6SJw/8cLN594sB7Q=
github.com/pires/go-proxyproto v0.3.3/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@@ -120,8 +137,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/seiflotfy/cuckoofilter v0.0.0-20201009151232-afb285a456ab h1:O43uBnD2Y6fo1oFsXY+Vqp1n3RFfxg1u3XATDGvUXgI=
github.com/seiflotfy/cuckoofilter v0.0.0-20201009151232-afb285a456ab/go.mod h1:ET5mVvNjwaGXRgZxO9UZr7X+8eAf87AfIYNwRSp9s4Y=
github.com/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c h1:pqy40B3MQWYrza7YZXOXgl0Nf0QGFqrOC0BKae1UNAA=
github.com/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
@@ -151,6 +168,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
@@ -159,8 +177,8 @@ github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499 h1:QHESTXtfgc1ABV+ArlbPVqU
github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499/go.mod h1:5TB2+k58gx4A4g2Nf5miSHNDF6CuAzHKpWBooLAshTs=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.starlark.net v0.0.0-20201204201740-42d4f566359b h1:yHUzJ1WfcdR1oOafytJ6K1/ntYwnEIXICNVzHb+FzbA=
go.starlark.net v0.0.0-20201204201740-42d4f566359b/go.mod h1:5YFcFnRptTN+41758c2bMPiqpGg4zBfYji1IQz8wNFk=
go.starlark.net v0.0.0-20201210151846-e81fc95f7bd5 h1:F1LaLz0cvAJWMa5r3bogEYXD7/5fgA9a9jOX4DAobN8=
go.starlark.net v0.0.0-20201210151846-e81fc95f7bd5/go.mod h1:vxxlMsgCAPH7BR2LtxjJC4WhhZhCGd/b01+CIpj8H4k=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -169,8 +187,8 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c h1:9HhBz5L/UjnK9XLtiZhYAdue5BVKep3PMmS2LuPDt8k=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -191,8 +209,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -204,7 +222,8 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -221,10 +240,11 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201223074533-0d417f636930 h1:vRgIt+nup/B/BwIS0g2oC0haq0iqbV3ZA+u6+0TlNCo=
golang.org/x/sys v0.0.0-20201223074533-0d417f636930/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -243,6 +263,7 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
@@ -281,17 +302,23 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
h12.io/socks v1.0.1/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck=
h12.io/socks v1.0.2 h1:cZhhbV8+DE0Y1kotwhr1a3RC3kFO7AtuZ4GLr3qKSc8=
h12.io/socks v1.0.2/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@@ -84,7 +84,7 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) {
geoipList, err := toCidrList(c.ExpectIPs)
if err != nil {
return nil, newError("invalid ip rule: ", c.ExpectIPs).Base(err)
return nil, newError("invalid IP rule: ", c.ExpectIPs).Base(err)
}
return &dns.NameServer{
@@ -142,7 +142,7 @@ func (c *DNSConfig) Build() (*dns.Config, error) {
for _, server := range c.Servers {
ns, err := server.Build()
if err != nil {
return nil, newError("failed to build name server").Base(err)
return nil, newError("failed to build nameserver").Base(err)
}
config.NameServer = append(config.NameServer, ns)
}
@@ -159,15 +159,23 @@ func (c *DNSConfig) Build() (*dns.Config, error) {
var mappings []*dns.Config_HostMapping
switch {
case strings.HasPrefix(domain, "domain:"):
domainName := domain[7:]
if len(domainName) == 0 {
return nil, newError("empty domain type of rule: ", domain)
}
mapping := getHostMapping(addr)
mapping.Type = dns.DomainMatchingType_Subdomain
mapping.Domain = domain[7:]
mapping.Domain = domainName
mappings = append(mappings, mapping)
case strings.HasPrefix(domain, "geosite:"):
domains, err := loadGeositeWithAttr("geosite.dat", strings.ToUpper(domain[8:]))
listName := domain[8:]
if len(listName) == 0 {
return nil, newError("empty geosite rule: ", domain)
}
domains, err := loadGeositeWithAttr("geosite.dat", listName)
if err != nil {
return nil, newError("invalid geosite settings: ", domain).Base(err)
return nil, newError("failed to load geosite: ", listName).Base(err)
}
for _, d := range domains {
mapping := getHostMapping(addr)
@@ -177,21 +185,33 @@ func (c *DNSConfig) Build() (*dns.Config, error) {
}
case strings.HasPrefix(domain, "regexp:"):
regexpVal := domain[7:]
if len(regexpVal) == 0 {
return nil, newError("empty regexp type of rule: ", domain)
}
mapping := getHostMapping(addr)
mapping.Type = dns.DomainMatchingType_Regex
mapping.Domain = domain[7:]
mapping.Domain = regexpVal
mappings = append(mappings, mapping)
case strings.HasPrefix(domain, "keyword:"):
keywordVal := domain[8:]
if len(keywordVal) == 0 {
return nil, newError("empty keyword type of rule: ", domain)
}
mapping := getHostMapping(addr)
mapping.Type = dns.DomainMatchingType_Keyword
mapping.Domain = domain[8:]
mapping.Domain = keywordVal
mappings = append(mappings, mapping)
case strings.HasPrefix(domain, "full:"):
fullVal := domain[5:]
if len(fullVal) == 0 {
return nil, newError("empty full domain type of rule: ", domain)
}
mapping := getHostMapping(addr)
mapping.Type = dns.DomainMatchingType_Full
mapping.Domain = domain[5:]
mapping.Domain = fullVal
mappings = append(mappings, mapping)
case strings.HasPrefix(domain, "dotless:"):
@@ -213,10 +233,10 @@ func (c *DNSConfig) Build() (*dns.Config, error) {
return nil, newError("invalid external resource: ", domain)
}
filename := kv[0]
country := kv[1]
domains, err := loadGeositeWithAttr(filename, country)
list := kv[1]
domains, err := loadGeositeWithAttr(filename, list)
if err != nil {
return nil, newError("failed to load domains: ", country, " from ", filename).Base(err)
return nil, newError("failed to load domain list: ", list, " from ", filename).Base(err)
}
for _, d := range domains {
mapping := getHostMapping(addr)

View File

@@ -2,6 +2,7 @@ package conf
import (
"encoding/json"
"runtime"
"strconv"
"strings"
@@ -147,46 +148,109 @@ func ParseIP(s string) (*router.CIDR, error) {
}
}
func loadGeoIP(country string) ([]*router.CIDR, error) {
return loadIP("geoip.dat", country)
func loadGeoIP(code string) ([]*router.CIDR, error) {
return loadIP("geoip.dat", code)
}
func loadIP(filename, country string) ([]*router.CIDR, error) {
geoipBytes, err := filesystem.ReadAsset(filename)
var (
FileCache = make(map[string][]byte)
IPCache = make(map[string]*router.GeoIP)
SiteCache = make(map[string]*router.GeoSite)
)
func loadFile(file string) ([]byte, error) {
if FileCache[file] == nil {
bs, err := filesystem.ReadAsset(file)
if err != nil {
return nil, newError("failed to open file: ", filename).Base(err)
return nil, newError("failed to open file: ", file).Base(err)
}
var geoipList router.GeoIPList
if err := proto.Unmarshal(geoipBytes, &geoipList); err != nil {
return nil, err
if len(bs) == 0 {
return nil, newError("empty file: ", file)
}
for _, geoip := range geoipList.Entry {
if geoip.CountryCode == country {
return geoip.Cidr, nil
// Do not cache file, may save RAM when there
// are many files, but consume CPU each time.
return bs, nil
FileCache[file] = bs
}
}
return nil, newError("country not found in ", filename, ": ", country)
return FileCache[file], nil
}
func loadSite(filename, country string) ([]*router.Domain, error) {
geositeBytes, err := filesystem.ReadAsset(filename)
func loadIP(file, code string) ([]*router.CIDR, error) {
index := file + ":" + code
if IPCache[index] == nil {
bs, err := loadFile(file)
if err != nil {
return nil, newError("failed to open file: ", filename).Base(err)
return nil, newError("failed to load file: ", file).Base(err)
}
var geositeList router.GeoSiteList
if err := proto.Unmarshal(geositeBytes, &geositeList); err != nil {
return nil, err
bs = find(bs, []byte(code))
if bs == nil {
return nil, newError("code not found in ", file, ": ", code)
}
var geoip router.GeoIP
if err := proto.Unmarshal(bs, &geoip); err != nil {
return nil, newError("error unmarshal IP in ", file, ": ", code).Base(err)
}
defer runtime.GC() // or debug.FreeOSMemory()
return geoip.Cidr, nil // do not cache geoip
IPCache[index] = &geoip
}
return IPCache[index].Cidr, nil
}
for _, site := range geositeList.Entry {
if site.CountryCode == country {
return site.Domain, nil
func loadSite(file, code string) ([]*router.Domain, error) {
index := file + ":" + code
if SiteCache[index] == nil {
bs, err := loadFile(file)
if err != nil {
return nil, newError("failed to load file: ", file).Base(err)
}
bs = find(bs, []byte(code))
if bs == nil {
return nil, newError("list not found in ", file, ": ", code)
}
var geosite router.GeoSite
if err := proto.Unmarshal(bs, &geosite); err != nil {
return nil, newError("error unmarshal Site in ", file, ": ", code).Base(err)
}
defer runtime.GC() // or debug.FreeOSMemory()
return geosite.Domain, nil // do not cache geosite
SiteCache[index] = &geosite
}
return SiteCache[index].Domain, nil
}
return nil, newError("list not found in ", filename, ": ", country)
func find(data, code []byte) []byte {
codeL := len(code)
if codeL == 0 {
return nil
}
for {
dataL := len(data)
if dataL < 2 {
return nil
}
x, y := proto.DecodeVarint(data[1:])
if x == 0 && y == 0 {
return nil
}
headL, bodyL := 1+y, int(x)
dataL -= headL
if dataL < bodyL {
return nil
}
data = data[headL:]
if int(data[1]) == codeL {
for i := 0; i < codeL && data[2+i] == code[i]; i++ {
if i+1 == codeL {
return data[:bodyL]
}
}
}
if dataL == bodyL {
return nil
}
data = data[bodyL:]
}
}
type AttributeMatcher interface {

View File

@@ -4,6 +4,10 @@ import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"github.com/BurntSushi/toml"
"github.com/ghodss/yaml"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/core"
@@ -80,3 +84,68 @@ func LoadJSONConfig(reader io.Reader) (*core.Config, error) {
return pbConfig, nil
}
// DecodeTOMLConfig reads from reader and decode the config into *conf.Config
// using github.com/BurntSushi/toml and map to convert toml to json.
func DecodeTOMLConfig(reader io.Reader) (*conf.Config, error) {
tomlFile, err := ioutil.ReadAll(reader)
if err != nil {
return nil, newError("failed to read config file").Base(err)
}
configMap := make(map[string]interface{})
if _, err := toml.Decode(string(tomlFile), &configMap); err != nil {
return nil, newError("failed to convert toml to map").Base(err)
}
jsonFile, err := json.Marshal(&configMap)
if err != nil {
return nil, newError("failed to convert map to json").Base(err)
}
return DecodeJSONConfig(bytes.NewReader(jsonFile))
}
func LoadTOMLConfig(reader io.Reader) (*core.Config, error) {
tomlConfig, err := DecodeTOMLConfig(reader)
if err != nil {
return nil, err
}
pbConfig, err := tomlConfig.Build()
if err != nil {
return nil, newError("failed to parse toml config").Base(err)
}
return pbConfig, nil
}
// DecodeYAMLConfig reads from reader and decode the config into *conf.Config
// using github.com/ghodss/yaml to convert yaml to json.
func DecodeYAMLConfig(reader io.Reader) (*conf.Config, error) {
yamlFile, err := ioutil.ReadAll(reader)
if err != nil {
return nil, newError("failed to read config file").Base(err)
}
jsonFile, err := yaml.YAMLToJSON(yamlFile)
if err != nil {
return nil, newError("failed to convert yaml to json").Base(err)
}
return DecodeJSONConfig(bytes.NewReader(jsonFile))
}
func LoadYAMLConfig(reader io.Reader) (*core.Config, error) {
yamlConfig, err := DecodeYAMLConfig(reader)
if err != nil {
return nil, err
}
pbConfig, err := yamlConfig.Build()
if err != nil {
return nil, newError("failed to parse yaml config").Base(err)
}
return pbConfig, nil
}

View File

@@ -252,6 +252,7 @@ type TLSCertConfig struct {
KeyFile string `json:"keyFile"`
KeyStr []string `json:"key"`
Usage string `json:"usage"`
OcspStapling int64 `json:"ocspStapling"`
}
// Build implements Buildable.
@@ -283,17 +284,22 @@ func (c *TLSCertConfig) Build() (*tls.Certificate, error) {
certificate.Usage = tls.Certificate_ENCIPHERMENT
}
certificate.OcspStapling = c.OcspStapling
return certificate, nil
}
type TLSConfig struct {
Insecure bool `json:"allowInsecure"`
InsecureCiphers bool `json:"allowInsecureCiphers"`
Certs []*TLSCertConfig `json:"certificates"`
ServerName string `json:"serverName"`
ALPN *StringList `json:"alpn"`
DisableSessionResumption bool `json:"disableSessionResumption"`
DisableSystemRoot bool `json:"disableSystemRoot"`
MinVersion string `json:"minVersion"`
MaxVersion string `json:"maxVersion"`
CipherSuites string `json:"cipherSuites"`
PreferServerCipherSuites bool `json:"preferServerCipherSuites"`
}
// Build implements Buildable.
@@ -309,7 +315,6 @@ func (c *TLSConfig) Build() (proto.Message, error) {
}
serverName := c.ServerName
config.AllowInsecure = c.Insecure
config.AllowInsecureCiphers = c.InsecureCiphers
if len(c.ServerName) > 0 {
config.ServerName = serverName
}
@@ -318,6 +323,10 @@ func (c *TLSConfig) Build() (proto.Message, error) {
}
config.DisableSessionResumption = c.DisableSessionResumption
config.DisableSystemRoot = c.DisableSystemRoot
config.MinVersion = c.MinVersion
config.MaxVersion = c.MaxVersion
config.CipherSuites = c.CipherSuites
config.PreferServerCipherSuites = c.PreferServerCipherSuites
return config, nil
}
@@ -327,6 +336,7 @@ type XTLSCertConfig struct {
KeyFile string `json:"keyFile"`
KeyStr []string `json:"key"`
Usage string `json:"usage"`
OcspStapling int64 `json:"ocspStapling"`
}
// Build implements Buildable.
@@ -358,17 +368,22 @@ func (c *XTLSCertConfig) Build() (*xtls.Certificate, error) {
certificate.Usage = xtls.Certificate_ENCIPHERMENT
}
certificate.OcspStapling = c.OcspStapling
return certificate, nil
}
type XTLSConfig struct {
Insecure bool `json:"allowInsecure"`
InsecureCiphers bool `json:"allowInsecureCiphers"`
Certs []*XTLSCertConfig `json:"certificates"`
ServerName string `json:"serverName"`
ALPN *StringList `json:"alpn"`
DisableSessionResumption bool `json:"disableSessionResumption"`
DisableSystemRoot bool `json:"disableSystemRoot"`
MinVersion string `json:"minVersion"`
MaxVersion string `json:"maxVersion"`
CipherSuites string `json:"cipherSuites"`
PreferServerCipherSuites bool `json:"preferServerCipherSuites"`
}
// Build implements Buildable.
@@ -384,7 +399,6 @@ func (c *XTLSConfig) Build() (proto.Message, error) {
}
serverName := c.ServerName
config.AllowInsecure = c.Insecure
config.AllowInsecureCiphers = c.InsecureCiphers
if len(c.ServerName) > 0 {
config.ServerName = serverName
}
@@ -393,6 +407,10 @@ func (c *XTLSConfig) Build() (proto.Message, error) {
}
config.DisableSessionResumption = c.DisableSessionResumption
config.DisableSystemRoot = c.DisableSystemRoot
config.MinVersion = c.MinVersion
config.MaxVersion = c.MaxVersion
config.CipherSuites = c.CipherSuites
config.PreferServerCipherSuites = c.PreferServerCipherSuites
return config, nil
}

View File

@@ -52,6 +52,17 @@ func (c *TrojanClientConfig) Build() (proto.Message, error) {
Password: rec.Password,
Flow: rec.Flow,
}
switch account.Flow {
case "", "xtls-rprx-origin", "xtls-rprx-origin-udp443", "xtls-rprx-direct", "xtls-rprx-direct-udp443":
case "xtls-rprx-splice", "xtls-rprx-splice-udp443":
if runtime.GOOS != "linux" && runtime.GOOS != "android" {
return nil, newError(`Trojan servers: "` + account.Flow + `" only support linux in this version`)
}
default:
return nil, newError(`Trojan servers: "flow" doesn't support "` + account.Flow + `" in this version`)
}
trojan := &protocol.ServerEndpoint{
Address: rec.Address.Build(),
Port: uint32(rec.Port),
@@ -107,6 +118,14 @@ func (c *TrojanServerConfig) Build() (proto.Message, error) {
Flow: rawUser.Flow,
}
switch account.Flow {
case "", "xtls-rprx-origin", "xtls-rprx-direct":
case "xtls-rprx-splice":
return nil, newError(`Trojan clients: inbound doesn't support "xtls-rprx-splice" in this version, please use "xtls-rprx-direct" instead`)
default:
return nil, newError(`Trojan clients: "flow" doesn't support "` + account.Flow + `" in this version`)
}
user.Email = rawUser.Email
user.Level = uint32(rawUser.Level)
user.Account = serial.ToTypedMessage(account)
@@ -148,7 +167,7 @@ func (c *TrojanServerConfig) Build() (proto.Message, error) {
switch fb.Dest[0] {
case '@', '/':
fb.Type = "unix"
if fb.Dest[0] == '@' && len(fb.Dest) > 1 && fb.Dest[1] == '@' && runtime.GOOS == "linux" {
if fb.Dest[0] == '@' && len(fb.Dest) > 1 && fb.Dest[1] == '@' && (runtime.GOOS == "linux" || runtime.GOOS == "android") {
fullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) // may need padding to work with haproxy
copy(fullAddr, fb.Dest[1:])
fb.Dest = string(fullAddr)

View File

@@ -101,7 +101,7 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) {
switch fb.Dest[0] {
case '@', '/':
fb.Type = "unix"
if fb.Dest[0] == '@' && len(fb.Dest) > 1 && fb.Dest[1] == '@' && runtime.GOOS == "linux" {
if fb.Dest[0] == '@' && len(fb.Dest) > 1 && fb.Dest[1] == '@' && (runtime.GOOS == "linux" || runtime.GOOS == "android") {
fullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) // may need padding to work with haproxy
copy(fullAddr, fb.Dest[1:])
fb.Dest = string(fullAddr)

View File

@@ -1,6 +1,7 @@
package main
import (
"flag"
"fmt"
"os"
"os/exec"
@@ -12,13 +13,25 @@ import (
"github.com/xtls/xray-core/core"
)
var directory = flag.String("pwd", "", "Working directory of Xray vprotogen.")
func main() {
flag.Usage = func() {
fmt.Fprintf(flag.CommandLine.Output(), "Usage of vprotogen:\n")
flag.PrintDefaults()
}
flag.Parse()
if !filepath.IsAbs(*directory) {
pwd, wdErr := os.Getwd()
if wdErr != nil {
fmt.Println("Can not get current working directory.")
os.Exit(1)
}
*directory = filepath.Join(pwd, *directory)
}
pwd := *directory
GOBIN := common.GetGOBIN()
binPath := os.Getenv("PATH")
pathSlice := []string{binPath, GOBIN, pwd}
@@ -39,7 +52,7 @@ func main() {
}
protoFilesMap := make(map[string][]string)
walkErr := filepath.Walk("./", func(path string, info os.FileInfo, err error) error {
walkErr := filepath.Walk(pwd, func(path string, info os.FileInfo, err error) error {
if err != nil {
fmt.Println(err)
return err
@@ -52,6 +65,7 @@ func main() {
dir := filepath.Dir(path)
filename := filepath.Base(path)
if strings.HasSuffix(filename, ".proto") {
path = path[len(pwd)+1:]
protoFilesMap[dir] = append(protoFilesMap[dir], path)
}
@@ -73,6 +87,7 @@ func main() {
args = append(args, relProtoFile)
cmd := exec.Command(protoc, args...)
cmd.Env = append(cmd.Env, os.Environ()...)
cmd.Dir = pwd
output, cmdErr := cmd.CombinedOutput()
if len(output) > 0 {
fmt.Println(string(output))

View File

@@ -57,15 +57,14 @@ import (
_ "github.com/xtls/xray-core/transport/internet/headers/wechat"
_ "github.com/xtls/xray-core/transport/internet/headers/wireguard"
// JSON config support. Choose only one from the two below.
// The following line loads JSON from xctl
// _ "github.com/xtls/xray-core/main/json"
// The following line loads JSON internally
_ "github.com/xtls/xray-core/main/jsonem"
// JSON & TOML & YAML
_ "github.com/xtls/xray-core/main/json"
_ "github.com/xtls/xray-core/main/toml"
_ "github.com/xtls/xray-core/main/yaml"
// Load config from file or http(s)
_ "github.com/xtls/xray-core/main/confloader/external"
// commands
// Commands
_ "github.com/xtls/xray-core/main/commands/all"
)

View File

@@ -1,38 +0,0 @@
package json
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
import (
"io"
"os"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/cmdarg"
core "github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/main/confloader"
)
func init() {
common.Must(core.RegisterConfigLoader(&core.ConfigFormat{
Name: "JSON",
Extension: []string{"json"},
Loader: func(input interface{}) (*core.Config, error) {
switch v := input.(type) {
case cmdarg.Arg:
r, err := confloader.LoadExtConfig(v, os.Stdin)
if err != nil {
return nil, newError("failed to execute xctl to convert config file.").Base(err).AtWarning()
}
return core.LoadConfig("protobuf", "", r)
case io.Reader:
r, err := confloader.LoadExtConfig([]string{"stdin:"}, os.Stdin)
if err != nil {
return nil, newError("failed to execute xctl to convert config file.").Base(err).AtWarning()
}
return core.LoadConfig("protobuf", "", r)
default:
return nil, newError("unknown type")
}
},
}))
}

View File

@@ -1,4 +1,4 @@
package jsonem
package json
import (
"io"
@@ -22,9 +22,13 @@ func init() {
for i, arg := range v {
newError("Reading config: ", arg).AtInfo().WriteToLog()
r, err := confloader.LoadConfig(arg)
common.Must(err)
if err != nil {
return nil, newError("failed to read config: ", arg).Base(err)
}
c, err := serial.DecodeJSONConfig(r)
common.Must(err)
if err != nil {
return nil, newError("failed to decode config: ", arg).Base(err)
}
if i == 0 {
// This ensure even if the muti-json parser do not support a setting,
// It is still respected automatically for the first configure file

View File

@@ -9,12 +9,14 @@ import (
"path"
"path/filepath"
"runtime"
"runtime/debug"
"strings"
"syscall"
"github.com/xtls/xray-core/common/cmdarg"
"github.com/xtls/xray-core/common/platform"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/infra/conf"
"github.com/xtls/xray-core/main/commands/base"
)
@@ -64,22 +66,29 @@ func executeRun(cmd *base.Command, args []string) {
printVersion()
server, err := startXray()
if err != nil {
base.Fatalf("Failed to start: %s", err)
fmt.Println("Failed to start:", err)
// Configuration error. Exit with a special value to prevent systemd from restarting.
os.Exit(23)
}
if *test {
fmt.Println("Configuration OK.")
base.SetExitStatus(0)
base.Exit()
os.Exit(0)
}
if err := server.Start(); err != nil {
base.Fatalf("Failed to start: %s", err)
fmt.Println("Failed to start:", err)
os.Exit(-1)
}
defer server.Close()
conf.FileCache = nil
conf.IPCache = nil
conf.SiteCache = nil
// Explicitly triggering GC to remove garbage from config loading.
runtime.GC()
debug.FreeOSMemory()
{
osSignals := make(chan os.Signal, 1)
@@ -147,6 +156,10 @@ func getConfigFormat() string {
switch strings.ToLower(*format) {
case "pb", "protobuf":
return "protobuf"
case "yaml", "yml":
return "yaml"
case "toml":
return "toml"
default:
return "json"
}
@@ -156,8 +169,11 @@ func startXray() (core.Server, error) {
configFiles := getConfigFilePath()
config, err := core.LoadConfig(getConfigFormat(), configFiles[0], configFiles)
//config, err := core.LoadConfigs(getConfigFormat(), configFiles)
if err != nil {
return nil, newError("failed to read config files: [", configFiles.String(), "]").Base(err)
return nil, newError("failed to load config files: [", configFiles.String(), "]").Base(err)
}
server, err := core.New(config)

View File

@@ -0,0 +1,9 @@
package toml
import "github.com/xtls/xray-core/common/errors"
type errPathObjHolder struct{}
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).WithPathObj(errPathObjHolder{})
}

48
main/toml/toml.go Normal file
View File

@@ -0,0 +1,48 @@
package toml
import (
"io"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/cmdarg"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/infra/conf"
"github.com/xtls/xray-core/infra/conf/serial"
"github.com/xtls/xray-core/main/confloader"
)
func init() {
common.Must(core.RegisterConfigLoader(&core.ConfigFormat{
Name: "TOML",
Extension: []string{"toml"},
Loader: func(input interface{}) (*core.Config, error) {
switch v := input.(type) {
case cmdarg.Arg:
cf := &conf.Config{}
for i, arg := range v {
newError("Reading config: ", arg).AtInfo().WriteToLog()
r, err := confloader.LoadConfig(arg)
if err != nil {
return nil, newError("failed to read config: ", arg).Base(err)
}
c, err := serial.DecodeTOMLConfig(r)
if err != nil {
return nil, newError("failed to decode config: ", arg).Base(err)
}
if i == 0 {
// This ensure even if the muti-json parser do not support a setting,
// It is still respected automatically for the first configure file
*cf = *c
continue
}
cf.Override(c, arg)
}
return cf.Build()
case io.Reader:
return serial.LoadTOMLConfig(v)
default:
return nil, newError("unknow type")
}
},
}))
}

View File

@@ -0,0 +1,9 @@
package yaml
import "github.com/xtls/xray-core/common/errors"
type errPathObjHolder struct{}
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).WithPathObj(errPathObjHolder{})
}

48
main/yaml/yaml.go Normal file
View File

@@ -0,0 +1,48 @@
package yaml
import (
"io"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/cmdarg"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/infra/conf"
"github.com/xtls/xray-core/infra/conf/serial"
"github.com/xtls/xray-core/main/confloader"
)
func init() {
common.Must(core.RegisterConfigLoader(&core.ConfigFormat{
Name: "YAML",
Extension: []string{"yaml", "yml"},
Loader: func(input interface{}) (*core.Config, error) {
switch v := input.(type) {
case cmdarg.Arg:
cf := &conf.Config{}
for i, arg := range v {
newError("Reading config: ", arg).AtInfo().WriteToLog()
r, err := confloader.LoadConfig(arg)
if err != nil {
return nil, newError("failed to read config: ", arg).Base(err)
}
c, err := serial.DecodeYAMLConfig(r)
if err != nil {
return nil, newError("failed to decode config: ", arg).Base(err)
}
if i == 0 {
// This ensure even if the muti-json parser do not support a setting,
// It is still respected automatically for the first configure file
*cf = *c
continue
}
cf.Override(c, arg)
}
return cf.Build()
case io.Reader:
return serial.LoadYAMLConfig(v)
default:
return nil, newError("unknow type")
}
},
}))
}

View File

@@ -1,5 +1,3 @@
// +build !confonly
// Package blackhole is an outbound handler that blocks all connections.
package blackhole

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dns
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package dokodemo
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@@ -1,5 +1,3 @@
// +build !confonly
package freedom
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
@@ -19,6 +17,7 @@ import (
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/dns"
"github.com/xtls/xray-core/features/policy"
"github.com/xtls/xray-core/features/stats"
"github.com/xtls/xray-core/transport"
"github.com/xtls/xray-core/transport/internet"
)
@@ -150,7 +149,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
if destination.Network == net.Network_TCP {
writer = buf.NewWriter(conn)
} else {
writer = &buf.SequentialWriter{Writer: conn}
writer = NewPacketWriter(conn)
}
if err := buf.Copy(input, writer, buf.UpdateActivity(timer)); err != nil {
@@ -167,7 +166,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
if destination.Network == net.Network_TCP {
reader = buf.NewReader(conn)
} else {
reader = buf.NewPacketReader(conn)
reader = NewPacketReader(conn)
}
if err := buf.Copy(reader, output, buf.UpdateActivity(timer)); err != nil {
return newError("failed to process response").Base(err)
@@ -182,3 +181,93 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
return nil
}
func NewPacketReader(conn net.Conn) buf.Reader {
iConn := conn
statConn, ok := iConn.(*internet.StatCouterConnection)
if ok {
iConn = statConn.Connection
}
var counter stats.Counter
if statConn != nil {
counter = statConn.ReadCounter
}
if c, ok := iConn.(*internet.PacketConnWrapper); ok {
return &PacketReader{
PacketConnWrapper: c,
Counter: counter,
}
}
return &buf.PacketReader{Reader: conn}
}
type PacketReader struct {
*internet.PacketConnWrapper
stats.Counter
}
func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
b := buf.New()
b.Resize(0, buf.Size)
n, d, err := r.PacketConnWrapper.ReadFrom(b.Bytes())
if err != nil {
b.Release()
return nil, err
}
b.Resize(0, int32(n))
b.UDP = d.(*net.UDPAddr)
if r.Counter != nil {
r.Counter.Add(int64(n))
}
return buf.MultiBuffer{b}, nil
}
func NewPacketWriter(conn net.Conn) buf.Writer {
iConn := conn
statConn, ok := iConn.(*internet.StatCouterConnection)
if ok {
iConn = statConn.Connection
}
var counter stats.Counter
if statConn != nil {
counter = statConn.WriteCounter
}
if c, ok := iConn.(*internet.PacketConnWrapper); ok {
return &PacketWriter{
PacketConnWrapper: c,
Counter: counter,
}
}
return &buf.SequentialWriter{Writer: conn}
}
type PacketWriter struct {
*internet.PacketConnWrapper
stats.Counter
}
func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
for {
mb2, b := buf.SplitFirst(mb)
mb = mb2
if b == nil {
break
}
var n int
var err error
if b.UDP != nil {
n, err = w.PacketConnWrapper.WriteTo(b.Bytes(), b.UDP)
} else {
n, err = w.PacketConnWrapper.Write(b.Bytes())
}
b.Release()
if err != nil {
buf.ReleaseMulti(mb)
return err
}
if w.Counter != nil {
w.Counter.Add(int64(n))
}
}
return nil
}

View File

@@ -1,5 +1,3 @@
// +build !confonly
package http
import (
@@ -170,6 +168,7 @@ func setUpHTTPTunnel(ctx context.Context, dest net.Destination, target string, u
rawConn.Close()
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
rawConn.Close()

View File

@@ -1,5 +1,3 @@
// +build !confonly
package http
import (
@@ -295,6 +293,7 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, wri
response.Close = true
result = nil
}
defer response.Body.Close()
} else {
newError("failed to read response from ", request.Host).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))
response = &http.Response{

View File

@@ -1,5 +1,3 @@
// +build !confonly
package mtproto
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package shadowsocks
import (
@@ -136,14 +134,15 @@ 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,
}}
requestDone := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
writer := &UDPWriter{
Writer: conn,
Request: request,
}
if err := buf.Copy(link.Reader, writer, buf.UpdateActivity(timer)); err != nil {
return newError("failed to transport all UDP request").Base(err)
}

View File

@@ -1,5 +1,3 @@
// +build !confonly
package shadowsocks
import (
@@ -232,11 +230,15 @@ func (v *UDPReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
buffer.Release()
return nil, err
}
_, payload, err := DecodeUDPPacket(v.User, buffer)
u, payload, err := DecodeUDPPacket(v.User, buffer)
if err != nil {
buffer.Release()
return nil, err
}
payload.UDP = &net.UDPAddr{
IP: u.Address.IP(),
Port: int(u.Port),
}
return buf.MultiBuffer{payload}, nil
}
@@ -245,13 +247,36 @@ type UDPWriter struct {
Request *protocol.RequestHeader
}
// Write implements io.Writer.
func (w *UDPWriter) Write(payload []byte) (int, error) {
packet, err := EncodeUDPPacket(w.Request, payload)
func (w *UDPWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
for {
mb2, b := buf.SplitFirst(mb)
mb = mb2
if b == nil {
break
}
var packet *buf.Buffer
var err error
if b.UDP != nil {
request := &protocol.RequestHeader{
User: w.Request.User,
Address: net.IPAddress(b.UDP.IP),
Port: net.Port(b.UDP.Port),
}
packet, err = EncodeUDPPacket(request, b.Bytes())
} else {
packet, err = EncodeUDPPacket(w.Request, b.Bytes())
}
b.Release()
if err != nil {
return 0, err
buf.ReleaseMulti(mb)
return err
}
_, err = w.Writer.Write(packet.Bytes())
packet.Release()
return len(payload), err
if err != nil {
buf.ReleaseMulti(mb)
return err
}
}
return nil
}

View File

@@ -145,7 +145,7 @@ func TestUDPReaderWriter(t *testing.T) {
cache := buf.New()
defer cache.Release()
writer := &buf.SequentialWriter{Writer: &UDPWriter{
writer := &UDPWriter{
Writer: cache,
Request: &protocol.RequestHeader{
Version: Version,
@@ -153,7 +153,7 @@ func TestUDPReaderWriter(t *testing.T) {
Port: 123,
User: user,
},
}}
}
reader := &UDPReader{
Reader: cache,

View File

@@ -1,5 +1,3 @@
// +build !confonly
package shadowsocks
import (
@@ -79,6 +77,15 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
}
payload := packet.Payload
if payload.UDP != nil {
request = &protocol.RequestHeader{
User: request.User,
Address: net.IPAddress(payload.UDP.IP),
Port: net.Port(payload.UDP.Port),
}
}
data, err := EncodeUDPPacket(request, payload.Bytes())
payload.Release()
if err != nil {
@@ -96,6 +103,8 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
}
inbound.User = s.user
var dest net.Destination
reader := buf.NewPacketReader(conn)
for {
mpayload, err := reader.ReadMultiBuffer()
@@ -120,17 +129,25 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
}
currentPacketCtx := ctx
dest := request.Destination()
if inbound.Source.IsValid() {
currentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
From: inbound.Source,
To: dest,
To: request.Destination(),
Status: log.AccessAccepted,
Reason: "",
Email: request.User.Email,
})
}
newError("tunnelling request to ", dest).WriteToLog(session.ExportIDToError(currentPacketCtx))
newError("tunnelling request to ", request.Destination()).WriteToLog(session.ExportIDToError(currentPacketCtx))
data.UDP = &net.UDPAddr{
IP: request.Address.IP(),
Port: int(request.Port),
}
if dest.Network == 0 {
dest = request.Destination() // JUST FOLLOW THE FIREST PACKET
}
currentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request)
udpServer.Dispatch(currentPacketCtx, dest, data)

View File

@@ -1,5 +1,3 @@
// +build !confonly
package socks
import (
@@ -53,14 +51,19 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
if outbound == nil || !outbound.Target.IsValid() {
return newError("target not specified.")
}
// Destination of the inner request.
destination := outbound.Target
// Outbound server.
var server *protocol.ServerSpec
// Outbound server's destination.
var dest net.Destination
// Connection to the outbound server.
var conn internet.Connection
if err := retry.ExponentialBackoff(5, 100).On(func() error {
server = c.serverPicker.PickServer()
dest := server.Destination()
dest = server.Destination()
rawConn, err := dialer.Dial(ctx, dest)
if err != nil {
return err
@@ -103,6 +106,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
if err != nil {
return newError("failed to establish connection to server").AtWarning().Base(err)
}
if udpRequest != nil {
if udpRequest.Address == net.AnyIP || udpRequest.Address == net.AnyIPv6 {
udpRequest.Address = dest.Address
}
}
if err := conn.SetDeadline(time.Time{}); err != nil {
newError("failed to clear deadline after handshake").Base(err).WriteToLog(session.ExportIDToError(ctx))

View File

@@ -1,5 +1,3 @@
// +build !confonly
package socks
import "github.com/xtls/xray-core/common/protocol"

View File

@@ -1,5 +1,3 @@
// +build !confonly
package socks
import (
@@ -18,7 +16,7 @@ const (
cmdTCPConnect = 0x01
cmdTCPBind = 0x02
cmdUDPPort = 0x03
cmdUDPAssociate = 0x03
cmdTorResolve = 0xF0
cmdTorResolvePTR = 0xF1
@@ -42,7 +40,9 @@ var addrParser = protocol.NewAddressParser(
type ServerSession struct {
config *ServerConfig
address net.Address
port net.Port
clientAddress net.Address
}
func (s *ServerSession) handshake4(cmd byte, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) {
@@ -164,7 +164,7 @@ func (s *ServerSession) handshake5(nMethod byte, reader io.Reader, writer io.Wri
case cmdTCPConnect, cmdTorResolve, cmdTorResolvePTR:
// We don't have a solution for Tor case now. Simply treat it as connect command.
request.Command = protocol.RequestCommandTCP
case cmdUDPPort:
case cmdUDPAssociate:
if !s.config.UdpEnabled {
writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0))
return nil, newError("UDP is not enabled.")
@@ -187,15 +187,20 @@ func (s *ServerSession) handshake5(nMethod byte, reader io.Reader, writer io.Wri
request.Address = addr
request.Port = port
responseAddress := net.AnyIP
responsePort := net.Port(1717)
responseAddress := s.address
responsePort := s.port
//nolint:gocritic // Use if else chain for clarity
if request.Command == protocol.RequestCommandUDP {
addr := s.config.Address.AsAddress()
if addr == nil {
addr = net.LocalHostIP
if s.config.Address != nil {
// Use configured IP as remote address in the response to UdpAssociate
responseAddress = s.config.Address.AsAddress()
} else if s.clientAddress == net.LocalHostIP || s.clientAddress == net.LocalHostIPv6 {
// For localhost clients use loopback IP
responseAddress = s.clientAddress
} else {
// For non-localhost clients use inbound listening address
responseAddress = s.address
}
responseAddress = addr
responsePort = s.port
}
if err := writeSocks5Response(writer, statusSuccess, responseAddress, responsePort); err != nil {
return nil, err
@@ -448,7 +453,7 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i
command := byte(cmdTCPConnect)
if request.Command == protocol.RequestCommandUDP {
command = byte(cmdUDPPort)
command = byte(cmdUDPAssociate)
}
common.Must2(b.Write([]byte{socks5Version, command, 0x00 /* reserved */}))
if err := addrParser.WriteAddressPort(b, request.Address, request.Port); err != nil {

View File

@@ -1,5 +1,3 @@
// +build !confonly
package socks
import (
@@ -92,7 +90,9 @@ func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispa
svrSession := &ServerSession{
config: s.config,
address: inbound.Gateway.Address,
port: inbound.Gateway.Port,
clientAddress: inbound.Source.Address,
}
reader := &buf.BufferedReader{Reader: buf.NewReader(conn)}
@@ -198,6 +198,15 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
if request == nil {
return
}
if payload.UDP != nil {
request = &protocol.RequestHeader{
User: request.User,
Address: net.IPAddress(payload.UDP.IP),
Port: net.Port(payload.UDP.Port),
}
}
udpMessage, err := EncodeUDPPacket(request, payload.Bytes())
payload.Release()
@@ -213,6 +222,8 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
newError("client UDP connection from ", inbound.Source).WriteToLog(session.ExportIDToError(ctx))
}
var dest net.Destination
reader := buf.NewPacketReader(conn)
for {
mpayload, err := reader.ReadMultiBuffer()
@@ -244,8 +255,17 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
})
}
payload.UDP = &net.UDPAddr{
IP: request.Address.IP(),
Port: int(request.Port),
}
if dest.Network == 0 {
dest = request.Destination() // JUST FOLLOW THE FIREST PACKET
}
currentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request)
udpServer.Dispatch(currentPacketCtx, request.Destination(), payload)
udpServer.Dispatch(currentPacketCtx, dest, payload)
}
}
}

View File

@@ -1,5 +1,3 @@
// +build !confonly
package trojan
import (
@@ -81,56 +79,63 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
defer conn.Close()
user := server.PickUser()
account, ok := user.Account.(*MemoryAccount)
if !ok {
return newError("user account is not valid")
}
iConn := conn
statConn, ok := iConn.(*internet.StatCouterConnection)
if ok {
iConn = statConn.Connection
}
var rawConn syscall.RawConn
user := server.PickUser()
account, ok := user.Account.(*MemoryAccount)
if !ok {
return newError("user account is not valid")
}
connWriter := &ConnWriter{
Flow: account.Flow,
}
var rawConn syscall.RawConn
var sctx context.Context
connWriter := &ConnWriter{}
allowUDP443 := false
switch account.Flow {
case XRO + "-udp443", XRD + "-udp443":
switch connWriter.Flow {
case XRO + "-udp443", XRD + "-udp443", XRS + "-udp443":
allowUDP443 = true
account.Flow = account.Flow[:16]
connWriter.Flow = connWriter.Flow[:16]
fallthrough
case XRO, XRD:
case XRO, XRD, XRS:
if destination.Address.Family().IsDomain() && destination.Address.Domain() == muxCoolAddress {
return newError(account.Flow + " doesn't support Mux").AtWarning()
return newError(connWriter.Flow + " doesn't support Mux").AtWarning()
}
if destination.Network == net.Network_UDP {
if !allowUDP443 && destination.Port == 443 {
return newError(account.Flow + " stopped UDP/443").AtInfo()
return newError(connWriter.Flow + " stopped UDP/443").AtInfo()
}
connWriter.Flow = ""
} else { // enable XTLS only if making TCP request
if xtlsConn, ok := iConn.(*xtls.Conn); ok {
xtlsConn.RPRX = true
xtlsConn.SHOW = trojanXTLSShow
connWriter.Flow = account.Flow
if account.Flow == XRD {
xtlsConn.DirectMode = true
xtlsConn.SHOW = xtls_show
xtlsConn.MARK = "XTLS"
if connWriter.Flow == XRS {
sctx = ctx
connWriter.Flow = XRD
}
if connWriter.Flow == XRD {
xtlsConn.DirectMode = true
if sc, ok := xtlsConn.Connection.(syscall.Conn); ok {
rawConn, _ = sc.SyscallConn()
}
}
} else {
return newError(`failed to use ` + account.Flow + `, maybe "security" is not "xtls"`).AtWarning()
return newError(`failed to use ` + connWriter.Flow + `, maybe "security" is not "xtls"`).AtWarning()
}
}
case "":
default:
if _, ok := iConn.(*xtls.Conn); ok {
panic(`To avoid misunderstanding, you must fill in Trojan "flow" when using XTLS.`)
}
default:
return newError("unsupported flow " + account.Flow).AtWarning()
}
sessionPolicy := c.policyManager.ForLevel(user.Level)
@@ -185,7 +190,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
if statConn != nil {
counter = statConn.ReadCounter
}
return ReadV(reader, link.Writer, timer, iConn.(*xtls.Conn), rawConn, counter)
return ReadV(reader, link.Writer, timer, iConn.(*xtls.Conn), rawConn, counter, sctx)
}
return buf.Copy(reader, link.Writer, buf.UpdateActivity(timer))
}
@@ -207,6 +212,6 @@ func init() {
xtlsShow := platform.NewEnvFlag("xray.trojan.xtls.show").GetValue(func() string { return defaultFlagValue })
if xtlsShow == "true" {
trojanXTLSShow = true
xtls_show = true
}
}

View File

@@ -1,17 +1,21 @@
package trojan
import (
"context"
"encoding/binary"
fmt "fmt"
"io"
"runtime"
"syscall"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/common/signal"
"github.com/xtls/xray-core/features/stats"
"github.com/xtls/xray-core/transport/internet"
"github.com/xtls/xray-core/transport/internet/xtls"
)
@@ -24,11 +28,13 @@ var (
protocol.AddressFamilyByte(0x03, net.AddressFamilyDomain),
)
trojanXTLSShow = false
xtls_show = false
)
const (
maxLength = 8192
// XRS is constant for XTLS splice mode
XRS = "xtls-rprx-splice"
// XRD is constant for XTLS direct mode
XRD = "xtls-rprx-direct"
// XRO is constant for XTLS origin mode
@@ -84,10 +90,10 @@ func (c *ConnWriter) writeHeader() error {
command := commandTCP
if c.Target.Network == net.Network_UDP {
command = commandUDP
} else if c.Flow == XRO {
command = commandXRO
} else if c.Flow == XRD {
command = commandXRD
} else if c.Flow == XRO {
command = commandXRO
}
if _, err := buffer.Write(c.Account.Key); err != nil {
@@ -122,31 +128,43 @@ type PacketWriter struct {
// WriteMultiBuffer implements buf.Writer
func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
b := make([]byte, maxLength)
for !mb.IsEmpty() {
var length int
mb, length = buf.SplitBytes(mb, b)
if _, err := w.writePacket(b[:length], w.Target); err != nil {
for {
mb2, b := buf.SplitFirst(mb)
mb = mb2
if b == nil {
break
}
target := w.Target
if b.UDP != nil {
target.Address = net.IPAddress(b.UDP.IP)
target.Port = net.Port(b.UDP.Port)
}
if _, err := w.writePacket(b.Bytes(), target); err != nil {
buf.ReleaseMulti(mb)
return err
}
}
return nil
}
// WriteMultiBufferWithMetadata writes udp packet with destination specified
func (w *PacketWriter) WriteMultiBufferWithMetadata(mb buf.MultiBuffer, dest net.Destination) error {
b := make([]byte, maxLength)
for !mb.IsEmpty() {
var length int
mb, length = buf.SplitBytes(mb, b)
if _, err := w.writePacket(b[:length], dest); err != nil {
for {
mb2, b := buf.SplitFirst(mb)
mb = mb2
if b == nil {
break
}
source := dest
if b.UDP != nil {
source.Address = net.IPAddress(b.UDP.IP)
source.Port = net.Port(b.UDP.Port)
}
if _, err := w.writePacket(b.Bytes(), source); err != nil {
buf.ReleaseMulti(mb)
return err
}
}
return nil
}
@@ -205,10 +223,10 @@ func (c *ConnReader) ParseHeader() error {
network := net.Network_TCP
if command[0] == commandUDP {
network = net.Network_UDP
} else if command[0] == commandXRO {
c.Flow = XRO
} else if command[0] == commandXRD {
c.Flow = XRD
} else if command[0] == commandXRO {
c.Flow = XRO
}
addr, port, err := addrParser.ReadAddressPort(nil, c.Reader)
@@ -294,6 +312,10 @@ func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) {
}
b := buf.New()
b.UDP = &net.UDPAddr{
IP: addr.IP(),
Port: int(port.Value()),
}
mb = append(mb, b)
n, err := b.ReadFullFrom(r, int32(length))
if err != nil {
@@ -307,12 +329,42 @@ func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) {
return &PacketPayload{Target: dest, Buffer: mb}, nil
}
func ReadV(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn *xtls.Conn, rawConn syscall.RawConn, counter stats.Counter) error {
func ReadV(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn *xtls.Conn, rawConn syscall.RawConn, counter stats.Counter, sctx context.Context) error {
err := func() error {
var ct stats.Counter
for {
if conn.DirectIn {
conn.DirectIn = false
if sctx != nil {
if inbound := session.InboundFromContext(sctx); inbound != nil && inbound.Conn != nil {
iConn := inbound.Conn
statConn, ok := iConn.(*internet.StatCouterConnection)
if ok {
iConn = statConn.Connection
}
if xc, ok := iConn.(*xtls.Conn); ok {
iConn = xc.Connection
}
if tc, ok := iConn.(*net.TCPConn); ok {
if conn.SHOW {
fmt.Println(conn.MARK, "Splice")
}
runtime.Gosched() // necessary
w, err := tc.ReadFrom(conn.Connection)
if counter != nil {
counter.Add(w)
}
if statConn != nil && statConn.WriteCounter != nil {
statConn.WriteCounter.Add(w)
}
return err
} else {
panic("XTLS Splice: not TCP inbound")
}
} else {
//panic("XTLS Splice: nil inbound or nil inbound.Conn")
}
}
reader = buf.NewReadVReader(conn.Connection, rawConn)
ct = counter
if conn.SHOW {

View File

@@ -1,5 +1,3 @@
// +build !confonly
package trojan
import (
@@ -40,7 +38,7 @@ func init() {
xtlsShow := platform.NewEnvFlag("xray.trojan.xtls.show").GetValue(func() string { return defaultFlagValue })
if xtlsShow == "true" {
trojanXTLSShow = true
xtls_show = true
}
}
@@ -221,7 +219,8 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet
}
if xtlsConn, ok := iConn.(*xtls.Conn); ok {
xtlsConn.RPRX = true
xtlsConn.SHOW = trojanXTLSShow
xtlsConn.SHOW = xtls_show
xtlsConn.MARK = "XTLS"
if clientReader.Flow == XRD {
xtlsConn.DirectMode = true
if sc, ok := xtlsConn.Connection.(syscall.Conn); ok {
@@ -232,11 +231,9 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet
return newError(`failed to use ` + clientReader.Flow + `, maybe "security" is not "xtls"`).AtWarning()
}
} else {
return newError("unable to use ", clientReader.Flow).AtWarning()
return newError(account.Password + " is not able to use " + clientReader.Flow).AtWarning()
}
case "":
default:
return newError("unsupported flow " + account.Flow).AtWarning()
}
ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
@@ -259,6 +256,8 @@ func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReade
inbound := session.InboundFromContext(ctx)
user := inbound.User
var dest net.Destination
for {
select {
case <-ctx.Done():
@@ -281,8 +280,12 @@ func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReade
})
newError("tunnelling request to ", p.Target).WriteToLog(session.ExportIDToError(ctx))
if dest.Network == 0 {
dest = p.Target // JUST FOLLOW THE FIREST PACKET
}
for _, b := range p.Buffer {
udpServer.Dispatch(ctx, p.Target, b)
udpServer.Dispatch(ctx, dest, b)
}
}
}
@@ -310,7 +313,7 @@ func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Sess
if statConn != nil {
counter = statConn.ReadCounter
}
err = ReadV(clientReader, link.Writer, timer, iConn.(*xtls.Conn), rawConn, counter)
err = ReadV(clientReader, link.Writer, timer, iConn.(*xtls.Conn), rawConn, counter, nil)
} else {
err = buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer))
}

View File

@@ -1,5 +1,3 @@
// +build !confonly
package trojan
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package vless
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package encoding
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package encoding
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
@@ -8,8 +6,8 @@ import (
"context"
"fmt"
"io"
"runtime"
"syscall"
"time"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/errors"
@@ -191,11 +189,14 @@ func ReadV(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, c
if ok {
iConn = statConn.Connection
}
if xc, ok := iConn.(*xtls.Conn); ok {
iConn = xc.Connection
}
if tc, ok := iConn.(*net.TCPConn); ok {
if conn.SHOW {
fmt.Println(conn.MARK, "Splice")
}
time.Sleep(time.Millisecond) // necessary
runtime.Gosched() // necessary
w, err := tc.ReadFrom(conn.Connection)
if counter != nil {
counter.Add(w)

View File

@@ -1,3 +1 @@
// +build !confonly
package inbound

View File

@@ -1,5 +1,3 @@
// +build !confonly
package inbound
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@@ -1,3 +1 @@
// +build !confonly
package outbound

View File

@@ -1,5 +1,3 @@
// +build !confonly
package outbound
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@@ -1,5 +1,3 @@
// +build !confonly
package vless
import (

View File

@@ -1,5 +1,3 @@
// +build !confonly
package vmess
import (

View File

@@ -57,14 +57,14 @@ func TestRequestSerialization(t *testing.T) {
defer common.Close(userValidator)
server := NewServerSession(userValidator, sessionHistory)
actualRequest, err := server.DecodeRequestHeader(buffer)
actualRequest, err := server.DecodeRequestHeader(buffer, false)
common.Must(err)
if r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != "" {
t.Error(r)
}
_, err = server.DecodeRequestHeader(buffer2)
_, err = server.DecodeRequestHeader(buffer2, false)
// anti replay attack
if err == nil {
t.Error("nil error")
@@ -107,7 +107,7 @@ func TestInvalidRequest(t *testing.T) {
defer common.Close(userValidator)
server := NewServerSession(userValidator, sessionHistory)
_, err := server.DecodeRequestHeader(buffer)
_, err := server.DecodeRequestHeader(buffer, false)
if err == nil {
t.Error("nil error")
}
@@ -148,7 +148,7 @@ func TestMuxRequest(t *testing.T) {
defer common.Close(userValidator)
server := NewServerSession(userValidator, sessionHistory)
actualRequest, err := server.DecodeRequestHeader(buffer)
actualRequest, err := server.DecodeRequestHeader(buffer, false)
common.Must(err)
if r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != "" {

View File

@@ -131,7 +131,7 @@ func parseSecurityType(b byte) protocol.SecurityType {
}
// DecodeRequestHeader decodes and returns (if successful) a RequestHeader from an input stream.
func (s *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.RequestHeader, error) {
func (s *ServerSession) DecodeRequestHeader(reader io.Reader, isDrain bool) (*protocol.RequestHeader, error) {
buffer := buf.New()
behaviorRand := dice.NewDeterministicDice(int64(s.userValidator.GetBehaviorSeed()))
BaseDrainSize := behaviorRand.Roll(3266)
@@ -143,7 +143,7 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
drainConnection := func(e error) error {
// We read a deterministic generated length of data before closing the connection to offset padding read pattern
readSizeRemain -= int(buffer.Len())
if readSizeRemain > 0 {
if readSizeRemain > 0 && isDrain {
err := s.DrainConnN(reader, readSizeRemain)
if err != nil {
return newError("failed to drain connection DrainSize = ", BaseDrainSize, " ", RandDrainMax, " ", RandDrainRolled).Base(err).Base(e)

View File

@@ -1,5 +1,3 @@
// +build !confonly
package inbound
// GetDefaultValue returns default settings of DefaultConfig.

View File

@@ -1,5 +1,3 @@
// +build !confonly
package inbound
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
@@ -222,9 +220,18 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
return newError("unable to set read deadline").Base(err).AtWarning()
}
iConn := connection
if statConn, ok := iConn.(*internet.StatCouterConnection); ok {
iConn = statConn.Connection
}
_, isDrain := iConn.(*net.TCPConn)
if !isDrain {
_, isDrain = iConn.(*net.UnixConn)
}
reader := &buf.BufferedReader{Reader: buf.NewReader(connection)}
svrSession := encoding.NewServerSession(h.clients, h.sessionHistory)
request, err := svrSession.DecodeRequestHeader(reader)
request, err := svrSession.DecodeRequestHeader(reader, isDrain)
if err != nil {
if errors.Cause(err) != io.EOF {
log.Record(&log.AccessMessage{

View File

@@ -1,5 +1,3 @@
// +build !confonly
package outbound
import (

Some files were not shown because too many files have changed in this diff Show More