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 Jun 5, 2024
2 parents 6098b8a + 063836f commit 5ac2257
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 26 deletions.
54 changes: 39 additions & 15 deletions component/process/process_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@ package process

import (
"bytes"
"context"
"encoding/binary"
"fmt"
"net/netip"
"os"
"path"
"path/filepath"
"runtime"
"strings"
"sync"
"syscall"
"unicode"
"unsafe"

"github.com/metacubex/mihomo/log"

"github.com/mdlayher/netlink"
tun "github.com/metacubex/sing-tun"
"golang.org/x/sys/unix"
)

Expand Down Expand Up @@ -59,6 +63,19 @@ type inetDiagResponse struct {
INode uint32
}

type MyCallback struct{}

var (
packageManager tun.PackageManager
once sync.Once
)

func (cb *MyCallback) OnPackagesUpdated(packageCount int, sharedCount int) {}

func (cb *MyCallback) NewError(ctx context.Context, err error) {
log.Warnln("%s", err)
}

func findProcessName(network string, ip netip.Addr, srcPort int) (uint32, string, error) {
uid, inode, err := resolveSocketByNetlink(network, ip, srcPort)
if err != nil {
Expand Down Expand Up @@ -162,12 +179,7 @@ func resolveProcessNameByProcSearch(inode, uid uint32) (string, error) {
}
if runtime.GOOS == "android" {
if bytes.Equal(buffer[:n], socket) {
cmdline, err := os.ReadFile(path.Join(processPath, "cmdline"))
if err != nil {
return "", err
}

return splitCmdline(cmdline), nil
return findPackageName(uid), nil
}
} else {
if bytes.Equal(buffer[:n], socket) {
Expand All @@ -181,17 +193,29 @@ func resolveProcessNameByProcSearch(inode, uid uint32) (string, error) {
return "", fmt.Errorf("process of uid(%d),inode(%d) not found", uid, inode)
}

func splitCmdline(cmdline []byte) string {
cmdline = bytes.Trim(cmdline, " ")

idx := bytes.IndexFunc(cmdline, func(r rune) bool {
return unicode.IsControl(r) || unicode.IsSpace(r) || r == ':'
func findPackageName(uid uint32) string {
once.Do(func() {
callback := &MyCallback{}
var err error
packageManager, err = tun.NewPackageManager(callback)
if err != nil {
log.Warnln("%s", err)
}
err = packageManager.Start()
if err != nil {
log.Warnln("%s", err)
return
}
})

if idx == -1 {
return filepath.Base(string(cmdline))
if sharedPackage, loaded := packageManager.SharedPackageByID(uid % 100000); loaded {
fmt.Println(loaded)
return sharedPackage
}
if packageName, loaded := packageManager.PackageByID(uid % 100000); loaded {
return packageName
}
return filepath.Base(string(cmdline[:idx]))
return ""
}

func isPid(s string) bool {
Expand Down
11 changes: 7 additions & 4 deletions listener/sing_tun/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/ranges"
"golang.org/x/exp/slices"
)

var InterfaceName = "Meta"
Expand Down Expand Up @@ -60,19 +61,21 @@ func CalculateInterfaceName(name string) (tunName string) {
return
}
tunIndex := 0
indexSet := make(map[int]struct{})
indexArr := make([]int, 0, len(interfaces))
for _, netInterface := range interfaces {
if strings.HasPrefix(netInterface.Name, tunName) {
index, parseErr := strconv.ParseInt(netInterface.Name[len(tunName):], 10, 16)
if parseErr == nil {
indexSet[int(index)] = struct{}{}
indexArr = append(indexArr, int(index))
}
}
}
for index := range indexSet {
slices.Sort(indexArr)
indexArr = slices.Compact(indexArr)
for _, index := range indexArr {
if index == tunIndex {
tunIndex += 1
} else { // indexSet already sorted and distinct, so this tunIndex nobody used
} else { // indexArr already sorted and distinct, so this tunIndex nobody used
break
}
}
Expand Down
13 changes: 6 additions & 7 deletions transport/tuic/congestion_v2/bbr_sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const (
// Flag.
defaultStartupFullLossCount = 8
quicBbr2DefaultLossThreshold = 0.02
maxBbrBurstPackets = 3
maxBbrBurstPackets = 10
)

type bbrMode int
Expand Down Expand Up @@ -334,6 +334,8 @@ func (b *bbrSender) OnPacketSent(
}

b.sampler.OnPacketSent(sentTime, packetNumber, bytes, bytesInFlight, isRetransmittable)

b.maybeAppLimited(bytesInFlight)
}

// CanSend implements the SendAlgorithm interface.
Expand Down Expand Up @@ -413,8 +415,6 @@ func (b *bbrSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, even
// packet in lost_packets.
var lastPacketSendState sendTimeState

b.maybeApplimited(priorInFlight)

// Update bytesInFlight
b.bytesInFlight = priorInFlight
for _, p := range ackedPackets {
Expand Down Expand Up @@ -541,7 +541,7 @@ func (b *bbrSender) setDrainGain(drainGain float64) {
b.drainGain = drainGain
}

// What's the current estimated bandwidth in bytes per second.
// Get the current bandwidth estimate. Note that Bandwidth is in bits per second.
func (b *bbrSender) bandwidthEstimate() Bandwidth {
return b.maxBandwidth.GetBest()
}
Expand Down Expand Up @@ -700,14 +700,13 @@ func (b *bbrSender) checkIfFullBandwidthReached(lastPacketSendState *sendTimeSta
}
}

func (b *bbrSender) maybeApplimited(bytesInFlight congestion.ByteCount) {
func (b *bbrSender) maybeAppLimited(bytesInFlight congestion.ByteCount) {
congestionWindow := b.GetCongestionWindow()
if bytesInFlight >= congestionWindow {
return
}
availableBytes := congestionWindow - bytesInFlight
drainLimited := b.mode == bbrModeDrain && bytesInFlight > congestionWindow/2
if !drainLimited || availableBytes > maxBbrBurstPackets*b.maxDatagramSize {
if availableBytes > maxBbrBurstPackets*b.maxDatagramSize {
b.sampler.OnAppLimited()
}
}
Expand Down

0 comments on commit 5ac2257

Please sign in to comment.