Refactor TLS

This commit is contained in:
世界 2022-09-09 18:45:10 +08:00
parent 099358d3e5
commit ee7e976084
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
32 changed files with 438 additions and 319 deletions

View file

@ -1,6 +1,6 @@
//go:build with_acme
package inbound
package tls
import (
"context"

View file

@ -1,6 +1,6 @@
//go:build !with_acme
package inbound
package tls
import (
"context"

57
common/tls/client.go Normal file
View file

@ -0,0 +1,57 @@
package tls
import (
"context"
"net"
"os"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
func NewDialerFromOptions(router adapter.Router, dialer N.Dialer, serverAddress string, options option.OutboundTLSOptions) (N.Dialer, error) {
config, err := NewClient(router, serverAddress, options)
if err != nil {
return nil, err
}
return NewDialer(dialer, config), nil
}
func NewClient(router adapter.Router, serverAddress string, options option.OutboundTLSOptions) (Config, error) {
return newStdClient(serverAddress, options)
}
func ClientHandshake(ctx context.Context, conn net.Conn, config Config) (net.Conn, error) {
tlsConn := config.Client(conn)
ctx, cancel := context.WithTimeout(ctx, C.TCPTimeout)
defer cancel()
err := tlsConn.HandshakeContext(ctx)
return tlsConn, err
}
type Dialer struct {
dialer N.Dialer
config Config
}
func NewDialer(dialer N.Dialer, config Config) N.Dialer {
return &Dialer{dialer, config}
}
func (d *Dialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
if network != N.NetworkTCP {
return nil, os.ErrInvalid
}
conn, err := d.dialer.DialContext(ctx, network, destination)
if err != nil {
return nil, err
}
return ClientHandshake(ctx, conn, d.config)
}
func (d *Dialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
return nil, os.ErrInvalid
}

12
common/tls/common.go Normal file
View file

@ -0,0 +1,12 @@
package tls
const (
VersionTLS10 = 0x0301
VersionTLS11 = 0x0302
VersionTLS12 = 0x0303
VersionTLS13 = 0x0304
// Deprecated: SSLv3 is cryptographically broken, and is no longer
// supported by this package. See golang.org/issue/32716.
VersionSSL30 = 0x0300
)

46
common/tls/config.go Normal file
View file

@ -0,0 +1,46 @@
package tls
import (
"context"
"crypto/tls"
"net"
"github.com/sagernet/sing-box/adapter"
E "github.com/sagernet/sing/common/exceptions"
)
type (
STDConfig = tls.Config
STDConn = tls.Conn
)
type Config interface {
Config() (*STDConfig, error)
Client(conn net.Conn) Conn
}
type ServerConfig interface {
Config
adapter.Service
Server(conn net.Conn) Conn
}
type Conn interface {
net.Conn
HandshakeContext(ctx context.Context) error
}
func ParseTLSVersion(version string) (uint16, error) {
switch version {
case "1.0":
return tls.VersionTLS10, nil
case "1.1":
return tls.VersionTLS11, nil
case "1.2":
return tls.VersionTLS12, nil
case "1.3":
return tls.VersionTLS13, nil
default:
return 0, E.New("unknown tls version:", version)
}
}

View file

@ -1,34 +1,26 @@
package dialer
package tls
import (
"context"
"crypto/tls"
"crypto/x509"
"net"
"net/netip"
"os"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type TLSDialer struct {
dialer N.Dialer
type stdClientConfig struct {
config *tls.Config
}
func TLSConfig(serverAddress string, options option.OutboundTLSOptions) (*tls.Config, error) {
if !options.Enabled {
return nil, nil
}
func newStdClient(serverAddress string, options option.OutboundTLSOptions) (Config, error) {
var serverName string
if options.ServerName != "" {
serverName = options.ServerName
} else if serverAddress != "" {
if _, err := netip.ParseAddr(serverName); err == nil {
if _, err := netip.ParseAddr(serverName); err != nil {
serverName = serverAddress
}
}
@ -62,14 +54,14 @@ func TLSConfig(serverAddress string, options option.OutboundTLSOptions) (*tls.Co
tlsConfig.NextProtos = options.ALPN
}
if options.MinVersion != "" {
minVersion, err := option.ParseTLSVersion(options.MinVersion)
minVersion, err := ParseTLSVersion(options.MinVersion)
if err != nil {
return nil, E.Cause(err, "parse min_version")
}
tlsConfig.MinVersion = minVersion
}
if options.MaxVersion != "" {
maxVersion, err := option.ParseTLSVersion(options.MaxVersion)
maxVersion, err := ParseTLSVersion(options.MaxVersion)
if err != nil {
return nil, E.Cause(err, "parse max_version")
}
@ -104,42 +96,13 @@ func TLSConfig(serverAddress string, options option.OutboundTLSOptions) (*tls.Co
}
tlsConfig.RootCAs = certPool
}
return &tlsConfig, nil
return &stdClientConfig{&tlsConfig}, nil
}
func NewTLS(dialer N.Dialer, serverAddress string, options option.OutboundTLSOptions) (N.Dialer, error) {
if !options.Enabled {
return dialer, nil
}
tlsConfig, err := TLSConfig(serverAddress, options)
if err != nil {
return nil, err
}
return &TLSDialer{
dialer: dialer,
config: tlsConfig,
}, nil
func (s *stdClientConfig) Config() (*STDConfig, error) {
return s.config, nil
}
func (d *TLSDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
if network != N.NetworkTCP {
return nil, os.ErrInvalid
}
conn, err := d.dialer.DialContext(ctx, network, destination)
if err != nil {
return nil, err
}
return TLSClient(ctx, conn, d.config)
}
func (d *TLSDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
return nil, os.ErrInvalid
}
func TLSClient(ctx context.Context, conn net.Conn, tlsConfig *tls.Config) (*tls.Conn, error) {
tlsConn := tls.Client(conn, tlsConfig)
ctx, cancel := context.WithTimeout(ctx, C.TCPTimeout)
defer cancel()
err := tlsConn.HandshakeContext(ctx)
return tlsConn, err
func (s *stdClientConfig) Client(conn net.Conn) Conn {
return tls.Client(conn, s.config)
}

View file

@ -1,8 +1,9 @@
package inbound
package tls
import (
"context"
"crypto/tls"
"net"
"os"
"github.com/sagernet/sing-box/adapter"
@ -14,9 +15,7 @@ import (
"github.com/fsnotify/fsnotify"
)
var _ adapter.Service = (*TLSConfig)(nil)
type TLSConfig struct {
type STDServerConfig struct {
config *tls.Config
logger log.Logger
acmeService adapter.Service
@ -27,105 +26,7 @@ type TLSConfig struct {
watcher *fsnotify.Watcher
}
func (c *TLSConfig) Config() *tls.Config {
return c.config
}
func (c *TLSConfig) Start() error {
if c.acmeService != nil {
return c.acmeService.Start()
} else {
if c.certificatePath == "" && c.keyPath == "" {
return nil
}
err := c.startWatcher()
if err != nil {
c.logger.Warn("create fsnotify watcher: ", err)
}
return nil
}
}
func (c *TLSConfig) startWatcher() error {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return err
}
if c.certificatePath != "" {
err = watcher.Add(c.certificatePath)
if err != nil {
return err
}
}
if c.keyPath != "" {
err = watcher.Add(c.keyPath)
if err != nil {
return err
}
}
c.watcher = watcher
go c.loopUpdate()
return nil
}
func (c *TLSConfig) loopUpdate() {
for {
select {
case event, ok := <-c.watcher.Events:
if !ok {
return
}
if event.Op&fsnotify.Write != fsnotify.Write {
continue
}
err := c.reloadKeyPair()
if err != nil {
c.logger.Error(E.Cause(err, "reload TLS key pair"))
}
case err, ok := <-c.watcher.Errors:
if !ok {
return
}
c.logger.Error(E.Cause(err, "fsnotify error"))
}
}
}
func (c *TLSConfig) reloadKeyPair() error {
if c.certificatePath != "" {
certificate, err := os.ReadFile(c.certificatePath)
if err != nil {
return E.Cause(err, "reload certificate from ", c.certificatePath)
}
c.certificate = certificate
}
if c.keyPath != "" {
key, err := os.ReadFile(c.keyPath)
if err != nil {
return E.Cause(err, "reload key from ", c.keyPath)
}
c.key = key
}
keyPair, err := tls.X509KeyPair(c.certificate, c.key)
if err != nil {
return E.Cause(err, "reload key pair")
}
c.config.Certificates = []tls.Certificate{keyPair}
c.logger.Info("reloaded TLS certificate")
return nil
}
func (c *TLSConfig) Close() error {
if c.acmeService != nil {
return c.acmeService.Close()
}
if c.watcher != nil {
return c.watcher.Close()
}
return nil
}
func NewTLSConfig(ctx context.Context, logger log.Logger, options option.InboundTLSOptions) (*TLSConfig, error) {
func NewServer(ctx context.Context, logger log.Logger, options option.InboundTLSOptions) (ServerConfig, error) {
if !options.Enabled {
return nil, nil
}
@ -147,14 +48,14 @@ func NewTLSConfig(ctx context.Context, logger log.Logger, options option.Inbound
tlsConfig.NextProtos = append(tlsConfig.NextProtos, options.ALPN...)
}
if options.MinVersion != "" {
minVersion, err := option.ParseTLSVersion(options.MinVersion)
minVersion, err := ParseTLSVersion(options.MinVersion)
if err != nil {
return nil, E.Cause(err, "parse min_version")
}
tlsConfig.MinVersion = minVersion
}
if options.MaxVersion != "" {
maxVersion, err := option.ParseTLSVersion(options.MaxVersion)
maxVersion, err := ParseTLSVersion(options.MaxVersion)
if err != nil {
return nil, E.Cause(err, "parse max_version")
}
@ -205,7 +106,7 @@ func NewTLSConfig(ctx context.Context, logger log.Logger, options option.Inbound
}
tlsConfig.Certificates = []tls.Certificate{keyPair}
}
return &TLSConfig{
return &STDServerConfig{
config: tlsConfig,
logger: logger,
acmeService: acmeService,
@ -215,3 +116,109 @@ func NewTLSConfig(ctx context.Context, logger log.Logger, options option.Inbound
keyPath: options.KeyPath,
}, nil
}
func (c *STDServerConfig) Config() (*STDConfig, error) {
return c.config, nil
}
func (c *STDServerConfig) Client(conn net.Conn) Conn {
return tls.Client(conn, c.config)
}
func (c *STDServerConfig) Server(conn net.Conn) Conn {
return tls.Server(conn, c.config)
}
func (c *STDServerConfig) Start() error {
if c.acmeService != nil {
return c.acmeService.Start()
} else {
if c.certificatePath == "" && c.keyPath == "" {
return nil
}
err := c.startWatcher()
if err != nil {
c.logger.Warn("create fsnotify watcher: ", err)
}
return nil
}
}
func (c *STDServerConfig) startWatcher() error {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return err
}
if c.certificatePath != "" {
err = watcher.Add(c.certificatePath)
if err != nil {
return err
}
}
if c.keyPath != "" {
err = watcher.Add(c.keyPath)
if err != nil {
return err
}
}
c.watcher = watcher
go c.loopUpdate()
return nil
}
func (c *STDServerConfig) loopUpdate() {
for {
select {
case event, ok := <-c.watcher.Events:
if !ok {
return
}
if event.Op&fsnotify.Write != fsnotify.Write {
continue
}
err := c.reloadKeyPair()
if err != nil {
c.logger.Error(E.Cause(err, "reload TLS key pair"))
}
case err, ok := <-c.watcher.Errors:
if !ok {
return
}
c.logger.Error(E.Cause(err, "fsnotify error"))
}
}
}
func (c *STDServerConfig) reloadKeyPair() error {
if c.certificatePath != "" {
certificate, err := os.ReadFile(c.certificatePath)
if err != nil {
return E.Cause(err, "reload certificate from ", c.certificatePath)
}
c.certificate = certificate
}
if c.keyPath != "" {
key, err := os.ReadFile(c.keyPath)
if err != nil {
return E.Cause(err, "reload key from ", c.keyPath)
}
c.key = key
}
keyPair, err := tls.X509KeyPair(c.certificate, c.key)
if err != nil {
return E.Cause(err, "reload key pair")
}
c.config.Certificates = []tls.Certificate{keyPair}
c.logger.Info("reloaded TLS certificate")
return nil
}
func (c *STDServerConfig) Close() error {
if c.acmeService != nil {
return c.acmeService.Close()
}
if c.watcher != nil {
return c.watcher.Close()
}
return nil
}

View file

@ -3,11 +3,11 @@ package inbound
import (
std_bufio "bufio"
"context"
"crypto/tls"
"net"
"os"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
@ -26,7 +26,7 @@ var (
type HTTP struct {
myInboundAdapter
authenticator auth.Authenticator
tlsConfig *TLSConfig
tlsConfig tls.ServerConfig
}
func NewHTTP(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.HTTPMixedInboundOptions) (*HTTP, error) {
@ -44,7 +44,7 @@ func NewHTTP(ctx context.Context, router adapter.Router, logger log.ContextLogge
authenticator: auth.NewAuthenticator(options.Users),
}
if options.TLS != nil {
tlsConfig, err := NewTLSConfig(ctx, logger, common.PtrValueOrDefault(options.TLS))
tlsConfig, err := tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS))
if err != nil {
return nil, err
}
@ -67,13 +67,13 @@ func (h *HTTP) Start() error {
func (h *HTTP) Close() error {
return common.Close(
&h.myInboundAdapter,
common.PtrOrNil(h.tlsConfig),
h.tlsConfig,
)
}
func (h *HTTP) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
if h.tlsConfig != nil {
conn = tls.Server(conn, h.tlsConfig.Config())
conn = h.tlsConfig.Server(conn)
}
return http.HandleConnection(ctx, conn, std_bufio.NewReader(conn), h.authenticator, h.upstreamUserHandler(metadata), adapter.UpstreamMetadata(metadata))
}

View file

@ -10,6 +10,7 @@ import (
"github.com/sagernet/quic-go"
"github.com/sagernet/quic-go/congestion"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
@ -26,7 +27,7 @@ var _ adapter.Inbound = (*Hysteria)(nil)
type Hysteria struct {
myInboundAdapter
quicConfig *quic.Config
tlsConfig *TLSConfig
tlsConfig tls.ServerConfig
authKey []byte
xplusKey []byte
sendBPS uint64
@ -116,7 +117,7 @@ func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextL
if len(options.TLS.ALPN) == 0 {
options.TLS.ALPN = []string{hysteria.DefaultALPN}
}
tlsConfig, err := NewTLSConfig(ctx, logger, common.PtrValueOrDefault(options.TLS))
tlsConfig, err := tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS))
if err != nil {
return nil, err
}
@ -137,7 +138,11 @@ func (h *Hysteria) Start() error {
if err != nil {
return err
}
listener, err := quic.Listen(packetConn, h.tlsConfig.Config(), h.quicConfig)
rawConfig, err := h.tlsConfig.Config()
if err != nil {
return err
}
listener, err := quic.Listen(packetConn, rawConfig, h.quicConfig)
if err != nil {
return err
}
@ -301,6 +306,6 @@ func (h *Hysteria) Close() error {
return common.Close(
&h.myInboundAdapter,
h.listener,
common.PtrOrNil(h.tlsConfig),
h.tlsConfig,
)
}

View file

@ -2,7 +2,6 @@ package inbound
import (
"context"
"crypto/tls"
"encoding/base64"
"encoding/binary"
"io"
@ -14,6 +13,7 @@ import (
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
@ -32,7 +32,7 @@ var _ adapter.Inbound = (*Naive)(nil)
type Naive struct {
myInboundAdapter
authenticator auth.Authenticator
tlsConfig *TLSConfig
tlsConfig tls.ServerConfig
httpServer *http.Server
h3Server any
}
@ -59,7 +59,7 @@ func NewNaive(ctx context.Context, router adapter.Router, logger log.ContextLogg
return nil, E.New("missing users")
}
if options.TLS != nil {
tlsConfig, err := NewTLSConfig(ctx, logger, common.PtrValueOrDefault(options.TLS))
tlsConfig, err := tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS))
if err != nil {
return nil, err
}
@ -69,13 +69,16 @@ func NewNaive(ctx context.Context, router adapter.Router, logger log.ContextLogg
}
func (n *Naive) Start() error {
var tlsConfig *tls.Config
var tlsConfig *tls.STDConfig
if n.tlsConfig != nil {
err := n.tlsConfig.Start()
if err != nil {
return E.Cause(err, "create TLS config")
}
tlsConfig = n.tlsConfig.Config()
tlsConfig, err = n.tlsConfig.Config()
if err != nil {
return err
}
}
if common.Contains(n.network, N.NetworkTCP) {
@ -117,7 +120,7 @@ func (n *Naive) Close() error {
&n.myInboundAdapter,
common.PtrOrNil(n.httpServer),
n.h3Server,
common.PtrOrNil(n.tlsConfig),
n.tlsConfig,
)
}

View file

@ -8,9 +8,13 @@ import (
)
func (n *Naive) configureHTTP3Listener() error {
tlsConfig, err := n.tlsConfig.Config()
if err != nil {
return err
}
h3Server := &http3.Server{
Port: int(n.listenOptions.ListenPort),
TLSConfig: n.tlsConfig.Config(),
TLSConfig: tlsConfig,
Handler: n,
}

View file

@ -2,11 +2,11 @@ package inbound
import (
"context"
"crypto/tls"
"net"
"os"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
@ -29,7 +29,7 @@ type Trojan struct {
myInboundAdapter
service *trojan.Service[int]
users []option.TrojanUser
tlsConfig *TLSConfig
tlsConfig tls.ServerConfig
fallbackAddr M.Socksaddr
fallbackAddrTLSNextProto map[string]M.Socksaddr
transport adapter.V2RayServerTransport
@ -49,7 +49,7 @@ func NewTrojan(ctx context.Context, router adapter.Router, logger log.ContextLog
users: options.Users,
}
if options.TLS != nil {
tlsConfig, err := NewTLSConfig(ctx, logger, common.PtrValueOrDefault(options.TLS))
tlsConfig, err := tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS))
if err != nil {
return nil, err
}
@ -89,11 +89,7 @@ func NewTrojan(ctx context.Context, router adapter.Router, logger log.ContextLog
return nil, err
}
if options.Transport != nil {
var tlsConfig *tls.Config
if inbound.tlsConfig != nil {
tlsConfig = inbound.tlsConfig.Config()
}
inbound.transport, err = v2ray.NewServerTransport(ctx, common.PtrValueOrDefault(options.Transport), tlsConfig, adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newTransportConnection, nil, nil), inbound)
inbound.transport, err = v2ray.NewServerTransport(ctx, common.PtrValueOrDefault(options.Transport), inbound.tlsConfig, adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newTransportConnection, nil, nil), inbound)
if err != nil {
return nil, E.Cause(err, "create server transport: ", options.Transport.Type)
}
@ -143,7 +139,7 @@ func (h *Trojan) Start() error {
func (h *Trojan) Close() error {
return common.Close(
&h.myInboundAdapter,
common.PtrOrNil(h.tlsConfig),
h.tlsConfig,
h.transport,
)
}
@ -155,7 +151,7 @@ func (h *Trojan) newTransportConnection(ctx context.Context, conn net.Conn, meta
func (h *Trojan) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
if h.tlsConfig != nil && h.transport == nil {
conn = tls.Server(conn, h.tlsConfig.Config())
conn = h.tlsConfig.Server(conn)
}
return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata))
}
@ -182,7 +178,7 @@ func (h *Trojan) newConnection(ctx context.Context, conn net.Conn, metadata adap
func (h *Trojan) fallbackConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
var fallbackAddr M.Socksaddr
if len(h.fallbackAddrTLSNextProto) > 0 {
if tlsConn, loaded := common.Cast[*tls.Conn](conn); loaded {
if tlsConn, loaded := common.Cast[*tls.STDConn](conn); loaded {
connectionState := tlsConn.ConnectionState()
if connectionState.NegotiatedProtocol != "" {
if fallbackAddr, loaded = h.fallbackAddrTLSNextProto[connectionState.NegotiatedProtocol]; !loaded {

View file

@ -2,11 +2,11 @@ package inbound
import (
"context"
"crypto/tls"
"net"
"os"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
@ -31,7 +31,7 @@ type VMess struct {
ctx context.Context
service *vmess.Service[int]
users []option.VMessUser
tlsConfig *TLSConfig
tlsConfig tls.ServerConfig
transport adapter.V2RayServerTransport
}
@ -62,17 +62,13 @@ func NewVMess(ctx context.Context, router adapter.Router, logger log.ContextLogg
return nil, err
}
if options.TLS != nil {
inbound.tlsConfig, err = NewTLSConfig(ctx, logger, common.PtrValueOrDefault(options.TLS))
inbound.tlsConfig, err = tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS))
if err != nil {
return nil, err
}
}
if options.Transport != nil {
var tlsConfig *tls.Config
if inbound.tlsConfig != nil {
tlsConfig = inbound.tlsConfig.Config()
}
inbound.transport, err = v2ray.NewServerTransport(ctx, common.PtrValueOrDefault(options.Transport), tlsConfig, adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newTransportConnection, nil, nil), inbound)
inbound.transport, err = v2ray.NewServerTransport(ctx, common.PtrValueOrDefault(options.Transport), inbound.tlsConfig, adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newTransportConnection, nil, nil), inbound)
if err != nil {
return nil, E.Cause(err, "create server transport: ", options.Transport.Type)
}
@ -84,7 +80,7 @@ func NewVMess(ctx context.Context, router adapter.Router, logger log.ContextLogg
func (h *VMess) Start() error {
err := common.Start(
h.service,
common.PtrOrNil(h.tlsConfig),
h.tlsConfig,
)
if err != nil {
return err
@ -123,7 +119,7 @@ func (h *VMess) Close() error {
return common.Close(
h.service,
&h.myInboundAdapter,
common.PtrOrNil(h.tlsConfig),
h.tlsConfig,
h.transport,
)
}
@ -135,7 +131,7 @@ func (h *VMess) newTransportConnection(ctx context.Context, conn net.Conn, metad
func (h *VMess) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
if h.tlsConfig != nil && h.transport == nil {
conn = tls.Server(conn, h.tlsConfig.Config())
conn = h.tlsConfig.Server(conn)
}
return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata))
}

View file

@ -1,11 +1,5 @@
package option
import (
"crypto/tls"
E "github.com/sagernet/sing/common/exceptions"
)
type InboundTLSOptions struct {
Enabled bool `json:"enabled,omitempty"`
ServerName string `json:"server_name,omitempty"`
@ -32,18 +26,3 @@ type OutboundTLSOptions struct {
Certificate string `json:"certificate,omitempty"`
CertificatePath string `json:"certificate_path,omitempty"`
}
func ParseTLSVersion(version string) (uint16, error) {
switch version {
case "1.0":
return tls.VersionTLS10, nil
case "1.1":
return tls.VersionTLS11, nil
case "1.2":
return tls.VersionTLS12, nil
case "1.3":
return tls.VersionTLS13, nil
default:
return 0, E.New("unknown tls version:", version)
}
}

View file

@ -7,6 +7,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/dialer"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
@ -24,7 +25,7 @@ type HTTP struct {
}
func NewHTTP(router adapter.Router, logger log.ContextLogger, tag string, options option.HTTPOutboundOptions) (*HTTP, error) {
detour, err := dialer.NewTLS(dialer.New(router, options.DialerOptions), options.Server, common.PtrValueOrDefault(options.TLS))
detour, err := tls.NewDialerFromOptions(router, dialer.New(router, options.DialerOptions), options.Server, common.PtrValueOrDefault(options.TLS))
if err != nil {
return nil, err
}

View file

@ -4,7 +4,6 @@ package outbound
import (
"context"
"crypto/tls"
"net"
"sync"
@ -12,6 +11,7 @@ import (
"github.com/sagernet/quic-go/congestion"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/dialer"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
@ -30,7 +30,7 @@ type Hysteria struct {
ctx context.Context
dialer N.Dialer
serverAddr M.Socksaddr
tlsConfig *tls.Config
tlsConfig *tls.STDConfig
quicConfig *quic.Config
authKey []byte
xplusKey []byte
@ -47,7 +47,11 @@ func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextL
if options.TLS == nil || !options.TLS.Enabled {
return nil, C.ErrTLSRequired
}
tlsConfig, err := dialer.TLSConfig(options.Server, common.PtrValueOrDefault(options.TLS))
abstractTLSConfig, err := tls.NewClient(router, options.Server, common.PtrValueOrDefault(options.TLS))
if err != nil {
return nil, err
}
tlsConfig, err := abstractTLSConfig.Config()
if err != nil {
return nil, err
}

View file

@ -2,12 +2,12 @@ package outbound
import (
"context"
"crypto/tls"
"net"
"os"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/dialer"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
@ -22,7 +22,7 @@ type ShadowTLS struct {
myOutboundAdapter
dialer N.Dialer
serverAddr M.Socksaddr
tlsConfig *tls.Config
tlsConfig tls.Config
}
func NewShadowTLS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowTLSOutboundOptions) (*ShadowTLS, error) {
@ -43,7 +43,7 @@ func NewShadowTLS(ctx context.Context, router adapter.Router, logger log.Context
options.TLS.MinVersion = "1.2"
options.TLS.MaxVersion = "1.2"
var err error
outbound.tlsConfig, err = dialer.TLSConfig(options.Server, common.PtrValueOrDefault(options.TLS))
outbound.tlsConfig, err = tls.NewClient(router, options.Server, common.PtrValueOrDefault(options.TLS))
if err != nil {
return nil, err
}
@ -60,15 +60,7 @@ func (s *ShadowTLS) DialContext(ctx context.Context, network string, destination
if err != nil {
return nil, err
}
tlsConn, err := dialer.TLSClient(ctx, conn, s.tlsConfig)
if err != nil {
return nil, err
}
err = tlsConn.HandshakeContext(ctx)
if err != nil {
return nil, err
}
return conn, nil
return tls.ClientHandshake(ctx, conn, s.tlsConfig)
}
func (s *ShadowTLS) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {

View file

@ -2,12 +2,12 @@ package outbound
import (
"context"
"crypto/tls"
"net"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/dialer"
"github.com/sagernet/sing-box/common/mux"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
@ -28,7 +28,7 @@ type Trojan struct {
serverAddr M.Socksaddr
key [56]byte
multiplexDialer N.Dialer
tlsConfig *tls.Config
tlsConfig tls.Config
transport adapter.V2RayClientTransport
}
@ -47,7 +47,7 @@ func NewTrojan(ctx context.Context, router adapter.Router, logger log.ContextLog
}
var err error
if options.TLS != nil {
outbound.tlsConfig, err = dialer.TLSConfig(options.Server, common.PtrValueOrDefault(options.TLS))
outbound.tlsConfig, err = tls.NewClient(router, options.Server, common.PtrValueOrDefault(options.TLS))
if err != nil {
return nil, err
}
@ -116,7 +116,7 @@ func (h *trojanDialer) DialContext(ctx context.Context, network string, destinat
} else {
conn, err = h.dialer.DialContext(ctx, N.NetworkTCP, h.serverAddr)
if err == nil && h.tlsConfig != nil {
conn, err = dialer.TLSClient(ctx, conn, h.tlsConfig)
conn, err = tls.ClientHandshake(ctx, conn, h.tlsConfig)
}
}
if err != nil {

View file

@ -2,12 +2,12 @@ package outbound
import (
"context"
"crypto/tls"
"net"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/dialer"
"github.com/sagernet/sing-box/common/mux"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
@ -28,7 +28,7 @@ type VMess struct {
client *vmess.Client
serverAddr M.Socksaddr
multiplexDialer N.Dialer
tlsConfig *tls.Config
tlsConfig tls.Config
transport adapter.V2RayClientTransport
packetAddr bool
}
@ -47,7 +47,7 @@ func NewVMess(ctx context.Context, router adapter.Router, logger log.ContextLogg
}
var err error
if options.TLS != nil {
outbound.tlsConfig, err = dialer.TLSConfig(options.Server, common.PtrValueOrDefault(options.TLS))
outbound.tlsConfig, err = tls.NewClient(router, options.Server, common.PtrValueOrDefault(options.TLS))
if err != nil {
return nil, err
}
@ -142,7 +142,7 @@ func (h *vmessDialer) DialContext(ctx context.Context, network string, destinati
} else {
conn, err = h.dialer.DialContext(ctx, N.NetworkTCP, h.serverAddr)
if err == nil && h.tlsConfig != nil {
conn, err = dialer.TLSClient(ctx, conn, h.tlsConfig)
conn, err = tls.ClientHandshake(ctx, conn, h.tlsConfig)
}
}
if err != nil {
@ -169,7 +169,7 @@ func (h *vmessDialer) ListenPacket(ctx context.Context, destination M.Socksaddr)
} else {
conn, err = h.dialer.DialContext(ctx, N.NetworkTCP, h.serverAddr)
if err == nil && h.tlsConfig != nil {
conn, err = dialer.TLSClient(ctx, conn, h.tlsConfig)
conn, err = tls.ClientHandshake(ctx, conn, h.tlsConfig)
}
}
if err != nil {

View file

@ -4,9 +4,9 @@ package v2ray
import (
"context"
"crypto/tls"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/transport/v2raygrpc"
"github.com/sagernet/sing-box/transport/v2raygrpclite"
@ -15,16 +15,16 @@ import (
N "github.com/sagernet/sing/common/network"
)
func NewGRPCServer(ctx context.Context, options option.V2RayGRPCOptions, tlsConfig *tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) (adapter.V2RayServerTransport, error) {
func NewGRPCServer(ctx context.Context, options option.V2RayGRPCOptions, tlsConfig tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) (adapter.V2RayServerTransport, error) {
if options.ForceLite {
return v2raygrpclite.NewServer(ctx, options, tlsConfig, handler, errorHandler), nil
return v2raygrpclite.NewServer(ctx, options, tlsConfig, handler, errorHandler)
}
return v2raygrpc.NewServer(ctx, options, tlsConfig, handler), nil
return v2raygrpc.NewServer(ctx, options, tlsConfig, handler)
}
func NewGRPCClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayGRPCOptions, tlsConfig *tls.Config) (adapter.V2RayClientTransport, error) {
func NewGRPCClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayGRPCOptions, tlsConfig tls.Config) (adapter.V2RayClientTransport, error) {
if options.ForceLite {
return v2raygrpclite.NewClient(ctx, dialer, serverAddr, options, tlsConfig), nil
}
return v2raygrpc.NewClient(ctx, dialer, serverAddr, options, tlsConfig), nil
return v2raygrpc.NewClient(ctx, dialer, serverAddr, options, tlsConfig)
}

View file

@ -4,9 +4,9 @@ package v2ray
import (
"context"
"crypto/tls"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/transport/v2rayquic"
E "github.com/sagernet/sing/common/exceptions"
@ -14,10 +14,10 @@ import (
N "github.com/sagernet/sing/common/network"
)
func NewQUICServer(ctx context.Context, options option.V2RayQUICOptions, tlsConfig *tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) (adapter.V2RayServerTransport, error) {
return v2rayquic.NewServer(ctx, options, tlsConfig, handler, errorHandler), nil
func NewQUICServer(ctx context.Context, options option.V2RayQUICOptions, tlsConfig tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) (adapter.V2RayServerTransport, error) {
return v2rayquic.NewServer(ctx, options, tlsConfig, handler, errorHandler)
}
func NewQUICClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayQUICOptions, tlsConfig *tls.Config) (adapter.V2RayClientTransport, error) {
return v2rayquic.NewClient(ctx, dialer, serverAddr, options, tlsConfig), nil
func NewQUICClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayQUICOptions, tlsConfig tls.Config) (adapter.V2RayClientTransport, error) {
return v2rayquic.NewClient(ctx, dialer, serverAddr, options, tlsConfig)
}

View file

@ -2,9 +2,9 @@ package v2ray
import (
"context"
"crypto/tls"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/transport/v2rayhttp"
@ -14,15 +14,15 @@ import (
N "github.com/sagernet/sing/common/network"
)
func NewServerTransport(ctx context.Context, options option.V2RayTransportOptions, tlsConfig *tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) (adapter.V2RayServerTransport, error) {
func NewServerTransport(ctx context.Context, options option.V2RayTransportOptions, tlsConfig tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) (adapter.V2RayServerTransport, error) {
if options.Type == "" {
return nil, nil
}
switch options.Type {
case C.V2RayTransportTypeHTTP:
return v2rayhttp.NewServer(ctx, options.HTTPOptions, tlsConfig, handler, errorHandler), nil
return v2rayhttp.NewServer(ctx, options.HTTPOptions, tlsConfig, handler, errorHandler)
case C.V2RayTransportTypeWebsocket:
return v2raywebsocket.NewServer(ctx, options.WebsocketOptions, tlsConfig, handler, errorHandler), nil
return v2raywebsocket.NewServer(ctx, options.WebsocketOptions, tlsConfig, handler, errorHandler)
case C.V2RayTransportTypeQUIC:
if tlsConfig == nil {
return nil, C.ErrTLSRequired
@ -35,7 +35,7 @@ func NewServerTransport(ctx context.Context, options option.V2RayTransportOption
}
}
func NewClientTransport(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayTransportOptions, tlsConfig *tls.Config) (adapter.V2RayClientTransport, error) {
func NewClientTransport(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayTransportOptions, tlsConfig tls.Config) (adapter.V2RayClientTransport, error) {
if options.Type == "" {
return nil, nil
}

View file

@ -2,12 +2,12 @@ package v2raygrpc
import (
"context"
"crypto/tls"
"net"
"sync"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
M "github.com/sagernet/sing/common/metadata"
@ -32,10 +32,14 @@ type Client struct {
connAccess sync.Mutex
}
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayGRPCOptions, tlsConfig *tls.Config) adapter.V2RayClientTransport {
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 {
dialOptions = append(dialOptions, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
stdConfig, err := tlsConfig.Config()
if err != nil {
return nil, err
}
dialOptions = append(dialOptions, grpc.WithTransportCredentials(credentials.NewTLS(stdConfig)))
} else {
dialOptions = append(dialOptions, grpc.WithTransportCredentials(insecure.NewCredentials()))
}
@ -58,7 +62,7 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
serverAddr: serverAddr.String(),
serviceName: options.ServiceName,
dialOptions: dialOptions,
}
}, nil
}
func (c *Client) Close() error {

View file

@ -2,11 +2,11 @@ package v2raygrpc
import (
"context"
"crypto/tls"
"net"
"os"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
"github.com/sagernet/sing-box/option"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
@ -23,15 +23,19 @@ type Server struct {
server *grpc.Server
}
func NewServer(ctx context.Context, options option.V2RayGRPCOptions, tlsConfig *tls.Config, handler N.TCPConnectionHandler) *Server {
func NewServer(ctx context.Context, options option.V2RayGRPCOptions, tlsConfig tls.Config, handler N.TCPConnectionHandler) (*Server, error) {
var serverOptions []grpc.ServerOption
if tlsConfig != nil {
tlsConfig.NextProtos = []string{"h2"}
serverOptions = append(serverOptions, grpc.Creds(credentials.NewTLS(tlsConfig)))
stdConfig, err := tlsConfig.Config()
if err != nil {
return nil, err
}
stdConfig.NextProtos = []string{"h2"}
serverOptions = append(serverOptions, grpc.Creds(credentials.NewTLS(stdConfig)))
}
server := &Server{ctx, handler, grpc.NewServer(serverOptions...)}
RegisterGunServiceCustomNameServer(server.server, server, options.ServiceName)
return server
return server, nil
}
func (s *Server) Tun(server GunService_TunServer) error {

View file

@ -2,7 +2,6 @@ package v2raygrpclite
import (
"context"
"crypto/tls"
"fmt"
"io"
"net"
@ -10,6 +9,7 @@ import (
"net/url"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
"github.com/sagernet/sing-box/option"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
@ -32,18 +32,21 @@ type Client struct {
url *url.URL
}
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayGRPCOptions, tlsConfig *tls.Config) adapter.V2RayClientTransport {
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayGRPCOptions, tlsConfig tls.Config) adapter.V2RayClientTransport {
return &Client{
ctx: ctx,
dialer: dialer,
serverAddr: serverAddr,
options: options,
transport: &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
conn, err := dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
if err != nil {
return nil, err
}
return tls.ClientHandshake(ctx, conn, tlsConfig)
},
ForceAttemptHTTP2: true,
TLSClientConfig: tlsConfig,
},
url: &url.URL{
Scheme: "https",

View file

@ -2,7 +2,6 @@ package v2raygrpclite
import (
"context"
"crypto/tls"
"fmt"
"net"
"net/http"
@ -11,6 +10,7 @@ import (
"strings"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
@ -32,22 +32,26 @@ func (s *Server) Network() []string {
return []string{N.NetworkTCP}
}
func NewServer(ctx context.Context, options option.V2RayGRPCOptions, tlsConfig *tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) *Server {
func NewServer(ctx context.Context, options option.V2RayGRPCOptions, tlsConfig tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) (*Server, error) {
server := &Server{
handler: handler,
errorHandler: errorHandler,
path: fmt.Sprintf("/%s/Tun", url.QueryEscape(options.ServiceName)),
}
if tlsConfig != nil {
if !common.Contains(tlsConfig.NextProtos, "h2") {
tlsConfig.NextProtos = append(tlsConfig.NextProtos, "h2")
}
}
server.httpServer = &http.Server{
Handler: server,
TLSConfig: tlsConfig,
}
return server
if tlsConfig != nil {
stdConfig, err := tlsConfig.Config()
if err != nil {
return nil, err
}
if !common.Contains(stdConfig.NextProtos, "h2") {
stdConfig.NextProtos = append(stdConfig.NextProtos, "h2")
}
server.httpServer.TLSConfig = stdConfig
}
return server, nil
}
func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {

View file

@ -3,7 +3,6 @@ package v2rayhttp
import (
"bufio"
"context"
"crypto/tls"
"io"
"math/rand"
"net"
@ -12,6 +11,7 @@ import (
"strings"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
@ -32,7 +32,7 @@ type Client struct {
headers http.Header
}
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayHTTPOptions, tlsConfig *tls.Config) adapter.V2RayClientTransport {
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayHTTPOptions, tlsConfig tls.Config) adapter.V2RayClientTransport {
client := &Client{
ctx: ctx,
dialer: dialer,
@ -40,16 +40,26 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
host: options.Host,
method: options.Method,
headers: make(http.Header),
client: &http.Client{
Transport: &http.Transport{
client: &http.Client{},
http2: tlsConfig != nil,
}
if client.http2 {
client.client.Transport = &http.Transport{
DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
conn, err := dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
if err != nil {
return nil, err
}
return tls.ClientHandshake(ctx, conn, tlsConfig)
},
ForceAttemptHTTP2: true,
}
} else {
client.client.Transport = &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
},
ForceAttemptHTTP2: true,
TLSClientConfig: tlsConfig,
},
},
http2: tlsConfig != nil,
}
}
if client.method == "" {
client.method = "PUT"

View file

@ -2,13 +2,13 @@ package v2rayhttp
import (
"context"
"crypto/tls"
"net"
"net/http"
"os"
"strings"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
@ -35,7 +35,7 @@ func (s *Server) Network() []string {
return []string{N.NetworkTCP}
}
func NewServer(ctx context.Context, options option.V2RayHTTPOptions, tlsConfig *tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) *Server {
func NewServer(ctx context.Context, options option.V2RayHTTPOptions, tlsConfig tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) (*Server, error) {
server := &Server{
ctx: ctx,
handler: handler,
@ -58,9 +58,15 @@ func NewServer(ctx context.Context, options option.V2RayHTTPOptions, tlsConfig *
Handler: server,
ReadHeaderTimeout: C.TCPTimeout,
MaxHeaderBytes: http.DefaultMaxHeaderBytes,
TLSConfig: tlsConfig,
}
return server
if tlsConfig != nil {
stdConfig, err := tlsConfig.Config()
if err != nil {
return nil, err
}
server.httpServer.TLSConfig = stdConfig
}
return server, nil
}
func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {

View file

@ -2,12 +2,12 @@ package v2rayquic
import (
"context"
"crypto/tls"
"net"
"sync"
"github.com/sagernet/quic-go"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/transport/hysteria"
@ -23,26 +23,30 @@ type Client struct {
ctx context.Context
dialer N.Dialer
serverAddr M.Socksaddr
tlsConfig *tls.Config
tlsConfig *tls.STDConfig
quicConfig *quic.Config
conn quic.Connection
connAccess sync.Mutex
}
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayQUICOptions, tlsConfig *tls.Config) adapter.V2RayClientTransport {
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayQUICOptions, tlsConfig tls.Config) (adapter.V2RayClientTransport, error) {
quicConfig := &quic.Config{
DisablePathMTUDiscovery: !C.IsLinux && !C.IsWindows,
}
if len(tlsConfig.NextProtos) == 0 {
tlsConfig.NextProtos = []string{"h2", "http/1.1"}
stdConfig, err := tlsConfig.Config()
if err != nil {
return nil, err
}
if len(stdConfig.NextProtos) == 0 {
stdConfig.NextProtos = []string{"h2", "http/1.1"}
}
return &Client{
ctx: ctx,
dialer: dialer,
serverAddr: serverAddr,
tlsConfig: tlsConfig,
tlsConfig: stdConfig,
quicConfig: quicConfig,
}
}, nil
}
func (c *Client) offer() (quic.Connection, error) {

View file

@ -2,12 +2,12 @@ package v2rayquic
import (
"context"
"crypto/tls"
"net"
"os"
"github.com/sagernet/quic-go"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/transport/hysteria"
@ -21,7 +21,7 @@ var _ adapter.V2RayServerTransport = (*Server)(nil)
type Server struct {
ctx context.Context
tlsConfig *tls.Config
tlsConfig *tls.STDConfig
quicConfig *quic.Config
handler N.TCPConnectionHandler
errorHandler E.Handler
@ -29,21 +29,25 @@ type Server struct {
quicListener quic.Listener
}
func NewServer(ctx context.Context, options option.V2RayQUICOptions, tlsConfig *tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) *Server {
func NewServer(ctx context.Context, options option.V2RayQUICOptions, tlsConfig tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) (*Server, error) {
quicConfig := &quic.Config{
DisablePathMTUDiscovery: !C.IsLinux && !C.IsWindows,
}
if len(tlsConfig.NextProtos) == 0 {
tlsConfig.NextProtos = []string{"h2", "http/1.1"}
stdConfig, err := tlsConfig.Config()
if err != nil {
return nil, err
}
if len(stdConfig.NextProtos) == 0 {
stdConfig.NextProtos = []string{"h2", "http/1.1"}
}
server := &Server{
ctx: ctx,
tlsConfig: tlsConfig,
tlsConfig: stdConfig,
quicConfig: quicConfig,
handler: handler,
errorHandler: errorHandler,
}
return server
return server, nil
}
func (s *Server) Network() []string {

View file

@ -2,7 +2,6 @@ package v2raywebsocket
import (
"context"
"crypto/tls"
"net"
"net/http"
"net/url"
@ -10,6 +9,7 @@ import (
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
@ -28,16 +28,25 @@ type Client struct {
earlyDataHeaderName string
}
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayWebsocketOptions, tlsConfig *tls.Config) adapter.V2RayClientTransport {
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayWebsocketOptions, tlsConfig tls.Config) adapter.V2RayClientTransport {
wsDialer := &websocket.Dialer{
NetDialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
},
TLSClientConfig: tlsConfig,
ReadBufferSize: 4 * 1024,
WriteBufferSize: 4 * 1024,
HandshakeTimeout: time.Second * 8,
}
if tlsConfig != nil {
wsDialer.NetDialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
conn, err := dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
if err != nil {
return nil, err
}
return tls.ClientHandshake(ctx, conn, tlsConfig)
}
} else {
wsDialer.NetDialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
}
}
var uri url.URL
if tlsConfig == nil {
uri.Scheme = "ws"

View file

@ -2,7 +2,6 @@ package v2raywebsocket
import (
"context"
"crypto/tls"
"encoding/base64"
"net"
"net/http"
@ -10,6 +9,7 @@ import (
"strings"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
@ -35,7 +35,7 @@ type Server struct {
earlyDataHeaderName string
}
func NewServer(ctx context.Context, options option.V2RayWebsocketOptions, tlsConfig *tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) *Server {
func NewServer(ctx context.Context, options option.V2RayWebsocketOptions, tlsConfig tls.Config, handler N.TCPConnectionHandler, errorHandler E.Handler) (*Server, error) {
server := &Server{
ctx: ctx,
handler: handler,
@ -51,9 +51,15 @@ func NewServer(ctx context.Context, options option.V2RayWebsocketOptions, tlsCon
Handler: server,
ReadHeaderTimeout: C.TCPTimeout,
MaxHeaderBytes: http.DefaultMaxHeaderBytes,
TLSConfig: tlsConfig,
}
return server
if tlsConfig != nil {
stdConfig, err := tlsConfig.Config()
if err != nil {
return nil, err
}
server.httpServer.TLSConfig = stdConfig
}
return server, nil
}
var upgrader = websocket.Upgrader{