mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-15 01:09:20 +02:00
Merge branch 'dns' into dns-geo
This commit is contained in:
commit
8a7cd65fc2
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
func TestLocalNameServer(t *testing.T) {
|
func TestLocalNameServer(t *testing.T) {
|
||||||
s := NewLocalNameServer()
|
s := NewLocalNameServer()
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||||
ips, err := s.QueryIP(ctx, "google.com", net.IP{}, dns.IPOption{
|
ips, err := s.QueryIP(ctx, "google.com", net.IP{}, dns.IPOption{
|
||||||
IPv4Enable: true,
|
IPv4Enable: true,
|
||||||
IPv6Enable: true,
|
IPv6Enable: true,
|
||||||
|
|
|
@ -27,8 +27,6 @@ import (
|
||||||
// by selecting the ALPN token "dq" in the crypto handshake.
|
// by selecting the ALPN token "dq" in the crypto handshake.
|
||||||
const NextProtoDQ = "doq-i00"
|
const NextProtoDQ = "doq-i00"
|
||||||
|
|
||||||
const handshakeTimeout = time.Second * 8
|
|
||||||
|
|
||||||
// QUICNameServer implemented DNS over QUIC
|
// QUICNameServer implemented DNS over QUIC
|
||||||
type QUICNameServer struct {
|
type QUICNameServer struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
|
@ -373,9 +371,7 @@ func (s *QUICNameServer) getSession() (quic.Session, error) {
|
||||||
|
|
||||||
func (s *QUICNameServer) openSession() (quic.Session, error) {
|
func (s *QUICNameServer) openSession() (quic.Session, error) {
|
||||||
tlsConfig := tls.Config{}
|
tlsConfig := tls.Config{}
|
||||||
quicConfig := &quic.Config{
|
quicConfig := &quic.Config{}
|
||||||
HandshakeTimeout: handshakeTimeout,
|
|
||||||
}
|
|
||||||
|
|
||||||
session, err := quic.DialAddrContext(context.Background(), s.destination.NetAddr(), tlsConfig.GetTLSConfig(tls.WithNextProto("http/1.1", http2.NextProtoTLS, NextProtoDQ)), quicConfig)
|
session, err := quic.DialAddrContext(context.Background(), s.destination.NetAddr(), tlsConfig.GetTLSConfig(tls.WithNextProto("http/1.1", http2.NextProtoTLS, NextProtoDQ)), quicConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -19,7 +19,7 @@ func TestQUICNameServer(t *testing.T) {
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
s, err := NewQUICNameServer(url)
|
s, err := NewQUICNameServer(url)
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||||
ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns_feature.IPOption{
|
ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns_feature.IPOption{
|
||||||
IPv4Enable: true,
|
IPv4Enable: true,
|
||||||
IPv6Enable: true,
|
IPv6Enable: true,
|
||||||
|
@ -36,7 +36,7 @@ func TestQUICNameServerWithCache(t *testing.T) {
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
s, err := NewQUICNameServer(url)
|
s, err := NewQUICNameServer(url)
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||||
ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns_feature.IPOption{
|
ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns_feature.IPOption{
|
||||||
IPv4Enable: true,
|
IPv4Enable: true,
|
||||||
IPv6Enable: true,
|
IPv6Enable: true,
|
||||||
|
@ -47,7 +47,7 @@ func TestQUICNameServerWithCache(t *testing.T) {
|
||||||
t.Error("expect some ips, but got 0")
|
t.Error("expect some ips, but got 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx2, cancel := context.WithTimeout(context.Background(), time.Second*2)
|
ctx2, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||||
ips2, err := s.QueryIP(ctx2, "google.com", net.IP(nil), dns_feature.IPOption{
|
ips2, err := s.QueryIP(ctx2, "google.com", net.IP(nil), dns_feature.IPOption{
|
||||||
IPv4Enable: true,
|
IPv4Enable: true,
|
||||||
IPv6Enable: true,
|
IPv6Enable: true,
|
||||||
|
|
|
@ -38,7 +38,7 @@ func NewExisted(b []byte) *Buffer {
|
||||||
|
|
||||||
oLen := len(b)
|
oLen := len(b)
|
||||||
if oLen < Size {
|
if oLen < Size {
|
||||||
b = append(b, make([]byte, Size-oLen)...)
|
b = b[:Size]
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Buffer{
|
return &Buffer{
|
||||||
|
|
|
@ -80,14 +80,25 @@ func getFormat(filename string) string {
|
||||||
func LoadConfig(formatName string, input interface{}) (*Config, error) {
|
func LoadConfig(formatName string, input interface{}) (*Config, error) {
|
||||||
switch v := input.(type) {
|
switch v := input.(type) {
|
||||||
case cmdarg.Arg:
|
case cmdarg.Arg:
|
||||||
|
|
||||||
formats := make([]string, len(v))
|
formats := make([]string, len(v))
|
||||||
hasProtobuf := false
|
hasProtobuf := false
|
||||||
for i, file := range v {
|
for i, file := range v {
|
||||||
f := getFormat(file)
|
var f string
|
||||||
if f == "" {
|
|
||||||
|
if formatName == "auto" {
|
||||||
|
if file != "stdin:" {
|
||||||
|
f = getFormat(file)
|
||||||
|
} else {
|
||||||
|
f = "json"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
f = formatName
|
f = formatName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f == "" {
|
||||||
|
return nil, newError("Failed to get format of ", file).AtWarning()
|
||||||
|
}
|
||||||
|
|
||||||
if f == "protobuf" {
|
if f == "protobuf" {
|
||||||
hasProtobuf = true
|
hasProtobuf = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
version = "1.4.0"
|
version = "1.4.2"
|
||||||
build = "Custom"
|
build = "Custom"
|
||||||
codename = "Xray, Penetrates Everything."
|
codename = "Xray, Penetrates Everything."
|
||||||
intro = "A unified platform for anti-censorship."
|
intro = "A unified platform for anti-censorship."
|
||||||
|
|
17
go.mod
17
go.mod
|
@ -5,22 +5,23 @@ go 1.16
|
||||||
require (
|
require (
|
||||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
|
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
|
||||||
github.com/golang/mock v1.5.0
|
github.com/golang/mock v1.5.0
|
||||||
github.com/golang/protobuf v1.4.3
|
github.com/golang/protobuf v1.5.2
|
||||||
github.com/google/go-cmp v0.5.5
|
github.com/google/go-cmp v0.5.5
|
||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
github.com/lucas-clemente/quic-go v0.19.3
|
github.com/lucas-clemente/quic-go v0.20.0
|
||||||
github.com/miekg/dns v1.1.40
|
github.com/miekg/dns v1.1.41
|
||||||
github.com/pelletier/go-toml v1.8.1
|
github.com/pelletier/go-toml v1.8.1
|
||||||
github.com/pires/go-proxyproto v0.5.0
|
github.com/pires/go-proxyproto v0.5.0
|
||||||
|
github.com/refraction-networking/utls v0.0.0-20201210053706-2179f286686b
|
||||||
github.com/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c
|
github.com/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499
|
github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499
|
||||||
go.starlark.net v0.0.0-20210312235212-74c10e2c17dc
|
go.starlark.net v0.0.0-20210312235212-74c10e2c17dc
|
||||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
|
golang.org/x/net v0.0.0-20210330230544-e57232859fb2
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||||
golang.org/x/sys v0.0.0-20210313202042-bd2e13477e9c
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44
|
||||||
google.golang.org/grpc v1.36.0
|
google.golang.org/grpc v1.36.1
|
||||||
google.golang.org/protobuf v1.25.0
|
google.golang.org/protobuf v1.26.0
|
||||||
h12.io/socks v1.0.2
|
h12.io/socks v1.0.2
|
||||||
)
|
)
|
||||||
|
|
61
go.sum
61
go.sum
|
@ -43,12 +43,9 @@ github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev
|
||||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
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=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
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.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/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||||
github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
|
github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
|
||||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||||
|
@ -62,8 +59,9 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||||
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
@ -98,19 +96,19 @@ 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/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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
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.20.0 h1:FSU3YN5VnLafHR27Ejs1r1CYMS7XMyIVDzRewkDLNBw=
|
||||||
github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8=
|
github.com/lucas-clemente/quic-go v0.20.0/go.mod h1:fZq/HUDIM+mW6X6wtzORjC0E/WDBMKe5Hf9bgjISwLk=
|
||||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
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/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/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
|
||||||
github.com/marten-seemann/qtls v0.10.0 h1:ECsuYUKalRL240rRD4Ri33ISb7kAQ3qGDlrrl55b2pc=
|
github.com/marten-seemann/qtls-go1-15 v0.1.4 h1:RehYMOyRW8hPVEja1KBVsFVNSm35Jj9Mvs5yNoZZ28A=
|
||||||
github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs=
|
github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
|
||||||
github.com/marten-seemann/qtls-go1-15 v0.1.1 h1:LIH6K34bPVttyXnUWixk0bzH6/N07VxbSabxn5A5gZQ=
|
github.com/marten-seemann/qtls-go1-16 v0.1.3 h1:XEZ1xGorVy9u+lJq+WXNE+hiqRYLNvJGYmwfwKQN2gU=
|
||||||
github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
|
github.com/marten-seemann/qtls-go1-16 v0.1.3/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
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/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||||
github.com/miekg/dns v1.1.40 h1:pyyPFfGMnciYUk/mXpKkVmeMQjfXqt3FAJ2hy7tPiLA=
|
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
|
||||||
github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
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/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/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||||
|
@ -139,6 +137,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
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/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/refraction-networking/utls v0.0.0-20201210053706-2179f286686b h1:lzo71oHzQEz0fKMSjR0BpVzuh2hOHvJTxnN3Rnikmtg=
|
||||||
|
github.com/refraction-networking/utls v0.0.0-20201210053706-2179f286686b/go.mod h1:tz9gX959MEFfFN5whTIocCLUG57WiILqtdVxI8c6Wj0=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c h1:pqy40B3MQWYrza7YZXOXgl0Nf0QGFqrOC0BKae1UNAA=
|
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/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
|
||||||
|
@ -169,7 +169,6 @@ github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:Udh
|
||||||
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
|
@ -180,7 +179,6 @@ github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMI
|
||||||
github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499 h1:QHESTXtfgc1ABV+ArlbPVqUx9Ht5I0dDkYhxYoXFxNo=
|
github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499 h1:QHESTXtfgc1ABV+ArlbPVqUx9Ht5I0dDkYhxYoXFxNo=
|
||||||
github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499/go.mod h1:5TB2+k58gx4A4g2Nf5miSHNDF6CuAzHKpWBooLAshTs=
|
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.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.starlark.net v0.0.0-20210312235212-74c10e2c17dc h1:pVkptfeOTFfx+zXZo7HEHN3d5LmhatBFvHdm/f2QnpY=
|
go.starlark.net v0.0.0-20210312235212-74c10e2c17dc h1:pVkptfeOTFfx+zXZo7HEHN3d5LmhatBFvHdm/f2QnpY=
|
||||||
go.starlark.net v0.0.0-20210312235212-74c10e2c17dc/go.mod h1:t3mmBBPzAVvK0L0n1drDmrQsJ8FoIx4INCqVMTr/Zo0=
|
go.starlark.net v0.0.0-20210312235212-74c10e2c17dc/go.mod h1:t3mmBBPzAVvK0L0n1drDmrQsJ8FoIx4INCqVMTr/Zo0=
|
||||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||||
|
@ -191,14 +189,13 @@ 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-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-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-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
||||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
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-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -211,11 +208,11 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
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-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-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210330230544-e57232859fb2 h1:nGCZOty+lVDsc4H2qPFksI5Se296+V+GhMiL/TzmYNk=
|
||||||
|
golang.org/x/net v0.0.0-20210330230544-e57232859fb2/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
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-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
@ -235,22 +232,19 @@ golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
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-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210313202042-bd2e13477e9c h1:coiPEfMv+ThsjULRDygLrJVlNE1gDdL2g65s0LhV2os=
|
golang.org/x/sys v0.0.0-20201231184435-2d18734c6014/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210313202042-bd2e13477e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c=
|
||||||
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
@ -267,7 +261,6 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
@ -285,7 +278,6 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA
|
||||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||||
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
|
@ -293,12 +285,11 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE
|
||||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/grpc v1.36.0 h1:o1bcQ6imQMIOpdrO3SWf2z5RV72WbDwdXuK0MDlc8As=
|
google.golang.org/grpc v1.36.1 h1:cmUfbeGKnz9+2DD/UYsMQXeqbHZqZDs4eQwW0sFOpBY=
|
||||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
|
@ -307,8 +298,10 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
|
||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
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=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
|
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||||
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
@ -331,7 +324,5 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/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=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
|
||||||
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||||
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
|
|
||||||
type NameServerConfig struct {
|
type NameServerConfig struct {
|
||||||
Address *Address
|
Address *Address
|
||||||
|
ClientIP *Address
|
||||||
Port uint16
|
Port uint16
|
||||||
Domains []string
|
Domains []string
|
||||||
ExpectIPs StringList
|
ExpectIPs StringList
|
||||||
|
@ -30,12 +31,14 @@ func (c *NameServerConfig) UnmarshalJSON(data []byte) error {
|
||||||
|
|
||||||
var advanced struct {
|
var advanced struct {
|
||||||
Address *Address `json:"address"`
|
Address *Address `json:"address"`
|
||||||
|
ClientIP *Address `json:"clientIp"`
|
||||||
Port uint16 `json:"port"`
|
Port uint16 `json:"port"`
|
||||||
Domains []string `json:"domains"`
|
Domains []string `json:"domains"`
|
||||||
ExpectIPs StringList `json:"expectIps"`
|
ExpectIPs StringList `json:"expectIps"`
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(data, &advanced); err == nil {
|
if err := json.Unmarshal(data, &advanced); err == nil {
|
||||||
c.Address = advanced.Address
|
c.Address = advanced.Address
|
||||||
|
c.ClientIP = advanced.ClientIP
|
||||||
c.Port = advanced.Port
|
c.Port = advanced.Port
|
||||||
c.Domains = advanced.Domains
|
c.Domains = advanced.Domains
|
||||||
c.ExpectIPs = advanced.ExpectIPs
|
c.ExpectIPs = advanced.ExpectIPs
|
||||||
|
@ -76,12 +79,20 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) {
|
||||||
return nil, newError("invalid IP rule: ", c.ExpectIPs).Base(err)
|
return nil, newError("invalid IP rule: ", c.ExpectIPs).Base(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var myClientIP []byte
|
||||||
|
if c.ClientIP != nil {
|
||||||
|
if !c.ClientIP.Family().IsIP() {
|
||||||
|
return nil, newError("not an IP address:", c.ClientIP.String())
|
||||||
|
}
|
||||||
|
myClientIP = []byte(c.ClientIP.IP())
|
||||||
|
}
|
||||||
return &dns.NameServer{
|
return &dns.NameServer{
|
||||||
Address: &net.Endpoint{
|
Address: &net.Endpoint{
|
||||||
Network: net.Network_UDP,
|
Network: net.Network_UDP,
|
||||||
Address: c.Address.Build(),
|
Address: c.Address.Build(),
|
||||||
Port: uint32(c.Port),
|
Port: uint32(c.Port),
|
||||||
},
|
},
|
||||||
|
ClientIp: myClientIP,
|
||||||
PrioritizedDomain: domains,
|
PrioritizedDomain: domains,
|
||||||
Geoip: geoipList,
|
Geoip: geoipList,
|
||||||
OriginalRules: originalRules,
|
OriginalRules: originalRules,
|
||||||
|
|
|
@ -68,6 +68,7 @@ func TestDNSConfigParsing(t *testing.T) {
|
||||||
Input: `{
|
Input: `{
|
||||||
"servers": [{
|
"servers": [{
|
||||||
"address": "8.8.8.8",
|
"address": "8.8.8.8",
|
||||||
|
"clientIp": "10.0.0.1",
|
||||||
"port": 5353,
|
"port": 5353,
|
||||||
"domains": ["domain:example.com"]
|
"domains": ["domain:example.com"]
|
||||||
}],
|
}],
|
||||||
|
@ -95,6 +96,7 @@ func TestDNSConfigParsing(t *testing.T) {
|
||||||
Network: net.Network_UDP,
|
Network: net.Network_UDP,
|
||||||
Port: 5353,
|
Port: 5353,
|
||||||
},
|
},
|
||||||
|
ClientIp: []byte{10, 0, 0, 1},
|
||||||
PrioritizedDomain: []*domain.Domain{
|
PrioritizedDomain: []*domain.Domain{
|
||||||
{
|
{
|
||||||
Type: domain.MatchingType_Subdomain,
|
Type: domain.MatchingType_Subdomain,
|
||||||
|
|
|
@ -321,6 +321,7 @@ type TLSConfig struct {
|
||||||
MaxVersion string `json:"maxVersion"`
|
MaxVersion string `json:"maxVersion"`
|
||||||
CipherSuites string `json:"cipherSuites"`
|
CipherSuites string `json:"cipherSuites"`
|
||||||
PreferServerCipherSuites bool `json:"preferServerCipherSuites"`
|
PreferServerCipherSuites bool `json:"preferServerCipherSuites"`
|
||||||
|
Fingerprint string `json:"fingerprint"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build implements Buildable.
|
// Build implements Buildable.
|
||||||
|
@ -348,6 +349,7 @@ func (c *TLSConfig) Build() (proto.Message, error) {
|
||||||
config.MaxVersion = c.MaxVersion
|
config.MaxVersion = c.MaxVersion
|
||||||
config.CipherSuites = c.CipherSuites
|
config.CipherSuites = c.CipherSuites
|
||||||
config.PreferServerCipherSuites = c.PreferServerCipherSuites
|
config.PreferServerCipherSuites = c.PreferServerCipherSuites
|
||||||
|
config.Fingerprint = strings.ToLower(c.Fingerprint)
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,22 +478,19 @@ type SocketConfig struct {
|
||||||
|
|
||||||
// Build implements Buildable.
|
// Build implements Buildable.
|
||||||
func (c *SocketConfig) Build() (*internet.SocketConfig, error) {
|
func (c *SocketConfig) Build() (*internet.SocketConfig, error) {
|
||||||
tfo := int32(-1)
|
tfo := int32(0) // don't invoke setsockopt() for TFO
|
||||||
if c.TFO != nil {
|
if c.TFO != nil {
|
||||||
switch v := c.TFO.(type) {
|
switch v := c.TFO.(type) {
|
||||||
case bool:
|
case bool:
|
||||||
if v {
|
if v {
|
||||||
tfo = 256
|
tfo = 256
|
||||||
} else {
|
} else {
|
||||||
tfo = 0
|
tfo = -1 // TFO need to be disabled
|
||||||
}
|
}
|
||||||
case float64:
|
case float64:
|
||||||
if v < 0 {
|
|
||||||
return nil, newError("tcpFastOpen: only boolean and non-negative integer value is acceptable")
|
|
||||||
}
|
|
||||||
tfo = int32(math.Min(v, math.MaxInt32))
|
tfo = int32(math.Min(v, math.MaxInt32))
|
||||||
default:
|
default:
|
||||||
return nil, newError("tcpFastOpen: only boolean and non-negative integer value is acceptable")
|
return nil, newError("tcpFastOpen: only boolean and integer value is acceptable")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var tproxy internet.SocketConfig_TProxyMode
|
var tproxy internet.SocketConfig_TProxyMode
|
||||||
|
|
|
@ -31,6 +31,13 @@ func TestSocketConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test "tcpFastOpen": true, queue length 256 is expected. other parameters are tested here too
|
||||||
|
expectedOutput := &internet.SocketConfig{
|
||||||
|
Mark: 1,
|
||||||
|
Tfo: 256,
|
||||||
|
DomainStrategy: internet.DomainStrategy_USE_IP,
|
||||||
|
DialerProxy: "tag",
|
||||||
|
}
|
||||||
runMultiTestCase(t, []TestCase{
|
runMultiTestCase(t, []TestCase{
|
||||||
{
|
{
|
||||||
Input: `{
|
Input: `{
|
||||||
|
@ -40,38 +47,118 @@ func TestSocketConfig(t *testing.T) {
|
||||||
"dialerProxy": "tag"
|
"dialerProxy": "tag"
|
||||||
}`,
|
}`,
|
||||||
Parser: createParser(),
|
Parser: createParser(),
|
||||||
Output: &internet.SocketConfig{
|
Output: expectedOutput,
|
||||||
Mark: 1,
|
|
||||||
Tfo: 256,
|
|
||||||
DomainStrategy: internet.DomainStrategy_USE_IP,
|
|
||||||
DialerProxy: "tag",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
if expectedOutput.ParseTFOValue() != 256 {
|
||||||
|
t.Fatalf("unexpected parsed TFO value, which should be 256")
|
||||||
|
}
|
||||||
|
|
||||||
|
// test "tcpFastOpen": false, disabled TFO is expected
|
||||||
|
expectedOutput = &internet.SocketConfig{
|
||||||
|
Mark: 0,
|
||||||
|
Tfo: -1,
|
||||||
|
}
|
||||||
runMultiTestCase(t, []TestCase{
|
runMultiTestCase(t, []TestCase{
|
||||||
{
|
{
|
||||||
Input: `{
|
Input: `{
|
||||||
"tcpFastOpen": false
|
"tcpFastOpen": false
|
||||||
}`,
|
}`,
|
||||||
Parser: createParser(),
|
Parser: createParser(),
|
||||||
Output: &internet.SocketConfig{
|
Output: expectedOutput,
|
||||||
Mark: 0,
|
|
||||||
Tfo: 0,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
if expectedOutput.ParseTFOValue() != 0 {
|
||||||
|
t.Fatalf("unexpected parsed TFO value, which should be 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
// test "tcpFastOpen": 65535, queue length 65535 is expected
|
||||||
|
expectedOutput = &internet.SocketConfig{
|
||||||
|
Mark: 0,
|
||||||
|
Tfo: 65535,
|
||||||
|
}
|
||||||
runMultiTestCase(t, []TestCase{
|
runMultiTestCase(t, []TestCase{
|
||||||
{
|
{
|
||||||
Input: `{
|
Input: `{
|
||||||
"tcpFastOpen": 65535
|
"tcpFastOpen": 65535
|
||||||
}`,
|
}`,
|
||||||
Parser: createParser(),
|
Parser: createParser(),
|
||||||
Output: &internet.SocketConfig{
|
Output: expectedOutput,
|
||||||
Mark: 0,
|
|
||||||
Tfo: 65535,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
if expectedOutput.ParseTFOValue() != 65535 {
|
||||||
|
t.Fatalf("unexpected parsed TFO value, which should be 65535")
|
||||||
|
}
|
||||||
|
|
||||||
|
// test "tcpFastOpen": -65535, disable TFO is expected
|
||||||
|
expectedOutput = &internet.SocketConfig{
|
||||||
|
Mark: 0,
|
||||||
|
Tfo: -65535,
|
||||||
|
}
|
||||||
|
runMultiTestCase(t, []TestCase{
|
||||||
|
{
|
||||||
|
Input: `{
|
||||||
|
"tcpFastOpen": -65535
|
||||||
|
}`,
|
||||||
|
Parser: createParser(),
|
||||||
|
Output: expectedOutput,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if expectedOutput.ParseTFOValue() != 0 {
|
||||||
|
t.Fatalf("unexpected parsed TFO value, which should be 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
// test "tcpFastOpen": 0, no operation is expected
|
||||||
|
expectedOutput = &internet.SocketConfig{
|
||||||
|
Mark: 0,
|
||||||
|
Tfo: 0,
|
||||||
|
}
|
||||||
|
runMultiTestCase(t, []TestCase{
|
||||||
|
{
|
||||||
|
Input: `{
|
||||||
|
"tcpFastOpen": 0
|
||||||
|
}`,
|
||||||
|
Parser: createParser(),
|
||||||
|
Output: expectedOutput,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if expectedOutput.ParseTFOValue() != -1 {
|
||||||
|
t.Fatalf("unexpected parsed TFO value, which should be -1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// test omit "tcpFastOpen", no operation is expected
|
||||||
|
expectedOutput = &internet.SocketConfig{
|
||||||
|
Mark: 0,
|
||||||
|
Tfo: 0,
|
||||||
|
}
|
||||||
|
runMultiTestCase(t, []TestCase{
|
||||||
|
{
|
||||||
|
Input: `{}`,
|
||||||
|
Parser: createParser(),
|
||||||
|
Output: expectedOutput,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if expectedOutput.ParseTFOValue() != -1 {
|
||||||
|
t.Fatalf("unexpected parsed TFO value, which should be -1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// test "tcpFastOpen": null, no operation is expected
|
||||||
|
expectedOutput = &internet.SocketConfig{
|
||||||
|
Mark: 0,
|
||||||
|
Tfo: 0,
|
||||||
|
}
|
||||||
|
runMultiTestCase(t, []TestCase{
|
||||||
|
{
|
||||||
|
Input: `{
|
||||||
|
"tcpFastOpen": null
|
||||||
|
}`,
|
||||||
|
Parser: createParser(),
|
||||||
|
Output: expectedOutput,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if expectedOutput.ParseTFOValue() != -1 {
|
||||||
|
t.Fatalf("unexpected parsed TFO value, which should be -1")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTransportConfig(t *testing.T) {
|
func TestTransportConfig(t *testing.T) {
|
||||||
|
|
|
@ -26,6 +26,9 @@ Arguments:
|
||||||
-domain=domain_name
|
-domain=domain_name
|
||||||
The domain name for the certificate.
|
The domain name for the certificate.
|
||||||
|
|
||||||
|
-name=common_name
|
||||||
|
The common name for the certificate.
|
||||||
|
|
||||||
-org=organization
|
-org=organization
|
||||||
The organization name for the certificate.
|
The organization name for the certificate.
|
||||||
|
|
||||||
|
|
22
main/run.go
22
main/run.go
|
@ -11,6 +11,7 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/cmdarg"
|
"github.com/xtls/xray-core/common/cmdarg"
|
||||||
|
@ -31,7 +32,7 @@ Xray. Multiple assign is accepted.
|
||||||
The -confdir=dir flag sets a dir with multiple json config
|
The -confdir=dir flag sets a dir with multiple json config
|
||||||
|
|
||||||
The -format=json flag sets the format of config files.
|
The -format=json flag sets the format of config files.
|
||||||
Default "json".
|
Default "auto".
|
||||||
|
|
||||||
The -test flag tells Xray to test config files only,
|
The -test flag tells Xray to test config files only,
|
||||||
without launching the server
|
without launching the server
|
||||||
|
@ -46,7 +47,7 @@ var (
|
||||||
configFiles cmdarg.Arg // "Config file for Xray.", the option is customed type, parse in main
|
configFiles cmdarg.Arg // "Config file for Xray.", the option is customed type, parse in main
|
||||||
configDir string
|
configDir string
|
||||||
test = cmdRun.Flag.Bool("test", false, "Test config file only, without launching Xray server.")
|
test = cmdRun.Flag.Bool("test", false, "Test config file only, without launching Xray server.")
|
||||||
format = cmdRun.Flag.String("format", "json", "Format of input file.")
|
format = cmdRun.Flag.String("format", "auto", "Format of input file.")
|
||||||
|
|
||||||
/* We have to do this here because Golang's Test will also need to parse flag, before
|
/* We have to do this here because Golang's Test will also need to parse flag, before
|
||||||
* main func in this file is run.
|
* main func in this file is run.
|
||||||
|
@ -111,13 +112,26 @@ func dirExists(file string) bool {
|
||||||
return err == nil && info.IsDir()
|
return err == nil && info.IsDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getRegepxByFormat() string {
|
||||||
|
switch strings.ToLower(*format) {
|
||||||
|
case "json":
|
||||||
|
return `^.+\.json$`
|
||||||
|
case "toml":
|
||||||
|
return `^.+\.toml$`
|
||||||
|
case "yaml", "yml":
|
||||||
|
return `^.+\.(yaml|yml)$`
|
||||||
|
default:
|
||||||
|
return `^.+\.(json|toml|yaml|yml)$`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func readConfDir(dirPath string) {
|
func readConfDir(dirPath string) {
|
||||||
confs, err := ioutil.ReadDir(dirPath)
|
confs, err := ioutil.ReadDir(dirPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
for _, f := range confs {
|
for _, f := range confs {
|
||||||
matched, err := regexp.MatchString(`^.+\.(json|toml|yaml|yml)$`, f.Name())
|
matched, err := regexp.MatchString(getRegepxByFormat(), f.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
@ -160,7 +174,7 @@ func getConfigFilePath() cmdarg.Arg {
|
||||||
func getConfigFormat() string {
|
func getConfigFormat() string {
|
||||||
f := core.GetFormatByExtension(*format)
|
f := core.GetFormatByExtension(*format)
|
||||||
if f == "" {
|
if f == "" {
|
||||||
f = "json"
|
f = "auto"
|
||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,7 +242,6 @@ func (h *Handler) handleIPQuery(id uint16, qType dnsmessage.Type, domain string,
|
||||||
RecursionAvailable: true,
|
RecursionAvailable: true,
|
||||||
RecursionDesired: true,
|
RecursionDesired: true,
|
||||||
Response: true,
|
Response: true,
|
||||||
Authoritative: true,
|
|
||||||
})
|
})
|
||||||
builder.EnableCompression()
|
builder.EnableCompression()
|
||||||
common.Must(builder.StartQuestions())
|
common.Must(builder.StartQuestions())
|
||||||
|
|
|
@ -36,6 +36,7 @@ func init() {
|
||||||
type dialerConf struct {
|
type dialerConf struct {
|
||||||
net.Destination
|
net.Destination
|
||||||
*internet.SocketConfig
|
*internet.SocketConfig
|
||||||
|
*tls.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -46,14 +47,9 @@ var (
|
||||||
func dialgRPC(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (net.Conn, error) {
|
func dialgRPC(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (net.Conn, error) {
|
||||||
grpcSettings := streamSettings.ProtocolSettings.(*Config)
|
grpcSettings := streamSettings.ProtocolSettings.(*Config)
|
||||||
|
|
||||||
config := tls.ConfigFromStreamSettings(streamSettings)
|
tlsConfig := tls.ConfigFromStreamSettings(streamSettings)
|
||||||
var dialOption = grpc.WithInsecure()
|
|
||||||
|
|
||||||
if config != nil {
|
conn, err := getGrpcClient(ctx, dest, tlsConfig, streamSettings.SocketSettings)
|
||||||
dialOption = grpc.WithTransportCredentials(credentials.NewTLS(config.GetTLSConfig()))
|
|
||||||
}
|
|
||||||
|
|
||||||
conn, err := getGrpcClient(ctx, dest, dialOption, streamSettings.SocketSettings)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("Cannot dial gRPC").Base(err)
|
return nil, newError("Cannot dial gRPC").Base(err)
|
||||||
|
@ -76,7 +72,7 @@ func dialgRPC(ctx context.Context, dest net.Destination, streamSettings *interne
|
||||||
return encoding.NewHunkConn(grpcService, nil), nil
|
return encoding.NewHunkConn(grpcService, nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getGrpcClient(ctx context.Context, dest net.Destination, dialOption grpc.DialOption, sockopt *internet.SocketConfig) (*grpc.ClientConn, error) {
|
func getGrpcClient(ctx context.Context, dest net.Destination, tlsConfig *tls.Config, sockopt *internet.SocketConfig) (*grpc.ClientConn, error) {
|
||||||
globalDialerAccess.Lock()
|
globalDialerAccess.Lock()
|
||||||
defer globalDialerAccess.Unlock()
|
defer globalDialerAccess.Unlock()
|
||||||
|
|
||||||
|
@ -84,12 +80,24 @@ func getGrpcClient(ctx context.Context, dest net.Destination, dialOption grpc.Di
|
||||||
globalDialerMap = make(map[dialerConf]*grpc.ClientConn)
|
globalDialerMap = make(map[dialerConf]*grpc.ClientConn)
|
||||||
}
|
}
|
||||||
|
|
||||||
if client, found := globalDialerMap[dialerConf{dest, sockopt}]; found && client.GetState() != connectivity.Shutdown {
|
if client, found := globalDialerMap[dialerConf{dest, sockopt, tlsConfig}]; found && client.GetState() != connectivity.Shutdown {
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialOption := grpc.WithInsecure()
|
||||||
|
|
||||||
|
if tlsConfig != nil {
|
||||||
|
dialOption = grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig.GetTLSConfig()))
|
||||||
|
}
|
||||||
|
|
||||||
|
var grpcDestHost string
|
||||||
|
if dest.Address.Family().IsDomain() {
|
||||||
|
grpcDestHost = dest.Address.Domain()
|
||||||
|
} else {
|
||||||
|
grpcDestHost = dest.Address.IP().String()
|
||||||
|
}
|
||||||
conn, err := grpc.Dial(
|
conn, err := grpc.Dial(
|
||||||
gonet.JoinHostPort(dest.Address.String(), dest.Port.String()),
|
gonet.JoinHostPort(grpcDestHost, dest.Port.String()),
|
||||||
dialOption,
|
dialOption,
|
||||||
grpc.WithConnectParams(grpc.ConnectParams{
|
grpc.WithConnectParams(grpc.ConnectParams{
|
||||||
Backoff: backoff.Config{
|
Backoff: backoff.Config{
|
||||||
|
@ -125,6 +133,6 @@ func getGrpcClient(ctx context.Context, dest net.Destination, dialOption grpc.Di
|
||||||
return internet.DialSystem(gctx, net.TCPDestination(address, port), sockopt)
|
return internet.DialSystem(gctx, net.TCPDestination(address, port), sockopt)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
globalDialerMap[dialerConf{dest, sockopt}] = conn
|
globalDialerMap[dialerConf{dest, sockopt, tlsConfig}] = conn
|
||||||
return conn, err
|
return conn, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ func (h *HunkReaderWriter) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cap(h.buf) == buf.Size {
|
if cap(h.buf) >= buf.Size {
|
||||||
b := h.buf
|
b := h.buf
|
||||||
h.index = len(h.buf)
|
h.index = len(h.buf)
|
||||||
return buf.MultiBuffer{buf.NewExisted(b)}, nil
|
return buf.MultiBuffer{buf.NewExisted(b)}, nil
|
||||||
|
|
|
@ -79,16 +79,20 @@ func (h *MultiHunkReaderWriter) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
||||||
|
|
||||||
var mb = make(buf.MultiBuffer, 0, len(h.buf))
|
var mb = make(buf.MultiBuffer, 0, len(h.buf))
|
||||||
for _, b := range h.buf {
|
for _, b := range h.buf {
|
||||||
if cap(b) >= buf.Size {
|
if len(b) == 0 {
|
||||||
mb = append(mb, buf.NewExisted(b))
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
nb := buf.New()
|
if cap(b) >= buf.Size {
|
||||||
nb.Extend(int32(len(b)))
|
mb = append(mb, buf.NewExisted(b))
|
||||||
copy(nb.Bytes(), b)
|
} else {
|
||||||
|
nb := buf.New()
|
||||||
|
nb.Extend(int32(len(b)))
|
||||||
|
copy(nb.Bytes(), b)
|
||||||
|
|
||||||
|
mb = append(mb, nb)
|
||||||
|
}
|
||||||
|
|
||||||
mb = append(mb, nb)
|
|
||||||
}
|
}
|
||||||
return mb, nil
|
return mb, nil
|
||||||
}
|
}
|
||||||
|
@ -99,12 +103,15 @@ func (h *MultiHunkReaderWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||||
return io.ErrClosedPipe
|
return io.ErrClosedPipe
|
||||||
}
|
}
|
||||||
|
|
||||||
hunk := &MultiHunk{Data: make([][]byte, len(mb))}
|
hunks := make([][]byte, 0, len(mb))
|
||||||
|
|
||||||
for _, b := range mb {
|
for _, b := range mb {
|
||||||
hunk.Data = append(hunk.Data, b.Bytes())
|
if b.Len() > 0 {
|
||||||
|
hunks = append(hunks, b.Bytes())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := h.hc.Send(hunk)
|
err := h.hc.Send(&MultiHunk{Data: hunks})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
type dialerConf struct {
|
type dialerConf struct {
|
||||||
net.Destination
|
net.Destination
|
||||||
*internet.SocketConfig
|
*internet.SocketConfig
|
||||||
|
*tls.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -36,7 +37,7 @@ func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.C
|
||||||
globalDialerMap = make(map[dialerConf]*http.Client)
|
globalDialerMap = make(map[dialerConf]*http.Client)
|
||||||
}
|
}
|
||||||
|
|
||||||
if client, found := globalDialerMap[dialerConf{dest, sockopt}]; found {
|
if client, found := globalDialerMap[dialerConf{dest, sockopt, tlsSettings}]; found {
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.C
|
||||||
Transport: transport,
|
Transport: transport,
|
||||||
}
|
}
|
||||||
|
|
||||||
globalDialerMap[dialerConf{dest, sockopt}] = client
|
globalDialerMap[dialerConf{dest, sockopt, tlsSettings}] = client
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,8 +148,7 @@ func (s *clientSessions) openConnection(destAddr net.Addr, config *Config, tlsCo
|
||||||
|
|
||||||
quicConfig := &quic.Config{
|
quicConfig := &quic.Config{
|
||||||
ConnectionIDLength: 12,
|
ConnectionIDLength: 12,
|
||||||
HandshakeTimeout: time.Second * 8,
|
KeepAlive: true,
|
||||||
MaxIdleTimeout: time.Second * 30,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := wrapSysConn(rawConn, config)
|
conn, err := wrapSysConn(rawConn, config)
|
||||||
|
|
|
@ -103,8 +103,7 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti
|
||||||
|
|
||||||
quicConfig := &quic.Config{
|
quicConfig := &quic.Config{
|
||||||
ConnectionIDLength: 12,
|
ConnectionIDLength: 12,
|
||||||
HandshakeTimeout: time.Second * 8,
|
KeepAlive: true,
|
||||||
MaxIdleTimeout: time.Second * 45,
|
|
||||||
MaxIncomingStreams: 32,
|
MaxIncomingStreams: 32,
|
||||||
MaxIncomingUniStreams: -1,
|
MaxIncomingUniStreams: -1,
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,3 +17,14 @@ func isUDPSocket(network string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *SocketConfig) ParseTFOValue() int {
|
||||||
|
if v.Tfo == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
tfo := int(v.Tfo)
|
||||||
|
if tfo < 0 {
|
||||||
|
tfo = 0
|
||||||
|
}
|
||||||
|
return tfo
|
||||||
|
}
|
||||||
|
|
|
@ -15,12 +15,12 @@ const (
|
||||||
|
|
||||||
func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {
|
func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {
|
||||||
if isTCPSocket(network) {
|
if isTCPSocket(network) {
|
||||||
tfo := config.Tfo
|
tfo := config.ParseTFOValue()
|
||||||
if tfo > 0 {
|
if tfo > 0 {
|
||||||
tfo = TCP_FASTOPEN_CLIENT
|
tfo = TCP_FASTOPEN_CLIENT
|
||||||
}
|
}
|
||||||
if tfo >= 0 {
|
if tfo >= 0 {
|
||||||
if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, TCP_FASTOPEN, int(tfo)); err != nil {
|
if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, TCP_FASTOPEN, tfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,12 +31,12 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
|
||||||
|
|
||||||
func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {
|
func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {
|
||||||
if isTCPSocket(network) {
|
if isTCPSocket(network) {
|
||||||
tfo := config.Tfo
|
tfo := config.ParseTFOValue()
|
||||||
if tfo > 0 {
|
if tfo > 0 {
|
||||||
tfo = TCP_FASTOPEN_SERVER
|
tfo = TCP_FASTOPEN_SERVER
|
||||||
}
|
}
|
||||||
if tfo >= 0 {
|
if tfo >= 0 {
|
||||||
if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, TCP_FASTOPEN, int(tfo)); err != nil {
|
if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, TCP_FASTOPEN, tfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
|
||||||
}
|
}
|
||||||
|
|
||||||
if isTCPSocket(network) {
|
if isTCPSocket(network) {
|
||||||
tfo := int(config.Tfo)
|
tfo := config.ParseTFOValue()
|
||||||
if tfo > 0 {
|
if tfo > 0 {
|
||||||
tfo = 1
|
tfo = 1
|
||||||
}
|
}
|
||||||
|
@ -163,9 +163,10 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isTCPSocket(network) {
|
if isTCPSocket(network) {
|
||||||
if config.Tfo >= 0 {
|
tfo := config.ParseTFOValue()
|
||||||
if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_FASTOPEN, int(config.Tfo)); err != nil {
|
if tfo >= 0 {
|
||||||
return newError("failed to set TCP_FASTOPEN=", config.Tfo).Base(err)
|
if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_FASTOPEN, tfo); err != nil {
|
||||||
|
return newError("failed to set TCP_FASTOPEN=", tfo).Base(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
|
||||||
}
|
}
|
||||||
|
|
||||||
if isTCPSocket(network) {
|
if isTCPSocket(network) {
|
||||||
tfo := int(config.Tfo)
|
tfo := config.ParseTFOValue()
|
||||||
if tfo > 0 {
|
if tfo > 0 {
|
||||||
tfo = 1
|
tfo = 1
|
||||||
}
|
}
|
||||||
|
@ -75,9 +75,10 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isTCPSocket(network) {
|
if isTCPSocket(network) {
|
||||||
if config.Tfo >= 0 {
|
tfo := config.ParseTFOValue()
|
||||||
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN, int(config.Tfo)); err != nil {
|
if tfo >= 0 {
|
||||||
return newError("failed to set TCP_FASTOPEN=", config.Tfo).Base(err)
|
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN, tfo); err != nil {
|
||||||
|
return newError("failed to set TCP_FASTOPEN=", tfo).Base(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,12 @@ const (
|
||||||
TCP_FASTOPEN = 15
|
TCP_FASTOPEN = 15
|
||||||
)
|
)
|
||||||
|
|
||||||
func setTFO(fd syscall.Handle, tfo int32) error {
|
func setTFO(fd syscall.Handle, tfo int) error {
|
||||||
if tfo > 0 {
|
if tfo > 0 {
|
||||||
tfo = 1
|
tfo = 1
|
||||||
}
|
}
|
||||||
if tfo >= 0 {
|
if tfo >= 0 {
|
||||||
if err := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, TCP_FASTOPEN, int(tfo)); err != nil {
|
if err := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, TCP_FASTOPEN, tfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ func setTFO(fd syscall.Handle, tfo int32) error {
|
||||||
|
|
||||||
func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {
|
func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {
|
||||||
if isTCPSocket(network) {
|
if isTCPSocket(network) {
|
||||||
if err := setTFO(syscall.Handle(fd), config.Tfo); err != nil {
|
if err := setTFO(syscall.Handle(fd), config.ParseTFOValue()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
|
||||||
|
|
||||||
func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {
|
func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {
|
||||||
if isTCPSocket(network) {
|
if isTCPSocket(network) {
|
||||||
if err := setTFO(syscall.Handle(fd), config.Tfo); err != nil {
|
if err := setTFO(syscall.Handle(fd), config.ParseTFOValue()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,14 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
|
||||||
|
|
||||||
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
|
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||||
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
|
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
|
||||||
/*
|
if fingerprint, ok := tls.Fingerprints[config.Fingerprint]; ok {
|
||||||
if config.IsExperiment8357() {
|
conn = tls.UClient(conn, tlsConfig, fingerprint)
|
||||||
conn = tls.UClient(conn, tlsConfig)
|
if err := conn.(*tls.UConn).Handshake(); err != nil {
|
||||||
} else {
|
return nil, err
|
||||||
conn = tls.Client(conn, tlsConfig)
|
|
||||||
}
|
}
|
||||||
*/
|
} else {
|
||||||
conn = tls.Client(conn, tlsConfig)
|
conn = tls.Client(conn, tlsConfig)
|
||||||
|
}
|
||||||
} else if config := xtls.ConfigFromStreamSettings(streamSettings); config != nil {
|
} else if config := xtls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||||
xtlsConfig := config.GetXTLSConfig(xtls.WithDestination(dest))
|
xtlsConfig := config.GetXTLSConfig(xtls.WithDestination(dest))
|
||||||
conn = xtls.Client(conn, xtlsConfig)
|
conn = xtls.Client(conn, xtlsConfig)
|
||||||
|
|
|
@ -38,7 +38,8 @@ func ListenTCP(ctx context.Context, address net.Address, port net.Port, streamSe
|
||||||
if streamSettings.SocketSettings == nil {
|
if streamSettings.SocketSettings == nil {
|
||||||
streamSettings.SocketSettings = &internet.SocketConfig{}
|
streamSettings.SocketSettings = &internet.SocketConfig{}
|
||||||
}
|
}
|
||||||
streamSettings.SocketSettings.AcceptProxyProtocol = l.config.AcceptProxyProtocol
|
streamSettings.SocketSettings.AcceptProxyProtocol =
|
||||||
|
l.config.AcceptProxyProtocol || streamSettings.SocketSettings.AcceptProxyProtocol
|
||||||
}
|
}
|
||||||
var listener net.Listener
|
var listener net.Listener
|
||||||
var err error
|
var err error
|
||||||
|
|
|
@ -18,8 +18,6 @@ var (
|
||||||
globalSessionCache = tls.NewLRUClientSessionCache(128)
|
globalSessionCache = tls.NewLRUClientSessionCache(128)
|
||||||
)
|
)
|
||||||
|
|
||||||
const exp8357 = "experiment:8357"
|
|
||||||
|
|
||||||
// ParseCertificate converts a cert.Certificate to Certificate.
|
// ParseCertificate converts a cert.Certificate to Certificate.
|
||||||
func ParseCertificate(c *cert.Certificate) *Certificate {
|
func ParseCertificate(c *cert.Certificate) *Certificate {
|
||||||
if c != nil {
|
if c != nil {
|
||||||
|
@ -240,15 +238,7 @@ func getNewGetCertficateFunc(certs []*tls.Certificate) func(hello *tls.ClientHel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) IsExperiment8357() bool {
|
|
||||||
return strings.HasPrefix(c.ServerName, exp8357)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) parseServerName() string {
|
func (c *Config) parseServerName() string {
|
||||||
if c.IsExperiment8357() {
|
|
||||||
return c.ServerName[len(exp8357):]
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.ServerName
|
return c.ServerName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.25.0
|
// protoc-gen-go v1.25.0
|
||||||
// protoc v3.14.0
|
// protoc v3.15.6
|
||||||
// source: transport/internet/tls/config.proto
|
// source: transport/internet/tls/config.proto
|
||||||
|
|
||||||
package tls
|
package tls
|
||||||
|
@ -200,6 +200,8 @@ type Config struct {
|
||||||
CipherSuites string `protobuf:"bytes,9,opt,name=cipher_suites,json=cipherSuites,proto3" json:"cipher_suites,omitempty"`
|
CipherSuites string `protobuf:"bytes,9,opt,name=cipher_suites,json=cipherSuites,proto3" json:"cipher_suites,omitempty"`
|
||||||
// Whether the server selects its most preferred ciphersuite.
|
// Whether the server selects its most preferred ciphersuite.
|
||||||
PreferServerCipherSuites bool `protobuf:"varint,10,opt,name=prefer_server_cipher_suites,json=preferServerCipherSuites,proto3" json:"prefer_server_cipher_suites,omitempty"`
|
PreferServerCipherSuites bool `protobuf:"varint,10,opt,name=prefer_server_cipher_suites,json=preferServerCipherSuites,proto3" json:"prefer_server_cipher_suites,omitempty"`
|
||||||
|
// TLS Client Hello fingerprint (uTLS).
|
||||||
|
Fingerprint string `protobuf:"bytes,11,opt,name=fingerprint,proto3" json:"fingerprint,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Config) Reset() {
|
func (x *Config) Reset() {
|
||||||
|
@ -304,6 +306,13 @@ func (x *Config) GetPreferServerCipherSuites() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *Config) GetFingerprint() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Fingerprint
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
var File_transport_internet_tls_config_proto protoreflect.FileDescriptor
|
var File_transport_internet_tls_config_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
var file_transport_internet_tls_config_proto_rawDesc = []byte{
|
var file_transport_internet_tls_config_proto_rawDesc = []byte{
|
||||||
|
@ -333,7 +342,7 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{
|
||||||
0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10,
|
0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10,
|
||||||
0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59,
|
0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59,
|
||||||
0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f,
|
0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f,
|
||||||
0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0xd3, 0x03, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66,
|
0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0xf5, 0x03, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66,
|
||||||
0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x65,
|
0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x65,
|
||||||
0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f,
|
0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f,
|
||||||
0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x4a, 0x0a, 0x0b, 0x63, 0x65, 0x72,
|
0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x4a, 0x0a, 0x0b, 0x63, 0x65, 0x72,
|
||||||
|
@ -362,15 +371,17 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{
|
||||||
0x0a, 0x1b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f,
|
0x0a, 0x1b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f,
|
||||||
0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20,
|
0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20,
|
||||||
0x01, 0x28, 0x08, 0x52, 0x18, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65,
|
0x01, 0x28, 0x08, 0x52, 0x18, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65,
|
||||||
0x72, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x42, 0x73, 0x0a,
|
0x72, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x12, 0x20, 0x0a,
|
||||||
0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70,
|
0x0b, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01,
|
||||||
0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73,
|
0x28, 0x09, 0x52, 0x0b, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x42,
|
||||||
0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78,
|
0x73, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e,
|
||||||
0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72,
|
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74,
|
||||||
0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
|
0x6c, 0x73, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||||
0x2f, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x1b, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e,
|
0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f,
|
||||||
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54,
|
0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||||
0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x1b, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72,
|
||||||
|
0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
|
||||||
|
0x2e, 0x54, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -64,4 +64,7 @@ message Config {
|
||||||
|
|
||||||
// Whether the server selects its most preferred ciphersuite.
|
// Whether the server selects its most preferred ciphersuite.
|
||||||
bool prefer_server_cipher_suites = 10;
|
bool prefer_server_cipher_suites = 10;
|
||||||
|
|
||||||
|
// TLS Client Hello fingerprint (uTLS).
|
||||||
|
string fingerprint = 11;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package tls
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
|
||||||
|
utls "github.com/refraction-networking/utls"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/buf"
|
"github.com/xtls/xray-core/common/buf"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
)
|
)
|
||||||
|
@ -41,25 +43,43 @@ func Client(c net.Conn, config *tls.Config) net.Conn {
|
||||||
return &Conn{Conn: tlsConn}
|
return &Conn{Conn: tlsConn}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func copyConfig(c *tls.Config) *utls.Config {
|
|
||||||
return &utls.Config{
|
|
||||||
NextProtos: c.NextProtos,
|
|
||||||
ServerName: c.ServerName,
|
|
||||||
InsecureSkipVerify: c.InsecureSkipVerify,
|
|
||||||
MinVersion: utls.VersionTLS12,
|
|
||||||
MaxVersion: utls.VersionTLS12,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func UClient(c net.Conn, config *tls.Config) net.Conn {
|
|
||||||
uConfig := copyConfig(config)
|
|
||||||
return utls.Client(c, uConfig)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Server initiates a TLS server handshake on the given connection.
|
// Server initiates a TLS server handshake on the given connection.
|
||||||
func Server(c net.Conn, config *tls.Config) net.Conn {
|
func Server(c net.Conn, config *tls.Config) net.Conn {
|
||||||
tlsConn := tls.Server(c, config)
|
tlsConn := tls.Server(c, config)
|
||||||
return &Conn{Conn: tlsConn}
|
return &Conn{Conn: tlsConn}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UConn struct {
|
||||||
|
*utls.UConn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *UConn) HandshakeAddress() net.Address {
|
||||||
|
if err := c.Handshake(); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
state := c.ConnectionState()
|
||||||
|
if state.ServerName == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return net.ParseAddress(state.ServerName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UClient(c net.Conn, config *tls.Config, fingerprint *utls.ClientHelloID) net.Conn {
|
||||||
|
utlsConn := utls.UClient(c, copyConfig(config), *fingerprint)
|
||||||
|
return &UConn{UConn: utlsConn}
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyConfig(c *tls.Config) *utls.Config {
|
||||||
|
return &utls.Config{
|
||||||
|
RootCAs: c.RootCAs,
|
||||||
|
ServerName: c.ServerName,
|
||||||
|
InsecureSkipVerify: c.InsecureSkipVerify,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var Fingerprints = map[string]*utls.ClientHelloID{
|
||||||
|
"chrome": &utls.HelloChrome_Auto,
|
||||||
|
"firefox": &utls.HelloFirefox_Auto,
|
||||||
|
"safari": &utls.HelloIOS_Auto,
|
||||||
|
"randomized": &utls.HelloRandomized,
|
||||||
|
}
|
||||||
|
|
|
@ -2,8 +2,12 @@ package websocket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
_ "embed"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
|
@ -15,6 +19,27 @@ import (
|
||||||
"github.com/xtls/xray-core/transport/internet/tls"
|
"github.com/xtls/xray-core/transport/internet/tls"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:embed dialer.html
|
||||||
|
var webpage []byte
|
||||||
|
var conns chan *websocket.Conn
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if addr := os.Getenv("XRAY_BROWSER_DIALER"); addr != "" {
|
||||||
|
conns = make(chan *websocket.Conn, 256)
|
||||||
|
go http.ListenAndServe(addr, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.URL.Path == "/websocket" {
|
||||||
|
if conn, err := upgrader.Upgrade(w, r, nil); err == nil {
|
||||||
|
conns <- conn
|
||||||
|
} else {
|
||||||
|
fmt.Println("unexpected error")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
w.Write(webpage)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Dial dials a WebSocket connection to the given destination.
|
// Dial dials a WebSocket connection to the given destination.
|
||||||
func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {
|
func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {
|
||||||
newError("creating connection to ", dest).WriteToLog(session.ExportIDToError(ctx))
|
newError("creating connection to ", dest).WriteToLog(session.ExportIDToError(ctx))
|
||||||
|
@ -66,6 +91,30 @@ func dialWebSocket(ctx context.Context, dest net.Destination, streamSettings *in
|
||||||
}
|
}
|
||||||
uri := protocol + "://" + host + wsSettings.GetNormalizedPath()
|
uri := protocol + "://" + host + wsSettings.GetNormalizedPath()
|
||||||
|
|
||||||
|
if conns != nil {
|
||||||
|
data := []byte(uri)
|
||||||
|
if ed != nil {
|
||||||
|
data = append(data, " "+base64.RawURLEncoding.EncodeToString(ed)...)
|
||||||
|
}
|
||||||
|
var conn *websocket.Conn
|
||||||
|
for {
|
||||||
|
conn = <-conns
|
||||||
|
if conn.WriteMessage(websocket.TextMessage, data) != nil {
|
||||||
|
conn.Close()
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, p, err := conn.ReadMessage(); err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return nil, err
|
||||||
|
} else if s := string(p); s != "ok" {
|
||||||
|
conn.Close()
|
||||||
|
return nil, newError(s)
|
||||||
|
}
|
||||||
|
return newConnection(conn, conn.RemoteAddr(), nil), nil
|
||||||
|
}
|
||||||
|
|
||||||
header := wsSettings.GetRequestHeader()
|
header := wsSettings.GetRequestHeader()
|
||||||
if ed != nil {
|
if ed != nil {
|
||||||
header.Set("Sec-WebSocket-Protocol", base64.StdEncoding.EncodeToString(ed))
|
header.Set("Sec-WebSocket-Protocol", base64.StdEncoding.EncodeToString(ed))
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Browser Dialer</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
// Copyright (c) 2021 XRAY. Mozilla Public License 2.0.
|
||||||
|
var url = "ws://" + window.location.host + "/websocket"
|
||||||
|
var count = 0
|
||||||
|
setInterval(check, 1000)
|
||||||
|
function check() {
|
||||||
|
if (count <= 0) {
|
||||||
|
count += 1
|
||||||
|
console.log("Prepare", url)
|
||||||
|
var ws = new WebSocket(url)
|
||||||
|
var wss = undefined
|
||||||
|
var first = true
|
||||||
|
ws.onmessage = function (event) {
|
||||||
|
if (first) {
|
||||||
|
first = false
|
||||||
|
count -= 1
|
||||||
|
var arr = event.data.split(" ")
|
||||||
|
console.log("Dial", arr[0], arr[1])
|
||||||
|
wss = new WebSocket(arr[0], arr[1])
|
||||||
|
var opened = false
|
||||||
|
wss.onopen = function (event) {
|
||||||
|
opened = true
|
||||||
|
ws.send("ok")
|
||||||
|
}
|
||||||
|
wss.onmessage = function (event) {
|
||||||
|
ws.send(event.data)
|
||||||
|
}
|
||||||
|
wss.onclose = function (event) {
|
||||||
|
ws.close()
|
||||||
|
}
|
||||||
|
wss.onerror = function (event) {
|
||||||
|
!opened && ws.send("fail")
|
||||||
|
wss.close()
|
||||||
|
}
|
||||||
|
check()
|
||||||
|
} else wss.send(event.data)
|
||||||
|
}
|
||||||
|
ws.onclose = function (event) {
|
||||||
|
if (first) count -= 1
|
||||||
|
else wss.close()
|
||||||
|
}
|
||||||
|
ws.onerror = function (event) {
|
||||||
|
ws.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -25,6 +26,8 @@ type requestHandler struct {
|
||||||
ln *Listener
|
ln *Listener
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var replacer = strings.NewReplacer("+", "-", "/", "_", "=", "")
|
||||||
|
|
||||||
var upgrader = &websocket.Upgrader{
|
var upgrader = &websocket.Upgrader{
|
||||||
ReadBufferSize: 4 * 1024,
|
ReadBufferSize: 4 * 1024,
|
||||||
WriteBufferSize: 4 * 1024,
|
WriteBufferSize: 4 * 1024,
|
||||||
|
@ -39,7 +42,17 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
|
||||||
writer.WriteHeader(http.StatusNotFound)
|
writer.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conn, err := upgrader.Upgrade(writer, request, nil)
|
|
||||||
|
var extraReader io.Reader
|
||||||
|
var responseHeader = http.Header{}
|
||||||
|
if str := request.Header.Get("Sec-WebSocket-Protocol"); str != "" {
|
||||||
|
if ed, err := base64.RawURLEncoding.DecodeString(replacer.Replace(str)); err == nil && len(ed) > 0 {
|
||||||
|
extraReader = bytes.NewReader(ed)
|
||||||
|
responseHeader.Set("Sec-WebSocket-Protocol", str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := upgrader.Upgrade(writer, request, responseHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
newError("failed to convert to WebSocket connection").Base(err).WriteToLog()
|
newError("failed to convert to WebSocket connection").Base(err).WriteToLog()
|
||||||
return
|
return
|
||||||
|
@ -54,12 +67,6 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var extraReader io.Reader
|
|
||||||
if str := request.Header.Get("Sec-WebSocket-Protocol"); str != "" {
|
|
||||||
if ed, err := base64.StdEncoding.DecodeString(str); err == nil && len(ed) > 0 {
|
|
||||||
extraReader = bytes.NewReader(ed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h.ln.addConn(newConnection(conn, remoteAddr, extraReader))
|
h.ln.addConn(newConnection(conn, remoteAddr, extraReader))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +89,8 @@ func ListenWS(ctx context.Context, address net.Address, port net.Port, streamSet
|
||||||
if streamSettings.SocketSettings == nil {
|
if streamSettings.SocketSettings == nil {
|
||||||
streamSettings.SocketSettings = &internet.SocketConfig{}
|
streamSettings.SocketSettings = &internet.SocketConfig{}
|
||||||
}
|
}
|
||||||
streamSettings.SocketSettings.AcceptProxyProtocol = l.config.AcceptProxyProtocol
|
streamSettings.SocketSettings.AcceptProxyProtocol =
|
||||||
|
l.config.AcceptProxyProtocol || streamSettings.SocketSettings.AcceptProxyProtocol
|
||||||
}
|
}
|
||||||
var listener net.Listener
|
var listener net.Listener
|
||||||
var err error
|
var err error
|
||||||
|
@ -128,7 +136,7 @@ func ListenWS(ctx context.Context, address net.Address, port net.Port, streamSet
|
||||||
ln: l,
|
ln: l,
|
||||||
},
|
},
|
||||||
ReadHeaderTimeout: time.Second * 4,
|
ReadHeaderTimeout: time.Second * 4,
|
||||||
MaxHeaderBytes: 2048,
|
MaxHeaderBytes: 4096,
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
|
Loading…
Reference in New Issue