Compare commits

..

18 Commits

Author SHA1 Message Date
RPRX
e254424c43 v1.2.1 2021-01-10 07:58:53 +00:00
RPRX
ee15cc253f Improve configuration detector (cone or symmetric) 2021-01-10 07:50:21 +00:00
RPRX
43eb5d1b25 16 -> 60, 8 -> 300
https://github.com/XTLS/Xray-core/issues/129#issuecomment-757355137

十分感谢 @GleenJi 等协助测试
2021-01-10 04:50:26 +00:00
RPRX
700966508f Improve the response to UDP Associate in Socks5 2021-01-09 16:36:20 +00:00
RPRX
7427a55ef1 Adjust Trojan Outbound postRequest 2021-01-08 12:00:46 +00:00
RPRX
fb0e517158 Adjust Trojan & Socks handleUDPPayload 2021-01-08 06:00:51 +00:00
maskedeken
d5aeb6c545 Refine Trojan packet reader & writer (#142) 2021-01-08 03:55:25 +00:00
RPRX
161e18299c Fix TPROXY UDP/IPv6
https://github.com/XTLS/Xray-core/issues/137#issuecomment-756064627

十分感谢 @Ninedyz @changyp6
2021-01-07 12:21:27 +00:00
eMeab
be9421fedf Optimized log (#121) 2021-01-04 05:05:38 +00:00
RPRX
8fc2d3b61f v1.2.0 2021-01-01 12:30:16 +00:00
秋のかえで
9d4038427d Enable loading TOML & YAML by confdir (#120) 2021-01-01 12:16:22 +00:00
秋のかえで
38ec9208d8 Change TOML package to github.com/pelletier/go-toml (#119) 2021-01-01 11:37:38 +00:00
RPRX
7df135a5c4 Disable session resumption by default
https://github.com/v2fly/v2ray-core/issues/557#issuecomment-751962569
2021-01-01 11:33:09 +00:00
RPRX
c41a1a56fe Refactor: TPROXY inbound UDP write back
https://t.me/projectXray/119670

虽然不一定是最终的版本,但值得记录,感谢协助测试的各位朋友,特别感谢 @yichya @huyz
2020-12-31 15:57:15 +00:00
RPRX
310a938511 VLESS & VMess are not ready to accept FullCone yet 2020-12-30 08:10:26 +00:00
RPRX
2da07e0f8a Refactor: FullCone TPROXY Inbound & Socks Outbound
https://t.me/projectXray/116037
2020-12-29 11:50:17 +00:00
RPRX
13ad3fddf6 Refactor: *net.UDPAddr -> *net.Destination
https://t.me/projectXray/111998
2020-12-28 09:40:28 +00:00
RPRX
6bcac6cb10 Move common/net/connection.go into cnc folder 2020-12-28 03:20:39 +08:00
40 changed files with 542 additions and 292 deletions

View File

@@ -6,6 +6,7 @@ import (
"github.com/xtls/xray-core/common"
"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/transport"
)
@@ -79,7 +80,7 @@ func (co *Outbound) Dispatch(ctx context.Context, link *transport.Link) {
}
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.access.RUnlock()
<-closeSignal.Wait()

View File

@@ -263,9 +263,11 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.
skipRoutePick = content.SkipRoutePick
}
var inTag string
if d.router != nil && !skipRoutePick {
if route, err := d.router.PickRoute(routing_session.AsRoutingContext(ctx)); err == nil {
tag := route.GetOutboundTag()
inTag = route.GetInboundTag()
if h := d.ohm.GetHandler(tag); h != nil {
newError("taking detour [", tag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx))
handler = h
@@ -290,7 +292,11 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.
if accessMessage := log.AccessMessageFromContext(ctx); accessMessage != nil {
if tag := handler.Tag(); tag != "" {
accessMessage.Detour = tag
if inTag != "" {
accessMessage.Detour = inTag + " -> " + tag
} else {
accessMessage.Detour = tag
}
}
log.Record(accessMessage)
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/xtls/xray-core/common"
"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/session"
"github.com/xtls/xray-core/common/signal/pubsub"
@@ -65,9 +66,9 @@ func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, clientIP net.
if err != nil {
return nil, err
}
return net.NewConnection(
net.ConnectionInputMulti(link.Writer),
net.ConnectionOutputMulti(link.Reader),
return cnc.NewConnection(
cnc.ConnectionInputMulti(link.Writer),
cnc.ConnectionOutputMulti(link.Reader),
), nil
},
}

View File

@@ -136,6 +136,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
uplinkCounter: uplinkCounter,
downlinkCounter: downlinkCounter,
stream: mss,
ctx: ctx,
}
h.workers = append(h.workers, worker)
}

View File

@@ -156,6 +156,7 @@ func (h *DynamicInboundHandler) refresh() error {
uplinkCounter: uplinkCounter,
downlinkCounter: downlinkCounter,
stream: h.streamSettings,
ctx: h.ctx,
}
if err := worker.Start(); err != nil {
newError("failed to create UDP worker").Base(err).AtWarning().WriteToLog()

View File

@@ -239,6 +239,9 @@ type udpWorker struct {
checker *task.Periodic
activeConn map[connID]*udpConn
ctx context.Context
cone bool
}
func (w *udpWorker) getConnection(id connID) (*udpConn, bool) {
@@ -279,7 +282,10 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest
src: source,
}
if originalDest.IsValid() {
id.dest = originalDest
if !w.cone {
id.dest = originalDest
}
b.UDP = &originalDest
}
conn, existing := w.getConnection(id)
@@ -336,7 +342,7 @@ func (w *udpWorker) clean() error {
}
for addr, conn := range w.activeConn {
if nowSec-atomic.LoadInt64(&conn.lastActivityTime) > 8 { // TODO Timeout too small
if nowSec-atomic.LoadInt64(&conn.lastActivityTime) > 300 {
delete(w.activeConn, addr)
conn.Close()
}
@@ -357,8 +363,10 @@ func (w *udpWorker) Start() error {
return err
}
w.cone = w.ctx.Value("cone").(bool)
w.checker = &task.Periodic{
Interval: time.Second * 16,
Interval: time.Minute,
Execute: w.clean,
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/mux"
"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/core"
"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...)
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 {
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))

View File

@@ -2,9 +2,9 @@ package buf
import (
"io"
"net"
"github.com/xtls/xray-core/common/bytespool"
"github.com/xtls/xray-core/common/net"
)
const (
@@ -21,7 +21,7 @@ type Buffer struct {
v []byte
start int32
end int32
UDP *net.UDPAddr
UDP *net.Destination
}
// New creates a Buffer with 0 length and 2K capacity.
@@ -49,6 +49,7 @@ func (b *Buffer) Release() {
b.v = nil
b.Clear()
pool.Put(p)
b.UDP = nil
}
// Clear clears the content of the buffer, results an empty buffer with

View File

@@ -1,12 +1,12 @@
package net
package cnc
import (
"io"
"net"
"time"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/signal/done"
)
@@ -88,8 +88,8 @@ type connection struct {
writer buf.Writer
done *done.Instance
onClose io.Closer
local Addr
remote Addr
local net.Addr
remote net.Addr
}
func (c *connection) Read(b []byte) (int, error) {

View File

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

View File

@@ -6,6 +6,7 @@ import (
"github.com/xtls/xray-core/common"
"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/transport/internet/udp"
)
@@ -53,13 +54,13 @@ func Dial(ctx context.Context, v *Instance, dest net.Destination) (net.Conn, err
if err != nil {
return nil, err
}
var readerOpt net.ConnectionOption
var readerOpt cnc.ConnectionOption
if dest.Network == net.Network_TCP {
readerOpt = net.ConnectionOutputMulti(r.Reader)
readerOpt = cnc.ConnectionOutputMulti(r.Reader)
} 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.

View File

@@ -3,8 +3,13 @@ package core
import (
"context"
"reflect"
"runtime/debug"
"strings"
"sync"
"github.com/golang/protobuf/proto"
"github.com/xtls/xray-core/app/proxyman"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/features"
@@ -179,6 +184,31 @@ func NewWithContext(ctx context.Context, config *Config) (*Instance, error) {
}
func initInstanceWithConfig(config *Config, server *Instance) (bool, error) {
cone := true
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" {
t = true
var m proxyman.SenderConfig
proto.Unmarshal(outbound.SenderSettings.Value, &m)
if m.MultiplexSettings != nil && m.MultiplexSettings.Enabled {
cone = false
break
}
}
}
if v && !t {
cone = false
}
server.ctx = context.WithValue(server.ctx, "cone", cone)
defer debug.FreeOSMemory()
if config.Transport != nil {
features.PrintDeprecatedFeatureWarning("global transport settings")
}

4
go.mod
View File

@@ -3,7 +3,6 @@ module github.com/xtls/xray-core
go 1.15
require (
github.com/BurntSushi/toml v0.3.1
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
github.com/golang/mock v1.4.4
github.com/golang/protobuf v1.4.3
@@ -11,6 +10,7 @@ require (
github.com/gorilla/websocket v1.4.2
github.com/lucas-clemente/quic-go v0.19.3
github.com/miekg/dns v1.1.35
github.com/pelletier/go-toml v1.8.1
github.com/pires/go-proxyproto v0.3.3
github.com/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c
github.com/stretchr/testify v1.6.1
@@ -19,7 +19,7 @@ require (
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/net v0.0.0-20201224014010-6772e930b67b
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
golang.org/x/sys v0.0.0-20201223074533-0d417f636930
golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061
google.golang.org/grpc v1.34.0
google.golang.org/protobuf v1.25.0
h12.io/socks v1.0.2

7
go.sum
View File

@@ -7,7 +7,6 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -124,6 +123,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/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/pires/go-proxyproto v0.3.3 h1:jOXGrsAfSQVFiD1hWg1aiHpLYsd6SJw/8cLN594sB7Q=
@@ -241,8 +242,8 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201223074533-0d417f636930 h1:vRgIt+nup/B/BwIS0g2oC0haq0iqbV3ZA+u6+0TlNCo=
golang.org/x/sys v0.0.0-20201223074533-0d417f636930/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061 h1:DQmQoKxQWtyybCtX/3dIuDBcAhFszqq8YiNeS6sNu1c=
golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@@ -6,8 +6,8 @@ import (
"io"
"io/ioutil"
"github.com/BurntSushi/toml"
"github.com/ghodss/yaml"
"github.com/pelletier/go-toml"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/core"
@@ -86,7 +86,7 @@ func LoadJSONConfig(reader io.Reader) (*core.Config, error) {
}
// DecodeTOMLConfig reads from reader and decode the config into *conf.Config
// using github.com/BurntSushi/toml and map to convert toml to json.
// 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 {
@@ -94,7 +94,7 @@ func DecodeTOMLConfig(reader io.Reader) (*conf.Config, error) {
}
configMap := make(map[string]interface{})
if _, err := toml.Decode(string(tomlFile), &configMap); err != nil {
if err := toml.Unmarshal(tomlFile, &configMap); err != nil {
return nil, newError("failed to convert toml to map").Base(err)
}

View File

@@ -294,7 +294,7 @@ type TLSConfig struct {
Certs []*TLSCertConfig `json:"certificates"`
ServerName string `json:"serverName"`
ALPN *StringList `json:"alpn"`
DisableSessionResumption bool `json:"disableSessionResumption"`
EnableSessionResumption bool `json:"enableSessionResumption"`
DisableSystemRoot bool `json:"disableSystemRoot"`
MinVersion string `json:"minVersion"`
MaxVersion string `json:"maxVersion"`
@@ -321,7 +321,7 @@ func (c *TLSConfig) Build() (proto.Message, error) {
if c.ALPN != nil && len(*c.ALPN) > 0 {
config.NextProtocol = []string(*c.ALPN)
}
config.DisableSessionResumption = c.DisableSessionResumption
config.EnableSessionResumption = c.EnableSessionResumption
config.DisableSystemRoot = c.DisableSystemRoot
config.MinVersion = c.MinVersion
config.MaxVersion = c.MaxVersion
@@ -378,7 +378,7 @@ type XTLSConfig struct {
Certs []*XTLSCertConfig `json:"certificates"`
ServerName string `json:"serverName"`
ALPN *StringList `json:"alpn"`
DisableSessionResumption bool `json:"disableSessionResumption"`
EnableSessionResumption bool `json:"enableSessionResumption"`
DisableSystemRoot bool `json:"disableSystemRoot"`
MinVersion string `json:"minVersion"`
MaxVersion string `json:"maxVersion"`
@@ -405,7 +405,7 @@ func (c *XTLSConfig) Build() (proto.Message, error) {
if c.ALPN != nil && len(*c.ALPN) > 0 {
config.NextProtocol = []string(*c.ALPN)
}
config.DisableSessionResumption = c.DisableSessionResumption
config.EnableSessionResumption = c.EnableSessionResumption
config.DisableSystemRoot = c.DisableSystemRoot
config.MinVersion = c.MinVersion
config.MaxVersion = c.MaxVersion

View File

@@ -8,6 +8,7 @@ import (
"os/signal"
"path"
"path/filepath"
"regexp"
"runtime"
"runtime/debug"
"strings"
@@ -116,7 +117,11 @@ func readConfDir(dirPath string) {
log.Fatalln(err)
}
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()))
}
}

View File

@@ -163,36 +163,60 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
if !destinationOverridden {
writer = &buf.SequentialWriter{Writer: conn}
} else {
sockopt := &internet.SocketConfig{
Tproxy: internet.SocketConfig_TProxy,
back := conn.RemoteAddr().(*net.UDPAddr)
if !dest.Address.Family().IsIP() {
if len(back.IP) == 4 {
dest.Address = net.AnyIP
} else {
dest.Address = net.AnyIPv6
}
}
if dest.Address.Family().IsIP() {
sockopt.BindAddress = dest.Address.IP()
sockopt.BindPort = uint32(dest.Port)
addr := &net.UDPAddr{
IP: dest.Address.IP(),
Port: int(dest.Port),
}
var mark int
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 {
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)
writer = NewPacketWriter(pConn, &dest, mark, back)
defer writer.(*PacketWriter).Close()
/*
sockopt := &internet.SocketConfig{
Tproxy: internet.SocketConfig_TProxy,
}
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
}
*/
}
}
@@ -215,3 +239,74 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
return nil
}
func NewPacketWriter(conn net.PacketConn, d *net.Destination, mark int, back *net.UDPAddr) buf.Writer {
writer := &PacketWriter{
conn: conn,
conns: make(map[net.Destination]net.PacketConn),
mark: mark,
back: back,
}
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
}

View File

@@ -0,0 +1,72 @@
// +build linux
package dokodemo
import (
"fmt"
"net"
"os"
"syscall"
)
func FakeUDP(addr *net.UDPAddr, mark int) (net.PacketConn, error) {
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())
return &syscall.SockaddrInet6{Addr: ip, Port: addr.Port, ZoneId: 0}, syscall.AF_INET6, nil
}
}

View 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")}
}

View File

@@ -149,7 +149,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
if destination.Network == net.Network_TCP {
writer = buf.NewWriter(conn)
} else {
writer = NewPacketWriter(conn)
writer = NewPacketWriter(conn, h, ctx)
}
if err := buf.Copy(input, writer, buf.UpdateActivity(timer)); err != nil {
@@ -215,14 +215,18 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
return nil, err
}
b.Resize(0, int32(n))
b.UDP = d.(*net.UDPAddr)
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) buf.Writer {
func NewPacketWriter(conn net.Conn, h *Handler, ctx context.Context) buf.Writer {
iConn := conn
statConn, ok := iConn.(*internet.StatCouterConnection)
if ok {
@@ -236,6 +240,8 @@ func NewPacketWriter(conn net.Conn) buf.Writer {
return &PacketWriter{
PacketConnWrapper: c,
Counter: counter,
Handler: h,
Context: ctx,
}
}
return &buf.SequentialWriter{Writer: conn}
@@ -244,6 +250,8 @@ func NewPacketWriter(conn net.Conn) buf.Writer {
type PacketWriter struct {
*internet.PacketConnWrapper
stats.Counter
*Handler
context.Context
}
func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
@@ -256,7 +264,18 @@ func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
var n int
var err error
if b.UDP != nil {
n, err = w.PacketConnWrapper.WriteTo(b.Bytes(), b.UDP)
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())
}

View File

@@ -235,10 +235,8 @@ func (v *UDPReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
buffer.Release()
return nil, err
}
payload.UDP = &net.UDPAddr{
IP: u.Address.IP(),
Port: int(u.Port),
}
dest := u.Destination()
payload.UDP = &dest
return buf.MultiBuffer{payload}, nil
}
@@ -254,18 +252,15 @@ func (w *UDPWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
if b == nil {
break
}
var packet *buf.Buffer
var err error
request := w.Request
if b.UDP != nil {
request := &protocol.RequestHeader{
request = &protocol.RequestHeader{
User: w.Request.User,
Address: net.IPAddress(b.UDP.IP),
Port: net.Port(b.UDP.Port),
Address: b.UDP.Address,
Port: b.UDP.Port,
}
packet, err = EncodeUDPPacket(request, b.Bytes())
} else {
packet, err = EncodeUDPPacket(w.Request, b.Bytes())
}
packet, err := EncodeUDPPacket(request, b.Bytes())
b.Release()
if err != nil {
buf.ReleaseMulti(mb)

View File

@@ -24,6 +24,7 @@ type Server struct {
config *ServerConfig
user *protocol.MemoryUser
policyManager policy.Manager
cone bool
}
// NewServer create a new Shadowsocks server.
@@ -42,6 +43,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
config: config,
user: mUser,
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
cone: ctx.Value("cone").(bool),
}
return s, nil
@@ -81,8 +83,8 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
if payload.UDP != nil {
request = &protocol.RequestHeader{
User: request.User,
Address: net.IPAddress(payload.UDP.IP),
Port: net.Port(payload.UDP.Port),
Address: payload.UDP.Address,
Port: payload.UDP.Port,
}
}
@@ -103,7 +105,7 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
}
inbound.User = s.user
var dest net.Destination
var dest *net.Destination
reader := buf.NewPacketReader(conn)
for {
@@ -128,29 +130,28 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
continue
}
destination := request.Destination()
currentPacketCtx := ctx
if inbound.Source.IsValid() {
currentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
From: inbound.Source,
To: request.Destination(),
To: destination,
Status: log.AccessAccepted,
Reason: "",
Email: request.User.Email,
})
}
newError("tunnelling request to ", request.Destination()).WriteToLog(session.ExportIDToError(currentPacketCtx))
newError("tunnelling request to ", destination).WriteToLog(session.ExportIDToError(currentPacketCtx))
data.UDP = &net.UDPAddr{
IP: request.Address.IP(),
Port: int(request.Port),
}
data.UDP = &destination
if dest.Network == 0 {
dest = request.Destination() // JUST FOLLOW THE FIREST PACKET
if !s.cone || dest == nil {
dest = &destination
}
currentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request)
udpServer.Dispatch(currentPacketCtx, dest, data)
udpServer.Dispatch(currentPacketCtx, *dest, data)
}
}

View File

@@ -138,11 +138,12 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
defer udpConn.Close()
requestFunc = func() error {
defer timer.SetTimeout(p.Timeouts.DownlinkOnly)
return buf.Copy(link.Reader, &buf.SequentialWriter{Writer: NewUDPWriter(request, udpConn)}, buf.UpdateActivity(timer))
writer := &UDPWriter{Writer: udpConn, Request: request}
return buf.Copy(link.Reader, writer, buf.UpdateActivity(timer))
}
responseFunc = func() error {
defer timer.SetTimeout(p.Timeouts.UplinkOnly)
reader := &UDPReader{reader: udpConn}
reader := &UDPReader{Reader: udpConn}
return buf.Copy(reader, link.Writer, buf.UpdateActivity(timer))
}
}

View File

@@ -39,10 +39,10 @@ var addrParser = protocol.NewAddressParser(
)
type ServerSession struct {
config *ServerConfig
address net.Address
port net.Port
clientAddress net.Address
config *ServerConfig
address net.Address
port net.Port
localAddress net.Address
}
func (s *ServerSession) handshake4(cmd byte, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) {
@@ -192,14 +192,11 @@ func (s *ServerSession) handshake5(nMethod byte, reader io.Reader, writer io.Wri
//nolint:gocritic // Use if else chain for clarity
if request.Command == protocol.RequestCommandUDP {
if s.config.Address != nil {
// Use configured IP as remote address in the response to UdpAssociate
// Use configured IP as remote address in the response to UDP Associate
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
// Use conn.LocalAddr() IP as remote address in the response by default
responseAddress = s.localAddress
}
}
if err := writeSocks5Response(writer, statusSuccess, responseAddress, responsePort); err != nil {
@@ -360,47 +357,59 @@ func EncodeUDPPacket(request *protocol.RequestHeader, data []byte) (*buf.Buffer,
}
type UDPReader struct {
reader io.Reader
}
func NewUDPReader(reader io.Reader) *UDPReader {
return &UDPReader{reader: reader}
Reader io.Reader
}
func (r *UDPReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
b := buf.New()
if _, err := b.ReadFrom(r.reader); err != nil {
buffer := buf.New()
_, err := buffer.ReadFrom(r.Reader)
if err != nil {
buffer.Release()
return nil, err
}
if _, err := DecodeUDPPacket(b); err != nil {
u, err := DecodeUDPPacket(buffer)
if err != nil {
buffer.Release()
return nil, err
}
return buf.MultiBuffer{b}, nil
dest := u.Destination()
buffer.UDP = &dest
return buf.MultiBuffer{buffer}, nil
}
type UDPWriter struct {
request *protocol.RequestHeader
writer io.Writer
Writer io.Writer
Request *protocol.RequestHeader
}
func NewUDPWriter(request *protocol.RequestHeader, writer io.Writer) *UDPWriter {
return &UDPWriter{
request: request,
writer: writer,
func (w *UDPWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
for {
mb2, b := buf.SplitFirst(mb)
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
}
}
}
// 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
return nil
}
func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) {

View File

@@ -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}),
Port: 1024,
}
writer := &buf.SequentialWriter{Writer: NewUDPWriter(request, b)}
writer := &UDPWriter{Writer: b, Request: request}
content := []byte{'a'}
payload := buf.New()
payload.Write(content)
common.Must(writer.WriteMultiBuffer(buf.MultiBuffer{payload}))
reader := NewUDPReader(b)
reader := &UDPReader{Reader: b}
decodedPayload, err := reader.ReadMultiBuffer()
common.Must(err)

View File

@@ -26,6 +26,7 @@ import (
type Server struct {
config *ServerConfig
policyManager policy.Manager
cone bool
}
// NewServer creates a new Server object.
@@ -34,6 +35,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
s := &Server{
config: config,
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
cone: ctx.Value("cone").(bool),
}
return s, nil
}
@@ -89,10 +91,10 @@ func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispa
}
svrSession := &ServerSession{
config: s.config,
address: inbound.Gateway.Address,
port: inbound.Gateway.Port,
clientAddress: inbound.Source.Address,
config: s.config,
address: inbound.Gateway.Address,
port: inbound.Gateway.Port,
localAddress: net.IPAddress(conn.LocalAddr().(*net.TCPAddr).IP),
}
reader := &buf.BufferedReader{Reader: buf.NewReader(conn)}
@@ -202,8 +204,8 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
if payload.UDP != nil {
request = &protocol.RequestHeader{
User: request.User,
Address: net.IPAddress(payload.UDP.IP),
Port: net.Port(payload.UDP.Port),
Address: payload.UDP.Address,
Port: payload.UDP.Port,
}
}
@@ -218,11 +220,12 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
conn.Write(udpMessage.Bytes())
})
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {
inbound := session.InboundFromContext(ctx)
if inbound != nil && inbound.Source.IsValid() {
newError("client UDP connection from ", inbound.Source).WriteToLog(session.ExportIDToError(ctx))
}
var dest net.Destination
var dest *net.Destination
reader := buf.NewPacketReader(conn)
for {
@@ -244,28 +247,28 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
payload.Release()
continue
}
destination := request.Destination()
currentPacketCtx := ctx
newError("send packet to ", request.Destination(), " with ", payload.Len(), " bytes").AtDebug().WriteToLog(session.ExportIDToError(ctx))
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {
newError("send packet to ", destination, " with ", payload.Len(), " bytes").AtDebug().WriteToLog(session.ExportIDToError(ctx))
if inbound != nil && inbound.Source.IsValid() {
currentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
From: inbound.Source,
To: request.Destination(),
To: destination,
Status: log.AccessAccepted,
Reason: "",
})
}
payload.UDP = &net.UDPAddr{
IP: request.Address.IP(),
Port: int(request.Port),
}
payload.UDP = &destination
if dest.Network == 0 {
dest = request.Destination() // JUST FOLLOW THE FIREST PACKET
if !s.cone || dest == nil {
dest = &destination
}
currentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request)
udpServer.Dispatch(currentPacketCtx, dest, payload)
udpServer.Dispatch(currentPacketCtx, *dest, payload)
}
}
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/platform"
"github.com/xtls/xray-core/common/protocol"
@@ -145,12 +146,13 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
postRequest := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
var bodyWriter buf.Writer
bufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn))
connWriter.Writer = bufferWriter
connWriter.Target = destination
connWriter.Account = account
var bodyWriter buf.Writer
if destination.Network == net.Network_UDP {
bodyWriter = &PacketWriter{Writer: connWriter, Target: destination}
} else {
@@ -167,6 +169,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
return newError("failed to flush payload").Base(err).AtWarning()
}
// Send header if not sent yet
if _, err = connWriter.Write([]byte{}); err != nil {
return err.(*errors.Error).AtWarning()
}
if err = buf.Copy(link.Reader, bodyWriter, buf.UpdateActivity(timer)); err != nil {
return newError("failed to transfer request payload").Base(err).AtInfo()
}

View File

@@ -134,33 +134,11 @@ func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
if b == nil {
break
}
target := w.Target
target := &w.Target
if b.UDP != nil {
target.Address = net.IPAddress(b.UDP.IP)
target.Port = net.Port(b.UDP.Port)
target = b.UDP
}
if _, err := w.writePacket(b.Bytes(), target); err != nil {
buf.ReleaseMulti(mb)
return err
}
}
return nil
}
// WriteMultiBufferWithMetadata writes udp packet with destination specified
func (w *PacketWriter) WriteMultiBufferWithMetadata(mb buf.MultiBuffer, dest net.Destination) error {
for {
mb2, b := buf.SplitFirst(mb)
mb = mb2
if b == nil {
break
}
source := dest
if b.UDP != nil {
source.Address = net.IPAddress(b.UDP.IP)
source.Port = net.Port(b.UDP.Port)
}
if _, err := w.writePacket(b.Bytes(), source); err != nil {
if _, err := w.writePacket(b.Bytes(), *target); err != nil {
buf.ReleaseMulti(mb)
return err
}
@@ -261,12 +239,6 @@ func (c *ConnReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
return buf.MultiBuffer{b}, err
}
// PacketPayload combines udp payload and destination
type PacketPayload struct {
Target net.Destination
Buffer buf.MultiBuffer
}
// PacketReader is UDP Connection Reader Wrapper for trojan protocol
type PacketReader struct {
io.Reader
@@ -274,15 +246,6 @@ type PacketReader struct {
// ReadMultiBuffer implements buf.Reader
func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
p, err := r.ReadMultiBufferWithMetadata()
if p != nil {
return p.Buffer, err
}
return nil, err
}
// ReadMultiBufferWithMetadata reads udp packet with destination
func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) {
addr, port, err := addrParser.ReadAddressPort(nil, r)
if err != nil {
return nil, newError("failed to read address and port").Base(err)
@@ -312,10 +275,7 @@ func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) {
}
b := buf.New()
b.UDP = &net.UDPAddr{
IP: addr.IP(),
Port: int(port.Value()),
}
b.UDP = &dest
mb = append(mb, b)
n, err := b.ReadFullFrom(r, int32(length))
if err != nil {
@@ -326,7 +286,7 @@ func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) {
remain -= int(n)
}
return &PacketPayload{Target: dest, Buffer: mb}, nil
return mb, nil
}
func ReadV(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn *xtls.Conn, rawConn syscall.RawConn, counter stats.Counter, sctx context.Context) error {

View File

@@ -71,21 +71,22 @@ func TestUDPRequest(t *testing.T) {
common.Must(connReader.ParseHeader())
packetReader := &PacketReader{Reader: connReader}
p, err := packetReader.ReadMultiBufferWithMetadata()
mb, err := packetReader.ReadMultiBuffer()
common.Must(err)
if p.Buffer.IsEmpty() {
if mb.IsEmpty() {
t.Error("no request data")
}
if r := cmp.Diff(p.Target, destination); r != "" {
mb2, b := buf.SplitFirst(mb)
defer buf.ReleaseMulti(mb2)
dest := *b.UDP
if r := cmp.Diff(dest, destination); r != "" {
t.Error("destination: ", r)
}
mb, decoded := buf.SplitFirst(p.Buffer)
buf.ReleaseMulti(mb)
if r := cmp.Diff(decoded.Bytes(), payload); r != "" {
if r := cmp.Diff(b.Bytes(), payload); r != "" {
t.Error("data: ", r)
}
}

View File

@@ -47,6 +47,7 @@ type Server struct {
policyManager policy.Manager
validator *Validator
fallbacks map[string]map[string]*Fallback // or nil
cone bool
}
// NewServer creates a new trojan inbound handler.
@@ -67,6 +68,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
server := &Server{
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
validator: validator,
cone: ctx.Value("cone").(bool),
}
if config.Fallbacks != nil {
@@ -250,20 +252,24 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet
func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReader, clientWriter *PacketWriter, dispatcher routing.Dispatcher) error {
udpServer := udp.NewDispatcher(dispatcher, func(ctx context.Context, packet *udp_proto.Packet) {
common.Must(clientWriter.WriteMultiBufferWithMetadata(buf.MultiBuffer{packet.Payload}, packet.Source))
udpPayload := packet.Payload
if udpPayload.UDP == nil {
udpPayload.UDP = &packet.Source
}
common.Must(clientWriter.WriteMultiBuffer(buf.MultiBuffer{udpPayload}))
})
inbound := session.InboundFromContext(ctx)
user := inbound.User
var dest net.Destination
var dest *net.Destination
for {
select {
case <-ctx.Done():
return nil
default:
p, err := clientReader.ReadMultiBufferWithMetadata()
mb, err := clientReader.ReadMultiBuffer()
if err != nil {
if errors.Cause(err) != io.EOF {
return newError("unexpected EOF").Base(err)
@@ -271,21 +277,31 @@ func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReade
return nil
}
ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
From: inbound.Source,
To: p.Target,
Status: log.AccessAccepted,
Reason: "",
Email: user.Email,
})
newError("tunnelling request to ", p.Target).WriteToLog(session.ExportIDToError(ctx))
mb2, b := buf.SplitFirst(mb)
if b == nil {
continue
}
destination := *b.UDP
if dest.Network == 0 {
dest = p.Target // JUST FOLLOW THE FIREST PACKET
currentPacketCtx := ctx
if inbound.Source.IsValid() {
currentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
From: inbound.Source,
To: destination,
Status: log.AccessAccepted,
Reason: "",
Email: user.Email,
})
}
newError("tunnelling request to ", destination).WriteToLog(session.ExportIDToError(ctx))
if !s.cone || dest == nil {
dest = &destination
}
for _, b := range p.Buffer {
udpServer.Dispatch(ctx, dest, b)
udpServer.Dispatch(currentPacketCtx, *dest, b) // first packet
for _, payload := range mb2 {
udpServer.Dispatch(currentPacketCtx, *dest, payload)
}
}
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/net/cnc"
"github.com/xtls/xray-core/transport/internet"
"github.com/xtls/xray-core/transport/internet/tls"
"github.com/xtls/xray-core/transport/pipe"
@@ -124,10 +125,10 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
bwriter := buf.NewBufferedWriter(pwriter)
common.Must(bwriter.SetBuffered(false))
return net.NewConnection(
net.ConnectionOutput(response.Body),
net.ConnectionInput(bwriter),
net.ConnectionOnClose(common.ChainedClosable{breader, bwriter, response.Body}),
return cnc.NewConnection(
cnc.ConnectionOutput(response.Body),
cnc.ConnectionInput(bwriter),
cnc.ConnectionOnClose(common.ChainedClosable{breader, bwriter, response.Body}),
), nil
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/net/cnc"
http_proto "github.com/xtls/xray-core/common/protocol/http"
"github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/common/session"
@@ -97,12 +98,12 @@ func (l *Listener) ServeHTTP(writer http.ResponseWriter, request *http.Request)
}
done := done.New()
conn := net.NewConnection(
net.ConnectionOutput(request.Body),
net.ConnectionInput(flushWriter{w: writer, d: done}),
net.ConnectionOnClose(common.ChainedClosable{done, request.Body}),
net.ConnectionLocalAddr(l.Addr()),
net.ConnectionRemoteAddr(remoteAddr),
conn := cnc.NewConnection(
cnc.ConnectionOutput(request.Body),
cnc.ConnectionInput(flushWriter{w: writer, d: done}),
cnc.ConnectionOnClose(common.ChainedClosable{done, request.Body}),
cnc.ConnectionLocalAddr(l.Addr()),
cnc.ConnectionRemoteAddr(remoteAddr),
)
l.handler(conn)
<-done.Wait()

View File

@@ -194,7 +194,7 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
RootCAs: root,
InsecureSkipVerify: false,
NextProtos: nil,
SessionTicketsDisabled: false,
SessionTicketsDisabled: true,
}
}
@@ -203,7 +203,7 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
RootCAs: root,
InsecureSkipVerify: c.AllowInsecure,
NextProtos: c.NextProtocol,
SessionTicketsDisabled: c.DisableSessionResumption,
SessionTicketsDisabled: !c.EnableSessionResumption,
}
for _, opt := range opts {

View File

@@ -160,8 +160,8 @@ type Config struct {
ServerName string `protobuf:"bytes,3,opt,name=server_name,json=serverName,proto3" json:"server_name,omitempty"`
// Lists of string as ALPN values.
NextProtocol []string `protobuf:"bytes,4,rep,name=next_protocol,json=nextProtocol,proto3" json:"next_protocol,omitempty"`
// Whether or not to disable session (ticket) resumption.
DisableSessionResumption bool `protobuf:"varint,5,opt,name=disable_session_resumption,json=disableSessionResumption,proto3" json:"disable_session_resumption,omitempty"`
// Whether or not to enable session (ticket) resumption.
EnableSessionResumption bool `protobuf:"varint,5,opt,name=enable_session_resumption,json=enableSessionResumption,proto3" json:"enable_session_resumption,omitempty"`
// If true, root certificates on the system will not be loaded for
// verification.
DisableSystemRoot bool `protobuf:"varint,6,opt,name=disable_system_root,json=disableSystemRoot,proto3" json:"disable_system_root,omitempty"`
@@ -235,9 +235,9 @@ func (x *Config) GetNextProtocol() []string {
return nil
}
func (x *Config) GetDisableSessionResumption() bool {
func (x *Config) GetEnableSessionResumption() bool {
if x != nil {
return x.DisableSessionResumption
return x.EnableSessionResumption
}
return false
}
@@ -299,7 +299,7 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{
0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10,
0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59,
0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f,
0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0xd5, 0x03, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66,
0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0xd3, 0x03, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x65,
0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f,
0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x4a, 0x0a, 0x0b, 0x63, 0x65, 0x72,
@@ -311,32 +311,32 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6e,
0x65, 0x78, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x3c, 0x0a, 0x1a, 0x64,
0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72,
0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52,
0x18, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52,
0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x69, 0x73,
0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x72, 0x6f, 0x6f, 0x74,
0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53,
0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x69, 0x6e,
0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61,
0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0a, 0x6d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63,
0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73,
0x12, 0x3d, 0x0a, 0x1b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65,
0x72, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x18,
0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x42,
0x73, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e,
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74,
0x6c, 0x73, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f,
0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x1b, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72,
0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
0x2e, 0x54, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x78, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x3a, 0x0a, 0x19, 0x65,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65,
0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17,
0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62,
0x6c, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x06,
0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x79, 0x73,
0x74, 0x65, 0x6d, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x69, 0x6e, 0x5f, 0x76,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x69,
0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x78, 0x5f,
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d,
0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x69, 0x70,
0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x12, 0x3d,
0x0a, 0x1b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f,
0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20,
0x01, 0x28, 0x08, 0x52, 0x18, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65,
0x72, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x42, 0x73, 0x0a,
0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70,
0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73,
0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78,
0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72,
0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
0x2f, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x1b, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e,
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54,
0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -37,8 +37,8 @@ message Config {
// Lists of string as ALPN values.
repeated string next_protocol = 4;
// Whether or not to disable session (ticket) resumption.
bool disable_session_resumption = 5;
// Whether or not to enable session (ticket) resumption.
bool enable_session_resumption = 5;
// If true, root certificates on the system will not be loaded for
// verification.

View File

@@ -66,7 +66,7 @@ func (v *Dispatcher) getInboundRay(ctx context.Context, dest net.Destination) *c
cancel()
v.RemoveRay(dest)
}
timer := signal.CancelAfterInactivity(ctx, removeRay, time.Second*4)
timer := signal.CancelAfterInactivity(ctx, removeRay, time.Minute)
link, _ := v.dispatcher.Dispatch(ctx, dest)
entry := &connEntry{
link: link,

View File

@@ -185,7 +185,7 @@ func (c *Config) GetXTLSConfig(opts ...Option) *xtls.Config {
RootCAs: root,
InsecureSkipVerify: false,
NextProtos: nil,
SessionTicketsDisabled: false,
SessionTicketsDisabled: true,
}
}
@@ -194,7 +194,7 @@ func (c *Config) GetXTLSConfig(opts ...Option) *xtls.Config {
RootCAs: root,
InsecureSkipVerify: c.AllowInsecure,
NextProtos: c.NextProtocol,
SessionTicketsDisabled: c.DisableSessionResumption,
SessionTicketsDisabled: !c.EnableSessionResumption,
}
for _, opt := range opts {

View File

@@ -160,8 +160,8 @@ type Config struct {
ServerName string `protobuf:"bytes,3,opt,name=server_name,json=serverName,proto3" json:"server_name,omitempty"`
// Lists of string as ALPN values.
NextProtocol []string `protobuf:"bytes,4,rep,name=next_protocol,json=nextProtocol,proto3" json:"next_protocol,omitempty"`
// Whether or not to disable session (ticket) resumption.
DisableSessionResumption bool `protobuf:"varint,5,opt,name=disable_session_resumption,json=disableSessionResumption,proto3" json:"disable_session_resumption,omitempty"`
// Whether or not to enable session (ticket) resumption.
EnableSessionResumption bool `protobuf:"varint,5,opt,name=enable_session_resumption,json=enableSessionResumption,proto3" json:"enable_session_resumption,omitempty"`
// If true, root certificates on the system will not be loaded for
// verification.
DisableSystemRoot bool `protobuf:"varint,6,opt,name=disable_system_root,json=disableSystemRoot,proto3" json:"disable_system_root,omitempty"`
@@ -235,9 +235,9 @@ func (x *Config) GetNextProtocol() []string {
return nil
}
func (x *Config) GetDisableSessionResumption() bool {
func (x *Config) GetEnableSessionResumption() bool {
if x != nil {
return x.DisableSessionResumption
return x.EnableSessionResumption
}
return false
}
@@ -299,7 +299,7 @@ var file_transport_internet_xtls_config_proto_rawDesc = []byte{
0x0c, 0x45, 0x4e, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12,
0x14, 0x0a, 0x10, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x56, 0x45, 0x52,
0x49, 0x46, 0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49,
0x54, 0x59, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0xd6, 0x03, 0x0a, 0x06, 0x43,
0x54, 0x59, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0xd4, 0x03, 0x0a, 0x06, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x69,
0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61,
0x6c, 0x6c, 0x6f, 0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x4b, 0x0a, 0x0b,
@@ -312,32 +312,32 @@ var file_transport_internet_xtls_config_proto_rawDesc = []byte{
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65,
0x78, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x03, 0x28,
0x09, 0x52, 0x0c, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12,
0x3c, 0x0a, 0x1a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69,
0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20,
0x01, 0x28, 0x08, 0x52, 0x18, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x73,
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a,
0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f,
0x72, 0x6f, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x69, 0x73, 0x61,
0x62, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1f, 0x0a,
0x0b, 0x6d, 0x69, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f,
0x0a, 0x0b, 0x6d, 0x61, 0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
0x23, 0x0a, 0x0d, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73,
0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75,
0x69, 0x74, 0x65, 0x73, 0x12, 0x3d, 0x0a, 0x1b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73,
0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69,
0x74, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x70, 0x72, 0x65, 0x66, 0x65,
0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69,
0x74, 0x65, 0x73, 0x42, 0x76, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
0x65, 0x74, 0x2e, 0x78, 0x74, 0x6c, 0x73, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d,
0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69,
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x1c, 0x58,
0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x58, 0x74, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
0x3a, 0x0a, 0x19, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01,
0x28, 0x08, 0x52, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x64,
0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x72, 0x6f,
0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c,
0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d,
0x69, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b,
0x6d, 0x61, 0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a,
0x0d, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x09,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74,
0x65, 0x73, 0x12, 0x3d, 0x0a, 0x1b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x72,
0x76, 0x65, 0x72, 0x5f, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65,
0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x53,
0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65,
0x73, 0x42, 0x76, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72,
0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
0x2e, 0x78, 0x74, 0x6c, 0x73, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f,
0x72, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74,
0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x1c, 0x58, 0x72, 0x61,
0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x65, 0x74, 0x2e, 0x58, 0x74, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (

View File

@@ -37,8 +37,8 @@ message Config {
// Lists of string as ALPN values.
repeated string next_protocol = 4;
// Whether or not to disable session (ticket) resumption.
bool disable_session_resumption = 5;
// Whether or not to enable session (ticket) resumption.
bool enable_session_resumption = 5;
// If true, root certificates on the system will not be loaded for
// verification.