chore: more context passing in outbounds

This commit is contained in:
wwqgtxx
2023-05-18 13:15:08 +08:00
parent 6b1a4385b2
commit 033f902ace
16 changed files with 65 additions and 88 deletions

View File

@ -70,7 +70,7 @@ type Trojan struct {
hexPassword []byte
}
func (t *Trojan) StreamConn(conn net.Conn) (net.Conn, error) {
func (t *Trojan) StreamConn(ctx context.Context, conn net.Conn) (net.Conn, error) {
alpn := defaultALPN
if len(t.option.ALPN) != 0 {
alpn = t.option.ALPN
@ -149,7 +149,7 @@ func (t *Trojan) StreamConn(conn net.Conn) (net.Conn, error) {
}
}
func (t *Trojan) StreamWebsocketConn(conn net.Conn, wsOptions *WebsocketOption) (net.Conn, error) {
func (t *Trojan) StreamWebsocketConn(ctx context.Context, conn net.Conn, wsOptions *WebsocketOption) (net.Conn, error) {
alpn := defaultWebsocketALPN
if len(t.option.ALPN) != 0 {
alpn = t.option.ALPN
@ -162,7 +162,7 @@ func (t *Trojan) StreamWebsocketConn(conn net.Conn, wsOptions *WebsocketOption)
ServerName: t.option.ServerName,
}
return vmess.StreamWebsocketConn(conn, &vmess.WebsocketConfig{
return vmess.StreamWebsocketConn(ctx, conn, &vmess.WebsocketConfig{
Host: wsOptions.Host,
Port: wsOptions.Port,
Path: wsOptions.Path,

View File

@ -1,6 +1,7 @@
package obfs
import (
"context"
"crypto/tls"
"net"
"net/http"
@ -22,7 +23,7 @@ type Option struct {
}
// NewV2rayObfs return a HTTPObfs
func NewV2rayObfs(conn net.Conn, option *Option) (net.Conn, error) {
func NewV2rayObfs(ctx context.Context, conn net.Conn, option *Option) (net.Conn, error) {
header := http.Header{}
for k, v := range option.Headers {
header.Add(k, v)
@ -57,7 +58,7 @@ func NewV2rayObfs(conn net.Conn, option *Option) (net.Conn, error) {
}
var err error
conn, err = vmess.StreamWebsocketConn(conn, config)
conn, err = vmess.StreamWebsocketConn(ctx, conn, config)
if err != nil {
return nil, err
}

View File

@ -6,7 +6,6 @@ import (
"net"
tlsC "github.com/Dreamacro/clash/component/tls"
C "github.com/Dreamacro/clash/constant"
xtls "github.com/xtls/go"
)
@ -21,7 +20,7 @@ type XTLSConfig struct {
NextProtos []string
}
func StreamXTLSConn(conn net.Conn, cfg *XTLSConfig) (net.Conn, error) {
func StreamXTLSConn(ctx context.Context, conn net.Conn, cfg *XTLSConfig) (net.Conn, error) {
xtlsConfig := &xtls.Config{
ServerName: cfg.Host,
InsecureSkipVerify: cfg.SkipCertVerify,
@ -38,9 +37,6 @@ func StreamXTLSConn(conn net.Conn, cfg *XTLSConfig) (net.Conn, error) {
xtlsConn := xtls.Client(conn, xtlsConfig)
// fix xtls handshake not timeout
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
defer cancel()
err := xtlsConn.HandshakeContext(ctx)
return xtlsConn, err
}

View File

@ -7,7 +7,6 @@ import (
"net"
tlsC "github.com/Dreamacro/clash/component/tls"
C "github.com/Dreamacro/clash/constant"
)
type TLSConfig struct {
@ -19,7 +18,7 @@ type TLSConfig struct {
Reality *tlsC.RealityConfig
}
func StreamTLSConn(conn net.Conn, cfg *TLSConfig) (net.Conn, error) {
func StreamTLSConn(ctx context.Context, conn net.Conn, cfg *TLSConfig) (net.Conn, error) {
tlsConfig := &tls.Config{
ServerName: cfg.Host,
InsecureSkipVerify: cfg.SkipCertVerify,
@ -39,15 +38,10 @@ func StreamTLSConn(conn net.Conn, cfg *TLSConfig) (net.Conn, error) {
if cfg.Reality == nil {
utlsConn, valid := GetUTLSConn(conn, cfg.ClientFingerprint, tlsConfig)
if valid {
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
defer cancel()
err := utlsConn.(*tlsC.UConn).HandshakeContext(ctx)
return utlsConn, err
}
} else {
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
defer cancel()
return tlsC.GetRealityConn(ctx, conn, cfg.ClientFingerprint, tlsConfig, cfg.Reality)
}
}
@ -57,9 +51,6 @@ func StreamTLSConn(conn net.Conn, cfg *TLSConfig) (net.Conn, error) {
tlsConn := tls.Client(conn, tlsConfig)
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
defer cancel()
err := tlsConn.HandshakeContext(ctx)
return tlsConn, err
}

View File

@ -194,17 +194,17 @@ func (wsedc *websocketWithEarlyDataConn) Dial(earlyData []byte) error {
earlyDataBuf := bytes.NewBuffer(earlyData)
if _, err := base64EarlyDataEncoder.Write(earlyDataBuf.Next(wsedc.config.MaxEarlyData)); err != nil {
return errors.New("failed to encode early data: " + err.Error())
return fmt.Errorf("failed to encode early data: %w", err)
}
if errc := base64EarlyDataEncoder.Close(); errc != nil {
return errors.New("failed to encode early data tail: " + errc.Error())
return fmt.Errorf("failed to encode early data tail: %w", errc)
}
var err error
if wsedc.Conn, err = streamWebsocketConn(wsedc.underlay, wsedc.config, base64DataBuf); err != nil {
if wsedc.Conn, err = streamWebsocketConn(wsedc.ctx, wsedc.underlay, wsedc.config, base64DataBuf); err != nil {
wsedc.Close()
return errors.New("failed to dial WebSocket: " + err.Error())
return fmt.Errorf("failed to dial WebSocket: %w", err)
}
wsedc.dialed <- true
@ -340,7 +340,7 @@ func streamWebsocketWithEarlyDataConn(conn net.Conn, c *WebsocketConfig) (net.Co
return N.NewDeadlineConn(conn), nil
}
func streamWebsocketConn(conn net.Conn, c *WebsocketConfig, earlyData *bytes.Buffer) (net.Conn, error) {
func streamWebsocketConn(ctx context.Context, conn net.Conn, c *WebsocketConfig, earlyData *bytes.Buffer) (net.Conn, error) {
dialer := &websocket.Dialer{
NetDial: func(network, addr string) (net.Conn, error) {
@ -396,13 +396,13 @@ func streamWebsocketConn(conn net.Conn, c *WebsocketConfig, earlyData *bytes.Buf
}
}
wsConn, resp, err := dialer.Dial(uri.String(), headers)
wsConn, resp, err := dialer.DialContext(ctx, uri.String(), headers)
if err != nil {
reason := err.Error()
reason := err
if resp != nil {
reason = resp.Status
reason = errors.New(resp.Status)
}
return nil, fmt.Errorf("dial %s error: %s", uri.Host, reason)
return nil, fmt.Errorf("dial %s error: %w", uri.Host, reason)
}
conn = &websocketConn{
@ -417,7 +417,7 @@ func streamWebsocketConn(conn net.Conn, c *WebsocketConfig, earlyData *bytes.Buf
return N.NewDeadlineConn(conn), nil
}
func StreamWebsocketConn(conn net.Conn, c *WebsocketConfig) (net.Conn, error) {
func StreamWebsocketConn(ctx context.Context, conn net.Conn, c *WebsocketConfig) (net.Conn, error) {
if u, err := url.Parse(c.Path); err == nil {
if q := u.Query(); q.Get("ed") != "" {
if ed, err := strconv.Atoi(q.Get("ed")); err == nil {
@ -434,5 +434,5 @@ func StreamWebsocketConn(conn net.Conn, c *WebsocketConfig) (net.Conn, error) {
return streamWebsocketWithEarlyDataConn(conn, c)
}
return streamWebsocketConn(conn, c, nil)
return streamWebsocketConn(ctx, conn, c, nil)
}