mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-21 15:36:51 +00:00
109 lines
4.2 KiB
Go
109 lines
4.2 KiB
Go
//go:build linux
|
|
|
|
package process
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"net/netip"
|
|
"os"
|
|
"syscall"
|
|
"testing"
|
|
|
|
"github.com/sagernet/sing-box/log"
|
|
M "github.com/sagernet/sing/common/metadata"
|
|
N "github.com/sagernet/sing/common/network"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func socketInode(t *testing.T, conn syscall.Conn) uint32 {
|
|
rawConn, err := conn.SyscallConn()
|
|
require.NoError(t, err)
|
|
var inode uint32
|
|
err = rawConn.Control(func(fd uintptr) {
|
|
var stat syscall.Stat_t
|
|
require.NoError(t, syscall.Fstat(int(fd), &stat))
|
|
inode = uint32(stat.Ino)
|
|
})
|
|
require.NoError(t, err)
|
|
return inode
|
|
}
|
|
|
|
func TestDumpSocketDiagTCP(t *testing.T) {
|
|
t.Parallel()
|
|
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
|
require.NoError(t, err)
|
|
defer listener.Close()
|
|
first, err := (&net.Dialer{LocalAddr: &net.TCPAddr{IP: net.IPv4(127, 0, 0, 2)}}).Dial("tcp", listener.Addr().String())
|
|
require.NoError(t, err)
|
|
defer first.Close()
|
|
second, err := (&net.Dialer{LocalAddr: &net.TCPAddr{IP: net.IPv4(127, 0, 0, 3), Port: int(M.AddrPortFromNet(first.LocalAddr()).Port())}}).Dial("tcp", listener.Addr().String())
|
|
require.NoError(t, err)
|
|
defer second.Close()
|
|
destination := M.AddrPortFromNet(listener.Addr())
|
|
for _, conn := range []net.Conn{second, first} {
|
|
inode, uid, err := dumpSocketDiag(syscall.AF_INET, syscall.IPPROTO_TCP, M.AddrPortFromNet(conn.LocalAddr()), destination)
|
|
require.NoError(t, err)
|
|
require.Equal(t, socketInode(t, conn.(syscall.Conn)), inode)
|
|
require.Equal(t, uint32(os.Getuid()), uid)
|
|
inode, _, err = dumpSocketDiag(syscall.AF_INET, syscall.IPPROTO_TCP, M.AddrPortFromNet(conn.LocalAddr()), netip.AddrPort{})
|
|
require.NoError(t, err)
|
|
require.Equal(t, socketInode(t, conn.(syscall.Conn)), inode)
|
|
}
|
|
_, _, err = dumpSocketDiag(syscall.AF_INET, syscall.IPPROTO_TCP, netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 4}), M.AddrPortFromNet(first.LocalAddr()).Port()), destination)
|
|
require.ErrorIs(t, err, ErrNotFound)
|
|
}
|
|
|
|
func TestDumpSocketDiagUDP(t *testing.T) {
|
|
t.Parallel()
|
|
first, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 2)})
|
|
require.NoError(t, err)
|
|
defer first.Close()
|
|
port := M.AddrPortFromNet(first.LocalAddr()).Port()
|
|
second, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 3), Port: int(port)})
|
|
require.NoError(t, err)
|
|
defer second.Close()
|
|
for _, conn := range []*net.UDPConn{second, first} {
|
|
inode, _, err := dumpSocketDiag(syscall.AF_INET, syscall.IPPROTO_UDP, M.AddrPortFromNet(conn.LocalAddr()), netip.AddrPort{})
|
|
require.NoError(t, err)
|
|
require.Equal(t, socketInode(t, conn), inode)
|
|
}
|
|
_, _, err = dumpSocketDiag(syscall.AF_INET, syscall.IPPROTO_UDP, netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 4}), port), netip.AddrPort{})
|
|
require.ErrorIs(t, err, ErrNotFound)
|
|
|
|
wildcard, err := net.ListenUDP("udp4", &net.UDPAddr{})
|
|
require.NoError(t, err)
|
|
defer wildcard.Close()
|
|
inode, _, err := dumpSocketDiag(syscall.AF_INET, syscall.IPPROTO_UDP, netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 4}), M.AddrPortFromNet(wildcard.LocalAddr()).Port()), netip.AddrPort{})
|
|
require.NoError(t, err)
|
|
require.Equal(t, socketInode(t, wildcard), inode)
|
|
}
|
|
|
|
func TestLinuxSearcherFindProcessInfo(t *testing.T) {
|
|
t.Parallel()
|
|
searcher, err := NewSearcher(Config{Logger: log.NewNOPFactory().NewLogger("test")})
|
|
require.NoError(t, err)
|
|
defer searcher.Close()
|
|
executable, err := os.Executable()
|
|
require.NoError(t, err)
|
|
|
|
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
|
require.NoError(t, err)
|
|
defer listener.Close()
|
|
tcpConn, err := net.Dial("tcp", listener.Addr().String())
|
|
require.NoError(t, err)
|
|
defer tcpConn.Close()
|
|
info, err := searcher.FindProcessInfo(context.Background(), N.NetworkTCP, M.AddrPortFromNet(tcpConn.LocalAddr()), M.AddrPortFromNet(listener.Addr()))
|
|
require.NoError(t, err)
|
|
require.Equal(t, executable, info.ProcessPath)
|
|
require.Equal(t, int32(os.Getuid()), info.UserId)
|
|
|
|
udpConn, err := net.ListenUDP("udp4", &net.UDPAddr{})
|
|
require.NoError(t, err)
|
|
defer udpConn.Close()
|
|
info, err = searcher.FindProcessInfo(context.Background(), N.NetworkUDP, netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 1}), M.AddrPortFromNet(udpConn.LocalAddr()).Port()), netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 1}), 53))
|
|
require.NoError(t, err)
|
|
require.Equal(t, executable, info.ProcessPath)
|
|
}
|