mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-03 03:47:38 +03:00
Improve interface finder
This commit is contained in:
parent
2fa039945c
commit
eec2fc325a
5 changed files with 119 additions and 24 deletions
|
@ -1,30 +1,18 @@
|
|||
package control
|
||||
|
||||
import "net"
|
||||
import (
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
type InterfaceFinder interface {
|
||||
InterfaceIndexByName(name string) (int, error)
|
||||
InterfaceNameByIndex(index int) (string, error)
|
||||
InterfaceByAddr(addr netip.Addr) (*Interface, error)
|
||||
}
|
||||
|
||||
func DefaultInterfaceFinder() InterfaceFinder {
|
||||
return (*netInterfaceFinder)(nil)
|
||||
}
|
||||
|
||||
type netInterfaceFinder struct{}
|
||||
|
||||
func (w *netInterfaceFinder) InterfaceIndexByName(name string) (int, error) {
|
||||
netInterface, err := net.InterfaceByName(name)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return netInterface.Index, nil
|
||||
}
|
||||
|
||||
func (w *netInterfaceFinder) InterfaceNameByIndex(index int) (string, error) {
|
||||
netInterface, err := net.InterfaceByIndex(index)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return netInterface.Name, nil
|
||||
type Interface struct {
|
||||
Index int
|
||||
MTU int
|
||||
Name string
|
||||
Addresses []netip.Prefix
|
||||
}
|
||||
|
|
97
common/control/bind_finder_default.go
Normal file
97
common/control/bind_finder_default.go
Normal file
|
@ -0,0 +1,97 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
_ "unsafe"
|
||||
|
||||
"github.com/sagernet/sing/common"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
)
|
||||
|
||||
type DefaultInterfaceFinder struct {
|
||||
interfaces []Interface
|
||||
}
|
||||
|
||||
func NewDefaultInterfaceFinder() *DefaultInterfaceFinder {
|
||||
return &DefaultInterfaceFinder{}
|
||||
}
|
||||
|
||||
func (f *DefaultInterfaceFinder) Update() error {
|
||||
netIfs, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
interfaces := make([]Interface, 0, len(netIfs))
|
||||
for _, netIf := range netIfs {
|
||||
ifAddrs, err := netIf.Addrs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
interfaces = append(interfaces, Interface{
|
||||
Index: netIf.Index,
|
||||
MTU: netIf.MTU,
|
||||
Name: netIf.Name,
|
||||
Addresses: common.Map(ifAddrs, M.PrefixFromNet),
|
||||
})
|
||||
}
|
||||
f.interfaces = interfaces
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *DefaultInterfaceFinder) UpdateInterfaces(interfaces []Interface) {
|
||||
f.interfaces = interfaces
|
||||
}
|
||||
|
||||
func (f *DefaultInterfaceFinder) InterfaceIndexByName(name string) (int, error) {
|
||||
for _, netInterface := range f.interfaces {
|
||||
if netInterface.Name == name {
|
||||
return netInterface.Index, nil
|
||||
}
|
||||
}
|
||||
netInterface, err := net.InterfaceByName(name)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
f.Update()
|
||||
return netInterface.Index, nil
|
||||
}
|
||||
|
||||
func (f *DefaultInterfaceFinder) InterfaceNameByIndex(index int) (string, error) {
|
||||
for _, netInterface := range f.interfaces {
|
||||
if netInterface.Index == index {
|
||||
return netInterface.Name, nil
|
||||
}
|
||||
}
|
||||
netInterface, err := net.InterfaceByIndex(index)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
f.Update()
|
||||
return netInterface.Name, nil
|
||||
}
|
||||
|
||||
//go:linkname errNoSuchInterface net.errNoSuchInterface
|
||||
var errNoSuchInterface error
|
||||
|
||||
func (f *DefaultInterfaceFinder) InterfaceByAddr(addr netip.Addr) (*Interface, error) {
|
||||
for _, netInterface := range f.interfaces {
|
||||
for _, prefix := range netInterface.Addresses {
|
||||
if prefix.Contains(addr) {
|
||||
return &netInterface, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
err := f.Update()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, netInterface := range f.interfaces {
|
||||
for _, prefix := range netInterface.Addresses {
|
||||
if prefix.Contains(addr) {
|
||||
return &netInterface, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, &net.OpError{Op: "route", Net: "ip+net", Source: nil, Addr: &net.IPAddr{IP: addr.AsSlice()}, Err: errNoSuchInterface}
|
||||
}
|
|
@ -141,7 +141,7 @@ func SocksaddrFromNet(ap net.Addr) Socksaddr {
|
|||
return ParseSocksaddr(ap.String())
|
||||
}
|
||||
|
||||
func AddrFromNetAddr(netAddr net.Addr) netip.Addr {
|
||||
func AddrFromNet(netAddr net.Addr) netip.Addr {
|
||||
if addr := AddrPortFromNet(netAddr); addr.Addr().IsValid() {
|
||||
return addr.Addr()
|
||||
}
|
||||
|
@ -157,6 +157,16 @@ func AddrFromNetAddr(netAddr net.Addr) netip.Addr {
|
|||
}
|
||||
}
|
||||
|
||||
func PrefixFromNet(netAddr net.Addr) netip.Prefix {
|
||||
switch addr := netAddr.(type) {
|
||||
case *net.IPNet:
|
||||
bits, _ := addr.Mask.Size()
|
||||
return netip.PrefixFrom(AddrFromIP(addr.IP), bits)
|
||||
default:
|
||||
return netip.Prefix{}
|
||||
}
|
||||
}
|
||||
|
||||
func AddrPortFromNet(netAddr net.Addr) netip.AddrPort {
|
||||
var ip net.IP
|
||||
var port uint16
|
||||
|
|
|
@ -13,7 +13,7 @@ func LocalAddrs() ([]netip.Addr, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return common.Map(interfaceAddrs, M.AddrFromNetAddr), nil
|
||||
return common.Map(interfaceAddrs, M.AddrFromNet), nil
|
||||
}
|
||||
|
||||
func IsPublicAddr(addr netip.Addr) bool {
|
||||
|
|
|
@ -203,7 +203,7 @@ func HandleConnection0(ctx context.Context, conn net.Conn, version byte, authent
|
|||
return handler.NewConnection(ctx, conn, metadata)
|
||||
case socks5.CommandUDPAssociate:
|
||||
var udpConn *net.UDPConn
|
||||
udpConn, err = net.ListenUDP(M.NetworkFromNetAddr("udp", M.AddrFromNetAddr(conn.LocalAddr())), net.UDPAddrFromAddrPort(netip.AddrPortFrom(M.AddrFromNetAddr(conn.LocalAddr()), 0)))
|
||||
udpConn, err = net.ListenUDP(M.NetworkFromNetAddr("udp", M.AddrFromNet(conn.LocalAddr())), net.UDPAddrFromAddrPort(netip.AddrPortFrom(M.AddrFromNet(conn.LocalAddr()), 0)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue