mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-14 04:38:28 +10:00
Compare commits
22 Commits
v1.9.0-rc.
...
v1.9.0-rc.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3a143fa26 | ||
|
|
bf9fdd76d2 | ||
|
|
0040935aff | ||
|
|
b5dcede450 | ||
|
|
bdc1f5a5bf | ||
|
|
f01e9acf2c | ||
|
|
b892058119 | ||
|
|
f60ac7d40a | ||
|
|
91ce3534bc | ||
|
|
83c782f96e | ||
|
|
fd4f80d60e | ||
|
|
00f8a722d9 | ||
|
|
728923a59c | ||
|
|
3f44f74d95 | ||
|
|
81acdc82e2 | ||
|
|
7c1a9c5f29 | ||
|
|
e44156ebec | ||
|
|
09f125a906 | ||
|
|
74189ada09 | ||
|
|
6f86139635 | ||
|
|
de854b34df | ||
|
|
728834fde0 |
8
.github/workflows/linux.yml
vendored
8
.github/workflows/linux.yml
vendored
@@ -17,12 +17,6 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ^1.22
|
||||
- name: Extract signing key
|
||||
run: |-
|
||||
mkdir -p $HOME/.gnupg
|
||||
cat > $HOME/.gnupg/sagernet.key <<EOF
|
||||
${{ secrets.GPG_KEY }}
|
||||
EOF
|
||||
- name: Publish release
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
with:
|
||||
@@ -33,5 +27,3 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||
FURY_TOKEN: ${{ secrets.FURY_TOKEN }}
|
||||
NFPM_KEY_PATH: $HOME/.gnupg/sagernet.key
|
||||
NFPM_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
||||
|
||||
@@ -55,14 +55,6 @@ nfpms:
|
||||
dst: /usr/lib/systemd/system/sing-box@.service
|
||||
- src: LICENSE
|
||||
dst: /usr/share/licenses/sing-box/LICENSE
|
||||
deb:
|
||||
signature:
|
||||
key_file: "{{ .Env.NFPM_KEY_PATH }}"
|
||||
fields:
|
||||
Bugs: https://github.com/SagerNet/sing-box/issues
|
||||
rpm:
|
||||
signature:
|
||||
key_file: "{{ .Env.NFPM_KEY_PATH }}"
|
||||
conflicts:
|
||||
- sing-box-beta
|
||||
- id: package_beta
|
||||
@@ -80,8 +72,9 @@ furies:
|
||||
- account: sagernet
|
||||
ids:
|
||||
- package
|
||||
skip: "{{ not (not .Prerelease) }}"
|
||||
skip: "{{ .Prerelease }}"
|
||||
- account: sagernet
|
||||
ids:
|
||||
- package_beta
|
||||
skip: "{{ not .Prerelease }}"
|
||||
|
||||
|
||||
@@ -136,8 +136,6 @@ nfpms:
|
||||
deb:
|
||||
signature:
|
||||
key_file: "{{ .Env.NFPM_KEY_PATH }}"
|
||||
fields:
|
||||
Bugs: https://github.com/SagerNet/sing-box/issues
|
||||
rpm:
|
||||
signature:
|
||||
key_file: "{{ .Env.NFPM_KEY_PATH }}"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
icon: material/alert-decagram
|
||||
---
|
||||
|
||||
#### 1.9.0-rc.9
|
||||
#### 1.9.0-rc.6
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ icon: material/package
|
||||
=== ":material-debian: Debian / APT"
|
||||
|
||||
```bash
|
||||
sudo curl -fsSL https://sing-box.app/gpg.key -o /etc/apt/keyrings/sagernet.asc
|
||||
sudo curl -fsSL https://deb.sagernet.org/gpg.key -o /etc/apt/keyrings/sagernet.asc
|
||||
sudo chmod a+r /etc/apt/keyrings/sagernet.asc
|
||||
echo "deb [arch=`dpkg --print-architecture` signed-by=/etc/apt/keyrings/sagernet.asc] https://deb.sagernet.org/ * *" | \
|
||||
sudo tee /etc/apt/sources.list.d/sagernet.list > /dev/null
|
||||
@@ -21,7 +21,7 @@ icon: material/package
|
||||
|
||||
```bash
|
||||
sudo dnf -y install dnf-plugins-core
|
||||
sudo dnf config-manager --add-repo https://sing-box.app/sing-box.repo
|
||||
sudo dnf config-manager --add-repo https://sing-box.app/rpm.repo
|
||||
sudo dnf install sing-box # or sing-box-beta
|
||||
```
|
||||
|
||||
@@ -29,7 +29,7 @@ icon: material/package
|
||||
|
||||
```bash
|
||||
sudo yum install -y yum-utils
|
||||
sudo yum-config-manager --add-repo https://sing-box.app/sing-box.repo
|
||||
sudo yum-config-manager --add-repo https://sing-box.app/rpm.repo
|
||||
sudo yum install sing-box # or sing-box-beta
|
||||
```
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ icon: material/package
|
||||
=== ":material-debian: Debian / APT"
|
||||
|
||||
```bash
|
||||
sudo curl -fsSL https://sing-box.app/gpg.key -o /etc/apt/keyrings/sagernet.asc
|
||||
sudo curl -fsSL https://deb.sagernet.org/gpg.key -o /etc/apt/keyrings/sagernet.asc
|
||||
sudo chmod a+r /etc/apt/keyrings/sagernet.asc
|
||||
echo "deb [arch=`dpkg --print-architecture` signed-by=/etc/apt/keyrings/sagernet.asc] https://deb.sagernet.org/ * *" | \
|
||||
sudo tee /etc/apt/sources.list.d/sagernet.list > /dev/null
|
||||
@@ -21,7 +21,7 @@ icon: material/package
|
||||
|
||||
```bash
|
||||
sudo dnf -y install dnf-plugins-core
|
||||
sudo dnf config-manager --add-repo https://sing-box.app/sing-box.repo
|
||||
sudo dnf config-manager --add-repo https://sing-box.app/rpm.repo
|
||||
sudo dnf install sing-box # or sing-box-beta
|
||||
```
|
||||
|
||||
@@ -29,7 +29,7 @@ icon: material/package
|
||||
|
||||
```bash
|
||||
sudo yum install -y yum-utils
|
||||
sudo yum-config-manager --add-repo https://sing-box.app/sing-box.repo
|
||||
sudo yum-config-manager --add-repo https://sing-box.app/rpm.repo
|
||||
sudo yum install sing-box # or sing-box-beta
|
||||
```
|
||||
|
||||
|
||||
6
docs/installation/tools/rpm.repo
Normal file
6
docs/installation/tools/rpm.repo
Normal file
@@ -0,0 +1,6 @@
|
||||
[sing-box]
|
||||
name=sing-box
|
||||
baseurl=https://rpm.sagernet.org/
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
gpgkey=https://deb.sagernet.org/gpg.key
|
||||
@@ -1,8 +0,0 @@
|
||||
[sing-box]
|
||||
name=sing-box
|
||||
baseurl=https://rpm.sagernet.org/
|
||||
metalink=https://sing-box.app/sing-box.repo
|
||||
enabled=1
|
||||
repo_gpgcheck=1
|
||||
gpgcheck=1
|
||||
gpgkey=https://sing-box.app/gpg.key
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/sagernet/sing-box"
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/process"
|
||||
"github.com/sagernet/sing-box/experimental/libbox/platform"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-tun"
|
||||
"github.com/sagernet/sing/common/control"
|
||||
@@ -74,7 +75,7 @@ func (s *platformInterfaceStub) UsePlatformInterfaceGetter() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *platformInterfaceStub) Interfaces() ([]control.Interface, error) {
|
||||
func (s *platformInterfaceStub) Interfaces() ([]platform.NetworkInterface, error) {
|
||||
return nil, os.ErrInvalid
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package platform
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/process"
|
||||
@@ -19,9 +20,16 @@ type Interface interface {
|
||||
UsePlatformDefaultInterfaceMonitor() bool
|
||||
CreateDefaultInterfaceMonitor(logger logger.Logger) tun.DefaultInterfaceMonitor
|
||||
UsePlatformInterfaceGetter() bool
|
||||
Interfaces() ([]control.Interface, error)
|
||||
Interfaces() ([]NetworkInterface, error)
|
||||
UnderNetworkExtension() bool
|
||||
ClearDNSCache()
|
||||
ReadWIFIState() adapter.WIFIState
|
||||
process.Searcher
|
||||
}
|
||||
|
||||
type NetworkInterface struct {
|
||||
Index int
|
||||
MTU int
|
||||
Name string
|
||||
Addresses []netip.Prefix
|
||||
}
|
||||
|
||||
@@ -192,14 +192,14 @@ func (w *platformInterfaceWrapper) UsePlatformInterfaceGetter() bool {
|
||||
return w.iif.UsePlatformInterfaceGetter()
|
||||
}
|
||||
|
||||
func (w *platformInterfaceWrapper) Interfaces() ([]control.Interface, error) {
|
||||
func (w *platformInterfaceWrapper) Interfaces() ([]platform.NetworkInterface, error) {
|
||||
interfaceIterator, err := w.iif.GetInterfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var interfaces []control.Interface
|
||||
var interfaces []platform.NetworkInterface
|
||||
for _, netInterface := range iteratorToArray[*NetworkInterface](interfaceIterator) {
|
||||
interfaces = append(interfaces, control.Interface{
|
||||
interfaces = append(interfaces, platform.NetworkInterface{
|
||||
Index: int(netInterface.Index),
|
||||
MTU: int(netInterface.MTU),
|
||||
Name: netInterface.Name,
|
||||
|
||||
6
go.mod
6
go.mod
@@ -11,7 +11,7 @@ require (
|
||||
github.com/go-chi/chi/v5 v5.0.12
|
||||
github.com/go-chi/cors v1.2.1
|
||||
github.com/go-chi/render v1.0.3
|
||||
github.com/gofrs/uuid/v5 v5.1.0
|
||||
github.com/gofrs/uuid/v5 v5.0.0
|
||||
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2
|
||||
github.com/libdns/alidns v1.0.3
|
||||
github.com/libdns/cloudflare v0.1.1
|
||||
@@ -26,7 +26,7 @@ require (
|
||||
github.com/sagernet/gvisor v0.0.0-20240315080113-799fb6b6d311
|
||||
github.com/sagernet/quic-go v0.42.0-beta.2
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
|
||||
github.com/sagernet/sing v0.4.0-beta.15
|
||||
github.com/sagernet/sing v0.4.0-beta.12
|
||||
github.com/sagernet/sing-dns v0.2.0-beta.16
|
||||
github.com/sagernet/sing-mux v0.2.0
|
||||
github.com/sagernet/sing-quic v0.1.12-beta.1
|
||||
@@ -48,7 +48,7 @@ require (
|
||||
golang.org/x/net v0.24.0
|
||||
golang.org/x/sys v0.19.0
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
|
||||
google.golang.org/grpc v1.63.2
|
||||
google.golang.org/grpc v1.63.0
|
||||
google.golang.org/protobuf v1.33.0
|
||||
howett.net/plist v1.0.1
|
||||
)
|
||||
|
||||
12
go.sum
12
go.sum
@@ -34,8 +34,8 @@ github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gofrs/uuid/v5 v5.1.0 h1:S5rqVKIigghZTCBKPCw0Y+bXkn26K3TB5mvQq2Ix8dk=
|
||||
github.com/gofrs/uuid/v5 v5.1.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
|
||||
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
|
||||
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
@@ -106,8 +106,8 @@ github.com/sagernet/quic-go v0.42.0-beta.2/go.mod h1:lf8OYop+fMxIlrfM/ZHpENt/7ZD
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
||||
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
|
||||
github.com/sagernet/sing v0.4.0-beta.15 h1:KS6lC36Pzf562ukWXPka1uMSqgzmXP3vpTq50DXxdVM=
|
||||
github.com/sagernet/sing v0.4.0-beta.15/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI=
|
||||
github.com/sagernet/sing v0.4.0-beta.12 h1:f0f8DBPNf91NoAnJWm25LjPy/rC6u0R/nWIsGysl1cc=
|
||||
github.com/sagernet/sing v0.4.0-beta.12/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI=
|
||||
github.com/sagernet/sing-dns v0.2.0-beta.16 h1:bzd4B8eHD7/WO3HrYknvgE8A56/R3n5oXBjNF97iPzQ=
|
||||
github.com/sagernet/sing-dns v0.2.0-beta.16/go.mod h1:XU6Vqr6aHcMz/34Fcv8jmXpRCEuShzW+B7Qg1Xe1nxY=
|
||||
github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo=
|
||||
@@ -200,8 +200,8 @@ golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvY
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
|
||||
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
|
||||
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
|
||||
google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8=
|
||||
google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -51,7 +51,7 @@ func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, opti
|
||||
domainStrategy: dns.DomainStrategy(options.DomainStrategy),
|
||||
fallbackDelay: time.Duration(options.FallbackDelay),
|
||||
dialer: outboundDialer,
|
||||
loopBack: newLoopBackDetector(router),
|
||||
loopBack: newLoopBackDetector(),
|
||||
}
|
||||
if options.ProxyProtocol != 0 {
|
||||
return nil, E.New("Proxy Protocol is deprecated and removed in sing-box 1.6.0")
|
||||
|
||||
@@ -5,24 +5,21 @@ import (
|
||||
"net/netip"
|
||||
"sync"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
type loopBackDetector struct {
|
||||
router adapter.Router
|
||||
connAccess sync.RWMutex
|
||||
packetConnAccess sync.RWMutex
|
||||
connMap map[netip.AddrPort]bool
|
||||
packetConnMap map[uint16]bool
|
||||
packetConnMap map[netip.AddrPort]bool
|
||||
}
|
||||
|
||||
func newLoopBackDetector(router adapter.Router) *loopBackDetector {
|
||||
func newLoopBackDetector() *loopBackDetector {
|
||||
return &loopBackDetector{
|
||||
router: router,
|
||||
connMap: make(map[netip.AddrPort]bool),
|
||||
packetConnMap: make(map[uint16]bool),
|
||||
packetConnMap: make(map[netip.AddrPort]bool),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,16 +29,10 @@ func (l *loopBackDetector) NewConn(conn net.Conn) net.Conn {
|
||||
return conn
|
||||
}
|
||||
if udpConn, isUDPConn := conn.(abstractUDPConn); isUDPConn {
|
||||
if !connAddr.Addr().IsLoopback() {
|
||||
_, err := l.router.InterfaceFinder().InterfaceByAddr(connAddr.Addr())
|
||||
if err != nil {
|
||||
return conn
|
||||
}
|
||||
}
|
||||
l.packetConnAccess.Lock()
|
||||
l.packetConnMap[connAddr.Port()] = true
|
||||
l.packetConnMap[connAddr] = true
|
||||
l.packetConnAccess.Unlock()
|
||||
return &loopBackDetectUDPWrapper{abstractUDPConn: udpConn, detector: l, connPort: connAddr.Port()}
|
||||
return &loopBackDetectUDPWrapper{abstractUDPConn: udpConn, detector: l, connAddr: connAddr}
|
||||
} else {
|
||||
l.connAccess.Lock()
|
||||
l.connMap[connAddr] = true
|
||||
@@ -55,16 +46,10 @@ func (l *loopBackDetector) NewPacketConn(conn N.NetPacketConn) N.NetPacketConn {
|
||||
if !connAddr.IsValid() {
|
||||
return conn
|
||||
}
|
||||
if !connAddr.Addr().IsLoopback() {
|
||||
_, err := l.router.InterfaceFinder().InterfaceByAddr(connAddr.Addr())
|
||||
if err != nil {
|
||||
return conn
|
||||
}
|
||||
}
|
||||
l.packetConnAccess.Lock()
|
||||
l.packetConnMap[connAddr.Port()] = true
|
||||
l.packetConnMap[connAddr] = true
|
||||
l.packetConnAccess.Unlock()
|
||||
return &loopBackDetectPacketWrapper{NetPacketConn: conn, detector: l, connPort: connAddr.Port()}
|
||||
return &loopBackDetectPacketWrapper{NetPacketConn: conn, detector: l, connAddr: connAddr}
|
||||
}
|
||||
|
||||
func (l *loopBackDetector) CheckConn(connAddr netip.AddrPort) bool {
|
||||
@@ -74,18 +59,9 @@ func (l *loopBackDetector) CheckConn(connAddr netip.AddrPort) bool {
|
||||
}
|
||||
|
||||
func (l *loopBackDetector) CheckPacketConn(connAddr netip.AddrPort) bool {
|
||||
if !connAddr.IsValid() || !connAddr.Addr().IsLoopback() {
|
||||
return false
|
||||
}
|
||||
if !connAddr.Addr().IsLoopback() {
|
||||
_, err := l.router.InterfaceFinder().InterfaceByAddr(connAddr.Addr())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
l.packetConnAccess.RLock()
|
||||
defer l.packetConnAccess.RUnlock()
|
||||
return l.packetConnMap[connAddr.Port()]
|
||||
return l.packetConnMap[connAddr]
|
||||
}
|
||||
|
||||
type loopBackDetectWrapper struct {
|
||||
@@ -119,14 +95,14 @@ func (w *loopBackDetectWrapper) Upstream() any {
|
||||
type loopBackDetectPacketWrapper struct {
|
||||
N.NetPacketConn
|
||||
detector *loopBackDetector
|
||||
connPort uint16
|
||||
connAddr netip.AddrPort
|
||||
closeOnce sync.Once
|
||||
}
|
||||
|
||||
func (w *loopBackDetectPacketWrapper) Close() error {
|
||||
w.closeOnce.Do(func() {
|
||||
w.detector.packetConnAccess.Lock()
|
||||
delete(w.detector.packetConnMap, w.connPort)
|
||||
delete(w.detector.packetConnMap, w.connAddr)
|
||||
w.detector.packetConnAccess.Unlock()
|
||||
})
|
||||
return w.NetPacketConn.Close()
|
||||
@@ -152,14 +128,14 @@ type abstractUDPConn interface {
|
||||
type loopBackDetectUDPWrapper struct {
|
||||
abstractUDPConn
|
||||
detector *loopBackDetector
|
||||
connPort uint16
|
||||
connAddr netip.AddrPort
|
||||
closeOnce sync.Once
|
||||
}
|
||||
|
||||
func (w *loopBackDetectUDPWrapper) Close() error {
|
||||
w.closeOnce.Do(func() {
|
||||
w.detector.packetConnAccess.Lock()
|
||||
delete(w.detector.packetConnMap, w.connPort)
|
||||
delete(w.detector.packetConnMap, w.connAddr)
|
||||
w.detector.packetConnAccess.Unlock()
|
||||
})
|
||||
return w.abstractUDPConn.Close()
|
||||
|
||||
54
route/interface_finder.go
Normal file
54
route/interface_finder.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/sagernet/sing/common/control"
|
||||
)
|
||||
|
||||
var _ control.InterfaceFinder = (*myInterfaceFinder)(nil)
|
||||
|
||||
type myInterfaceFinder struct {
|
||||
interfaces []net.Interface
|
||||
}
|
||||
|
||||
func (f *myInterfaceFinder) update() error {
|
||||
ifs, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.interfaces = ifs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *myInterfaceFinder) updateInterfaces(interfaces []net.Interface) {
|
||||
f.interfaces = interfaces
|
||||
}
|
||||
|
||||
func (f *myInterfaceFinder) InterfaceIndexByName(name string) (interfaceIndex int, err error) {
|
||||
for _, netInterface := range f.interfaces {
|
||||
if netInterface.Name == name {
|
||||
return netInterface.Index, nil
|
||||
}
|
||||
}
|
||||
netInterface, err := net.InterfaceByName(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
f.update()
|
||||
return netInterface.Index, nil
|
||||
}
|
||||
|
||||
func (f *myInterfaceFinder) InterfaceNameByIndex(index int) (interfaceName string, err error) {
|
||||
for _, netInterface := range f.interfaces {
|
||||
if netInterface.Index == index {
|
||||
return netInterface.Name, nil
|
||||
}
|
||||
}
|
||||
netInterface, err := net.InterfaceByIndex(index)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
f.update()
|
||||
return netInterface.Name, nil
|
||||
}
|
||||
@@ -80,7 +80,7 @@ type Router struct {
|
||||
transportDomainStrategy map[dns.Transport]dns.DomainStrategy
|
||||
dnsReverseMapping *DNSReverseMapping
|
||||
fakeIPStore adapter.FakeIPStore
|
||||
interfaceFinder *control.DefaultInterfaceFinder
|
||||
interfaceFinder myInterfaceFinder
|
||||
autoDetectInterface bool
|
||||
defaultInterface string
|
||||
defaultMark int
|
||||
@@ -126,7 +126,6 @@ func NewRouter(
|
||||
dnsIndependentCache: dnsOptions.IndependentCache,
|
||||
defaultDetour: options.Final,
|
||||
defaultDomainStrategy: dns.DomainStrategy(dnsOptions.Strategy),
|
||||
interfaceFinder: control.NewDefaultInterfaceFinder(),
|
||||
autoDetectInterface: options.AutoDetectInterface,
|
||||
defaultInterface: options.DefaultInterface,
|
||||
defaultMark: options.DefaultMark,
|
||||
@@ -336,7 +335,7 @@ func NewRouter(
|
||||
}
|
||||
router.networkMonitor = networkMonitor
|
||||
networkMonitor.RegisterCallback(func() {
|
||||
_ = router.interfaceFinder.Update()
|
||||
_ = router.interfaceFinder.update()
|
||||
})
|
||||
interfaceMonitor, err := tun.NewDefaultInterfaceMonitor(router.networkMonitor, router.logger, tun.DefaultInterfaceMonitorOptions{
|
||||
OverrideAndroidVPN: options.OverrideAndroidVPN,
|
||||
@@ -1099,18 +1098,24 @@ func (r *Router) match0(ctx context.Context, metadata *adapter.InboundContext, d
|
||||
}
|
||||
|
||||
func (r *Router) InterfaceFinder() control.InterfaceFinder {
|
||||
return r.interfaceFinder
|
||||
return &r.interfaceFinder
|
||||
}
|
||||
|
||||
func (r *Router) UpdateInterfaces() error {
|
||||
if r.platformInterface == nil || !r.platformInterface.UsePlatformInterfaceGetter() {
|
||||
return r.interfaceFinder.Update()
|
||||
return r.interfaceFinder.update()
|
||||
} else {
|
||||
interfaces, err := r.platformInterface.Interfaces()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.interfaceFinder.UpdateInterfaces(interfaces)
|
||||
r.interfaceFinder.updateInterfaces(common.Map(interfaces, func(it platform.NetworkInterface) net.Interface {
|
||||
return net.Interface{
|
||||
Name: it.Name,
|
||||
Index: it.Index,
|
||||
MTU: it.MTU,
|
||||
}
|
||||
}))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
55
transport/fakeip/packet.go
Normal file
55
transport/fakeip/packet.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package fakeip
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
var _ N.PacketConn = (*NATPacketConn)(nil)
|
||||
|
||||
type NATPacketConn struct {
|
||||
N.PacketConn
|
||||
origin M.Socksaddr
|
||||
destination M.Socksaddr
|
||||
}
|
||||
|
||||
func NewNATPacketConn(conn N.PacketConn, origin M.Socksaddr, destination M.Socksaddr) *NATPacketConn {
|
||||
return &NATPacketConn{
|
||||
PacketConn: conn,
|
||||
origin: socksaddrWithoutPort(origin),
|
||||
destination: socksaddrWithoutPort(destination),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *NATPacketConn) ReadPacket(buffer *buf.Buffer) (destination M.Socksaddr, err error) {
|
||||
destination, err = c.PacketConn.ReadPacket(buffer)
|
||||
if socksaddrWithoutPort(destination) == c.origin {
|
||||
destination = M.Socksaddr{
|
||||
Addr: c.destination.Addr,
|
||||
Fqdn: c.destination.Fqdn,
|
||||
Port: destination.Port,
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *NATPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
|
||||
if socksaddrWithoutPort(destination) == c.destination {
|
||||
destination = M.Socksaddr{
|
||||
Addr: c.origin.Addr,
|
||||
Fqdn: c.origin.Fqdn,
|
||||
Port: destination.Port,
|
||||
}
|
||||
}
|
||||
return c.PacketConn.WritePacket(buffer, destination)
|
||||
}
|
||||
|
||||
func (c *NATPacketConn) Upstream() any {
|
||||
return c.PacketConn
|
||||
}
|
||||
|
||||
func socksaddrWithoutPort(destination M.Socksaddr) M.Socksaddr {
|
||||
destination.Port = 0
|
||||
return destination
|
||||
}
|
||||
37
transport/fakeip/packet_wait.go
Normal file
37
transport/fakeip/packet_wait.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package fakeip
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
func (c *NATPacketConn) CreatePacketReadWaiter() (N.PacketReadWaiter, bool) {
|
||||
waiter, created := bufio.CreatePacketReadWaiter(c.PacketConn)
|
||||
if !created {
|
||||
return nil, false
|
||||
}
|
||||
return &waitNATPacketConn{c, waiter}, true
|
||||
}
|
||||
|
||||
type waitNATPacketConn struct {
|
||||
*NATPacketConn
|
||||
readWaiter N.PacketReadWaiter
|
||||
}
|
||||
|
||||
func (c *waitNATPacketConn) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy bool) {
|
||||
return c.readWaiter.InitializeReadWaiter(options)
|
||||
}
|
||||
|
||||
func (c *waitNATPacketConn) WaitReadPacket() (buffer *buf.Buffer, destination M.Socksaddr, err error) {
|
||||
buffer, destination, err = c.readWaiter.WaitReadPacket()
|
||||
if err == nil && socksaddrWithoutPort(destination) == c.origin {
|
||||
destination = M.Socksaddr{
|
||||
Addr: c.destination.Addr,
|
||||
Fqdn: c.destination.Fqdn,
|
||||
Port: destination.Port,
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user