Skip to content

Commit

Permalink
Merge branch 'Alpha' into Meta
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] committed Jul 1, 2024
2 parents 48e481d + 0e22876 commit 4277dc6
Show file tree
Hide file tree
Showing 92 changed files with 1,693 additions and 945 deletions.
69 changes: 44 additions & 25 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ on:
branches:
- Alpha
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true

env:
Expand Down Expand Up @@ -206,6 +206,10 @@ jobs:
sudo apt-get install dpkg
if [ "${{matrix.jobs.abi}}" = "1" ]; then
ARCH=loongarch64
elif [ "${{matrix.jobs.goarm}}" = "7" ]; then
ARCH=armhf
elif [ "${{matrix.jobs.goarch}}" = "arm" ]; then
ARCH=armel
else
ARCH=${{matrix.jobs.goarch}}
fi
Expand Down Expand Up @@ -270,7 +274,7 @@ jobs:
- name: Archive production artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.jobs.goos }}-${{ matrix.jobs.output }}
name: "${{ matrix.jobs.goos }}-${{ matrix.jobs.output }}"
path: |
mihomo*.gz
mihomo*.deb
Expand Down Expand Up @@ -415,35 +419,35 @@ jobs:
uses: docker/setup-buildx-action@v3
with:
version: latest

- name: Set Docker tags and labels based on trigger
id: set-meta
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "tags=${{ github.event.inputs.version }}" >> $GITHUB_ENV
echo "labels=org.opencontainers.image.version=${{ github.event.inputs.version }}" >> $GITHUB_ENV
else
echo "tags=${{ steps.meta.outputs.tags }}" >> $GITHUB_ENV
echo "labels=${{ steps.meta.outputs.labels }}" >> $GITHUB_ENV
fi

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
if: ${{ github.event_name != 'workflow_dispatch' }}
id: meta_alpha
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ github.repository }}
tags: ${{ env.tags }}
labels: ${{ env.labels }}


images: '${{ env.REGISTRY }}/${{ github.repository }}'

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version != '' }}
id: meta_release
uses: docker/metadata-action@v5
with:
images: '${{ env.REGISTRY }}/${{ github.repository }}'
tags: |
${{ github.event.inputs.version }}
flavor: |
latest=true
labels: org.opencontainers.image.version=${{ github.event.inputs.version }}

- name: Show files
run: |
ls .
ls bin/
- name: login to docker REGISTRY
uses: docker/login-action@v3
with:
Expand All @@ -454,7 +458,22 @@ jobs:
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
if: ${{ github.event_name != 'workflow_dispatch' }}
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: ${{ github.event_name != 'pull_request' }}
platforms: |
linux/386
linux/amd64
linux/arm64
linux/arm/v7
tags: ${{ steps.meta_alpha.outputs.tags }}
labels: ${{ steps.meta_alpha.outputs.labels }}

- name: Build and push Docker image
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version != '' }}
uses: docker/build-push-action@v5
with:
context: .
Expand All @@ -465,5 +484,5 @@ jobs:
linux/amd64
linux/arm64
linux/arm/v7
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.meta_release.outputs.tags }}
labels: ${{ steps.meta_release.outputs.labels }}
14 changes: 1 addition & 13 deletions adapter/inbound/listen.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,10 @@ package inbound
import (
"context"
"net"

"github.com/metacubex/tfo-go"
)

var (
lc = tfo.ListenConfig{
DisableTFO: true,
}
)

func SetTfo(open bool) {
lc.DisableTFO = !open
}

func SetMPTCP(open bool) {
setMultiPathTCP(&lc.ListenConfig, open)
setMultiPathTCP(getListenConfig(), open)
}

func ListenContext(ctx context.Context, network, address string) (net.Listener, error) {
Expand Down
23 changes: 23 additions & 0 deletions adapter/inbound/listen_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:build unix

package inbound

import (
"net"

"github.com/metacubex/tfo-go"
)

var (
lc = tfo.ListenConfig{
DisableTFO: true,
}
)

func SetTfo(open bool) {
lc.DisableTFO = !open
}

func getListenConfig() *net.ListenConfig {
return &lc.ListenConfig
}
15 changes: 15 additions & 0 deletions adapter/inbound/listen_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package inbound

import (
"net"
)

var (
lc = net.ListenConfig{}
)

func SetTfo(open bool) {}

func getListenConfig() *net.ListenConfig {
return &lc
}
24 changes: 18 additions & 6 deletions adapter/outbound/direct.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ package outbound
import (
"context"
"errors"
"net/netip"
"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 @@ -24,8 +28,10 @@ type DirectOption struct {

// DialContext implements C.ProxyAdapter
func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) {
if err := d.loopBack.CheckConn(metadata); err != nil {
return nil, err
if !features.CMFA && !DisableLoopBackDetector {
if err := d.loopBack.CheckConn(metadata); err != nil {
return nil, err
}
}
opts = append(opts, dialer.WithResolver(resolver.DefaultResolver))
c, err := dialer.DialContext(ctx, "tcp", metadata.RemoteAddress(), d.Base.DialOptions(opts...)...)
Expand All @@ -38,8 +44,10 @@ func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...

// ListenPacketContext implements C.ProxyAdapter
func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
if err := d.loopBack.CheckPacketConn(metadata); err != nil {
return nil, err
if !features.CMFA && !DisableLoopBackDetector {
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() {
Expand All @@ -49,13 +57,17 @@ func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata,
}
metadata.DstIP = ip
}
pc, err := dialer.NewDialer(d.Base.DialOptions(opts...)...).ListenPacket(ctx, "udp", "", netip.AddrPortFrom(metadata.DstIP, metadata.DstPort))
pc, err := dialer.NewDialer(d.Base.DialOptions(opts...)...).ListenPacket(ctx, "udp", "", metadata.AddrPort())
if err != nil {
return nil, err
}
return d.loopBack.NewPacketConn(newPacketConn(pc, d)), nil
}

func (d *Direct) IsL3Protocol(metadata *C.Metadata) bool {
return true // tell DNSDialer don't send domain to DialContext, avoid lookback to DefaultResolver
}

func NewDirectWithOption(option DirectOption) *Direct {
return &Direct{
Base: &Base{
Expand Down
4 changes: 2 additions & 2 deletions adapter/outbound/hysteria2.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import (

"github.com/metacubex/sing-quic/hysteria2"

"github.com/metacubex/randv2"
M "github.com/sagernet/sing/common/metadata"
"github.com/zhangyunhao116/fastrand"
)

func init() {
Expand Down Expand Up @@ -165,7 +165,7 @@ func NewHysteria2(option Hysteria2Option) (*Hysteria2, error) {
})
if len(serverAddress) > 0 {
clientOptions.ServerAddress = func(ctx context.Context) (*net.UDPAddr, error) {
return resolveUDPAddrWithPrefer(ctx, "udp", serverAddress[fastrand.Intn(len(serverAddress))], C.NewDNSPrefer(option.IPVersion))
return resolveUDPAddrWithPrefer(ctx, "udp", serverAddress[randv2.IntN(len(serverAddress))], C.NewDNSPrefer(option.IPVersion))
}

if option.HopInterval == 0 {
Expand Down
8 changes: 4 additions & 4 deletions adapter/outbound/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"github.com/metacubex/mihomo/component/proxydialer"
C "github.com/metacubex/mihomo/constant"

"github.com/zhangyunhao116/fastrand"
"github.com/metacubex/randv2"
"golang.org/x/crypto/ssh"
)

Expand Down Expand Up @@ -180,10 +180,10 @@ func NewSsh(option SshOption) (*Ssh, error) {
}

version := "SSH-2.0-OpenSSH_"
if fastrand.Intn(2) == 0 {
version += "7." + strconv.Itoa(fastrand.Intn(10))
if randv2.IntN(2) == 0 {
version += "7." + strconv.Itoa(randv2.IntN(10))
} else {
version += "8." + strconv.Itoa(fastrand.Intn(9))
version += "8." + strconv.Itoa(randv2.IntN(9))
}
config.ClientVersion = version

Expand Down
43 changes: 43 additions & 0 deletions adapter/outbound/trojan.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package outbound
import (
"context"
"crypto/tls"
"errors"
"fmt"
"net"
"net/http"
Expand All @@ -15,6 +16,7 @@ import (
tlsC "github.com/metacubex/mihomo/component/tls"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/transport/gun"
"github.com/metacubex/mihomo/transport/shadowsocks/core"
"github.com/metacubex/mihomo/transport/trojan"
)

Expand All @@ -29,6 +31,8 @@ type Trojan struct {
transport *gun.TransportWrap

realityConfig *tlsC.RealityConfig

ssCipher core.Cipher
}

type TrojanOption struct {
Expand All @@ -46,9 +50,17 @@ type TrojanOption struct {
RealityOpts RealityOptions `proxy:"reality-opts,omitempty"`
GrpcOpts GrpcOptions `proxy:"grpc-opts,omitempty"`
WSOpts WSOptions `proxy:"ws-opts,omitempty"`
SSOpts TrojanSSOption `proxy:"ss-opts,omitempty"`
ClientFingerprint string `proxy:"client-fingerprint,omitempty"`
}

// TrojanSSOption from https://github.com/p4gefau1t/trojan-go/blob/v0.10.6/tunnel/shadowsocks/config.go#L5
type TrojanSSOption struct {
Enabled bool `proxy:"enabled,omitempty"`
Method string `proxy:"method,omitempty"`
Password string `proxy:"password,omitempty"`
}

func (t *Trojan) plainStream(ctx context.Context, c net.Conn) (net.Conn, error) {
if t.option.Network == "ws" {
host, port, _ := net.SplitHostPort(t.addr)
Expand Down Expand Up @@ -95,6 +107,10 @@ func (t *Trojan) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.
return nil, fmt.Errorf("%s connect error: %w", t.addr, err)
}

if t.ssCipher != nil {
c = t.ssCipher.StreamConn(c)
}

if metadata.NetWork == C.UDP {
err = t.instance.WriteHeader(c, trojan.CommandUDP, serializesSocksAddr(metadata))
return c, err
Expand All @@ -112,6 +128,10 @@ func (t *Trojan) DialContext(ctx context.Context, metadata *C.Metadata, opts ...
return nil, err
}

if t.ssCipher != nil {
c = t.ssCipher.StreamConn(c)
}

if err = t.instance.WriteHeader(c, trojan.CommandTCP, serializesSocksAddr(metadata)); err != nil {
c.Close()
return nil, err
Expand Down Expand Up @@ -161,6 +181,11 @@ func (t *Trojan) ListenPacketContext(ctx context.Context, metadata *C.Metadata,
defer func(c net.Conn) {
safeConnClose(c, err)
}(c)

if t.ssCipher != nil {
c = t.ssCipher.StreamConn(c)
}

err = t.instance.WriteHeader(c, trojan.CommandUDP, serializesSocksAddr(metadata))
if err != nil {
return nil, err
Expand Down Expand Up @@ -193,6 +218,10 @@ func (t *Trojan) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, me
return nil, fmt.Errorf("%s connect error: %w", t.addr, err)
}

if t.ssCipher != nil {
c = t.ssCipher.StreamConn(c)
}

err = t.instance.WriteHeader(c, trojan.CommandUDP, serializesSocksAddr(metadata))
if err != nil {
return nil, err
Expand Down Expand Up @@ -257,6 +286,20 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
}
tOption.Reality = t.realityConfig

if option.SSOpts.Enabled {
if option.SSOpts.Password == "" {
return nil, errors.New("empty password")
}
if option.SSOpts.Method == "" {
option.SSOpts.Method = "AES-128-GCM"
}
ciph, err := core.PickCipher(option.SSOpts.Method, nil, option.SSOpts.Password)
if err != nil {
return nil, err
}
t.ssCipher = ciph
}

if option.Network == "grpc" {
dialFn := func(network, addr string) (net.Conn, error) {
var err error
Expand Down
Loading

0 comments on commit 4277dc6

Please sign in to comment.