Skip to content

Commit

Permalink
Merge branch 'MetaCubeX:Alpha' into Alpha
Browse files Browse the repository at this point in the history
  • Loading branch information
xishang0128 authored Nov 17, 2024
2 parents 293f5ac + de19f92 commit 542059d
Show file tree
Hide file tree
Showing 139 changed files with 2,845 additions and 1,731 deletions.
21 changes: 19 additions & 2 deletions adapter/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"net/netip"
"net/url"
"strconv"
"strings"
"time"

"github.com/metacubex/mihomo/common/atomic"
Expand All @@ -18,6 +19,7 @@ import (
"github.com/metacubex/mihomo/component/ca"
"github.com/metacubex/mihomo/component/dialer"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/log"
"github.com/puzpuzpuz/xsync/v3"
)

Expand All @@ -39,6 +41,11 @@ type Proxy struct {
extra *xsync.MapOf[string, *internalProxyState]
}

// Adapter implements C.Proxy
func (p *Proxy) Adapter() C.ProxyAdapter {
return p.ProxyAdapter
}

// AliveForTestUrl implements C.Proxy
func (p *Proxy) AliveForTestUrl(url string) bool {
if state, ok := p.extra.Load(url); ok {
Expand Down Expand Up @@ -158,6 +165,8 @@ func (p *Proxy) MarshalJSON() ([]byte, error) {
mapping["udp"] = p.SupportUDP()
mapping["xudp"] = p.SupportXUDP()
mapping["tfo"] = p.SupportTFO()
mapping["mptcp"] = p.SupportMPTCP()
mapping["smux"] = p.SupportSMUX()
return json.Marshal(mapping)
}

Expand Down Expand Up @@ -255,10 +264,18 @@ func (p *Proxy) URLTest(ctx context.Context, url string, expectedStatus utils.In

if unifiedDelay {
second := time.Now()
resp, err = client.Do(req)
if err == nil {
var ignoredErr error
var secondResp *http.Response
secondResp, ignoredErr = client.Do(req)
if ignoredErr == nil {
resp = secondResp
_ = resp.Body.Close()
start = second
} else {
if strings.HasPrefix(url, "http://") {
log.Errorln("%s failed to get the second response from %s: %v", p.Name(), url, ignoredErr)
log.Warnln("It is recommended to use HTTPS for provider.health-check.url and group.url to ensure better reliability. Due to some proxy providers hijacking test addresses and not being compatible with repeated HEAD requests, using HTTP may result in failed tests.")
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions adapter/inbound/https.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
func NewHTTPS(request *http.Request, conn net.Conn, additions ...Addition) (net.Conn, *C.Metadata) {
metadata := parseHTTPAddr(request)
metadata.Type = C.HTTPS
metadata.RawSrcAddr = conn.RemoteAddr()
metadata.RawDstAddr = conn.LocalAddr()
ApplyAdditions(metadata, WithSrcAddr(conn.RemoteAddr()), WithInAddr(conn.LocalAddr()))
ApplyAdditions(metadata, additions...)
return conn, metadata
Expand Down
22 changes: 22 additions & 0 deletions adapter/inbound/listen.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package inbound
import (
"context"
"net"
"sync"

"github.com/metacubex/mihomo/component/keepalive"

"github.com/metacubex/tfo-go"
)
Expand All @@ -11,28 +14,47 @@ var (
lc = tfo.ListenConfig{
DisableTFO: true,
}
mutex sync.RWMutex
)

func SetTfo(open bool) {
mutex.Lock()
defer mutex.Unlock()
lc.DisableTFO = !open
}

func Tfo() bool {
mutex.RLock()
defer mutex.RUnlock()
return !lc.DisableTFO
}

func SetMPTCP(open bool) {
mutex.Lock()
defer mutex.Unlock()
setMultiPathTCP(&lc.ListenConfig, open)
}

func MPTCP() bool {
mutex.RLock()
defer mutex.RUnlock()
return getMultiPathTCP(&lc.ListenConfig)
}

func ListenContext(ctx context.Context, network, address string) (net.Listener, error) {
mutex.RLock()
defer mutex.RUnlock()
return lc.Listen(ctx, network, address)
}

func Listen(network, address string) (net.Listener, error) {
return ListenContext(context.Background(), network, address)
}

func init() {
keepalive.SetDisableKeepAliveCallback.Register(func(b bool) {
mutex.Lock()
defer mutex.Unlock()
keepalive.SetNetListenConfig(&lc.ListenConfig)
})
}
14 changes: 14 additions & 0 deletions adapter/inbound/listen_notwindows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//go:build !windows

package inbound

import (
"net"
"os"
)

const SupportNamedPipe = false

func ListenNamedPipe(path string) (net.Listener, error) {
return nil, os.ErrInvalid
}
32 changes: 32 additions & 0 deletions adapter/inbound/listen_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package inbound

import (
"net"
"os"

"github.com/metacubex/wireguard-go/ipc/namedpipe"
"golang.org/x/sys/windows"
)

const SupportNamedPipe = true

// windowsSDDL is the Security Descriptor set on the namedpipe.
// It provides read/write access to all users and the local system.
const windowsSDDL = "D:PAI(A;OICI;GWGR;;;BU)(A;OICI;GWGR;;;SY)"

func ListenNamedPipe(path string) (net.Listener, error) {
sddl := os.Getenv("LISTEN_NAMEDPIPE_SDDL")
if sddl == "" {
sddl = windowsSDDL
}
securityDescriptor, err := windows.SecurityDescriptorFromString(sddl)
if err != nil {
return nil, err
}
namedpipeLC := namedpipe.ListenConfig{
SecurityDescriptor: securityDescriptor,
InputBufferSize: 256 * 1024,
OutputBufferSize: 256 * 1024,
}
return namedpipeLC.Listen(path)
}
10 changes: 10 additions & 0 deletions adapter/outbound/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ func (b *Base) SupportTFO() bool {
return b.tfo
}

// SupportMPTCP implements C.ProxyAdapter
func (b *Base) SupportMPTCP() bool {
return b.mpTcp
}

// SupportSMUX implements C.ProxyAdapter
func (b *Base) SupportSMUX() bool {
return false
}

// IsL3Protocol implements C.ProxyAdapter
func (b *Base) IsL3Protocol(metadata *C.Metadata) bool {
return false
Expand Down
24 changes: 6 additions & 18 deletions adapter/outbound/direct.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,12 @@ package outbound
import (
"context"
"errors"
"os"
"strconv"

N "github.com/metacubex/mihomo/common/net"
"github.com/metacubex/mihomo/component/dialer"
"github.com/metacubex/mihomo/component/loopback"
"github.com/metacubex/mihomo/component/resolver"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/constant/features"
)

var DisableLoopBackDetector, _ = strconv.ParseBool(os.Getenv("DISABLE_LOOPBACK_DETECTOR"))

type Direct struct {
*Base
loopBack *loopback.Detector
Expand All @@ -28,30 +21,25 @@ type DirectOption struct {

// DialContext implements C.ProxyAdapter
func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) {
if !features.CMFA && !DisableLoopBackDetector {
if err := d.loopBack.CheckConn(metadata); err != nil {
return nil, err
}
if err := d.loopBack.CheckConn(metadata); err != nil {
return nil, err
}
opts = append(opts, dialer.WithResolver(resolver.DefaultResolver))
opts = append(opts, dialer.WithResolver(resolver.DirectHostResolver))
c, err := dialer.DialContext(ctx, "tcp", metadata.RemoteAddress(), d.Base.DialOptions(opts...)...)
if err != nil {
return nil, err
}
N.TCPKeepAlive(c)
return d.loopBack.NewConn(NewConn(c, d)), nil
}

// ListenPacketContext implements C.ProxyAdapter
func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
if !features.CMFA && !DisableLoopBackDetector {
if err := d.loopBack.CheckPacketConn(metadata); err != nil {
return nil, err
}
if err := d.loopBack.CheckPacketConn(metadata); err != nil {
return nil, err
}
// net.UDPConn.WriteTo only working with *net.UDPAddr, so we need a net.UDPAddr
if !metadata.Resolved() {
ip, err := resolver.ResolveIPWithResolver(ctx, metadata.Host, resolver.DefaultResolver)
ip, err := resolver.ResolveIPWithResolver(ctx, metadata.Host, resolver.DirectHostResolver)
if err != nil {
return nil, errors.New("can't resolve ip")
}
Expand Down
3 changes: 0 additions & 3 deletions adapter/outbound/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ import (
"encoding/base64"
"errors"
"fmt"

"io"
"net"
"net/http"
"strconv"

N "github.com/metacubex/mihomo/common/net"
"github.com/metacubex/mihomo/component/ca"
"github.com/metacubex/mihomo/component/dialer"
"github.com/metacubex/mihomo/component/proxydialer"
Expand Down Expand Up @@ -76,7 +74,6 @@ func (h *Http) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metad
if err != nil {
return nil, fmt.Errorf("%s connect error: %w", h.addr, err)
}
N.TCPKeepAlive(c)

defer func(c net.Conn) {
safeConnClose(c, err)
Expand Down
14 changes: 5 additions & 9 deletions adapter/outbound/hysteria.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (h *Hysteria) ListenPacketContext(ctx context.Context, metadata *C.Metadata
func (h *Hysteria) genHdc(ctx context.Context, opts ...dialer.Option) utils.PacketDialer {
return &hyDialerWithContext{
ctx: context.Background(),
hyDialer: func(network string) (net.PacketConn, error) {
hyDialer: func(network string, rAddr net.Addr) (net.PacketConn, error) {
var err error
var cDialer C.Dialer = dialer.NewDialer(h.Base.DialOptions(opts...)...)
if len(h.option.DialerProxy) > 0 {
Expand All @@ -78,7 +78,7 @@ func (h *Hysteria) genHdc(ctx context.Context, opts ...dialer.Option) utils.Pack
return nil, err
}
}
rAddrPort, _ := netip.ParseAddrPort(h.Addr())
rAddrPort, _ := netip.ParseAddrPort(rAddr.String())
return cDialer.ListenPacket(ctx, network, "", rAddrPort)
},
remoteAddr: func(addr string) (net.Addr, error) {
Expand Down Expand Up @@ -131,11 +131,7 @@ func (c *HysteriaOption) Speed() (uint64, uint64, error) {
}

func NewHysteria(option HysteriaOption) (*Hysteria, error) {
clientTransport := &transport.ClientTransport{
Dialer: &net.Dialer{
Timeout: 8 * time.Second,
},
}
clientTransport := &transport.ClientTransport{}
addr := net.JoinHostPort(option.Server, strconv.Itoa(option.Port))
ports := option.Ports

Expand Down Expand Up @@ -284,7 +280,7 @@ func (c *hyPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
}

type hyDialerWithContext struct {
hyDialer func(network string) (net.PacketConn, error)
hyDialer func(network string, rAddr net.Addr) (net.PacketConn, error)
ctx context.Context
remoteAddr func(host string) (net.Addr, error)
}
Expand All @@ -294,7 +290,7 @@ func (h *hyDialerWithContext) ListenPacket(rAddr net.Addr) (net.PacketConn, erro
if addrPort, err := netip.ParseAddrPort(rAddr.String()); err == nil {
network = dialer.ParseNetwork(network, addrPort.Addr())
}
return h.hyDialer(network)
return h.hyDialer(network, rAddr)
}

func (h *hyDialerWithContext) Context() context.Context {
Expand Down
2 changes: 1 addition & 1 deletion adapter/outbound/reject.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func NewRejectWithOption(option RejectOption) *Reject {
return &Reject{
Base: &Base{
name: option.Name,
tp: C.Direct,
tp: C.Reject,
udp: true,
},
}
Expand Down
1 change: 0 additions & 1 deletion adapter/outbound/shadowsocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ func (ss *ShadowSocks) DialContextWithDialer(ctx context.Context, dialer C.Diale
if err != nil {
return nil, fmt.Errorf("%s connect error: %w", ss.addr, err)
}
N.TCPKeepAlive(c)

defer func(c net.Conn) {
safeConnClose(c, err)
Expand Down
1 change: 0 additions & 1 deletion adapter/outbound/shadowsocksr.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ func (ssr *ShadowSocksR) DialContextWithDialer(ctx context.Context, dialer C.Dia
if err != nil {
return nil, fmt.Errorf("%s connect error: %w", ssr.addr, err)
}
N.TCPKeepAlive(c)

defer func(c net.Conn) {
safeConnClose(c, err)
Expand Down
4 changes: 4 additions & 0 deletions adapter/outbound/singmux.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ func (s *SingMux) SupportUOT() bool {
return true
}

func (s *SingMux) SupportSMUX() bool {
return true
}

func closeSingMux(s *SingMux) {
_ = s.client.Close()
}
Expand Down
6 changes: 1 addition & 5 deletions adapter/outbound/snell.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"net"
"strconv"

N "github.com/metacubex/mihomo/common/net"
"github.com/metacubex/mihomo/common/structure"
"github.com/metacubex/mihomo/component/dialer"
"github.com/metacubex/mihomo/component/proxydialer"
Expand Down Expand Up @@ -94,7 +93,6 @@ func (s *Snell) DialContextWithDialer(ctx context.Context, dialer C.Dialer, meta
if err != nil {
return nil, fmt.Errorf("%s connect error: %w", s.addr, err)
}
N.TCPKeepAlive(c)

defer func(c net.Conn) {
safeConnClose(c, err)
Expand Down Expand Up @@ -122,7 +120,6 @@ func (s *Snell) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
if err != nil {
return nil, err
}
N.TCPKeepAlive(c)
c = streamConn(c, streamOption{s.psk, s.version, s.addr, s.obfsOption})

err = snell.WriteUDPHeader(c, s.version)
Expand Down Expand Up @@ -207,8 +204,7 @@ func NewSnell(option SnellOption) (*Snell, error) {
if err != nil {
return nil, err
}

N.TCPKeepAlive(c)

return streamConn(c, streamOption{psk, option.Version, addr, obfsOption}), nil
})
}
Expand Down
Loading

0 comments on commit 542059d

Please sign in to comment.