mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-08-23 01:56:48 +08:00
Compare commits
39 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8fc2d3b61f | ||
![]() |
9d4038427d | ||
![]() |
38ec9208d8 | ||
![]() |
7df135a5c4 | ||
![]() |
c41a1a56fe | ||
![]() |
310a938511 | ||
![]() |
2da07e0f8a | ||
![]() |
13ad3fddf6 | ||
![]() |
6bcac6cb10 | ||
![]() |
0203190a98 | ||
![]() |
a78db47571 | ||
![]() |
ffd8fd1d8a | ||
![]() |
3d7e86efba | ||
![]() |
6f25191822 | ||
![]() |
85619b5a29 | ||
![]() |
f073456ac0 | ||
![]() |
09f9d03fb6 | ||
![]() |
8f8f7dd66f | ||
![]() |
4140ed7ab0 | ||
![]() |
f390047b37 | ||
![]() |
ff9bb2d8df | ||
![]() |
38faac5ffc | ||
![]() |
88dfed931b | ||
![]() |
19ce0e99a5 | ||
![]() |
fe445f8e1a | ||
![]() |
6a5618bc54 | ||
![]() |
ed0e9b12dc | ||
![]() |
dab978749c | ||
![]() |
45f44c401a | ||
![]() |
2e942e0303 | ||
![]() |
decb012f9d | ||
![]() |
574446f942 | ||
![]() |
d71fa16e64 | ||
![]() |
f8faf3c8b8 | ||
![]() |
b4e84603a2 | ||
![]() |
ee19bcc08c | ||
![]() |
9c0f0a0cd5 | ||
![]() |
f1eb5e3d08 | ||
![]() |
b3f3c5be81 |
@@ -13,13 +13,16 @@
|
|||||||
- [Xray-script](https://github.com/kirin10000/Xray-script)
|
- [Xray-script](https://github.com/kirin10000/Xray-script)
|
||||||
- Docker
|
- Docker
|
||||||
- [teddysun/xray](https://hub.docker.com/r/teddysun/xray)
|
- [teddysun/xray](https://hub.docker.com/r/teddysun/xray)
|
||||||
- [charlieethan](https://github.com/users/charlieethan/packages/container/package/xray)
|
- Xray-docker
|
||||||
- One Click
|
- One Click
|
||||||
- [ProxySU](https://github.com/proxysu/ProxySU)
|
- [ProxySU](https://github.com/proxysu/ProxySU)
|
||||||
- [v2ray-agent](https://github.com/mack-a/v2ray-agent)
|
- [v2ray-agent](https://github.com/mack-a/v2ray-agent)
|
||||||
- Magisk
|
- Magisk
|
||||||
- [Xray4Magisk](https://github.com/CerteKim/Xray4Magisk)
|
- [Xray4Magisk](https://github.com/CerteKim/Xray4Magisk)
|
||||||
- [Xray_For_Magisk](https://github.com/E7KMbb/Xray_For_Magisk)
|
- [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
|
## Usage
|
||||||
|
|
||||||
@@ -29,10 +32,14 @@
|
|||||||
|
|
||||||
- OpenWrt
|
- OpenWrt
|
||||||
- [PassWall](https://github.com/xiaorouji/openwrt-passwall)
|
- [PassWall](https://github.com/xiaorouji/openwrt-passwall)
|
||||||
|
- [Hello World](https://github.com/jerrykuku/luci-app-vssr)
|
||||||
|
- [ShadowSocksR Plus+](https://github.com/fw876/helloworld)
|
||||||
- Windows
|
- Windows
|
||||||
- [v2rayN](https://github.com/2dust/v2rayN)
|
- [v2rayN](https://github.com/2dust/v2rayN)
|
||||||
|
- [Qv2ray](https://github.com/Qv2ray/Qv2ray)
|
||||||
- Android
|
- Android
|
||||||
- [v2rayNG](https://github.com/2dust/v2rayNG)
|
- [v2rayNG](https://github.com/2dust/v2rayNG)
|
||||||
|
- [Kitsunebi](https://github.com/rurirei/Kitsunebi/tree/release_xtls)
|
||||||
- iOS / Mac
|
- iOS / Mac
|
||||||
- [Shadowrocket](https://apps.apple.com/app/shadowrocket/id932747118)
|
- [Shadowrocket](https://apps.apple.com/app/shadowrocket/id932747118)
|
||||||
|
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package commander
|
package commander
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package commander
|
package commander
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -8,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
|
"github.com/xtls/xray-core/common/net/cnc"
|
||||||
"github.com/xtls/xray-core/common/signal/done"
|
"github.com/xtls/xray-core/common/signal/done"
|
||||||
"github.com/xtls/xray-core/transport"
|
"github.com/xtls/xray-core/transport"
|
||||||
)
|
)
|
||||||
@@ -81,7 +80,7 @@ func (co *Outbound) Dispatch(ctx context.Context, link *transport.Link) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
closeSignal := done.New()
|
closeSignal := done.New()
|
||||||
c := net.NewConnection(net.ConnectionInputMulti(link.Writer), net.ConnectionOutputMulti(link.Reader), net.ConnectionOnClose(closeSignal))
|
c := cnc.NewConnection(cnc.ConnectionInputMulti(link.Writer), cnc.ConnectionOutputMulti(link.Reader), cnc.ConnectionOnClose(closeSignal))
|
||||||
co.listener.add(c)
|
co.listener.add(c)
|
||||||
co.access.RUnlock()
|
co.access.RUnlock()
|
||||||
<-closeSignal.Wait()
|
<-closeSignal.Wait()
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package commander
|
package commander
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dispatcher
|
package dispatcher
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dispatcher
|
package dispatcher
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dispatcher
|
package dispatcher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dispatcher
|
package dispatcher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -16,6 +14,7 @@ import (
|
|||||||
|
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
|
"github.com/xtls/xray-core/common/net/cnc"
|
||||||
"github.com/xtls/xray-core/common/protocol/dns"
|
"github.com/xtls/xray-core/common/protocol/dns"
|
||||||
"github.com/xtls/xray-core/common/session"
|
"github.com/xtls/xray-core/common/session"
|
||||||
"github.com/xtls/xray-core/common/signal/pubsub"
|
"github.com/xtls/xray-core/common/signal/pubsub"
|
||||||
@@ -67,9 +66,9 @@ func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, clientIP net.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return net.NewConnection(
|
return cnc.NewConnection(
|
||||||
net.ConnectionInputMulti(link.Writer),
|
cnc.ConnectionInputMulti(link.Writer),
|
||||||
net.ConnectionOutputMulti(link.Reader),
|
cnc.ConnectionOutputMulti(link.Reader),
|
||||||
), nil
|
), nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package command
|
package command
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//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) {
|
func (s *service) Register(server *grpc.Server) {
|
||||||
RegisterLoggerServiceServer(server, &LoggerServer{
|
ls := &LoggerServer{
|
||||||
V: s.v,
|
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() {
|
func init() {
|
||||||
|
@@ -63,7 +63,6 @@ type UnsafeLoggerServiceServer interface {
|
|||||||
|
|
||||||
func RegisterLoggerServiceServer(s grpc.ServiceRegistrar, srv LoggerServiceServer) {
|
func RegisterLoggerServiceServer(s grpc.ServiceRegistrar, srv LoggerServiceServer) {
|
||||||
s.RegisterService(&_LoggerService_serviceDesc, srv)
|
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) {
|
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{},
|
Streams: []grpc.StreamDesc{},
|
||||||
Metadata: "app/log/command/config.proto",
|
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",
|
|
||||||
}
|
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package log
|
package log
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package log
|
package log
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -140,6 +138,11 @@ func (s *service) Register(server *grpc.Server) {
|
|||||||
hs.ohm = om
|
hs.ohm = om
|
||||||
}))
|
}))
|
||||||
RegisterHandlerServiceServer(server, hs)
|
RegisterHandlerServiceServer(server, hs)
|
||||||
|
|
||||||
|
// For compatibility purposes
|
||||||
|
vCoreDesc := _HandlerService_serviceDesc
|
||||||
|
vCoreDesc.ServiceName = "v2ray.core.app.proxyman.command.HandlerService"
|
||||||
|
server.RegisterService(&vCoreDesc, hs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@@ -133,7 +133,6 @@ type UnsafeHandlerServiceServer interface {
|
|||||||
|
|
||||||
func RegisterHandlerServiceServer(s grpc.ServiceRegistrar, srv HandlerServiceServer) {
|
func RegisterHandlerServiceServer(s grpc.ServiceRegistrar, srv HandlerServiceServer) {
|
||||||
s.RegisterService(&_HandlerService_serviceDesc, srv)
|
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) {
|
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{},
|
Streams: []grpc.StreamDesc{},
|
||||||
Metadata: "app/proxyman/command/command.proto",
|
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",
|
|
||||||
}
|
|
||||||
|
@@ -279,7 +279,10 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest
|
|||||||
src: source,
|
src: source,
|
||||||
}
|
}
|
||||||
if originalDest.IsValid() {
|
if originalDest.IsValid() {
|
||||||
id.dest = originalDest
|
if !buf.Cone {
|
||||||
|
id.dest = originalDest
|
||||||
|
}
|
||||||
|
b.UDP = &originalDest
|
||||||
}
|
}
|
||||||
conn, existing := w.getConnection(id)
|
conn, existing := w.getConnection(id)
|
||||||
|
|
||||||
|
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
"github.com/xtls/xray-core/common/mux"
|
"github.com/xtls/xray-core/common/mux"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
|
"github.com/xtls/xray-core/common/net/cnc"
|
||||||
"github.com/xtls/xray-core/common/session"
|
"github.com/xtls/xray-core/common/session"
|
||||||
"github.com/xtls/xray-core/core"
|
"github.com/xtls/xray-core/core"
|
||||||
"github.com/xtls/xray-core/features/outbound"
|
"github.com/xtls/xray-core/features/outbound"
|
||||||
@@ -173,7 +174,7 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Conn
|
|||||||
downlinkReader, downlinkWriter := pipe.New(opts...)
|
downlinkReader, downlinkWriter := pipe.New(opts...)
|
||||||
|
|
||||||
go handler.Dispatch(ctx, &transport.Link{Reader: uplinkReader, Writer: downlinkWriter})
|
go handler.Dispatch(ctx, &transport.Link{Reader: uplinkReader, Writer: downlinkWriter})
|
||||||
conn := net.NewConnection(net.ConnectionInputMulti(uplinkWriter), net.ConnectionOutputMulti(downlinkReader))
|
conn := cnc.NewConnection(cnc.ConnectionInputMulti(uplinkWriter), cnc.ConnectionOutputMulti(downlinkReader))
|
||||||
|
|
||||||
if config := tls.ConfigFromStreamSettings(h.streamSettings); config != nil {
|
if config := tls.ConfigFromStreamSettings(h.streamSettings); config != nil {
|
||||||
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
|
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package reverse
|
package reverse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package reverse
|
package reverse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package reverse
|
package reverse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package reverse
|
package reverse
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package command
|
package command
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//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) {
|
func (s *service) Register(server *grpc.Server) {
|
||||||
common.Must(s.v.RequireFeatures(func(router routing.Router, stats stats.Manager) {
|
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)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -100,7 +100,6 @@ type UnsafeRoutingServiceServer interface {
|
|||||||
|
|
||||||
func RegisterRoutingServiceServer(s grpc.ServiceRegistrar, srv RoutingServiceServer) {
|
func RegisterRoutingServiceServer(s grpc.ServiceRegistrar, srv RoutingServiceServer) {
|
||||||
s.RegisterService(&_RoutingService_serviceDesc, srv)
|
s.RegisterService(&_RoutingService_serviceDesc, srv)
|
||||||
s.RegisterService(&_RoutingService_serviceDesc2, srv)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func _RoutingService_SubscribeRoutingStats_Handler(srv interface{}, stream grpc.ServerStream) error {
|
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",
|
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",
|
|
||||||
}
|
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package router
|
package router
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package command
|
package command
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//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) {
|
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() {
|
func init() {
|
||||||
|
@@ -91,7 +91,6 @@ type UnsafeStatsServiceServer interface {
|
|||||||
|
|
||||||
func RegisterStatsServiceServer(s grpc.ServiceRegistrar, srv StatsServiceServer) {
|
func RegisterStatsServiceServer(s grpc.ServiceRegistrar, srv StatsServiceServer) {
|
||||||
s.RegisterService(&_StatsService_serviceDesc, srv)
|
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) {
|
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{},
|
Streams: []grpc.StreamDesc{},
|
||||||
Metadata: "app/stats/command/command.proto",
|
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",
|
|
||||||
}
|
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package stats
|
package stats
|
||||||
|
|
||||||
import "sync/atomic"
|
import "sync/atomic"
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package stats
|
package stats
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/bytespool"
|
"github.com/xtls/xray-core/common/bytespool"
|
||||||
|
"github.com/xtls/xray-core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -13,6 +14,8 @@ const (
|
|||||||
|
|
||||||
var pool = bytespool.GetPool(Size)
|
var pool = bytespool.GetPool(Size)
|
||||||
|
|
||||||
|
var Cone = true
|
||||||
|
|
||||||
// Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles
|
// Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles
|
||||||
// the buffer into an internal buffer pool, in order to recreate a buffer more
|
// the buffer into an internal buffer pool, in order to recreate a buffer more
|
||||||
// quickly.
|
// quickly.
|
||||||
@@ -20,6 +23,7 @@ type Buffer struct {
|
|||||||
v []byte
|
v []byte
|
||||||
start int32
|
start int32
|
||||||
end int32
|
end int32
|
||||||
|
UDP *net.Destination
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a Buffer with 0 length and 2K capacity.
|
// New creates a Buffer with 0 length and 2K capacity.
|
||||||
@@ -47,6 +51,7 @@ func (b *Buffer) Release() {
|
|||||||
b.v = nil
|
b.v = nil
|
||||||
b.Clear()
|
b.Clear()
|
||||||
pool.Put(p)
|
pool.Put(p)
|
||||||
|
b.UDP = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear clears the content of the buffer, results an empty buffer with
|
// Clear clears the content of the buffer, results an empty buffer with
|
||||||
|
@@ -36,19 +36,23 @@ func (m *AccessMessage) String() string {
|
|||||||
builder.WriteString(string(m.Status))
|
builder.WriteString(string(m.Status))
|
||||||
builder.WriteByte(' ')
|
builder.WriteByte(' ')
|
||||||
builder.WriteString(serial.ToString(m.To))
|
builder.WriteString(serial.ToString(m.To))
|
||||||
builder.WriteByte(' ')
|
|
||||||
if len(m.Detour) > 0 {
|
if len(m.Detour) > 0 {
|
||||||
builder.WriteByte('[')
|
builder.WriteString(" [")
|
||||||
builder.WriteString(m.Detour)
|
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 {
|
if len(m.Email) > 0 {
|
||||||
builder.WriteString("email:")
|
builder.WriteString(" email: ")
|
||||||
builder.WriteString(m.Email)
|
builder.WriteString(m.Email)
|
||||||
builder.WriteByte(' ')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.String()
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,14 +1,12 @@
|
|||||||
// +build !confonly
|
package cnc
|
||||||
|
|
||||||
package net
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"net"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
"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/signal/done"
|
"github.com/xtls/xray-core/common/signal/done"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -90,8 +88,8 @@ type connection struct {
|
|||||||
writer buf.Writer
|
writer buf.Writer
|
||||||
done *done.Instance
|
done *done.Instance
|
||||||
onClose io.Closer
|
onClose io.Closer
|
||||||
local Addr
|
local net.Addr
|
||||||
remote Addr
|
remote net.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *connection) Read(b []byte) (int, error) {
|
func (c *connection) Read(b []byte) (int, error) {
|
@@ -1,4 +1,4 @@
|
|||||||
package jsonem
|
package ocsp
|
||||||
|
|
||||||
import "github.com/xtls/xray-core/common/errors"
|
import "github.com/xtls/xray-core/common/errors"
|
||||||
|
|
136
common/ocsp/ocsp.go
Normal file
136
common/ocsp/ocsp.go
Normal 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
|
||||||
|
}
|
@@ -8,7 +8,7 @@ import (
|
|||||||
// ToString serialize an arbitrary value into string.
|
// ToString serialize an arbitrary value into string.
|
||||||
func ToString(v interface{}) string {
|
func ToString(v interface{}) string {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return " "
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
switch value := v.(type) {
|
switch value := v.(type) {
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -18,7 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
version = "1.1.2"
|
version = "1.2.0"
|
||||||
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."
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -8,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
|
"github.com/xtls/xray-core/common/net/cnc"
|
||||||
"github.com/xtls/xray-core/features/routing"
|
"github.com/xtls/xray-core/features/routing"
|
||||||
"github.com/xtls/xray-core/transport/internet/udp"
|
"github.com/xtls/xray-core/transport/internet/udp"
|
||||||
)
|
)
|
||||||
@@ -55,13 +54,13 @@ func Dial(ctx context.Context, v *Instance, dest net.Destination) (net.Conn, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var readerOpt net.ConnectionOption
|
var readerOpt cnc.ConnectionOption
|
||||||
if dest.Network == net.Network_TCP {
|
if dest.Network == net.Network_TCP {
|
||||||
readerOpt = net.ConnectionOutputMulti(r.Reader)
|
readerOpt = cnc.ConnectionOutputMulti(r.Reader)
|
||||||
} else {
|
} else {
|
||||||
readerOpt = net.ConnectionOutputMultiUDP(r.Reader)
|
readerOpt = cnc.ConnectionOutputMultiUDP(r.Reader)
|
||||||
}
|
}
|
||||||
return net.NewConnection(net.ConnectionInputMulti(r.Writer), readerOpt), nil
|
return cnc.NewConnection(cnc.ConnectionInputMulti(r.Writer), readerOpt), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialUDP provides a way to exchange UDP packets through Xray instance to remote servers.
|
// DialUDP provides a way to exchange UDP packets through Xray instance to remote servers.
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package core
|
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/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/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/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/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/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/proxy.go -mock_names Inbound=ProxyInbound,Outbound=ProxyOutbound github.com/xtls/xray-core/proxy Inbound,Outbound
|
||||||
|
@@ -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/protobuf/cmd/protoc-gen-go
|
||||||
//go:generate go install -v google.golang.org/grpc/cmd/protoc-gen-go-grpc
|
//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 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
|
// ProtoFilesUsingProtocGenGoFast is the map of Proto files
|
||||||
// that use `protoc-gen-gofast` to generate pb.go files
|
// that use `protoc-gen-gofast` to generate pb.go files
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
19
go.mod
19
go.mod
@@ -3,23 +3,24 @@ module github.com/xtls/xray-core
|
|||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 // indirect
|
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
|
||||||
github.com/golang/mock v1.4.4
|
github.com/golang/mock v1.4.4
|
||||||
github.com/golang/protobuf v1.4.3
|
github.com/golang/protobuf v1.4.3
|
||||||
github.com/google/go-cmp v0.5.4
|
github.com/google/go-cmp v0.5.4
|
||||||
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.19.3
|
||||||
github.com/miekg/dns v1.1.35
|
github.com/miekg/dns v1.1.35
|
||||||
github.com/pires/go-proxyproto v0.3.2
|
github.com/pelletier/go-toml v1.8.1
|
||||||
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/stretchr/testify v1.6.1
|
||||||
github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499
|
github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499
|
||||||
go.starlark.net v0.0.0-20201204201740-42d4f566359b
|
go.starlark.net v0.0.0-20201210151846-e81fc95f7bd5
|
||||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
|
||||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
|
golang.org/x/net v0.0.0-20201224014010-6772e930b67b
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
||||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88
|
golang.org/x/sys v0.0.0-20201231184435-2d18734c6014
|
||||||
google.golang.org/grpc v1.34.0
|
google.golang.org/grpc v1.34.0
|
||||||
google.golang.org/protobuf v1.25.0
|
google.golang.org/protobuf v1.25.0
|
||||||
h12.io/socks v1.0.1
|
h12.io/socks v1.0.2
|
||||||
)
|
)
|
||||||
|
58
go.sum
58
go.sum
@@ -22,6 +22,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/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/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.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/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 h1:BS21ZUJ/B5X2UVUbczfmdWH7GapPWAhxcMsDnjJTU1E=
|
||||||
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
|
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
|
||||||
@@ -33,8 +34,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/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/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.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/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.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/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/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=
|
||||||
@@ -45,6 +49,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.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.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/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.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
@@ -64,6 +69,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.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.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.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-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-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=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
@@ -77,42 +83,54 @@ 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/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/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/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/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/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/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/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/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/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/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.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/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.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4=
|
||||||
github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8=
|
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/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 v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs=
|
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 h1:LIH6K34bPVttyXnUWixk0bzH6/N07VxbSabxn5A5gZQ=
|
||||||
github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
|
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/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.35 h1:oTfOaDH+mZkdcgdIjH6yBajRGtIwcwcaR+rt23ZSrJs=
|
||||||
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
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/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=
|
||||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
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/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.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.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/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.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/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/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||||
|
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
||||||
|
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||||
|
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/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.3 h1:jOXGrsAfSQVFiD1hWg1aiHpLYsd6SJw/8cLN594sB7Q=
|
||||||
github.com/pires/go-proxyproto v0.3.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
|
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/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/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_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=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
@@ -120,8 +138,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/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/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-20201009151232-afb285a456ab h1:O43uBnD2Y6fo1oFsXY+Vqp1n3RFfxg1u3XATDGvUXgI=
|
github.com/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c h1:pqy40B3MQWYrza7YZXOXgl0Nf0QGFqrOC0BKae1UNAA=
|
||||||
github.com/seiflotfy/cuckoofilter v0.0.0-20201009151232-afb285a456ab/go.mod h1:ET5mVvNjwaGXRgZxO9UZr7X+8eAf87AfIYNwRSp9s4Y=
|
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/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/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=
|
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||||
@@ -151,6 +169,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.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
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 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||||
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/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
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=
|
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||||
@@ -159,8 +178,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=
|
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.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-20201210151846-e81fc95f7bd5 h1:F1LaLz0cvAJWMa5r3bogEYXD7/5fgA9a9jOX4DAobN8=
|
||||||
go.starlark.net v0.0.0-20201204201740-42d4f566359b/go.mod h1:5YFcFnRptTN+41758c2bMPiqpGg4zBfYji1IQz8wNFk=
|
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=
|
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/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=
|
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
@@ -169,8 +188,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-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-20201203163018-be400aefbc4c h1:9HhBz5L/UjnK9XLtiZhYAdue5BVKep3PMmS2LuPDt8k=
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
||||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
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/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=
|
||||||
@@ -191,8 +210,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-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-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
|
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
|
||||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
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-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=
|
||||||
@@ -204,7 +223,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-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-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-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-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-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -221,10 +241,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-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-20200803210538-64077c9b5642/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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso=
|
golang.org/x/sys v0.0.0-20201231184435-2d18734c6014 h1:joucsQqXmyBVxViHCPFjG3hx8JzIFSaym3l3MM/Jsdg=
|
||||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201231184435-2d18734c6014/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-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.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=
|
||||||
@@ -243,6 +264,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-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
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-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=
|
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-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
@@ -281,17 +303,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 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=
|
||||||
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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
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/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.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.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.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.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-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=
|
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-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-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=
|
||||||
|
@@ -84,7 +84,7 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) {
|
|||||||
|
|
||||||
geoipList, err := toCidrList(c.ExpectIPs)
|
geoipList, err := toCidrList(c.ExpectIPs)
|
||||||
if err != nil {
|
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{
|
return &dns.NameServer{
|
||||||
@@ -142,7 +142,7 @@ func (c *DNSConfig) Build() (*dns.Config, error) {
|
|||||||
for _, server := range c.Servers {
|
for _, server := range c.Servers {
|
||||||
ns, err := server.Build()
|
ns, err := server.Build()
|
||||||
if err != nil {
|
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)
|
config.NameServer = append(config.NameServer, ns)
|
||||||
}
|
}
|
||||||
@@ -159,15 +159,23 @@ func (c *DNSConfig) Build() (*dns.Config, error) {
|
|||||||
var mappings []*dns.Config_HostMapping
|
var mappings []*dns.Config_HostMapping
|
||||||
switch {
|
switch {
|
||||||
case strings.HasPrefix(domain, "domain:"):
|
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 := getHostMapping(addr)
|
||||||
mapping.Type = dns.DomainMatchingType_Subdomain
|
mapping.Type = dns.DomainMatchingType_Subdomain
|
||||||
mapping.Domain = domain[7:]
|
mapping.Domain = domainName
|
||||||
mappings = append(mappings, mapping)
|
mappings = append(mappings, mapping)
|
||||||
|
|
||||||
case strings.HasPrefix(domain, "geosite:"):
|
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 {
|
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 {
|
for _, d := range domains {
|
||||||
mapping := getHostMapping(addr)
|
mapping := getHostMapping(addr)
|
||||||
@@ -177,21 +185,33 @@ func (c *DNSConfig) Build() (*dns.Config, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case strings.HasPrefix(domain, "regexp:"):
|
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 := getHostMapping(addr)
|
||||||
mapping.Type = dns.DomainMatchingType_Regex
|
mapping.Type = dns.DomainMatchingType_Regex
|
||||||
mapping.Domain = domain[7:]
|
mapping.Domain = regexpVal
|
||||||
mappings = append(mappings, mapping)
|
mappings = append(mappings, mapping)
|
||||||
|
|
||||||
case strings.HasPrefix(domain, "keyword:"):
|
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 := getHostMapping(addr)
|
||||||
mapping.Type = dns.DomainMatchingType_Keyword
|
mapping.Type = dns.DomainMatchingType_Keyword
|
||||||
mapping.Domain = domain[8:]
|
mapping.Domain = keywordVal
|
||||||
mappings = append(mappings, mapping)
|
mappings = append(mappings, mapping)
|
||||||
|
|
||||||
case strings.HasPrefix(domain, "full:"):
|
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 := getHostMapping(addr)
|
||||||
mapping.Type = dns.DomainMatchingType_Full
|
mapping.Type = dns.DomainMatchingType_Full
|
||||||
mapping.Domain = domain[5:]
|
mapping.Domain = fullVal
|
||||||
mappings = append(mappings, mapping)
|
mappings = append(mappings, mapping)
|
||||||
|
|
||||||
case strings.HasPrefix(domain, "dotless:"):
|
case strings.HasPrefix(domain, "dotless:"):
|
||||||
@@ -213,10 +233,10 @@ func (c *DNSConfig) Build() (*dns.Config, error) {
|
|||||||
return nil, newError("invalid external resource: ", domain)
|
return nil, newError("invalid external resource: ", domain)
|
||||||
}
|
}
|
||||||
filename := kv[0]
|
filename := kv[0]
|
||||||
country := kv[1]
|
list := kv[1]
|
||||||
domains, err := loadGeositeWithAttr(filename, country)
|
domains, err := loadGeositeWithAttr(filename, list)
|
||||||
if err != nil {
|
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 {
|
for _, d := range domains {
|
||||||
mapping := getHostMapping(addr)
|
mapping := getHostMapping(addr)
|
||||||
|
@@ -2,6 +2,7 @@ package conf
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -147,46 +148,109 @@ func ParseIP(s string) (*router.CIDR, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadGeoIP(country string) ([]*router.CIDR, error) {
|
func loadGeoIP(code string) ([]*router.CIDR, error) {
|
||||||
return loadIP("geoip.dat", country)
|
return loadIP("geoip.dat", code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadIP(filename, country string) ([]*router.CIDR, error) {
|
var (
|
||||||
geoipBytes, err := filesystem.ReadAsset(filename)
|
FileCache = make(map[string][]byte)
|
||||||
if err != nil {
|
IPCache = make(map[string]*router.GeoIP)
|
||||||
return nil, newError("failed to open file: ", filename).Base(err)
|
SiteCache = make(map[string]*router.GeoSite)
|
||||||
}
|
)
|
||||||
var geoipList router.GeoIPList
|
|
||||||
if err := proto.Unmarshal(geoipBytes, &geoipList); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, geoip := range geoipList.Entry {
|
func loadFile(file string) ([]byte, error) {
|
||||||
if geoip.CountryCode == country {
|
if FileCache[file] == nil {
|
||||||
return geoip.Cidr, nil
|
bs, err := filesystem.ReadAsset(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, newError("failed to open file: ", file).Base(err)
|
||||||
}
|
}
|
||||||
|
if len(bs) == 0 {
|
||||||
|
return nil, newError("empty file: ", file)
|
||||||
|
}
|
||||||
|
// Do not cache file, may save RAM when there
|
||||||
|
// are many files, but consume CPU each time.
|
||||||
|
return bs, nil
|
||||||
|
FileCache[file] = bs
|
||||||
}
|
}
|
||||||
|
return FileCache[file], nil
|
||||||
return nil, newError("country not found in ", filename, ": ", country)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadSite(filename, country string) ([]*router.Domain, error) {
|
func loadIP(file, code string) ([]*router.CIDR, error) {
|
||||||
geositeBytes, err := filesystem.ReadAsset(filename)
|
index := file + ":" + code
|
||||||
if err != nil {
|
if IPCache[index] == nil {
|
||||||
return nil, newError("failed to open file: ", filename).Base(err)
|
bs, err := loadFile(file)
|
||||||
}
|
if err != nil {
|
||||||
var geositeList router.GeoSiteList
|
return nil, newError("failed to load file: ", file).Base(err)
|
||||||
if err := proto.Unmarshal(geositeBytes, &geositeList); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, site := range geositeList.Entry {
|
|
||||||
if site.CountryCode == country {
|
|
||||||
return site.Domain, nil
|
|
||||||
}
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
return nil, newError("list not found in ", filename, ": ", country)
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
type AttributeMatcher interface {
|
||||||
|
@@ -4,6 +4,10 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/ghodss/yaml"
|
||||||
|
"github.com/pelletier/go-toml"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
"github.com/xtls/xray-core/core"
|
"github.com/xtls/xray-core/core"
|
||||||
@@ -80,3 +84,68 @@ func LoadJSONConfig(reader io.Reader) (*core.Config, error) {
|
|||||||
|
|
||||||
return pbConfig, nil
|
return pbConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecodeTOMLConfig reads from reader and decode the config into *conf.Config
|
||||||
|
// using github.com/pelletier/go-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.Unmarshal(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
|
||||||
|
}
|
||||||
|
@@ -247,11 +247,12 @@ func readFileOrString(f string, s []string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TLSCertConfig struct {
|
type TLSCertConfig struct {
|
||||||
CertFile string `json:"certificateFile"`
|
CertFile string `json:"certificateFile"`
|
||||||
CertStr []string `json:"certificate"`
|
CertStr []string `json:"certificate"`
|
||||||
KeyFile string `json:"keyFile"`
|
KeyFile string `json:"keyFile"`
|
||||||
KeyStr []string `json:"key"`
|
KeyStr []string `json:"key"`
|
||||||
Usage string `json:"usage"`
|
Usage string `json:"usage"`
|
||||||
|
OcspStapling int64 `json:"ocspStapling"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build implements Buildable.
|
// Build implements Buildable.
|
||||||
@@ -283,17 +284,22 @@ func (c *TLSCertConfig) Build() (*tls.Certificate, error) {
|
|||||||
certificate.Usage = tls.Certificate_ENCIPHERMENT
|
certificate.Usage = tls.Certificate_ENCIPHERMENT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
certificate.OcspStapling = c.OcspStapling
|
||||||
|
|
||||||
return certificate, nil
|
return certificate, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type TLSConfig struct {
|
type TLSConfig struct {
|
||||||
Insecure bool `json:"allowInsecure"`
|
Insecure bool `json:"allowInsecure"`
|
||||||
InsecureCiphers bool `json:"allowInsecureCiphers"`
|
|
||||||
Certs []*TLSCertConfig `json:"certificates"`
|
Certs []*TLSCertConfig `json:"certificates"`
|
||||||
ServerName string `json:"serverName"`
|
ServerName string `json:"serverName"`
|
||||||
ALPN *StringList `json:"alpn"`
|
ALPN *StringList `json:"alpn"`
|
||||||
DisableSessionResumption bool `json:"disableSessionResumption"`
|
EnableSessionResumption bool `json:"enableSessionResumption"`
|
||||||
DisableSystemRoot bool `json:"disableSystemRoot"`
|
DisableSystemRoot bool `json:"disableSystemRoot"`
|
||||||
|
MinVersion string `json:"minVersion"`
|
||||||
|
MaxVersion string `json:"maxVersion"`
|
||||||
|
CipherSuites string `json:"cipherSuites"`
|
||||||
|
PreferServerCipherSuites bool `json:"preferServerCipherSuites"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build implements Buildable.
|
// Build implements Buildable.
|
||||||
@@ -309,24 +315,28 @@ func (c *TLSConfig) Build() (proto.Message, error) {
|
|||||||
}
|
}
|
||||||
serverName := c.ServerName
|
serverName := c.ServerName
|
||||||
config.AllowInsecure = c.Insecure
|
config.AllowInsecure = c.Insecure
|
||||||
config.AllowInsecureCiphers = c.InsecureCiphers
|
|
||||||
if len(c.ServerName) > 0 {
|
if len(c.ServerName) > 0 {
|
||||||
config.ServerName = serverName
|
config.ServerName = serverName
|
||||||
}
|
}
|
||||||
if c.ALPN != nil && len(*c.ALPN) > 0 {
|
if c.ALPN != nil && len(*c.ALPN) > 0 {
|
||||||
config.NextProtocol = []string(*c.ALPN)
|
config.NextProtocol = []string(*c.ALPN)
|
||||||
}
|
}
|
||||||
config.DisableSessionResumption = c.DisableSessionResumption
|
config.EnableSessionResumption = c.EnableSessionResumption
|
||||||
config.DisableSystemRoot = c.DisableSystemRoot
|
config.DisableSystemRoot = c.DisableSystemRoot
|
||||||
|
config.MinVersion = c.MinVersion
|
||||||
|
config.MaxVersion = c.MaxVersion
|
||||||
|
config.CipherSuites = c.CipherSuites
|
||||||
|
config.PreferServerCipherSuites = c.PreferServerCipherSuites
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type XTLSCertConfig struct {
|
type XTLSCertConfig struct {
|
||||||
CertFile string `json:"certificateFile"`
|
CertFile string `json:"certificateFile"`
|
||||||
CertStr []string `json:"certificate"`
|
CertStr []string `json:"certificate"`
|
||||||
KeyFile string `json:"keyFile"`
|
KeyFile string `json:"keyFile"`
|
||||||
KeyStr []string `json:"key"`
|
KeyStr []string `json:"key"`
|
||||||
Usage string `json:"usage"`
|
Usage string `json:"usage"`
|
||||||
|
OcspStapling int64 `json:"ocspStapling"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build implements Buildable.
|
// Build implements Buildable.
|
||||||
@@ -358,17 +368,22 @@ func (c *XTLSCertConfig) Build() (*xtls.Certificate, error) {
|
|||||||
certificate.Usage = xtls.Certificate_ENCIPHERMENT
|
certificate.Usage = xtls.Certificate_ENCIPHERMENT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
certificate.OcspStapling = c.OcspStapling
|
||||||
|
|
||||||
return certificate, nil
|
return certificate, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type XTLSConfig struct {
|
type XTLSConfig struct {
|
||||||
Insecure bool `json:"allowInsecure"`
|
Insecure bool `json:"allowInsecure"`
|
||||||
InsecureCiphers bool `json:"allowInsecureCiphers"`
|
|
||||||
Certs []*XTLSCertConfig `json:"certificates"`
|
Certs []*XTLSCertConfig `json:"certificates"`
|
||||||
ServerName string `json:"serverName"`
|
ServerName string `json:"serverName"`
|
||||||
ALPN *StringList `json:"alpn"`
|
ALPN *StringList `json:"alpn"`
|
||||||
DisableSessionResumption bool `json:"disableSessionResumption"`
|
EnableSessionResumption bool `json:"enableSessionResumption"`
|
||||||
DisableSystemRoot bool `json:"disableSystemRoot"`
|
DisableSystemRoot bool `json:"disableSystemRoot"`
|
||||||
|
MinVersion string `json:"minVersion"`
|
||||||
|
MaxVersion string `json:"maxVersion"`
|
||||||
|
CipherSuites string `json:"cipherSuites"`
|
||||||
|
PreferServerCipherSuites bool `json:"preferServerCipherSuites"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build implements Buildable.
|
// Build implements Buildable.
|
||||||
@@ -384,15 +399,18 @@ func (c *XTLSConfig) Build() (proto.Message, error) {
|
|||||||
}
|
}
|
||||||
serverName := c.ServerName
|
serverName := c.ServerName
|
||||||
config.AllowInsecure = c.Insecure
|
config.AllowInsecure = c.Insecure
|
||||||
config.AllowInsecureCiphers = c.InsecureCiphers
|
|
||||||
if len(c.ServerName) > 0 {
|
if len(c.ServerName) > 0 {
|
||||||
config.ServerName = serverName
|
config.ServerName = serverName
|
||||||
}
|
}
|
||||||
if c.ALPN != nil && len(*c.ALPN) > 0 {
|
if c.ALPN != nil && len(*c.ALPN) > 0 {
|
||||||
config.NextProtocol = []string(*c.ALPN)
|
config.NextProtocol = []string(*c.ALPN)
|
||||||
}
|
}
|
||||||
config.DisableSessionResumption = c.DisableSessionResumption
|
config.EnableSessionResumption = c.EnableSessionResumption
|
||||||
config.DisableSystemRoot = c.DisableSystemRoot
|
config.DisableSystemRoot = c.DisableSystemRoot
|
||||||
|
config.MinVersion = c.MinVersion
|
||||||
|
config.MaxVersion = c.MaxVersion
|
||||||
|
config.CipherSuites = c.CipherSuites
|
||||||
|
config.PreferServerCipherSuites = c.PreferServerCipherSuites
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,6 +52,17 @@ func (c *TrojanClientConfig) Build() (proto.Message, error) {
|
|||||||
Password: rec.Password,
|
Password: rec.Password,
|
||||||
Flow: rec.Flow,
|
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{
|
trojan := &protocol.ServerEndpoint{
|
||||||
Address: rec.Address.Build(),
|
Address: rec.Address.Build(),
|
||||||
Port: uint32(rec.Port),
|
Port: uint32(rec.Port),
|
||||||
@@ -107,6 +118,14 @@ func (c *TrojanServerConfig) Build() (proto.Message, error) {
|
|||||||
Flow: rawUser.Flow,
|
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.Email = rawUser.Email
|
||||||
user.Level = uint32(rawUser.Level)
|
user.Level = uint32(rawUser.Level)
|
||||||
user.Account = serial.ToTypedMessage(account)
|
user.Account = serial.ToTypedMessage(account)
|
||||||
@@ -148,7 +167,7 @@ func (c *TrojanServerConfig) Build() (proto.Message, error) {
|
|||||||
switch fb.Dest[0] {
|
switch fb.Dest[0] {
|
||||||
case '@', '/':
|
case '@', '/':
|
||||||
fb.Type = "unix"
|
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
|
fullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) // may need padding to work with haproxy
|
||||||
copy(fullAddr, fb.Dest[1:])
|
copy(fullAddr, fb.Dest[1:])
|
||||||
fb.Dest = string(fullAddr)
|
fb.Dest = string(fullAddr)
|
||||||
|
@@ -101,7 +101,7 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) {
|
|||||||
switch fb.Dest[0] {
|
switch fb.Dest[0] {
|
||||||
case '@', '/':
|
case '@', '/':
|
||||||
fb.Type = "unix"
|
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
|
fullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) // may need padding to work with haproxy
|
||||||
copy(fullAddr, fb.Dest[1:])
|
copy(fullAddr, fb.Dest[1:])
|
||||||
fb.Dest = string(fullAddr)
|
fb.Dest = string(fullAddr)
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@@ -12,13 +13,25 @@ import (
|
|||||||
"github.com/xtls/xray-core/core"
|
"github.com/xtls/xray-core/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var directory = flag.String("pwd", "", "Working directory of Xray vprotogen.")
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
pwd, wdErr := os.Getwd()
|
flag.Usage = func() {
|
||||||
if wdErr != nil {
|
fmt.Fprintf(flag.CommandLine.Output(), "Usage of vprotogen:\n")
|
||||||
fmt.Println("Can not get current working directory.")
|
flag.PrintDefaults()
|
||||||
os.Exit(1)
|
}
|
||||||
|
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()
|
GOBIN := common.GetGOBIN()
|
||||||
binPath := os.Getenv("PATH")
|
binPath := os.Getenv("PATH")
|
||||||
pathSlice := []string{binPath, GOBIN, pwd}
|
pathSlice := []string{binPath, GOBIN, pwd}
|
||||||
@@ -39,7 +52,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protoFilesMap := make(map[string][]string)
|
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 {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return err
|
return err
|
||||||
@@ -52,6 +65,7 @@ func main() {
|
|||||||
dir := filepath.Dir(path)
|
dir := filepath.Dir(path)
|
||||||
filename := filepath.Base(path)
|
filename := filepath.Base(path)
|
||||||
if strings.HasSuffix(filename, ".proto") {
|
if strings.HasSuffix(filename, ".proto") {
|
||||||
|
path = path[len(pwd)+1:]
|
||||||
protoFilesMap[dir] = append(protoFilesMap[dir], path)
|
protoFilesMap[dir] = append(protoFilesMap[dir], path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,6 +87,7 @@ func main() {
|
|||||||
args = append(args, relProtoFile)
|
args = append(args, relProtoFile)
|
||||||
cmd := exec.Command(protoc, args...)
|
cmd := exec.Command(protoc, args...)
|
||||||
cmd.Env = append(cmd.Env, os.Environ()...)
|
cmd.Env = append(cmd.Env, os.Environ()...)
|
||||||
|
cmd.Dir = pwd
|
||||||
output, cmdErr := cmd.CombinedOutput()
|
output, cmdErr := cmd.CombinedOutput()
|
||||||
if len(output) > 0 {
|
if len(output) > 0 {
|
||||||
fmt.Println(string(output))
|
fmt.Println(string(output))
|
||||||
|
@@ -57,15 +57,14 @@ import (
|
|||||||
_ "github.com/xtls/xray-core/transport/internet/headers/wechat"
|
_ "github.com/xtls/xray-core/transport/internet/headers/wechat"
|
||||||
_ "github.com/xtls/xray-core/transport/internet/headers/wireguard"
|
_ "github.com/xtls/xray-core/transport/internet/headers/wireguard"
|
||||||
|
|
||||||
// JSON config support. Choose only one from the two below.
|
// JSON & TOML & YAML
|
||||||
// The following line loads JSON from xctl
|
_ "github.com/xtls/xray-core/main/json"
|
||||||
// _ "github.com/xtls/xray-core/main/json"
|
_ "github.com/xtls/xray-core/main/toml"
|
||||||
// The following line loads JSON internally
|
_ "github.com/xtls/xray-core/main/yaml"
|
||||||
_ "github.com/xtls/xray-core/main/jsonem"
|
|
||||||
|
|
||||||
// Load config from file or http(s)
|
// Load config from file or http(s)
|
||||||
_ "github.com/xtls/xray-core/main/confloader/external"
|
_ "github.com/xtls/xray-core/main/confloader/external"
|
||||||
|
|
||||||
// commands
|
// Commands
|
||||||
_ "github.com/xtls/xray-core/main/commands/all"
|
_ "github.com/xtls/xray-core/main/commands/all"
|
||||||
)
|
)
|
||||||
|
@@ -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")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
}
|
|
@@ -1,4 +1,4 @@
|
|||||||
package jsonem
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
@@ -22,9 +22,13 @@ func init() {
|
|||||||
for i, arg := range v {
|
for i, arg := range v {
|
||||||
newError("Reading config: ", arg).AtInfo().WriteToLog()
|
newError("Reading config: ", arg).AtInfo().WriteToLog()
|
||||||
r, err := confloader.LoadConfig(arg)
|
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)
|
c, err := serial.DecodeJSONConfig(r)
|
||||||
common.Must(err)
|
if err != nil {
|
||||||
|
return nil, newError("failed to decode config: ", arg).Base(err)
|
||||||
|
}
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
// This ensure even if the muti-json parser do not support a setting,
|
// This ensure even if the muti-json parser do not support a setting,
|
||||||
// It is still respected automatically for the first configure file
|
// It is still respected automatically for the first configure file
|
57
main/run.go
57
main/run.go
@@ -8,13 +8,20 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
|
||||||
|
"github.com/xtls/xray-core/app/proxyman"
|
||||||
|
"github.com/xtls/xray-core/common/buf"
|
||||||
"github.com/xtls/xray-core/common/cmdarg"
|
"github.com/xtls/xray-core/common/cmdarg"
|
||||||
"github.com/xtls/xray-core/common/platform"
|
"github.com/xtls/xray-core/common/platform"
|
||||||
"github.com/xtls/xray-core/core"
|
"github.com/xtls/xray-core/core"
|
||||||
|
"github.com/xtls/xray-core/infra/conf"
|
||||||
"github.com/xtls/xray-core/main/commands/base"
|
"github.com/xtls/xray-core/main/commands/base"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -64,22 +71,29 @@ func executeRun(cmd *base.Command, args []string) {
|
|||||||
printVersion()
|
printVersion()
|
||||||
server, err := startXray()
|
server, err := startXray()
|
||||||
if err != nil {
|
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 {
|
if *test {
|
||||||
fmt.Println("Configuration OK.")
|
fmt.Println("Configuration OK.")
|
||||||
base.SetExitStatus(0)
|
os.Exit(0)
|
||||||
base.Exit()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := server.Start(); err != nil {
|
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()
|
defer server.Close()
|
||||||
|
|
||||||
|
conf.FileCache = nil
|
||||||
|
conf.IPCache = nil
|
||||||
|
conf.SiteCache = nil
|
||||||
|
|
||||||
// Explicitly triggering GC to remove garbage from config loading.
|
// Explicitly triggering GC to remove garbage from config loading.
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
|
debug.FreeOSMemory()
|
||||||
|
|
||||||
{
|
{
|
||||||
osSignals := make(chan os.Signal, 1)
|
osSignals := make(chan os.Signal, 1)
|
||||||
@@ -107,7 +121,11 @@ func readConfDir(dirPath string) {
|
|||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
for _, f := range confs {
|
for _, f := range confs {
|
||||||
if strings.HasSuffix(f.Name(), ".json") {
|
matched, err := regexp.MatchString(`^.+\.(json|toml|yaml|yml)$`, f.Name())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
if matched {
|
||||||
configFiles.Set(path.Join(dirPath, f.Name()))
|
configFiles.Set(path.Join(dirPath, f.Name()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,6 +165,10 @@ func getConfigFormat() string {
|
|||||||
switch strings.ToLower(*format) {
|
switch strings.ToLower(*format) {
|
||||||
case "pb", "protobuf":
|
case "pb", "protobuf":
|
||||||
return "protobuf"
|
return "protobuf"
|
||||||
|
case "yaml", "yml":
|
||||||
|
return "yaml"
|
||||||
|
case "toml":
|
||||||
|
return "toml"
|
||||||
default:
|
default:
|
||||||
return "json"
|
return "json"
|
||||||
}
|
}
|
||||||
@@ -156,8 +178,31 @@ func startXray() (core.Server, error) {
|
|||||||
configFiles := getConfigFilePath()
|
configFiles := getConfigFilePath()
|
||||||
|
|
||||||
config, err := core.LoadConfig(getConfigFormat(), configFiles[0], configFiles)
|
config, err := core.LoadConfig(getConfigFormat(), configFiles[0], configFiles)
|
||||||
|
|
||||||
|
//config, err := core.LoadConfigs(getConfigFormat(), configFiles)
|
||||||
|
|
||||||
if err != nil {
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
v, t := false, false
|
||||||
|
for _, outbound := range config.Outbound {
|
||||||
|
s := strings.ToLower(outbound.ProxySettings.Type)
|
||||||
|
l := len(s)
|
||||||
|
if l >= 16 && s[11:16] == "vless" || l >= 16 && s[11:16] == "vmess" {
|
||||||
|
v = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if l >= 17 && s[11:17] == "trojan" || l >= 22 && s[11:22] == "shadowsocks" {
|
||||||
|
var m proxyman.SenderConfig
|
||||||
|
proto.Unmarshal(outbound.SenderSettings.Value, &m)
|
||||||
|
if m.MultiplexSettings == nil || !m.MultiplexSettings.Enabled {
|
||||||
|
t = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v && !t {
|
||||||
|
buf.Cone = false
|
||||||
}
|
}
|
||||||
|
|
||||||
server, err := core.New(config)
|
server, err := core.New(config)
|
||||||
|
9
main/toml/errors.generated.go
Normal file
9
main/toml/errors.generated.go
Normal 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
48
main/toml/toml.go
Normal 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")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
}
|
9
main/yaml/errors.generated.go
Normal file
9
main/yaml/errors.generated.go
Normal 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
48
main/yaml/yaml.go
Normal 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")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
}
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
// Package blackhole is an outbound handler that blocks all connections.
|
// Package blackhole is an outbound handler that blocks all connections.
|
||||||
package blackhole
|
package blackhole
|
||||||
|
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package dokodemo
|
package dokodemo
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
@@ -165,36 +163,56 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
|
|||||||
if !destinationOverridden {
|
if !destinationOverridden {
|
||||||
writer = &buf.SequentialWriter{Writer: conn}
|
writer = &buf.SequentialWriter{Writer: conn}
|
||||||
} else {
|
} else {
|
||||||
sockopt := &internet.SocketConfig{
|
var addr *net.UDPAddr
|
||||||
Tproxy: internet.SocketConfig_TProxy,
|
var mark int
|
||||||
}
|
|
||||||
if dest.Address.Family().IsIP() {
|
if dest.Address.Family().IsIP() {
|
||||||
sockopt.BindAddress = dest.Address.IP()
|
addr = &net.UDPAddr{
|
||||||
sockopt.BindPort = uint32(dest.Port)
|
IP: dest.Address.IP(),
|
||||||
|
Port: int(dest.Port),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if d.sockopt != nil {
|
if d.sockopt != nil {
|
||||||
sockopt.Mark = d.sockopt.Mark
|
mark = int(d.sockopt.Mark)
|
||||||
}
|
}
|
||||||
tConn, err := internet.DialSystem(ctx, net.DestinationFromAddr(conn.RemoteAddr()), sockopt)
|
pConn, err := FakeUDP(addr, mark)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer tConn.Close()
|
back := net.DestinationFromAddr(conn.RemoteAddr())
|
||||||
|
writer = NewPacketWriter(pConn, &dest, mark, &back)
|
||||||
writer = &buf.SequentialWriter{Writer: tConn}
|
defer writer.(*PacketWriter).Close()
|
||||||
tReader := buf.NewPacketReader(tConn)
|
/*
|
||||||
requestCount++
|
sockopt := &internet.SocketConfig{
|
||||||
tproxyRequest = func() error {
|
Tproxy: internet.SocketConfig_TProxy,
|
||||||
defer func() {
|
|
||||||
if atomic.AddInt32(&requestCount, -1) == 0 {
|
|
||||||
timer.SetTimeout(plcy.Timeouts.DownlinkOnly)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err := buf.Copy(tReader, link.Writer, buf.UpdateActivity(timer)); err != nil {
|
|
||||||
return newError("failed to transport request (TPROXY conn)").Base(err)
|
|
||||||
}
|
}
|
||||||
return nil
|
if dest.Address.Family().IsIP() {
|
||||||
}
|
sockopt.BindAddress = dest.Address.IP()
|
||||||
|
sockopt.BindPort = uint32(dest.Port)
|
||||||
|
}
|
||||||
|
if d.sockopt != nil {
|
||||||
|
sockopt.Mark = d.sockopt.Mark
|
||||||
|
}
|
||||||
|
tConn, err := internet.DialSystem(ctx, net.DestinationFromAddr(conn.RemoteAddr()), sockopt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer tConn.Close()
|
||||||
|
|
||||||
|
writer = &buf.SequentialWriter{Writer: tConn}
|
||||||
|
tReader := buf.NewPacketReader(tConn)
|
||||||
|
requestCount++
|
||||||
|
tproxyRequest = func() error {
|
||||||
|
defer func() {
|
||||||
|
if atomic.AddInt32(&requestCount, -1) == 0 {
|
||||||
|
timer.SetTimeout(plcy.Timeouts.DownlinkOnly)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err := buf.Copy(tReader, link.Writer, buf.UpdateActivity(timer)); err != nil {
|
||||||
|
return newError("failed to transport request (TPROXY conn)").Base(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,3 +235,77 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewPacketWriter(conn net.PacketConn, d *net.Destination, mark int, back *net.Destination) buf.Writer {
|
||||||
|
writer := &PacketWriter{
|
||||||
|
conn: conn,
|
||||||
|
conns: make(map[net.Destination]net.PacketConn),
|
||||||
|
mark: mark,
|
||||||
|
back: &net.UDPAddr{
|
||||||
|
IP: back.Address.IP(),
|
||||||
|
Port: int(back.Port),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
writer.conns[*d] = conn
|
||||||
|
return writer
|
||||||
|
}
|
||||||
|
|
||||||
|
type PacketWriter struct {
|
||||||
|
conn net.PacketConn
|
||||||
|
conns map[net.Destination]net.PacketConn
|
||||||
|
mark int
|
||||||
|
back *net.UDPAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||||
|
for {
|
||||||
|
mb2, b := buf.SplitFirst(mb)
|
||||||
|
mb = mb2
|
||||||
|
if b == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
if b.UDP != nil && b.UDP.Address.Family().IsIP() {
|
||||||
|
conn := w.conns[*b.UDP]
|
||||||
|
if conn == nil {
|
||||||
|
conn, err = FakeUDP(
|
||||||
|
&net.UDPAddr{
|
||||||
|
IP: b.UDP.Address.IP(),
|
||||||
|
Port: int(b.UDP.Port),
|
||||||
|
},
|
||||||
|
w.mark,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
b.Release()
|
||||||
|
buf.ReleaseMulti(mb)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.conns[*b.UDP] = conn
|
||||||
|
}
|
||||||
|
_, err = conn.WriteTo(b.Bytes(), w.back)
|
||||||
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
|
w.conns[*b.UDP] = nil
|
||||||
|
newError(err).WriteToLog()
|
||||||
|
}
|
||||||
|
b.Release()
|
||||||
|
} else {
|
||||||
|
_, err = w.conn.WriteTo(b.Bytes(), w.back)
|
||||||
|
b.Release()
|
||||||
|
if err != nil {
|
||||||
|
buf.ReleaseMulti(mb)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *PacketWriter) Close() error {
|
||||||
|
for _, conn := range w.conns {
|
||||||
|
if conn != nil {
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
85
proxy/dokodemo/fakeudp_linux.go
Normal file
85
proxy/dokodemo/fakeudp_linux.go
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
// +build linux
|
||||||
|
|
||||||
|
package dokodemo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FakeUDP(addr *net.UDPAddr, mark int) (net.PacketConn, error) {
|
||||||
|
|
||||||
|
if addr == nil {
|
||||||
|
addr = &net.UDPAddr{
|
||||||
|
IP: []byte{0, 0, 0, 0},
|
||||||
|
Port: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
localSocketAddress, af, err := udpAddrToSocketAddr(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("build local socket address: %s", err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileDescriptor, err := syscall.Socket(af, syscall.SOCK_DGRAM, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("socket open: %s", err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
if mark != 0 {
|
||||||
|
if err = syscall.SetsockoptInt(fileDescriptor, syscall.SOL_SOCKET, syscall.SO_MARK, mark); err != nil {
|
||||||
|
syscall.Close(fileDescriptor)
|
||||||
|
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("set socket option: SO_MARK: %s", err)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = syscall.SetsockoptInt(fileDescriptor, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
|
||||||
|
syscall.Close(fileDescriptor)
|
||||||
|
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("set socket option: SO_REUSEADDR: %s", err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = syscall.SetsockoptInt(fileDescriptor, syscall.SOL_IP, syscall.IP_TRANSPARENT, 1); err != nil {
|
||||||
|
syscall.Close(fileDescriptor)
|
||||||
|
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("set socket option: IP_TRANSPARENT: %s", err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = syscall.Bind(fileDescriptor, localSocketAddress); err != nil {
|
||||||
|
syscall.Close(fileDescriptor)
|
||||||
|
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("socket bind: %s", err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
fdFile := os.NewFile(uintptr(fileDescriptor), fmt.Sprintf("net-udp-fake-%s", addr.String()))
|
||||||
|
defer fdFile.Close()
|
||||||
|
|
||||||
|
packetConn, err := net.FilePacketConn(fdFile)
|
||||||
|
if err != nil {
|
||||||
|
syscall.Close(fileDescriptor)
|
||||||
|
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("convert file descriptor to connection: %s", err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
return packetConn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func udpAddrToSocketAddr(addr *net.UDPAddr) (syscall.Sockaddr, int, error) {
|
||||||
|
switch {
|
||||||
|
case addr.IP.To4() != nil:
|
||||||
|
ip := [4]byte{}
|
||||||
|
copy(ip[:], addr.IP.To4())
|
||||||
|
|
||||||
|
return &syscall.SockaddrInet4{Addr: ip, Port: addr.Port}, syscall.AF_INET, nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
ip := [16]byte{}
|
||||||
|
copy(ip[:], addr.IP.To16())
|
||||||
|
|
||||||
|
zoneID, err := strconv.ParseUint(addr.Zone, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &syscall.SockaddrInet6{Addr: ip, Port: addr.Port, ZoneId: uint32(zoneID)}, syscall.AF_INET6, nil
|
||||||
|
}
|
||||||
|
}
|
12
proxy/dokodemo/fakeudp_other.go
Normal file
12
proxy/dokodemo/fakeudp_other.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// +build !linux
|
||||||
|
|
||||||
|
package dokodemo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FakeUDP(addr *net.UDPAddr, mark int) (net.PacketConn, error) {
|
||||||
|
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("!linux")}
|
||||||
|
}
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package freedom
|
package freedom
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//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/core"
|
||||||
"github.com/xtls/xray-core/features/dns"
|
"github.com/xtls/xray-core/features/dns"
|
||||||
"github.com/xtls/xray-core/features/policy"
|
"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"
|
||||||
"github.com/xtls/xray-core/transport/internet"
|
"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 {
|
if destination.Network == net.Network_TCP {
|
||||||
writer = buf.NewWriter(conn)
|
writer = buf.NewWriter(conn)
|
||||||
} else {
|
} else {
|
||||||
writer = &buf.SequentialWriter{Writer: conn}
|
writer = NewPacketWriter(conn, h, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := buf.Copy(input, writer, buf.UpdateActivity(timer)); err != nil {
|
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 {
|
if destination.Network == net.Network_TCP {
|
||||||
reader = buf.NewReader(conn)
|
reader = buf.NewReader(conn)
|
||||||
} else {
|
} else {
|
||||||
reader = buf.NewPacketReader(conn)
|
reader = NewPacketReader(conn)
|
||||||
}
|
}
|
||||||
if err := buf.Copy(reader, output, buf.UpdateActivity(timer)); err != nil {
|
if err := buf.Copy(reader, output, buf.UpdateActivity(timer)); err != nil {
|
||||||
return newError("failed to process response").Base(err)
|
return newError("failed to process response").Base(err)
|
||||||
@@ -182,3 +181,112 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||||||
|
|
||||||
return nil
|
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 = &net.Destination{
|
||||||
|
Address: net.IPAddress(d.(*net.UDPAddr).IP),
|
||||||
|
Port: net.Port(d.(*net.UDPAddr).Port),
|
||||||
|
Network: net.Network_UDP,
|
||||||
|
}
|
||||||
|
if r.Counter != nil {
|
||||||
|
r.Counter.Add(int64(n))
|
||||||
|
}
|
||||||
|
return buf.MultiBuffer{b}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPacketWriter(conn net.Conn, h *Handler, ctx context.Context) 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,
|
||||||
|
Handler: h,
|
||||||
|
Context: ctx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &buf.SequentialWriter{Writer: conn}
|
||||||
|
}
|
||||||
|
|
||||||
|
type PacketWriter struct {
|
||||||
|
*internet.PacketConnWrapper
|
||||||
|
stats.Counter
|
||||||
|
*Handler
|
||||||
|
context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if w.Handler.config.useIP() && b.UDP.Address.Family().IsDomain() {
|
||||||
|
ip := w.Handler.resolveIP(w.Context, b.UDP.Address.Domain(), nil)
|
||||||
|
if ip != nil {
|
||||||
|
b.UDP.Address = ip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
destAddr, _ := net.ResolveUDPAddr("udp", b.UDP.NetAddr())
|
||||||
|
if destAddr == nil {
|
||||||
|
b.Release()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
n, err = w.PacketConnWrapper.WriteTo(b.Bytes(), destAddr)
|
||||||
|
} 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
|
||||||
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -170,6 +168,7 @@ func setUpHTTPTunnel(ctx context.Context, dest net.Destination, target string, u
|
|||||||
rawConn.Close()
|
rawConn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
rawConn.Close()
|
rawConn.Close()
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -295,6 +293,7 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, wri
|
|||||||
response.Close = true
|
response.Close = true
|
||||||
result = nil
|
result = nil
|
||||||
}
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
} else {
|
} else {
|
||||||
newError("failed to read response from ", request.Host).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))
|
newError("failed to read response from ", request.Host).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))
|
||||||
response = &http.Response{
|
response = &http.Response{
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package mtproto
|
package mtproto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package shadowsocks
|
package shadowsocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -136,14 +134,15 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||||||
}
|
}
|
||||||
|
|
||||||
if request.Command == protocol.RequestCommandUDP {
|
if request.Command == protocol.RequestCommandUDP {
|
||||||
writer := &buf.SequentialWriter{Writer: &UDPWriter{
|
|
||||||
Writer: conn,
|
|
||||||
Request: request,
|
|
||||||
}}
|
|
||||||
|
|
||||||
requestDone := func() error {
|
requestDone := func() error {
|
||||||
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
|
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
|
||||||
|
|
||||||
|
writer := &UDPWriter{
|
||||||
|
Writer: conn,
|
||||||
|
Request: request,
|
||||||
|
}
|
||||||
|
|
||||||
if err := buf.Copy(link.Reader, writer, buf.UpdateActivity(timer)); err != nil {
|
if err := buf.Copy(link.Reader, writer, buf.UpdateActivity(timer)); err != nil {
|
||||||
return newError("failed to transport all UDP request").Base(err)
|
return newError("failed to transport all UDP request").Base(err)
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package shadowsocks
|
package shadowsocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -232,11 +230,13 @@ func (v *UDPReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
|||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, payload, err := DecodeUDPPacket(v.User, buffer)
|
u, payload, err := DecodeUDPPacket(v.User, buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
dest := u.Destination()
|
||||||
|
payload.UDP = &dest
|
||||||
return buf.MultiBuffer{payload}, nil
|
return buf.MultiBuffer{payload}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,13 +245,33 @@ type UDPWriter struct {
|
|||||||
Request *protocol.RequestHeader
|
Request *protocol.RequestHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write implements io.Writer.
|
func (w *UDPWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||||
func (w *UDPWriter) Write(payload []byte) (int, error) {
|
for {
|
||||||
packet, err := EncodeUDPPacket(w.Request, payload)
|
mb2, b := buf.SplitFirst(mb)
|
||||||
if err != nil {
|
mb = mb2
|
||||||
return 0, err
|
if b == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
request := w.Request
|
||||||
|
if b.UDP != nil {
|
||||||
|
request = &protocol.RequestHeader{
|
||||||
|
User: w.Request.User,
|
||||||
|
Address: b.UDP.Address,
|
||||||
|
Port: b.UDP.Port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packet, err := EncodeUDPPacket(request, b.Bytes())
|
||||||
|
b.Release()
|
||||||
|
if err != nil {
|
||||||
|
buf.ReleaseMulti(mb)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = w.Writer.Write(packet.Bytes())
|
||||||
|
packet.Release()
|
||||||
|
if err != nil {
|
||||||
|
buf.ReleaseMulti(mb)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_, err = w.Writer.Write(packet.Bytes())
|
return nil
|
||||||
packet.Release()
|
|
||||||
return len(payload), err
|
|
||||||
}
|
}
|
||||||
|
@@ -145,7 +145,7 @@ func TestUDPReaderWriter(t *testing.T) {
|
|||||||
cache := buf.New()
|
cache := buf.New()
|
||||||
defer cache.Release()
|
defer cache.Release()
|
||||||
|
|
||||||
writer := &buf.SequentialWriter{Writer: &UDPWriter{
|
writer := &UDPWriter{
|
||||||
Writer: cache,
|
Writer: cache,
|
||||||
Request: &protocol.RequestHeader{
|
Request: &protocol.RequestHeader{
|
||||||
Version: Version,
|
Version: Version,
|
||||||
@@ -153,7 +153,7 @@ func TestUDPReaderWriter(t *testing.T) {
|
|||||||
Port: 123,
|
Port: 123,
|
||||||
User: user,
|
User: user,
|
||||||
},
|
},
|
||||||
}}
|
}
|
||||||
|
|
||||||
reader := &UDPReader{
|
reader := &UDPReader{
|
||||||
Reader: cache,
|
Reader: cache,
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package shadowsocks
|
package shadowsocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -79,6 +77,15 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
payload := packet.Payload
|
payload := packet.Payload
|
||||||
|
|
||||||
|
if payload.UDP != nil {
|
||||||
|
request = &protocol.RequestHeader{
|
||||||
|
User: request.User,
|
||||||
|
Address: payload.UDP.Address,
|
||||||
|
Port: payload.UDP.Port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data, err := EncodeUDPPacket(request, payload.Bytes())
|
data, err := EncodeUDPPacket(request, payload.Bytes())
|
||||||
payload.Release()
|
payload.Release()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -96,6 +103,8 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
|
|||||||
}
|
}
|
||||||
inbound.User = s.user
|
inbound.User = s.user
|
||||||
|
|
||||||
|
var dest *net.Destination
|
||||||
|
|
||||||
reader := buf.NewPacketReader(conn)
|
reader := buf.NewPacketReader(conn)
|
||||||
for {
|
for {
|
||||||
mpayload, err := reader.ReadMultiBuffer()
|
mpayload, err := reader.ReadMultiBuffer()
|
||||||
@@ -119,21 +128,28 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destination := request.Destination()
|
||||||
|
|
||||||
currentPacketCtx := ctx
|
currentPacketCtx := ctx
|
||||||
dest := request.Destination()
|
|
||||||
if inbound.Source.IsValid() {
|
if inbound.Source.IsValid() {
|
||||||
currentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
|
currentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
|
||||||
From: inbound.Source,
|
From: inbound.Source,
|
||||||
To: dest,
|
To: destination,
|
||||||
Status: log.AccessAccepted,
|
Status: log.AccessAccepted,
|
||||||
Reason: "",
|
Reason: "",
|
||||||
Email: request.User.Email,
|
Email: request.User.Email,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
newError("tunnelling request to ", dest).WriteToLog(session.ExportIDToError(currentPacketCtx))
|
newError("tunnelling request to ", destination).WriteToLog(session.ExportIDToError(currentPacketCtx))
|
||||||
|
|
||||||
|
data.UDP = &destination
|
||||||
|
|
||||||
|
if !buf.Cone || dest == nil {
|
||||||
|
dest = &destination
|
||||||
|
}
|
||||||
|
|
||||||
currentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request)
|
currentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request)
|
||||||
udpServer.Dispatch(currentPacketCtx, dest, data)
|
udpServer.Dispatch(currentPacketCtx, *dest, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package socks
|
package socks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -53,14 +51,19 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||||||
if outbound == nil || !outbound.Target.IsValid() {
|
if outbound == nil || !outbound.Target.IsValid() {
|
||||||
return newError("target not specified.")
|
return newError("target not specified.")
|
||||||
}
|
}
|
||||||
|
// Destination of the inner request.
|
||||||
destination := outbound.Target
|
destination := outbound.Target
|
||||||
|
|
||||||
|
// Outbound server.
|
||||||
var server *protocol.ServerSpec
|
var server *protocol.ServerSpec
|
||||||
|
// Outbound server's destination.
|
||||||
|
var dest net.Destination
|
||||||
|
// Connection to the outbound server.
|
||||||
var conn internet.Connection
|
var conn internet.Connection
|
||||||
|
|
||||||
if err := retry.ExponentialBackoff(5, 100).On(func() error {
|
if err := retry.ExponentialBackoff(5, 100).On(func() error {
|
||||||
server = c.serverPicker.PickServer()
|
server = c.serverPicker.PickServer()
|
||||||
dest := server.Destination()
|
dest = server.Destination()
|
||||||
rawConn, err := dialer.Dial(ctx, dest)
|
rawConn, err := dialer.Dial(ctx, dest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -103,6 +106,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return newError("failed to establish connection to server").AtWarning().Base(err)
|
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 {
|
if err := conn.SetDeadline(time.Time{}); err != nil {
|
||||||
newError("failed to clear deadline after handshake").Base(err).WriteToLog(session.ExportIDToError(ctx))
|
newError("failed to clear deadline after handshake").Base(err).WriteToLog(session.ExportIDToError(ctx))
|
||||||
@@ -130,11 +138,12 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||||||
defer udpConn.Close()
|
defer udpConn.Close()
|
||||||
requestFunc = func() error {
|
requestFunc = func() error {
|
||||||
defer timer.SetTimeout(p.Timeouts.DownlinkOnly)
|
defer timer.SetTimeout(p.Timeouts.DownlinkOnly)
|
||||||
return buf.Copy(link.Reader, &buf.SequentialWriter{Writer: NewUDPWriter(request, udpConn)}, buf.UpdateActivity(timer))
|
writer := &UDPWriter{Writer: udpConn, Request: request}
|
||||||
|
return buf.Copy(link.Reader, writer, buf.UpdateActivity(timer))
|
||||||
}
|
}
|
||||||
responseFunc = func() error {
|
responseFunc = func() error {
|
||||||
defer timer.SetTimeout(p.Timeouts.UplinkOnly)
|
defer timer.SetTimeout(p.Timeouts.UplinkOnly)
|
||||||
reader := &UDPReader{reader: udpConn}
|
reader := &UDPReader{Reader: udpConn}
|
||||||
return buf.Copy(reader, link.Writer, buf.UpdateActivity(timer))
|
return buf.Copy(reader, link.Writer, buf.UpdateActivity(timer))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package socks
|
package socks
|
||||||
|
|
||||||
import "github.com/xtls/xray-core/common/protocol"
|
import "github.com/xtls/xray-core/common/protocol"
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package socks
|
package socks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -18,7 +16,7 @@ const (
|
|||||||
|
|
||||||
cmdTCPConnect = 0x01
|
cmdTCPConnect = 0x01
|
||||||
cmdTCPBind = 0x02
|
cmdTCPBind = 0x02
|
||||||
cmdUDPPort = 0x03
|
cmdUDPAssociate = 0x03
|
||||||
cmdTorResolve = 0xF0
|
cmdTorResolve = 0xF0
|
||||||
cmdTorResolvePTR = 0xF1
|
cmdTorResolvePTR = 0xF1
|
||||||
|
|
||||||
@@ -41,8 +39,10 @@ var addrParser = protocol.NewAddressParser(
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ServerSession struct {
|
type ServerSession struct {
|
||||||
config *ServerConfig
|
config *ServerConfig
|
||||||
port net.Port
|
address net.Address
|
||||||
|
port net.Port
|
||||||
|
clientAddress net.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServerSession) handshake4(cmd byte, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) {
|
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:
|
case cmdTCPConnect, cmdTorResolve, cmdTorResolvePTR:
|
||||||
// We don't have a solution for Tor case now. Simply treat it as connect command.
|
// We don't have a solution for Tor case now. Simply treat it as connect command.
|
||||||
request.Command = protocol.RequestCommandTCP
|
request.Command = protocol.RequestCommandTCP
|
||||||
case cmdUDPPort:
|
case cmdUDPAssociate:
|
||||||
if !s.config.UdpEnabled {
|
if !s.config.UdpEnabled {
|
||||||
writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0))
|
writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0))
|
||||||
return nil, newError("UDP is not enabled.")
|
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.Address = addr
|
||||||
request.Port = port
|
request.Port = port
|
||||||
|
|
||||||
responseAddress := net.AnyIP
|
responseAddress := s.address
|
||||||
responsePort := net.Port(1717)
|
responsePort := s.port
|
||||||
|
//nolint:gocritic // Use if else chain for clarity
|
||||||
if request.Command == protocol.RequestCommandUDP {
|
if request.Command == protocol.RequestCommandUDP {
|
||||||
addr := s.config.Address.AsAddress()
|
if s.config.Address != nil {
|
||||||
if addr == nil {
|
// Use configured IP as remote address in the response to UdpAssociate
|
||||||
addr = net.LocalHostIP
|
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 {
|
if err := writeSocks5Response(writer, statusSuccess, responseAddress, responsePort); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -355,47 +360,59 @@ func EncodeUDPPacket(request *protocol.RequestHeader, data []byte) (*buf.Buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UDPReader struct {
|
type UDPReader struct {
|
||||||
reader io.Reader
|
Reader io.Reader
|
||||||
}
|
|
||||||
|
|
||||||
func NewUDPReader(reader io.Reader) *UDPReader {
|
|
||||||
return &UDPReader{reader: reader}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *UDPReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
func (r *UDPReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
||||||
b := buf.New()
|
buffer := buf.New()
|
||||||
if _, err := b.ReadFrom(r.reader); err != nil {
|
_, err := buffer.ReadFrom(r.Reader)
|
||||||
|
if err != nil {
|
||||||
|
buffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if _, err := DecodeUDPPacket(b); err != nil {
|
u, err := DecodeUDPPacket(buffer)
|
||||||
|
if err != nil {
|
||||||
|
buffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return buf.MultiBuffer{b}, nil
|
dest := u.Destination()
|
||||||
|
buffer.UDP = &dest
|
||||||
|
return buf.MultiBuffer{buffer}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type UDPWriter struct {
|
type UDPWriter struct {
|
||||||
request *protocol.RequestHeader
|
Writer io.Writer
|
||||||
writer io.Writer
|
Request *protocol.RequestHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUDPWriter(request *protocol.RequestHeader, writer io.Writer) *UDPWriter {
|
func (w *UDPWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||||
return &UDPWriter{
|
for {
|
||||||
request: request,
|
mb2, b := buf.SplitFirst(mb)
|
||||||
writer: writer,
|
mb = mb2
|
||||||
|
if b == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
request := w.Request
|
||||||
|
if b.UDP != nil {
|
||||||
|
request = &protocol.RequestHeader{
|
||||||
|
Address: b.UDP.Address,
|
||||||
|
Port: b.UDP.Port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
packet, err := EncodeUDPPacket(request, b.Bytes())
|
||||||
|
b.Release()
|
||||||
|
if err != nil {
|
||||||
|
buf.ReleaseMulti(mb)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = w.Writer.Write(packet.Bytes())
|
||||||
|
packet.Release()
|
||||||
|
if err != nil {
|
||||||
|
buf.ReleaseMulti(mb)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return nil
|
||||||
|
|
||||||
// Write implements io.Writer.
|
|
||||||
func (w *UDPWriter) Write(b []byte) (int, error) {
|
|
||||||
eb, err := EncodeUDPPacket(w.request, b)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
defer eb.Release()
|
|
||||||
if _, err := w.writer.Write(eb.Bytes()); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return len(b), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) {
|
func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) {
|
||||||
@@ -448,7 +465,7 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i
|
|||||||
|
|
||||||
command := byte(cmdTCPConnect)
|
command := byte(cmdTCPConnect)
|
||||||
if request.Command == protocol.RequestCommandUDP {
|
if request.Command == protocol.RequestCommandUDP {
|
||||||
command = byte(cmdUDPPort)
|
command = byte(cmdUDPAssociate)
|
||||||
}
|
}
|
||||||
common.Must2(b.Write([]byte{socks5Version, command, 0x00 /* reserved */}))
|
common.Must2(b.Write([]byte{socks5Version, command, 0x00 /* reserved */}))
|
||||||
if err := addrParser.WriteAddressPort(b, request.Address, request.Port); err != nil {
|
if err := addrParser.WriteAddressPort(b, request.Address, request.Port); err != nil {
|
||||||
|
@@ -20,14 +20,14 @@ func TestUDPEncoding(t *testing.T) {
|
|||||||
Address: net.IPAddress([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6}),
|
Address: net.IPAddress([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6}),
|
||||||
Port: 1024,
|
Port: 1024,
|
||||||
}
|
}
|
||||||
writer := &buf.SequentialWriter{Writer: NewUDPWriter(request, b)}
|
writer := &UDPWriter{Writer: b, Request: request}
|
||||||
|
|
||||||
content := []byte{'a'}
|
content := []byte{'a'}
|
||||||
payload := buf.New()
|
payload := buf.New()
|
||||||
payload.Write(content)
|
payload.Write(content)
|
||||||
common.Must(writer.WriteMultiBuffer(buf.MultiBuffer{payload}))
|
common.Must(writer.WriteMultiBuffer(buf.MultiBuffer{payload}))
|
||||||
|
|
||||||
reader := NewUDPReader(b)
|
reader := &UDPReader{Reader: b}
|
||||||
|
|
||||||
decodedPayload, err := reader.ReadMultiBuffer()
|
decodedPayload, err := reader.ReadMultiBuffer()
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package socks
|
package socks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -91,8 +89,10 @@ func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispa
|
|||||||
}
|
}
|
||||||
|
|
||||||
svrSession := &ServerSession{
|
svrSession := &ServerSession{
|
||||||
config: s.config,
|
config: s.config,
|
||||||
port: inbound.Gateway.Port,
|
address: inbound.Gateway.Address,
|
||||||
|
port: inbound.Gateway.Port,
|
||||||
|
clientAddress: inbound.Source.Address,
|
||||||
}
|
}
|
||||||
|
|
||||||
reader := &buf.BufferedReader{Reader: buf.NewReader(conn)}
|
reader := &buf.BufferedReader{Reader: buf.NewReader(conn)}
|
||||||
@@ -198,6 +198,15 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
|
|||||||
if request == nil {
|
if request == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if payload.UDP != nil {
|
||||||
|
request = &protocol.RequestHeader{
|
||||||
|
User: request.User,
|
||||||
|
Address: payload.UDP.Address,
|
||||||
|
Port: payload.UDP.Port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
udpMessage, err := EncodeUDPPacket(request, payload.Bytes())
|
udpMessage, err := EncodeUDPPacket(request, payload.Bytes())
|
||||||
payload.Release()
|
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))
|
newError("client UDP connection from ", inbound.Source).WriteToLog(session.ExportIDToError(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dest *net.Destination
|
||||||
|
|
||||||
reader := buf.NewPacketReader(conn)
|
reader := buf.NewPacketReader(conn)
|
||||||
for {
|
for {
|
||||||
mpayload, err := reader.ReadMultiBuffer()
|
mpayload, err := reader.ReadMultiBuffer()
|
||||||
@@ -233,19 +244,28 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
|
|||||||
payload.Release()
|
payload.Release()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destination := request.Destination()
|
||||||
|
|
||||||
currentPacketCtx := ctx
|
currentPacketCtx := ctx
|
||||||
newError("send packet to ", request.Destination(), " with ", payload.Len(), " bytes").AtDebug().WriteToLog(session.ExportIDToError(ctx))
|
newError("send packet to ", destination, " with ", payload.Len(), " bytes").AtDebug().WriteToLog(session.ExportIDToError(ctx))
|
||||||
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {
|
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {
|
||||||
currentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
|
currentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
|
||||||
From: inbound.Source,
|
From: inbound.Source,
|
||||||
To: request.Destination(),
|
To: destination,
|
||||||
Status: log.AccessAccepted,
|
Status: log.AccessAccepted,
|
||||||
Reason: "",
|
Reason: "",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
payload.UDP = &destination
|
||||||
|
|
||||||
|
if !buf.Cone || dest == nil {
|
||||||
|
dest = &destination
|
||||||
|
}
|
||||||
|
|
||||||
currentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request)
|
currentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request)
|
||||||
udpServer.Dispatch(currentPacketCtx, request.Destination(), payload)
|
udpServer.Dispatch(currentPacketCtx, *dest, payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package trojan
|
package trojan
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -81,56 +79,63 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||||||
|
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
user := server.PickUser()
|
|
||||||
account, ok := user.Account.(*MemoryAccount)
|
|
||||||
if !ok {
|
|
||||||
return newError("user account is not valid")
|
|
||||||
}
|
|
||||||
|
|
||||||
iConn := conn
|
iConn := conn
|
||||||
statConn, ok := iConn.(*internet.StatCouterConnection)
|
statConn, ok := iConn.(*internet.StatCouterConnection)
|
||||||
if ok {
|
if ok {
|
||||||
iConn = statConn.Connection
|
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
|
allowUDP443 := false
|
||||||
switch account.Flow {
|
switch connWriter.Flow {
|
||||||
case XRO + "-udp443", XRD + "-udp443":
|
case XRO + "-udp443", XRD + "-udp443", XRS + "-udp443":
|
||||||
allowUDP443 = true
|
allowUDP443 = true
|
||||||
account.Flow = account.Flow[:16]
|
connWriter.Flow = connWriter.Flow[:16]
|
||||||
fallthrough
|
fallthrough
|
||||||
case XRO, XRD:
|
case XRO, XRD, XRS:
|
||||||
if destination.Address.Family().IsDomain() && destination.Address.Domain() == muxCoolAddress {
|
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 destination.Network == net.Network_UDP {
|
||||||
if !allowUDP443 && destination.Port == 443 {
|
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
|
} else { // enable XTLS only if making TCP request
|
||||||
if xtlsConn, ok := iConn.(*xtls.Conn); ok {
|
if xtlsConn, ok := iConn.(*xtls.Conn); ok {
|
||||||
xtlsConn.RPRX = true
|
xtlsConn.RPRX = true
|
||||||
xtlsConn.SHOW = trojanXTLSShow
|
xtlsConn.SHOW = xtls_show
|
||||||
connWriter.Flow = account.Flow
|
xtlsConn.MARK = "XTLS"
|
||||||
if account.Flow == XRD {
|
if connWriter.Flow == XRS {
|
||||||
xtlsConn.DirectMode = true
|
sctx = ctx
|
||||||
|
connWriter.Flow = XRD
|
||||||
}
|
}
|
||||||
if sc, ok := xtlsConn.Connection.(syscall.Conn); ok {
|
if connWriter.Flow == XRD {
|
||||||
rawConn, _ = sc.SyscallConn()
|
xtlsConn.DirectMode = true
|
||||||
|
if sc, ok := xtlsConn.Connection.(syscall.Conn); ok {
|
||||||
|
rawConn, _ = sc.SyscallConn()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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 {
|
if _, ok := iConn.(*xtls.Conn); ok {
|
||||||
panic(`To avoid misunderstanding, you must fill in Trojan "flow" when using XTLS.`)
|
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)
|
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 {
|
if statConn != nil {
|
||||||
counter = statConn.ReadCounter
|
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))
|
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 })
|
xtlsShow := platform.NewEnvFlag("xray.trojan.xtls.show").GetValue(func() string { return defaultFlagValue })
|
||||||
if xtlsShow == "true" {
|
if xtlsShow == "true" {
|
||||||
trojanXTLSShow = true
|
xtls_show = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,17 +1,21 @@
|
|||||||
package trojan
|
package trojan
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
fmt "fmt"
|
fmt "fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"runtime"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/buf"
|
"github.com/xtls/xray-core/common/buf"
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/common/protocol"
|
"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/common/signal"
|
||||||
"github.com/xtls/xray-core/features/stats"
|
"github.com/xtls/xray-core/features/stats"
|
||||||
|
"github.com/xtls/xray-core/transport/internet"
|
||||||
"github.com/xtls/xray-core/transport/internet/xtls"
|
"github.com/xtls/xray-core/transport/internet/xtls"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -24,11 +28,13 @@ var (
|
|||||||
protocol.AddressFamilyByte(0x03, net.AddressFamilyDomain),
|
protocol.AddressFamilyByte(0x03, net.AddressFamilyDomain),
|
||||||
)
|
)
|
||||||
|
|
||||||
trojanXTLSShow = false
|
xtls_show = false
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
maxLength = 8192
|
maxLength = 8192
|
||||||
|
// XRS is constant for XTLS splice mode
|
||||||
|
XRS = "xtls-rprx-splice"
|
||||||
// XRD is constant for XTLS direct mode
|
// XRD is constant for XTLS direct mode
|
||||||
XRD = "xtls-rprx-direct"
|
XRD = "xtls-rprx-direct"
|
||||||
// XRO is constant for XTLS origin mode
|
// XRO is constant for XTLS origin mode
|
||||||
@@ -84,10 +90,10 @@ func (c *ConnWriter) writeHeader() error {
|
|||||||
command := commandTCP
|
command := commandTCP
|
||||||
if c.Target.Network == net.Network_UDP {
|
if c.Target.Network == net.Network_UDP {
|
||||||
command = commandUDP
|
command = commandUDP
|
||||||
} else if c.Flow == XRO {
|
|
||||||
command = commandXRO
|
|
||||||
} else if c.Flow == XRD {
|
} else if c.Flow == XRD {
|
||||||
command = commandXRD
|
command = commandXRD
|
||||||
|
} else if c.Flow == XRO {
|
||||||
|
command = commandXRO
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := buffer.Write(c.Account.Key); err != nil {
|
if _, err := buffer.Write(c.Account.Key); err != nil {
|
||||||
@@ -122,31 +128,41 @@ type PacketWriter struct {
|
|||||||
|
|
||||||
// WriteMultiBuffer implements buf.Writer
|
// WriteMultiBuffer implements buf.Writer
|
||||||
func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||||
b := make([]byte, maxLength)
|
for {
|
||||||
for !mb.IsEmpty() {
|
mb2, b := buf.SplitFirst(mb)
|
||||||
var length int
|
mb = mb2
|
||||||
mb, length = buf.SplitBytes(mb, b)
|
if b == nil {
|
||||||
if _, err := w.writePacket(b[:length], w.Target); err != nil {
|
break
|
||||||
|
}
|
||||||
|
target := &w.Target
|
||||||
|
if b.UDP != nil {
|
||||||
|
target = b.UDP
|
||||||
|
}
|
||||||
|
if _, err := w.writePacket(b.Bytes(), *target); err != nil {
|
||||||
buf.ReleaseMulti(mb)
|
buf.ReleaseMulti(mb)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMultiBufferWithMetadata writes udp packet with destination specified
|
// WriteMultiBufferWithMetadata writes udp packet with destination specified
|
||||||
func (w *PacketWriter) WriteMultiBufferWithMetadata(mb buf.MultiBuffer, dest net.Destination) error {
|
func (w *PacketWriter) WriteMultiBufferWithMetadata(mb buf.MultiBuffer, dest net.Destination) error {
|
||||||
b := make([]byte, maxLength)
|
for {
|
||||||
for !mb.IsEmpty() {
|
mb2, b := buf.SplitFirst(mb)
|
||||||
var length int
|
mb = mb2
|
||||||
mb, length = buf.SplitBytes(mb, b)
|
if b == nil {
|
||||||
if _, err := w.writePacket(b[:length], dest); err != nil {
|
break
|
||||||
|
}
|
||||||
|
source := &dest
|
||||||
|
if b.UDP != nil {
|
||||||
|
source = b.UDP
|
||||||
|
}
|
||||||
|
if _, err := w.writePacket(b.Bytes(), *source); err != nil {
|
||||||
buf.ReleaseMulti(mb)
|
buf.ReleaseMulti(mb)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,10 +221,10 @@ func (c *ConnReader) ParseHeader() error {
|
|||||||
network := net.Network_TCP
|
network := net.Network_TCP
|
||||||
if command[0] == commandUDP {
|
if command[0] == commandUDP {
|
||||||
network = net.Network_UDP
|
network = net.Network_UDP
|
||||||
} else if command[0] == commandXRO {
|
|
||||||
c.Flow = XRO
|
|
||||||
} else if command[0] == commandXRD {
|
} else if command[0] == commandXRD {
|
||||||
c.Flow = XRD
|
c.Flow = XRD
|
||||||
|
} else if command[0] == commandXRO {
|
||||||
|
c.Flow = XRO
|
||||||
}
|
}
|
||||||
|
|
||||||
addr, port, err := addrParser.ReadAddressPort(nil, c.Reader)
|
addr, port, err := addrParser.ReadAddressPort(nil, c.Reader)
|
||||||
@@ -294,6 +310,7 @@ func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
b := buf.New()
|
b := buf.New()
|
||||||
|
b.UDP = &dest
|
||||||
mb = append(mb, b)
|
mb = append(mb, b)
|
||||||
n, err := b.ReadFullFrom(r, int32(length))
|
n, err := b.ReadFullFrom(r, int32(length))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -307,12 +324,42 @@ func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) {
|
|||||||
return &PacketPayload{Target: dest, Buffer: mb}, nil
|
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 {
|
err := func() error {
|
||||||
var ct stats.Counter
|
var ct stats.Counter
|
||||||
for {
|
for {
|
||||||
if conn.DirectIn {
|
if conn.DirectIn {
|
||||||
conn.DirectIn = false
|
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)
|
reader = buf.NewReadVReader(conn.Connection, rawConn)
|
||||||
ct = counter
|
ct = counter
|
||||||
if conn.SHOW {
|
if conn.SHOW {
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package trojan
|
package trojan
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -40,7 +38,7 @@ func init() {
|
|||||||
|
|
||||||
xtlsShow := platform.NewEnvFlag("xray.trojan.xtls.show").GetValue(func() string { return defaultFlagValue })
|
xtlsShow := platform.NewEnvFlag("xray.trojan.xtls.show").GetValue(func() string { return defaultFlagValue })
|
||||||
if xtlsShow == "true" {
|
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 {
|
if xtlsConn, ok := iConn.(*xtls.Conn); ok {
|
||||||
xtlsConn.RPRX = true
|
xtlsConn.RPRX = true
|
||||||
xtlsConn.SHOW = trojanXTLSShow
|
xtlsConn.SHOW = xtls_show
|
||||||
|
xtlsConn.MARK = "XTLS"
|
||||||
if clientReader.Flow == XRD {
|
if clientReader.Flow == XRD {
|
||||||
xtlsConn.DirectMode = true
|
xtlsConn.DirectMode = true
|
||||||
if sc, ok := xtlsConn.Connection.(syscall.Conn); ok {
|
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()
|
return newError(`failed to use ` + clientReader.Flow + `, maybe "security" is not "xtls"`).AtWarning()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return newError("unable to use ", clientReader.Flow).AtWarning()
|
return newError(account.Password + " is not able to use " + clientReader.Flow).AtWarning()
|
||||||
}
|
}
|
||||||
case "":
|
case "":
|
||||||
default:
|
|
||||||
return newError("unsupported flow " + account.Flow).AtWarning()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
|
ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
|
||||||
@@ -259,6 +256,8 @@ func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReade
|
|||||||
inbound := session.InboundFromContext(ctx)
|
inbound := session.InboundFromContext(ctx)
|
||||||
user := inbound.User
|
user := inbound.User
|
||||||
|
|
||||||
|
var dest *net.Destination
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
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))
|
newError("tunnelling request to ", p.Target).WriteToLog(session.ExportIDToError(ctx))
|
||||||
|
|
||||||
|
if !buf.Cone || dest == nil {
|
||||||
|
dest = &p.Target
|
||||||
|
}
|
||||||
|
|
||||||
for _, b := range p.Buffer {
|
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 {
|
if statConn != nil {
|
||||||
counter = statConn.ReadCounter
|
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 {
|
} else {
|
||||||
err = buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer))
|
err = buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer))
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package trojan
|
package trojan
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package vless
|
package vless
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package encoding
|
package encoding
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package encoding
|
package encoding
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
@@ -8,8 +6,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"runtime"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/buf"
|
"github.com/xtls/xray-core/common/buf"
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"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 {
|
if ok {
|
||||||
iConn = statConn.Connection
|
iConn = statConn.Connection
|
||||||
}
|
}
|
||||||
|
if xc, ok := iConn.(*xtls.Conn); ok {
|
||||||
|
iConn = xc.Connection
|
||||||
|
}
|
||||||
if tc, ok := iConn.(*net.TCPConn); ok {
|
if tc, ok := iConn.(*net.TCPConn); ok {
|
||||||
if conn.SHOW {
|
if conn.SHOW {
|
||||||
fmt.Println(conn.MARK, "Splice")
|
fmt.Println(conn.MARK, "Splice")
|
||||||
}
|
}
|
||||||
time.Sleep(time.Millisecond) // necessary
|
runtime.Gosched() // necessary
|
||||||
w, err := tc.ReadFrom(conn.Connection)
|
w, err := tc.ReadFrom(conn.Connection)
|
||||||
if counter != nil {
|
if counter != nil {
|
||||||
counter.Add(w)
|
counter.Add(w)
|
||||||
|
@@ -1,3 +1 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package inbound
|
package inbound
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package inbound
|
package inbound
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
@@ -1,3 +1 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package outbound
|
package outbound
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package outbound
|
package outbound
|
||||||
|
|
||||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package vless
|
package vless
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
// +build !confonly
|
|
||||||
|
|
||||||
package vmess
|
package vmess
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user