Add requests page Fix checkUpdate dark mode style error Fix quickStart error open app Add memory proxies tab index Support hidden group Optimize logs
172 lines
2.7 KiB
Go
172 lines
2.7 KiB
Go
//go:build android
|
|
|
|
package platform
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/binary"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"unsafe"
|
|
)
|
|
|
|
var netIndexOfLocal = -1
|
|
var netIndexOfUid = -1
|
|
|
|
var nativeEndian binary.ByteOrder
|
|
|
|
func QuerySocketUidFromProcFs(source, _ net.Addr) int {
|
|
if netIndexOfLocal < 0 || netIndexOfUid < 0 {
|
|
return -1
|
|
}
|
|
|
|
network := source.Network()
|
|
|
|
if strings.HasSuffix(network, "4") || strings.HasSuffix(network, "6") {
|
|
network = network[:len(network)-1]
|
|
}
|
|
|
|
path := "/proc/net/" + network
|
|
|
|
var sIP net.IP
|
|
var sPort int
|
|
|
|
switch s := source.(type) {
|
|
case *net.TCPAddr:
|
|
sIP = s.IP
|
|
sPort = s.Port
|
|
case *net.UDPAddr:
|
|
sIP = s.IP
|
|
sPort = s.Port
|
|
default:
|
|
return -1
|
|
}
|
|
|
|
sIP = sIP.To16()
|
|
if sIP == nil {
|
|
return -1
|
|
}
|
|
|
|
uid := doQuery(path+"6", sIP, sPort)
|
|
if uid == -1 {
|
|
sIP = sIP.To4()
|
|
if sIP == nil {
|
|
return -1
|
|
}
|
|
uid = doQuery(path, sIP, sPort)
|
|
}
|
|
|
|
return uid
|
|
}
|
|
|
|
func doQuery(path string, sIP net.IP, sPort int) int {
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return -1
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
reader := bufio.NewReader(file)
|
|
|
|
var bytes [2]byte
|
|
|
|
binary.BigEndian.PutUint16(bytes[:], uint16(sPort))
|
|
|
|
local := fmt.Sprintf("%s:%s", hex.EncodeToString(nativeEndianIP(sIP)), hex.EncodeToString(bytes[:]))
|
|
|
|
for {
|
|
row, _, err := reader.ReadLine()
|
|
if err != nil {
|
|
return -1
|
|
}
|
|
|
|
fields := strings.Fields(string(row))
|
|
|
|
if len(fields) <= netIndexOfLocal || len(fields) <= netIndexOfUid {
|
|
continue
|
|
}
|
|
|
|
if strings.EqualFold(local, fields[netIndexOfLocal]) {
|
|
uid, err := strconv.Atoi(fields[netIndexOfUid])
|
|
if err != nil {
|
|
return -1
|
|
}
|
|
|
|
return uid
|
|
}
|
|
}
|
|
}
|
|
|
|
func nativeEndianIP(ip net.IP) []byte {
|
|
result := make([]byte, len(ip))
|
|
|
|
for i := 0; i < len(ip); i += 4 {
|
|
value := binary.BigEndian.Uint32(ip[i:])
|
|
|
|
nativeEndian.PutUint32(result[i:], value)
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func init() {
|
|
file, err := os.Open("/proc/net/tcp")
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
reader := bufio.NewReader(file)
|
|
|
|
header, _, err := reader.ReadLine()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
columns := strings.Fields(string(header))
|
|
|
|
var txQueue, rxQueue, tr, tmWhen bool
|
|
|
|
for idx, col := range columns {
|
|
offset := 0
|
|
|
|
if txQueue && rxQueue {
|
|
offset--
|
|
}
|
|
|
|
if tr && tmWhen {
|
|
offset--
|
|
}
|
|
|
|
switch col {
|
|
case "tx_queue":
|
|
txQueue = true
|
|
case "rx_queue":
|
|
rxQueue = true
|
|
case "tr":
|
|
tr = true
|
|
case "tm->when":
|
|
tmWhen = true
|
|
case "local_address":
|
|
netIndexOfLocal = idx + offset
|
|
case "uid":
|
|
netIndexOfUid = idx + offset
|
|
}
|
|
}
|
|
}
|
|
|
|
func init() {
|
|
var x uint32 = 0x01020304
|
|
if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
|
|
nativeEndian = binary.BigEndian
|
|
} else {
|
|
nativeEndian = binary.LittleEndian
|
|
}
|
|
}
|