Merge branch 'dev' into freebsd

This commit is contained in:
c1emon 2024-03-17 10:51:18 +08:00 committed by GitHub
commit 6837049db4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 89 additions and 75 deletions

9
go.mod
View file

@ -5,13 +5,12 @@ go 1.18
require ( require (
github.com/fsnotify/fsnotify v1.7.0 github.com/fsnotify/fsnotify v1.7.0
github.com/go-ole/go-ole v1.3.0 github.com/go-ole/go-ole v1.3.0
github.com/sagernet/gvisor v0.0.0-20240214044702-a3d61928a32f github.com/sagernet/gvisor v0.0.0-20240315080113-799fb6b6d311
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97
github.com/sagernet/sing v0.3.2 github.com/sagernet/sing v0.3.6
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/net v0.21.0 golang.org/x/net v0.22.0
golang.org/x/sys v0.17.0 golang.org/x/sys v0.18.0
) )
require ( require (

20
go.sum
View file

@ -6,25 +6,23 @@ github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/sagernet/gvisor v0.0.0-20240214044702-a3d61928a32f h1:7hj/CcCkUiC6gfhX4D+QNyodmhfurW2L2Q4qzJ1bPnI= github.com/sagernet/gvisor v0.0.0-20240315080113-799fb6b6d311 h1:eUQ6kJZXK77xYZeeNrBb/7JMv0S0Wkk7EpmKUb3fsfc=
github.com/sagernet/gvisor v0.0.0-20240214044702-a3d61928a32f/go.mod h1:bLmnT/4M4+yKB6F7JtRsbUr+YJ64yXwFIygjyYDFQzQ= github.com/sagernet/gvisor v0.0.0-20240315080113-799fb6b6d311/go.mod h1:mDrXZSv401qiaFiiIUC59Zp4VG5f4nqXFqDmp5o3hYI=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/sing v0.3.2 h1:CwWcxUBPkMvwgfe2/zUgY5oHG9qOL8Aob/evIFYK9jo= github.com/sagernet/sing v0.3.6 h1:dsEdYLKBQlrxUfw1a92x0VdPvR1/BOxQ+HIMyaoEJsQ=
github.com/sagernet/sing v0.3.2/go.mod h1:qHySJ7u8po9DABtMYEkNBcOumx7ZZJf/fbv2sfTkNHE= github.com/sagernet/sing v0.3.6/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI=
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 h1:rc/CcqLH3lh8n+csdOuDfP+NuykE0U6AeYSJJHKDgSg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9/go.mod h1:a/83NAfUXvEuLpmxDssAXxgUgrEy12MId3Wd7OTs76s=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View file

@ -12,7 +12,6 @@ import (
"github.com/go-ole/go-ole" "github.com/go-ole/go-ole"
"github.com/go-ole/go-ole/oleutil" "github.com/go-ole/go-ole/oleutil"
"github.com/scjalliance/comshim"
) )
// Firewall related API constants. // Firewall related API constants.
@ -250,7 +249,10 @@ func FirewallRuleExistsByName(rules *ole.IDispatch, name string) (bool, error) {
// then: // then:
// dispatch firewallAPIRelease(u, fwp) // dispatch firewallAPIRelease(u, fwp)
func firewallAPIInit() (*ole.IUnknown, *ole.IDispatch, error) { func firewallAPIInit() (*ole.IUnknown, *ole.IDispatch, error) {
comshim.Add(1) err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
if err != nil {
return nil, nil, fmt.Errorf("Failed to initialize COM: %s", err)
}
unknown, err := oleutil.CreateObject("HNetCfg.FwPolicy2") unknown, err := oleutil.CreateObject("HNetCfg.FwPolicy2")
if err != nil { if err != nil {
@ -270,5 +272,5 @@ func firewallAPIInit() (*ole.IUnknown, *ole.IDispatch, error) {
func firewallAPIRelease(u *ole.IUnknown, fwp *ole.IDispatch) { func firewallAPIRelease(u *ole.IUnknown, fwp *ole.IDispatch) {
fwp.Release() fwp.Release()
u.Release() u.Release()
comshim.Done() ole.CoUninitialize()
} }

View file

@ -42,7 +42,7 @@ func (m *networkUpdateMonitor) loopUpdate() {
select { select {
case <-m.done: case <-m.done:
return return
case <-time.After(time.Second): default:
} }
err := m.loopUpdate0() err := m.loopUpdate0()
if err != nil { if err != nil {
@ -67,7 +67,16 @@ func (m *networkUpdateMonitor) loopUpdate1(routeSocketFile *os.File) {
defer routeSocketFile.Close() defer routeSocketFile.Close()
buffer := buf.NewPacket() buffer := buf.NewPacket()
defer buffer.Release() defer buffer.Release()
done := make(chan struct{})
go func() {
select {
case <-m.done:
routeSocketFile.Close()
case <-done:
}
}()
n, err := routeSocketFile.Read(buffer.FreeBytes()) n, err := routeSocketFile.Read(buffer.FreeBytes())
close(done)
if err != nil { if err != nil {
return return
} }
@ -92,57 +101,59 @@ func (m *networkUpdateMonitor) Close() error {
} }
func (m *defaultInterfaceMonitor) checkUpdate() error { func (m *defaultInterfaceMonitor) checkUpdate() error {
ribMessage, err := route.FetchRIB(unix.AF_UNSPEC, route.RIBTypeRoute, 0) var (
if err != nil { defaultInterface *net.Interface
return err err error
} )
routeMessages, err := route.ParseRIB(route.RIBTypeRoute, ribMessage) if m.options.UnderNetworkExtension {
if err != nil { defaultInterface, err = getDefaultInterfaceBySocket()
return err
}
var defaultInterface *net.Interface
for _, rawRouteMessage := range routeMessages {
routeMessage := rawRouteMessage.(*route.RouteMessage)
if len(routeMessage.Addrs) <= unix.RTAX_NETMASK {
continue
}
destination, isIPv4Destination := routeMessage.Addrs[unix.RTAX_DST].(*route.Inet4Addr)
if !isIPv4Destination {
continue
}
if destination.IP != netip.IPv4Unspecified().As4() {
continue
}
mask, isIPv4Mask := routeMessage.Addrs[unix.RTAX_NETMASK].(*route.Inet4Addr)
if !isIPv4Mask {
continue
}
ones, _ := net.IPMask(mask.IP[:]).Size()
if ones != 0 {
continue
}
routeInterface, err := net.InterfaceByIndex(routeMessage.Index)
if err != nil { if err != nil {
return err return err
} }
if routeMessage.Flags&unix.RTF_UP == 0 { } else {
continue ribMessage, err := route.FetchRIB(unix.AF_UNSPEC, route.RIBTypeRoute, 0)
if err != nil {
return err
} }
if routeMessage.Flags&unix.RTF_GATEWAY == 0 { routeMessages, err := route.ParseRIB(route.RIBTypeRoute, ribMessage)
continue if err != nil {
return err
} }
if routeMessage.Flags&unix.RTF_IFSCOPE != 0 { for _, rawRouteMessage := range routeMessages {
// continue routeMessage := rawRouteMessage.(*route.RouteMessage)
} if len(routeMessage.Addrs) <= unix.RTAX_NETMASK {
defaultInterface = routeInterface continue
break }
} destination, isIPv4Destination := routeMessage.Addrs[unix.RTAX_DST].(*route.Inet4Addr)
if defaultInterface == nil { if !isIPv4Destination {
if m.options.UnderNetworkExtension { continue
defaultInterface, err = getDefaultInterfaceBySocket() }
if destination.IP != netip.IPv4Unspecified().As4() {
continue
}
mask, isIPv4Mask := routeMessage.Addrs[unix.RTAX_NETMASK].(*route.Inet4Addr)
if !isIPv4Mask {
continue
}
ones, _ := net.IPMask(mask.IP[:]).Size()
if ones != 0 {
continue
}
routeInterface, err := net.InterfaceByIndex(routeMessage.Index)
if err != nil { if err != nil {
return err return err
} }
if routeMessage.Flags&unix.RTF_UP == 0 {
continue
}
if routeMessage.Flags&unix.RTF_GATEWAY == 0 {
continue
}
if routeMessage.Flags&unix.RTF_IFSCOPE != 0 {
// continue
}
defaultInterface = routeInterface
break
} }
} }
if defaultInterface == nil { if defaultInterface == nil {

View file

@ -6,7 +6,6 @@ import (
"errors" "errors"
"net" "net"
"net/netip" "net/netip"
"runtime"
"sync" "sync"
"time" "time"
@ -44,6 +43,7 @@ type defaultInterfaceMonitor struct {
defaultInterfaceIndex int defaultInterfaceIndex int
androidVPNEnabled bool androidVPNEnabled bool
networkMonitor NetworkUpdateMonitor networkMonitor NetworkUpdateMonitor
checkUpdateTimer *time.Timer
element *list.Element[NetworkUpdateCallback] element *list.Element[NetworkUpdateCallback]
access sync.Mutex access sync.Mutex
callbacks list.List[DefaultInterfaceUpdateCallback] callbacks list.List[DefaultInterfaceUpdateCallback]
@ -72,9 +72,13 @@ func (m *defaultInterfaceMonitor) Start() error {
} }
func (m *defaultInterfaceMonitor) delayCheckUpdate() { func (m *defaultInterfaceMonitor) delayCheckUpdate() {
if runtime.GOOS == "android" { if m.checkUpdateTimer != nil {
time.Sleep(time.Second) m.checkUpdateTimer.Stop()
} }
m.checkUpdateTimer = time.AfterFunc(time.Second, m.postCheckUpdate)
}
func (m *defaultInterfaceMonitor) postCheckUpdate() {
err := m.updateInterfaces() err := m.updateInterfaces()
if err != nil { if err != nil {
m.logger.Error("update interfaces: ", err) m.logger.Error("update interfaces: ", err)

View file

@ -32,7 +32,7 @@ type networkDispatcherFilter struct {
writer N.VectorisedWriter writer N.VectorisedWriter
} }
func (w *networkDispatcherFilter) DeliverNetworkPacket(protocol tcpip.NetworkProtocolNumber, pkt stack.PacketBufferPtr) { func (w *networkDispatcherFilter) DeliverNetworkPacket(protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) {
var network header.Network var network header.Network
if protocol == header.IPv4ProtocolNumber { if protocol == header.IPv4ProtocolNumber {
if headerPackets, loaded := pkt.Data().PullUp(header.IPv4MinimumSize); loaded { if headerPackets, loaded := pkt.Data().PullUp(header.IPv4MinimumSize); loaded {

View file

@ -42,7 +42,7 @@ func NewUDPForwarder(ctx context.Context, stack *stack.Stack, handler Handler, u
} }
} }
func (f *UDPForwarder) HandlePacket(id stack.TransportEndpointID, pkt stack.PacketBufferPtr) bool { func (f *UDPForwarder) HandlePacket(id stack.TransportEndpointID, pkt *stack.PacketBuffer) bool {
var upstreamMetadata M.Metadata var upstreamMetadata M.Metadata
upstreamMetadata.Source = M.SocksaddrFrom(AddrFromAddress(id.RemoteAddress), id.RemotePort) upstreamMetadata.Source = M.SocksaddrFrom(AddrFromAddress(id.RemoteAddress), id.RemotePort)
upstreamMetadata.Destination = M.SocksaddrFrom(AddrFromAddress(id.LocalAddress), id.LocalPort) upstreamMetadata.Destination = M.SocksaddrFrom(AddrFromAddress(id.LocalAddress), id.LocalPort)
@ -174,7 +174,7 @@ func (c *gUDPConn) Close() error {
return c.UDPConn.Close() return c.UDPConn.Close()
} }
func gWriteUnreachable(gStack *stack.Stack, packet stack.PacketBufferPtr, err error) (retErr error) { func gWriteUnreachable(gStack *stack.Stack, packet *stack.PacketBuffer, err error) (retErr error) {
if errors.Is(err, syscall.ENETUNREACH) { if errors.Is(err, syscall.ENETUNREACH) {
if packet.NetworkProtocolNumber == header.IPv4ProtocolNumber { if packet.NetworkProtocolNumber == header.IPv4ProtocolNumber {
return gWriteUnreachable4(gStack, packet, stack.RejectIPv4WithICMPNetUnreachable) return gWriteUnreachable4(gStack, packet, stack.RejectIPv4WithICMPNetUnreachable)
@ -197,7 +197,7 @@ func gWriteUnreachable(gStack *stack.Stack, packet stack.PacketBufferPtr, err er
return nil return nil
} }
func gWriteUnreachable4(gStack *stack.Stack, packet stack.PacketBufferPtr, icmpCode stack.RejectIPv4WithICMPType) error { func gWriteUnreachable4(gStack *stack.Stack, packet *stack.PacketBuffer, icmpCode stack.RejectIPv4WithICMPType) error {
err := gStack.NetworkProtocolInstance(header.IPv4ProtocolNumber).(stack.RejectIPv4WithHandler).SendRejectionError(packet, icmpCode, true) err := gStack.NetworkProtocolInstance(header.IPv4ProtocolNumber).(stack.RejectIPv4WithHandler).SendRejectionError(packet, icmpCode, true)
if err != nil { if err != nil {
return wrapStackError(err) return wrapStackError(err)
@ -205,7 +205,7 @@ func gWriteUnreachable4(gStack *stack.Stack, packet stack.PacketBufferPtr, icmpC
return nil return nil
} }
func gWriteUnreachable6(gStack *stack.Stack, packet stack.PacketBufferPtr, icmpCode stack.RejectIPv6WithICMPType) error { func gWriteUnreachable6(gStack *stack.Stack, packet *stack.PacketBuffer, icmpCode stack.RejectIPv6WithICMPType) error {
err := gStack.NetworkProtocolInstance(header.IPv6ProtocolNumber).(stack.RejectIPv6WithHandler).SendRejectionError(packet, icmpCode, true) err := gStack.NetworkProtocolInstance(header.IPv6ProtocolNumber).(stack.RejectIPv6WithHandler).SendRejectionError(packet, icmpCode, true)
if err != nil { if err != nil {
return wrapStackError(err) return wrapStackError(err)

View file

@ -102,10 +102,10 @@ func (e *DarwinEndpoint) ARPHardwareType() header.ARPHardwareType {
return header.ARPHardwareNone return header.ARPHardwareNone
} }
func (e *DarwinEndpoint) AddHeader(buffer stack.PacketBufferPtr) { func (e *DarwinEndpoint) AddHeader(buffer *stack.PacketBuffer) {
} }
func (e *DarwinEndpoint) ParseHeader(ptr stack.PacketBufferPtr) bool { func (e *DarwinEndpoint) ParseHeader(ptr *stack.PacketBuffer) bool {
return true return true
} }

View file

@ -99,10 +99,10 @@ func (e *WintunEndpoint) ARPHardwareType() header.ARPHardwareType {
return header.ARPHardwareNone return header.ARPHardwareNone
} }
func (e *WintunEndpoint) AddHeader(buffer stack.PacketBufferPtr) { func (e *WintunEndpoint) AddHeader(buffer *stack.PacketBuffer) {
} }
func (e *WintunEndpoint) ParseHeader(ptr stack.PacketBufferPtr) bool { func (e *WintunEndpoint) ParseHeader(ptr *stack.PacketBuffer) bool {
return true return true
} }