mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-12 01:57:18 +10:00
Compare commits
9 Commits
v1.3-beta8
...
v1.2.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90c54c1a38 | ||
|
|
0dd19ac0f3 | ||
|
|
1f65ff88b5 | ||
|
|
bbdd495ed5 | ||
|
|
d686172854 | ||
|
|
e1d96cb64e | ||
|
|
d5f94b65b7 | ||
|
|
ec2d0b6b3c | ||
|
|
3a92bf993d |
@@ -1,3 +1,7 @@
|
||||
#### 1.2.5
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.2.4
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
)
|
||||
|
||||
type PlatformInterface interface {
|
||||
UsePlatformAutoDetectInterfaceControl() bool
|
||||
AutoDetectInterfaceControl(fd int32) error
|
||||
OpenTun(options TunOptions) (int32, error)
|
||||
WriteLog(message string)
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
type Interface interface {
|
||||
Initialize(ctx context.Context, router adapter.Router) error
|
||||
UsePlatformAutoDetectInterfaceControl() bool
|
||||
AutoDetectInterfaceControl() control.Func
|
||||
OpenTun(options *tun.Options, platformOptions option.TunPlatformOptions) (tun.Tun, error)
|
||||
UsePlatformDefaultInterfaceMonitor() bool
|
||||
|
||||
@@ -68,6 +68,10 @@ func (w *platformInterfaceWrapper) Initialize(ctx context.Context, router adapte
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *platformInterfaceWrapper) UsePlatformAutoDetectInterfaceControl() bool {
|
||||
return w.iif.UsePlatformAutoDetectInterfaceControl()
|
||||
}
|
||||
|
||||
func (w *platformInterfaceWrapper) AutoDetectInterfaceControl() control.Func {
|
||||
return func(network, address string, conn syscall.RawConn) error {
|
||||
return control.Raw(conn, func(fd uintptr) error {
|
||||
|
||||
@@ -90,6 +90,9 @@ func (n *Naive) Start() error {
|
||||
n.httpServer = &http.Server{
|
||||
Handler: n,
|
||||
TLSConfig: tlsConfig,
|
||||
BaseContext: func(listener net.Listener) context.Context {
|
||||
return n.ctx
|
||||
},
|
||||
}
|
||||
go func() {
|
||||
var sErr error
|
||||
|
||||
@@ -823,7 +823,7 @@ func (r *Router) AutoDetectInterface() bool {
|
||||
}
|
||||
|
||||
func (r *Router) AutoDetectInterfaceFunc() control.Func {
|
||||
if r.platformInterface != nil {
|
||||
if r.platformInterface != nil && r.platformInterface.UsePlatformAutoDetectInterfaceControl() {
|
||||
return r.platformInterface.AutoDetectInterfaceControl()
|
||||
} else {
|
||||
return control.BindToInterfaceFunc(r.InterfaceFinder(), func(network string, address string) (interfaceName string, interfaceIndex int) {
|
||||
|
||||
@@ -45,6 +45,7 @@ func newV2RayPlugin(pluginOpts Args, router adapter.Router, dialer N.Dialer, ser
|
||||
|
||||
if hostOpt, loaded := pluginOpts.Get("host"); loaded {
|
||||
host = hostOpt
|
||||
tlsOptions.ServerName = hostOpt
|
||||
}
|
||||
if pathOpt, loaded := pluginOpts.Get("path"); loaded {
|
||||
path = pathOpt
|
||||
|
||||
@@ -48,9 +48,6 @@ func NewClientTransport(ctx context.Context, dialer N.Dialer, serverAddr M.Socks
|
||||
case C.V2RayTransportTypeHTTP:
|
||||
return v2rayhttp.NewClient(ctx, dialer, serverAddr, options.HTTPOptions, tlsConfig)
|
||||
case C.V2RayTransportTypeGRPC:
|
||||
if tlsConfig == nil {
|
||||
return nil, C.ErrTLSRequired
|
||||
}
|
||||
return NewGRPCClient(ctx, dialer, serverAddr, options.GRPCOptions, tlsConfig)
|
||||
case C.V2RayTransportTypeWebsocket:
|
||||
return v2raywebsocket.NewClient(ctx, dialer, serverAddr, options.WebsocketOptions, tlsConfig), nil
|
||||
|
||||
@@ -36,7 +36,9 @@ type Client struct {
|
||||
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayGRPCOptions, tlsConfig tls.Config) (adapter.V2RayClientTransport, error) {
|
||||
var dialOptions []grpc.DialOption
|
||||
if tlsConfig != nil {
|
||||
tlsConfig.SetNextProtos([]string{http2.NextProtoTLS})
|
||||
if len(tlsConfig.NextProtos()) == 0 {
|
||||
tlsConfig.SetNextProtos([]string{http2.NextProtoTLS})
|
||||
}
|
||||
dialOptions = append(dialOptions, grpc.WithTransportCredentials(NewTLSTransportCredentials(tlsConfig)))
|
||||
} else {
|
||||
dialOptions = append(dialOptions, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
|
||||
@@ -2,7 +2,6 @@ package v2raygrpclite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -13,6 +12,7 @@ import (
|
||||
"github.com/sagernet/sing-box/common/tls"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-box/transport/v2rayhttp"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
@@ -31,56 +31,63 @@ type Client struct {
|
||||
ctx context.Context
|
||||
dialer N.Dialer
|
||||
serverAddr M.Socksaddr
|
||||
transport http.RoundTripper
|
||||
transport *http2.Transport
|
||||
options option.V2RayGRPCOptions
|
||||
url *url.URL
|
||||
}
|
||||
|
||||
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayGRPCOptions, tlsConfig tls.Config) adapter.V2RayClientTransport {
|
||||
var transport http.RoundTripper
|
||||
if tlsConfig == nil {
|
||||
transport = &http.Transport{
|
||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
|
||||
},
|
||||
}
|
||||
var host string
|
||||
if tlsConfig != nil && tlsConfig.ServerName() != "" {
|
||||
host = M.ParseSocksaddrHostPort(tlsConfig.ServerName(), serverAddr.Port).String()
|
||||
} else {
|
||||
tlsConfig.SetNextProtos([]string{http2.NextProtoTLS})
|
||||
transport = &http2.Transport{
|
||||
ReadIdleTimeout: time.Duration(options.IdleTimeout),
|
||||
PingTimeout: time.Duration(options.PingTimeout),
|
||||
DialTLSContext: func(ctx context.Context, network, addr string, cfg *tls.STDConfig) (net.Conn, error) {
|
||||
conn, err := dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tls.ClientHandshake(ctx, conn, tlsConfig)
|
||||
},
|
||||
}
|
||||
host = serverAddr.String()
|
||||
}
|
||||
return &Client{
|
||||
client := &Client{
|
||||
ctx: ctx,
|
||||
dialer: dialer,
|
||||
serverAddr: serverAddr,
|
||||
options: options,
|
||||
transport: transport,
|
||||
transport: &http2.Transport{
|
||||
ReadIdleTimeout: time.Duration(options.IdleTimeout),
|
||||
PingTimeout: time.Duration(options.PingTimeout),
|
||||
DisableCompression: true,
|
||||
},
|
||||
url: &url.URL{
|
||||
Scheme: "https",
|
||||
Host: serverAddr.String(),
|
||||
Path: fmt.Sprintf("/%s/Tun", url.QueryEscape(options.ServiceName)),
|
||||
Scheme: "https",
|
||||
Host: host,
|
||||
Path: "/" + options.ServiceName + "/Tun",
|
||||
RawPath: "/" + url.PathEscape(options.ServiceName) + "/Tun",
|
||||
},
|
||||
}
|
||||
|
||||
if tlsConfig == nil {
|
||||
client.transport.DialTLSContext = func(ctx context.Context, network, addr string, cfg *tls.STDConfig) (net.Conn, error) {
|
||||
return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
|
||||
}
|
||||
} else {
|
||||
if len(tlsConfig.NextProtos()) == 0 {
|
||||
tlsConfig.SetNextProtos([]string{http2.NextProtoTLS})
|
||||
}
|
||||
client.transport.DialTLSContext = func(ctx context.Context, network, addr string, cfg *tls.STDConfig) (net.Conn, error) {
|
||||
conn, err := dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tls.ClientHandshake(ctx, conn, tlsConfig)
|
||||
}
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
||||
pipeInReader, pipeInWriter := io.Pipe()
|
||||
request := &http.Request{
|
||||
Method: http.MethodPost,
|
||||
Body: pipeInReader,
|
||||
URL: c.url,
|
||||
Proto: "HTTP/2",
|
||||
ProtoMajor: 2,
|
||||
Header: defaultClientHeader,
|
||||
Method: http.MethodPost,
|
||||
Body: pipeInReader,
|
||||
URL: c.url,
|
||||
Header: defaultClientHeader,
|
||||
}
|
||||
request = request.WithContext(ctx)
|
||||
conn := newLateGunConn(pipeInWriter)
|
||||
@@ -88,6 +95,9 @@ func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
||||
response, err := c.transport.RoundTrip(request)
|
||||
if err == nil {
|
||||
conn.setup(response.Body, nil)
|
||||
} else if response.StatusCode != 200 {
|
||||
response.Body.Close()
|
||||
conn.setup(nil, E.New("unexpected status: ", response.StatusCode, " ", response.Status))
|
||||
} else {
|
||||
conn.setup(nil, err)
|
||||
}
|
||||
@@ -96,6 +106,8 @@ func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
||||
}
|
||||
|
||||
func (c *Client) Close() error {
|
||||
v2rayhttp.CloseIdleConnections(c.transport)
|
||||
if c.transport != nil {
|
||||
v2rayhttp.CloseIdleConnections(c.transport)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -117,6 +117,7 @@ func (c *GunConn) WriteBuffer(buffer *buf.Buffer) error {
|
||||
dataLen := buffer.Len()
|
||||
varLen := rw.UVariantLen(uint64(dataLen))
|
||||
header := buffer.ExtendHeader(6 + varLen)
|
||||
_ = header[6]
|
||||
header[0] = 0x00
|
||||
binary.BigEndian.PutUint32(header[1:5], uint32(1+varLen+dataLen))
|
||||
header[5] = 0x0A
|
||||
|
||||
@@ -2,10 +2,8 @@ package v2raygrpclite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -45,13 +43,16 @@ func NewServer(ctx context.Context, options option.V2RayGRPCOptions, tlsConfig t
|
||||
server := &Server{
|
||||
tlsConfig: tlsConfig,
|
||||
handler: handler,
|
||||
path: fmt.Sprintf("/%s/Tun", url.QueryEscape(options.ServiceName)),
|
||||
path: "/" + options.ServiceName + "/Tun",
|
||||
h2Server: &http2.Server{
|
||||
IdleTimeout: time.Duration(options.IdleTimeout),
|
||||
},
|
||||
}
|
||||
server.httpServer = &http.Server{
|
||||
Handler: server,
|
||||
BaseContext: func(net.Listener) context.Context {
|
||||
return ctx
|
||||
},
|
||||
}
|
||||
server.h2cHandler = h2c.NewHandler(server, server.h2Server)
|
||||
return server, nil
|
||||
|
||||
@@ -43,7 +43,9 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
|
||||
},
|
||||
}
|
||||
} else {
|
||||
tlsConfig.SetNextProtos([]string{http2.NextProtoTLS})
|
||||
if len(tlsConfig.NextProtos()) == 0 {
|
||||
tlsConfig.SetNextProtos([]string{http2.NextProtoTLS})
|
||||
}
|
||||
transport = &http2.Transport{
|
||||
ReadIdleTimeout: time.Duration(options.IdleTimeout),
|
||||
PingTimeout: time.Duration(options.PingTimeout),
|
||||
@@ -137,15 +139,16 @@ func (c *Client) dialHTTP2(ctx context.Context) (net.Conn, error) {
|
||||
default:
|
||||
request.Host = c.host[rand.Intn(hostLen)]
|
||||
}
|
||||
conn := newLateHTTPConn(pipeInWriter)
|
||||
conn := NewLateHTTPConn(pipeInWriter)
|
||||
go func() {
|
||||
response, err := c.transport.RoundTrip(request)
|
||||
if err != nil {
|
||||
conn.setup(nil, err)
|
||||
conn.Setup(nil, err)
|
||||
} else if response.StatusCode != 200 {
|
||||
conn.setup(nil, E.New("unexpected status: ", response.StatusCode, " ", response.Status))
|
||||
response.Body.Close()
|
||||
conn.Setup(nil, E.New("unexpected status: ", response.StatusCode, " ", response.Status))
|
||||
} else {
|
||||
conn.setup(response.Body, nil)
|
||||
conn.Setup(response.Body, nil)
|
||||
}
|
||||
}()
|
||||
return conn, nil
|
||||
|
||||
@@ -140,14 +140,14 @@ func NewHTTPConn(reader io.Reader, writer io.Writer) HTTP2Conn {
|
||||
}
|
||||
}
|
||||
|
||||
func newLateHTTPConn(writer io.Writer) *HTTP2Conn {
|
||||
func NewLateHTTPConn(writer io.Writer) *HTTP2Conn {
|
||||
return &HTTP2Conn{
|
||||
create: make(chan struct{}),
|
||||
writer: writer,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *HTTP2Conn) setup(reader io.Reader, err error) {
|
||||
func (c *HTTP2Conn) Setup(reader io.Reader, err error) {
|
||||
c.reader = reader
|
||||
c.err = err
|
||||
close(c.create)
|
||||
|
||||
@@ -70,6 +70,9 @@ func NewServer(ctx context.Context, options option.V2RayHTTPOptions, tlsConfig t
|
||||
Handler: server,
|
||||
ReadHeaderTimeout: C.TCPTimeout,
|
||||
MaxHeaderBytes: http.DefaultMaxHeaderBytes,
|
||||
BaseContext: func(net.Listener) context.Context {
|
||||
return ctx
|
||||
},
|
||||
}
|
||||
server.h2cHandler = h2c.NewHandler(server, server.h2Server)
|
||||
return server, nil
|
||||
|
||||
@@ -52,6 +52,9 @@ func NewServer(ctx context.Context, options option.V2RayWebsocketOptions, tlsCon
|
||||
Handler: server,
|
||||
ReadHeaderTimeout: C.TCPTimeout,
|
||||
MaxHeaderBytes: http.DefaultMaxHeaderBytes,
|
||||
BaseContext: func(net.Listener) context.Context {
|
||||
return ctx
|
||||
},
|
||||
}
|
||||
return server, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user