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

@ -45,8 +45,8 @@ func (b *Base) Type() C.AdapterType {
return b.tp
}
// StreamConn implements C.ProxyAdapter
func (b *Base) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
// StreamConnContext implements C.ProxyAdapter
func (b *Base) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
return c, C.ErrNotSupport
}

View File

@ -40,12 +40,10 @@ type HttpOption struct {
Headers map[string]string `proxy:"headers,omitempty"`
}
// StreamConn implements C.ProxyAdapter
func (h *Http) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
// StreamConnContext implements C.ProxyAdapter
func (h *Http) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
if h.tlsConfig != nil {
cc := tls.Client(c, h.tlsConfig)
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
defer cancel()
err := cc.HandshakeContext(ctx)
c = cc
if err != nil {
@ -82,7 +80,7 @@ func (h *Http) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metad
safeConnClose(c, err)
}(c)
c, err = h.StreamConn(c, metadata)
c, err = h.StreamConnContext(ctx, c, metadata)
if err != nil {
return nil, err
}

View File

@ -84,14 +84,7 @@ type restlsOption struct {
RestlsScript string `obfs:"restls-script,omitempty"`
}
// StreamConn implements C.ProxyAdapter
func (ss *ShadowSocks) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
// fix tls handshake not timeout
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
defer cancel()
return ss.StreamConnContext(ctx, c, metadata)
}
// StreamConnContext implements C.ProxyAdapter
func (ss *ShadowSocks) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
useEarly := false
switch ss.obfsMode {
@ -102,7 +95,7 @@ func (ss *ShadowSocks) StreamConnContext(ctx context.Context, c net.Conn, metada
c = obfs.NewHTTPObfs(c, ss.obfsOption.Host, port)
case "websocket":
var err error
c, err = v2rayObfs.NewV2rayObfs(c, ss.v2rayOption)
c, err = v2rayObfs.NewV2rayObfs(ctx, c, ss.v2rayOption)
if err != nil {
return nil, fmt.Errorf("%s connect error: %w", ss.addr, err)
}

View File

@ -38,8 +38,8 @@ type ShadowSocksROption struct {
UDP bool `proxy:"udp,omitempty"`
}
// StreamConn implements C.ProxyAdapter
func (ssr *ShadowSocksR) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
// StreamConnContext implements C.ProxyAdapter
func (ssr *ShadowSocksR) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
c = ssr.obfs.StreamConn(c)
c = ssr.cipher.StreamConn(c)
var (
@ -83,7 +83,7 @@ func (ssr *ShadowSocksR) DialContextWithDialer(ctx context.Context, dialer C.Dia
safeConnClose(c, err)
}(c)
c, err = ssr.StreamConn(c, metadata)
c, err = ssr.StreamConnContext(ctx, c, metadata)
return NewConn(c, ssr), err
}

View File

@ -52,8 +52,8 @@ func streamConn(c net.Conn, option streamOption) *snell.Snell {
return snell.StreamConn(c, option.psk, option.version)
}
// StreamConn implements C.ProxyAdapter
func (s *Snell) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
// StreamConnContext implements C.ProxyAdapter
func (s *Snell) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
c = streamConn(c, streamOption{s.psk, s.version, s.addr, s.obfsOption})
if metadata.NetWork == C.UDP {
err := snell.WriteUDPHeader(c, s.version)
@ -101,7 +101,7 @@ func (s *Snell) DialContextWithDialer(ctx context.Context, dialer C.Dialer, meta
safeConnClose(c, err)
}(c)
c, err = s.StreamConn(c, metadata)
c, err = s.StreamConnContext(ctx, c, metadata)
return NewConn(c, s), err
}

View File

@ -39,12 +39,10 @@ type Socks5Option struct {
Fingerprint string `proxy:"fingerprint,omitempty"`
}
// StreamConn implements C.ProxyAdapter
func (ss *Socks5) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
// StreamConnContext implements C.ProxyAdapter
func (ss *Socks5) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
if ss.tls {
cc := tls.Client(c, ss.tlsConfig)
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
defer cancel()
err := cc.HandshakeContext(ctx)
c = cc
if err != nil {
@ -88,7 +86,7 @@ func (ss *Socks5) DialContextWithDialer(ctx context.Context, dialer C.Dialer, me
safeConnClose(c, err)
}(c)
c, err = ss.StreamConn(c, metadata)
c, err = ss.StreamConnContext(ctx, c, metadata)
if err != nil {
return nil, err
}

View File

@ -50,7 +50,7 @@ type TrojanOption struct {
ClientFingerprint string `proxy:"client-fingerprint,omitempty"`
}
func (t *Trojan) plainStream(c net.Conn) (net.Conn, error) {
func (t *Trojan) plainStream(ctx context.Context, c net.Conn) (net.Conn, error) {
if t.option.Network == "ws" {
host, port, _ := net.SplitHostPort(t.addr)
wsOpts := &trojan.WebsocketOption{
@ -71,14 +71,14 @@ func (t *Trojan) plainStream(c net.Conn) (net.Conn, error) {
wsOpts.Headers = header
}
return t.instance.StreamWebsocketConn(c, wsOpts)
return t.instance.StreamWebsocketConn(ctx, c, wsOpts)
}
return t.instance.StreamConn(c)
return t.instance.StreamConn(ctx, c)
}
// StreamConn implements C.ProxyAdapter
func (t *Trojan) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
// StreamConnContext implements C.ProxyAdapter
func (t *Trojan) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
var err error
if tlsC.HaveGlobalFingerprint() && len(t.option.ClientFingerprint) == 0 {
@ -88,7 +88,7 @@ func (t *Trojan) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error)
if t.transport != nil {
c, err = gun.StreamGunWithConn(c, t.gunTLSConfig, t.gunConfig, t.realityConfig)
} else {
c, err = t.plainStream(c)
c, err = t.plainStream(ctx, c)
}
if err != nil {
@ -151,7 +151,7 @@ func (t *Trojan) DialContextWithDialer(ctx context.Context, dialer C.Dialer, met
safeConnClose(c, err)
}(c)
c, err = t.StreamConn(c, metadata)
c, err = t.StreamConnContext(ctx, c, metadata)
if err != nil {
return nil, err
}
@ -199,7 +199,7 @@ func (t *Trojan) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, me
safeConnClose(c, err)
}(c)
tcpKeepAlive(c)
c, err = t.plainStream(c)
c, err = t.plainStream(ctx, c)
if err != nil {
return nil, fmt.Errorf("%s connect error: %w", t.addr, err)
}

View File

@ -75,7 +75,7 @@ type VlessOption struct {
ClientFingerprint string `proxy:"client-fingerprint,omitempty"`
}
func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
func (v *Vless) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
var err error
if tlsC.HaveGlobalFingerprint() && len(v.option.ClientFingerprint) == 0 {
@ -129,10 +129,10 @@ func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
convert.SetUserAgent(wsOpts.Headers)
}
}
c, err = vmess.StreamWebsocketConn(c, wsOpts)
c, err = vmess.StreamWebsocketConn(ctx, c, wsOpts)
case "http":
// readability first, so just copy default TLS logic
c, err = v.streamTLSOrXTLSConn(c, false)
c, err = v.streamTLSOrXTLSConn(ctx, c, false)
if err != nil {
return nil, err
}
@ -147,7 +147,7 @@ func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
c = vmess.StreamHTTPConn(c, httpOpts)
case "h2":
c, err = v.streamTLSOrXTLSConn(c, true)
c, err = v.streamTLSOrXTLSConn(ctx, c, true)
if err != nil {
return nil, err
}
@ -163,7 +163,7 @@ func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
default:
// default tcp network
// handle TLS And XTLS
c, err = v.streamTLSOrXTLSConn(c, false)
c, err = v.streamTLSOrXTLSConn(ctx, c, false)
}
if err != nil {
@ -201,7 +201,7 @@ func (v *Vless) streamConn(c net.Conn, metadata *C.Metadata) (conn net.Conn, err
return
}
func (v *Vless) streamTLSOrXTLSConn(conn net.Conn, isH2 bool) (net.Conn, error) {
func (v *Vless) streamTLSOrXTLSConn(ctx context.Context, conn net.Conn, isH2 bool) (net.Conn, error) {
host, _, _ := net.SplitHostPort(v.addr)
if v.isLegacyXTLSEnabled() && !isH2 {
@ -215,7 +215,7 @@ func (v *Vless) streamTLSOrXTLSConn(conn net.Conn, isH2 bool) (net.Conn, error)
xtlsOpts.Host = v.option.ServerName
}
return vless.StreamXTLSConn(conn, &xtlsOpts)
return vless.StreamXTLSConn(ctx, conn, &xtlsOpts)
} else if v.option.TLS {
tlsOpts := vmess.TLSConfig{
@ -234,7 +234,7 @@ func (v *Vless) streamTLSOrXTLSConn(conn net.Conn, isH2 bool) (net.Conn, error)
tlsOpts.Host = v.option.ServerName
}
return vmess.StreamTLSConn(conn, &tlsOpts)
return vmess.StreamTLSConn(ctx, conn, &tlsOpts)
}
return conn, nil
@ -283,7 +283,7 @@ func (v *Vless) DialContextWithDialer(ctx context.Context, dialer C.Dialer, meta
safeConnClose(c, err)
}(c)
c, err = v.StreamConn(c, metadata)
c, err = v.StreamConnContext(ctx, c, metadata)
if err != nil {
return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
}
@ -348,7 +348,7 @@ func (v *Vless) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
safeConnClose(c, err)
}(c)
c, err = v.StreamConn(c, metadata)
c, err = v.StreamConnContext(ctx, c, metadata)
if err != nil {
return nil, fmt.Errorf("new vless client error: %v", err)
}

View File

@ -89,8 +89,8 @@ type WSOptions struct {
EarlyDataHeaderName string `proxy:"early-data-header-name,omitempty"`
}
// StreamConn implements C.ProxyAdapter
func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
// StreamConnContext implements C.ProxyAdapter
func (v *Vmess) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
var err error
if tlsC.HaveGlobalFingerprint() && (len(v.option.ClientFingerprint) == 0) {
@ -138,7 +138,7 @@ func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
wsOpts.TLSConfig.ServerName = host
}
}
c, err = clashVMess.StreamWebsocketConn(c, wsOpts)
c, err = clashVMess.StreamWebsocketConn(ctx, c, wsOpts)
case "http":
// readability first, so just copy default TLS logic
if v.option.TLS {
@ -153,7 +153,7 @@ func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
if v.option.ServerName != "" {
tlsOpts.Host = v.option.ServerName
}
c, err = clashVMess.StreamTLSConn(c, tlsOpts)
c, err = clashVMess.StreamTLSConn(ctx, c, tlsOpts)
if err != nil {
return nil, err
}
@ -182,7 +182,7 @@ func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
tlsOpts.Host = v.option.ServerName
}
c, err = clashVMess.StreamTLSConn(c, &tlsOpts)
c, err = clashVMess.StreamTLSConn(ctx, c, &tlsOpts)
if err != nil {
return nil, err
}
@ -210,7 +210,7 @@ func (v *Vmess) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
tlsOpts.Host = v.option.ServerName
}
c, err = clashVMess.StreamTLSConn(c, tlsOpts)
c, err = clashVMess.StreamTLSConn(ctx, c, tlsOpts)
}
}
@ -294,7 +294,7 @@ func (v *Vmess) DialContextWithDialer(ctx context.Context, dialer C.Dialer, meta
safeConnClose(c, err)
}(c)
c, err = v.StreamConn(c, metadata)
c, err = v.StreamConnContext(ctx, c, metadata)
return NewConn(c, v), err
}
@ -355,7 +355,7 @@ func (v *Vmess) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
safeConnClose(c, err)
}(c)
c, err = v.StreamConn(c, metadata)
c, err = v.StreamConnContext(ctx, c, metadata)
if err != nil {
return nil, fmt.Errorf("new vmess client error: %v", err)
}

View File

@ -499,9 +499,9 @@ func (r *refProxyAdapter) MarshalJSON() ([]byte, error) {
return nil, C.ErrNotSupport
}
func (r *refProxyAdapter) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
func (r *refProxyAdapter) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
if r.proxyAdapter != nil {
return r.proxyAdapter.StreamConn(c, metadata)
return r.proxyAdapter.StreamConnContext(ctx, c, metadata)
}
return nil, C.ErrNotSupport
}