Compare commits

...

15 Commits

Author SHA1 Message Date
世界
c8318058bb documentation: Bump version 2024-01-23 11:57:28 +08:00
世界
abca2118e7 documentation: Update geosite usage 2024-01-23 11:57:28 +08:00
世界
a8ee41715a platform: Add service error wrapper for macOS system extension 2024-01-22 19:00:09 +08:00
世界
94f76d6671 Update dependencies 2024-01-22 14:37:21 +08:00
世界
bf6cc8903c Fix missing write result in TFO open 2024-01-19 11:22:13 +08:00
世界
1b15e1692a Add sponsor button 2024-01-19 11:22:13 +08:00
世界
017372db25 Fix missing loopback detect 2024-01-19 11:22:12 +08:00
世界
216a0380fe documentation: Bump version 2024-01-16 05:50:07 +08:00
Noob Zhang
71b9e4ff17 Add network-online.target in .service files
This helps the daemon work better on IoT devices
like RaspberryPi.
According to systemd's documentation,
`network.target` means there has already been
a network manager started, but the network may
not be "up". On most PCs this does not matter
because the network will turn to "up" almost
immidiately. The IoT devices' network interface
may not be set up quickly enough, so they may
meet that the sing-box daemon is started before
network is ready, which results that sing-box
cannot find a working route. The workaround
of this is restarting sing-box daemon but it
absolutely is not the perfect solution.
As `network-online.target` must be triggered by
network manager after you configured it, I keep
`network.target` so there will be no change to
those who do not enabled proper trigger service
like `NetworkManager-wait-online.service`.

See also: https://systemd.io/NETWORK_ONLINE/
2024-01-16 05:50:07 +08:00
printfer
9b7deb5246 Enhanced light/dark mode support in mkdocs configuration 2024-01-16 05:50:07 +08:00
世界
a850a73e1a Fix missing upstream func for read wait conn 2024-01-16 05:50:07 +08:00
世界
c4d9be9e0d Fix rule match 2024-01-14 13:01:57 +08:00
世界
f31c604b3d documentation: Bump version 2024-01-09 12:22:22 +08:00
世界
4c8a50a52b Fix TLS conn cast for vision 2024-01-09 12:22:22 +08:00
世界
b326e60998 Update dependencies 2024-01-09 12:22:22 +08:00
24 changed files with 303 additions and 136 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
github: nekohasekai

View File

@@ -108,6 +108,10 @@ func (c *ReadWaitConn) WaitReadBuffer() (buffer *buf.Buffer, err error) {
return
}
func (c *ReadWaitConn) Upstream() any {
return c.STDConn
}
//go:linkname tlsReadRecord crypto/tls.(*Conn).readRecord
func tlsReadRecord(c *tls.STDConn) error

View File

@@ -80,6 +80,7 @@ func (c *slowOpenConn) Write(b []byte) (n int, err error) {
c.conn = nil
c.err = E.Cause(err, "dial tcp fast open")
}
n = len(b)
close(c.create)
return
}

View File

@@ -253,7 +253,7 @@ func writeDefaultRule(writer io.Writer, rule option.DefaultHeadlessRule) error {
if len(rule.SourceIPCIDR) > 0 {
err = writeRuleItemCIDR(writer, ruleItemSourceIPCIDR, rule.SourceIPCIDR)
if err != nil {
return E.Cause(err, "source_ipcidr")
return E.Cause(err, "source_ip_cidr")
}
}
if len(rule.IPCIDR) > 0 {

View File

@@ -2,6 +2,18 @@
icon: material/alert-decagram
---
#### 1.8.4
* Fixes and improvements
#### 1.8.2
* Fixes and improvements
#### 1.8.1
* Fixes and improvements
#### 1.8.0
* Fixes and improvements

View File

@@ -322,17 +322,7 @@ flowchart TB
"server": "google"
},
{
"type": "logical",
"mode": "and",
"rules": [
{
"geosite": "geolocation-!cn",
"invert": true
},
{
"geosite": "cn",
}
],
"geosite": "geolocation-cn",
"server": "local"
}
]
@@ -374,17 +364,7 @@ flowchart TB
"server": "google"
},
{
"type": "logical",
"mode": "and",
"rules": [
{
"rule_set": "geosite-geolocation-!cn",
"invert": true
},
{
"rule_set": "geosite-cn",
}
],
"rule_set": "geosite-geolocation-cn",
"server": "local"
}
]
@@ -393,15 +373,9 @@ flowchart TB
"rule_set": [
{
"type": "remote",
"tag": "geosite-cn",
"tag": "geosite-geolocation-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs"
},
{
"type": "remote",
"tag": "geosite-geolocation-!cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-!cn.srs"
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-cn.srs"
}
]
}
@@ -467,18 +441,7 @@ flowchart TB
"outbound": "block"
},
{
"type": "logical",
"mode": "and",
"rules": [
{
"geosite": "geolocation-!cn",
"invert": true
},
{
"geosite": "cn",
"geoip": "cn"
}
],
"geosite": "geolocation-cn",
"outbound": "direct"
}
]
@@ -545,19 +508,9 @@ flowchart TB
"outbound": "block"
},
{
"type": "logical",
"mode": "and",
"rules": [
{
"rule_set": "geosite-geolocation-!cn",
"invert": true
},
{
"rule_set": [
"geoip-cn",
"geosite-cn"
]
}
"rule_set": [
"geoip-cn",
"geosite-geolocation-cn"
],
"outbound": "direct"
}
@@ -571,15 +524,9 @@ flowchart TB
},
{
"type": "remote",
"tag": "geosite-cn",
"tag": "geosite-geolocation-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs"
},
{
"type": "remote",
"tag": "geosite-geolocation-!cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-!cn.srs"
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-cn.srs"
}
]
}

View File

@@ -93,13 +93,11 @@ func (s *CommandServer) listenUNIX() error {
if err != nil {
return E.Cause(err, "listen ", sockPath)
}
if sUserID > 0 {
err = os.Chown(sockPath, sUserID, sGroupID)
if err != nil {
listener.Close()
os.Remove(sockPath)
return E.Cause(err, "chown")
}
err = os.Chown(sockPath, sUserID, sGroupID)
if err != nil {
listener.Close()
os.Remove(sockPath)
return E.Cause(err, "chown")
}
s.listener = listener
go s.loopConnection(listener)

View File

@@ -20,13 +20,11 @@ func RedirectStderr(path string) error {
return err
}
if runtime.GOOS != "android" {
if sUserID > 0 {
err = outputFile.Chown(sUserID, sGroupID)
if err != nil {
outputFile.Close()
os.Remove(outputFile.Name())
return err
}
err = outputFile.Chown(sUserID, sGroupID)
if err != nil {
outputFile.Close()
os.Remove(outputFile.Name())
return err
}
}
err = unix.Dup2(int(outputFile.Fd()), int(os.Stderr.Fd()))

View File

@@ -0,0 +1,32 @@
package libbox
import (
"os"
"path/filepath"
)
func serviceErrorPath() string {
return filepath.Join(sWorkingPath, "network_extension_error")
}
func ClearServiceError() {
os.Remove(serviceErrorPath())
}
func ReadServiceError() (string, error) {
data, err := os.ReadFile(serviceErrorPath())
if err == nil {
os.Remove(serviceErrorPath())
}
return string(data), err
}
func WriteServiceError(message string) error {
errorFile, err := os.Create(serviceErrorPath())
if err != nil {
return err
}
errorFile.WriteString(message)
errorFile.Chown(sUserID, sGroupID)
return errorFile.Close()
}

View File

@@ -25,6 +25,8 @@ func Setup(basePath string, workingPath string, tempPath string, isTVOS bool) {
sUserID = os.Getuid()
sGroupID = os.Getgid()
sTVOS = isTVOS
os.MkdirAll(sWorkingPath, 0o777)
os.MkdirAll(sTempPath, 0o777)
}
func SetupWithUsername(basePath string, workingPath string, tempPath string, username string) error {
@@ -37,6 +39,10 @@ func SetupWithUsername(basePath string, workingPath string, tempPath string, use
}
sUserID, _ = strconv.Atoi(sUser.Uid)
sGroupID, _ = strconv.Atoi(sUser.Gid)
os.MkdirAll(sWorkingPath, 0o777)
os.MkdirAll(sTempPath, 0o777)
os.Chown(sWorkingPath, sUserID, sGroupID)
os.Chown(sTempPath, sUserID, sGroupID)
return nil
}

26
go.mod
View File

@@ -5,7 +5,7 @@ go 1.20
require (
berty.tech/go-libtor v1.0.385
github.com/caddyserver/certmagic v0.20.0
github.com/cloudflare/circl v1.3.6
github.com/cloudflare/circl v1.3.7
github.com/cretz/bine v0.2.0
github.com/fsnotify/fsnotify v1.7.0
github.com/go-chi/chi/v5 v5.0.11
@@ -17,23 +17,23 @@ require (
github.com/libdns/cloudflare v0.1.0
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/mholt/acmez v1.2.0
github.com/miekg/dns v1.1.57
github.com/miekg/dns v1.1.58
github.com/ooni/go-libtor v1.1.8
github.com/oschwald/maxminddb-golang v1.12.0
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1
github.com/sagernet/gomobile v0.1.1
github.com/sagernet/gvisor v0.0.0-20231209105102-8d27a30e436e
github.com/sagernet/quic-go v0.40.1-beta.2
github.com/sagernet/quic-go v0.40.1
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.3.0-rc.7
github.com/sagernet/sing v0.3.0
github.com/sagernet/sing-dns v0.1.12
github.com/sagernet/sing-mux v0.1.8-rc.1
github.com/sagernet/sing-quic v0.1.7-rc.2
github.com/sagernet/sing-mux v0.2.0
github.com/sagernet/sing-quic v0.1.7
github.com/sagernet/sing-shadowsocks v0.2.6
github.com/sagernet/sing-shadowsocks2 v0.1.6-rc.1
github.com/sagernet/sing-shadowsocks2 v0.2.0
github.com/sagernet/sing-shadowtls v0.1.4
github.com/sagernet/sing-tun v0.2.0-rc.1
github.com/sagernet/sing-tun v0.2.0
github.com/sagernet/sing-vmess v0.1.8
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7
github.com/sagernet/tfo-go v0.0.0-20231209031829-7b5343ac1dc6
@@ -44,9 +44,9 @@ require (
github.com/stretchr/testify v1.8.4
go.uber.org/zap v1.26.0
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto v0.17.0
golang.org/x/net v0.19.0
golang.org/x/sys v0.15.0
golang.org/x/crypto v0.18.0
golang.org/x/net v0.20.0
golang.org/x/sys v0.16.0
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
google.golang.org/grpc v1.60.1
google.golang.org/protobuf v1.32.0
@@ -86,11 +86,11 @@ require (
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.16.0 // indirect
golang.org/x/tools v0.17.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

56
go.sum
View File

@@ -6,8 +6,8 @@ github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sx
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc=
github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
github.com/cloudflare/circl v1.3.6 h1:/xbKIqSHbZXHwkhbrhrt2YOHIwYJlXH94E3tI/gDlUg=
github.com/cloudflare/circl v1.3.6/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cretz/bine v0.1.0/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw=
github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo=
@@ -74,8 +74,8 @@ github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczG
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss=
@@ -104,27 +104,27 @@ github.com/sagernet/gvisor v0.0.0-20231209105102-8d27a30e436e h1:DOkjByVeAR56dks
github.com/sagernet/gvisor v0.0.0-20231209105102-8d27a30e436e/go.mod h1:fLxq/gtp0qzkaEwywlRRiGmjOK5ES/xUzyIKIFP2Asw=
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/quic-go v0.40.1-beta.2 h1:USRwm36XuAFdcrmv4vDRD+YUOO08DfvLNruXThrVHZU=
github.com/sagernet/quic-go v0.40.1-beta.2/go.mod h1:CcKTpzTAISxrM4PA5M20/wYuz9Tj6Tx4DwGbNl9UQrU=
github.com/sagernet/quic-go v0.40.1 h1:qLeTIJR0d0JWRmDWo346nLsVN6EWihd1kalJYPEd0TM=
github.com/sagernet/quic-go v0.40.1/go.mod h1:CcKTpzTAISxrM4PA5M20/wYuz9Tj6Tx4DwGbNl9UQrU=
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.3.0-rc.7 h1:FmnzFRYC6usVgWf112cUxiexwvL+iAurKmCL4Axa9+A=
github.com/sagernet/sing v0.3.0-rc.7/go.mod h1:9pfuAH6mZfgnz/YjP6xu5sxx882rfyjpcrTdUpd6w3g=
github.com/sagernet/sing v0.3.0 h1:PIDVFZHnQAAYRL1UYqNM+0k5s8f/tb1lUW6UDcQiOc8=
github.com/sagernet/sing v0.3.0/go.mod h1:9pfuAH6mZfgnz/YjP6xu5sxx882rfyjpcrTdUpd6w3g=
github.com/sagernet/sing-dns v0.1.12 h1:1HqZ+ln+Rezx/aJMStaS0d7oPeX2EobSV1NT537kyj4=
github.com/sagernet/sing-dns v0.1.12/go.mod h1:rx/DTOisneQpCgNQ4jbFU/JNEtnz0lYcHXenlVzpjEU=
github.com/sagernet/sing-mux v0.1.8-rc.1 h1:5dsZgWmNr9W6JzQj4fb3xX2pMP0OyJH6kVtlqc2kFKA=
github.com/sagernet/sing-mux v0.1.8-rc.1/go.mod h1:KK5zCbNujj5kn36G+wLFROOXyJhaaXLyaZWY2w7kBNQ=
github.com/sagernet/sing-quic v0.1.7-rc.2 h1:rCWhtvzQwgkWbX4sVHYdNwzyPweoUPEgBCBatywHjMs=
github.com/sagernet/sing-quic v0.1.7-rc.2/go.mod h1:IbKCPWXP13zd3cdu0rirtYjkMlquc5zWtc3avfSUGAw=
github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo=
github.com/sagernet/sing-mux v0.2.0/go.mod h1:khzr9AOPocLa+g53dBplwNDz4gdsyx/YM3swtAhlkHQ=
github.com/sagernet/sing-quic v0.1.7 h1:SC45rAnvQ9BuyO0V186OdDScMBitmZo0XcM9LBYRUW8=
github.com/sagernet/sing-quic v0.1.7/go.mod h1:wUg1Z6AGKeJguruZo0lhrie3dqPiRCKaidLAbK2ttEs=
github.com/sagernet/sing-shadowsocks v0.2.6 h1:xr7ylAS/q1cQYS8oxKKajhuQcchd5VJJ4K4UZrrpp0s=
github.com/sagernet/sing-shadowsocks v0.2.6/go.mod h1:j2YZBIpWIuElPFL/5sJAj470bcn/3QQ5lxZUNKLDNAM=
github.com/sagernet/sing-shadowsocks2 v0.1.6-rc.1 h1:E+8OyyVg0YfFNUmxMx9jYBEhjLYMQSAMzJrUmE934bo=
github.com/sagernet/sing-shadowsocks2 v0.1.6-rc.1/go.mod h1:wFkU7sKxyZADS/idtJqBhtc+QBf5iwX9nZO7ymcn6MM=
github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg=
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
github.com/sagernet/sing-tun v0.2.0-rc.1 h1:CnlxRgrJKAMKYNuJOcKie6TjRz8wremEq1wndLup7cA=
github.com/sagernet/sing-tun v0.2.0-rc.1/go.mod h1:hpbL9jNAbYT9G2EHCpCXVIgSrM/2Wgnrm/Hped+8zdY=
github.com/sagernet/sing-tun v0.2.0 h1:/WloeRTWvwKIuiIvY+HVJaaZsTGb3XqJXZUbn6wVhz4=
github.com/sagernet/sing-tun v0.2.0/go.mod h1:vJHzPAbwFUHxdFHUFQlH+Fb4rT3K4/SHODdMLU1rrQI=
github.com/sagernet/sing-vmess v0.1.8 h1:XVWad1RpTy9b5tPxdm5MCU8cGfrTGdR8qCq6HV2aCNc=
github.com/sagernet/sing-vmess v0.1.8/go.mod h1:vhx32UNzTDUkNwOyIjcZQohre1CaytquC5mPplId8uA=
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
@@ -168,17 +168,17 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4=
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM=
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -188,10 +188,10 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
@@ -199,8 +199,8 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=

View File

@@ -11,12 +11,14 @@ theme:
logo: assets/icon.svg
favicon: assets/icon.svg
palette:
- scheme: default
- media: "(prefers-color-scheme: light)"
scheme: default
primary: white
toggle:
icon: material/brightness-7
name: Switch to dark mode
- scheme: slate
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: black
toggle:
icon: material/brightness-4

View File

@@ -30,6 +30,7 @@ type Direct struct {
fallbackDelay time.Duration
overrideOption int
overrideDestination M.Socksaddr
loopBack *loopBackDetector
}
func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, options option.DirectOutboundOptions) (*Direct, error) {
@@ -50,6 +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(),
}
if options.ProxyProtocol != 0 {
return nil, E.New("Proxy Protocol is deprecated and removed in sing-box 1.6.0")
@@ -88,7 +90,11 @@ func (h *Direct) DialContext(ctx context.Context, network string, destination M.
case N.NetworkUDP:
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
}
return h.dialer.DialContext(ctx, network, destination)
conn, err := h.dialer.DialContext(ctx, network, destination)
if err != nil {
return nil, err
}
return h.loopBack.NewConn(conn), nil
}
func (h *Direct) DialParallel(ctx context.Context, network string, destination M.Socksaddr, destinationAddresses []netip.Addr) (net.Conn, error) {
@@ -142,6 +148,7 @@ func (h *Direct) ListenPacket(ctx context.Context, destination M.Socksaddr) (net
if err != nil {
return nil, err
}
conn = h.loopBack.NewPacketConn(conn)
if originDestination != destination {
conn = bufio.NewNATPacketConn(bufio.NewPacketConn(conn), destination, originDestination)
}
@@ -149,9 +156,15 @@ func (h *Direct) ListenPacket(ctx context.Context, destination M.Socksaddr) (net
}
func (h *Direct) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
if h.loopBack.CheckConn(metadata.Source.AddrPort()) {
return E.New("reject loopback connection to ", metadata.Destination)
}
return NewConnection(ctx, h, conn, metadata)
}
func (h *Direct) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
if h.loopBack.CheckPacketConn(metadata.Source.AddrPort()) {
return E.New("reject loopback packet connection to ", metadata.Destination)
}
return NewPacketConnection(ctx, h, conn, metadata)
}

View File

@@ -0,0 +1,153 @@
package outbound
import (
"net"
"net/netip"
"sync"
M "github.com/sagernet/sing/common/metadata"
)
type loopBackDetector struct {
connAccess sync.RWMutex
packetConnAccess sync.RWMutex
connMap map[netip.AddrPort]bool
packetConnMap map[netip.AddrPort]bool
}
func newLoopBackDetector() *loopBackDetector {
return &loopBackDetector{
connMap: make(map[netip.AddrPort]bool),
packetConnMap: make(map[netip.AddrPort]bool),
}
}
func (l *loopBackDetector) NewConn(conn net.Conn) net.Conn {
connAddr := M.AddrPortFromNet(conn.LocalAddr())
if !connAddr.IsValid() {
return conn
}
if udpConn, isUDPConn := conn.(abstractUDPConn); isUDPConn {
l.packetConnAccess.Lock()
l.packetConnMap[connAddr] = true
l.packetConnAccess.Unlock()
return &loopBackDetectUDPWrapper{abstractUDPConn: udpConn, detector: l, connAddr: connAddr}
} else {
l.connAccess.Lock()
l.connMap[connAddr] = true
l.connAccess.Unlock()
return &loopBackDetectWrapper{Conn: conn, detector: l, connAddr: connAddr}
}
}
func (l *loopBackDetector) NewPacketConn(conn net.PacketConn) net.PacketConn {
connAddr := M.AddrPortFromNet(conn.LocalAddr())
if !connAddr.IsValid() {
return conn
}
l.packetConnAccess.Lock()
l.packetConnMap[connAddr] = true
l.packetConnAccess.Unlock()
return &loopBackDetectPacketWrapper{PacketConn: conn, detector: l, connAddr: connAddr}
}
func (l *loopBackDetector) CheckConn(connAddr netip.AddrPort) bool {
l.connAccess.RLock()
defer l.connAccess.RUnlock()
return l.connMap[connAddr]
}
func (l *loopBackDetector) CheckPacketConn(connAddr netip.AddrPort) bool {
l.packetConnAccess.RLock()
defer l.packetConnAccess.RUnlock()
return l.packetConnMap[connAddr]
}
type loopBackDetectWrapper struct {
net.Conn
detector *loopBackDetector
connAddr netip.AddrPort
closeOnce sync.Once
}
func (w *loopBackDetectWrapper) Close() error {
w.closeOnce.Do(func() {
w.detector.connAccess.Lock()
delete(w.detector.connMap, w.connAddr)
w.detector.connAccess.Unlock()
})
return w.Conn.Close()
}
func (w *loopBackDetectWrapper) ReaderReplaceable() bool {
return true
}
func (w *loopBackDetectWrapper) WriterReplaceable() bool {
return true
}
func (w *loopBackDetectWrapper) Upstream() any {
return w.Conn
}
type loopBackDetectPacketWrapper struct {
net.PacketConn
detector *loopBackDetector
connAddr netip.AddrPort
closeOnce sync.Once
}
func (w *loopBackDetectPacketWrapper) Close() error {
w.closeOnce.Do(func() {
w.detector.packetConnAccess.Lock()
delete(w.detector.packetConnMap, w.connAddr)
w.detector.packetConnAccess.Unlock()
})
return w.PacketConn.Close()
}
func (w *loopBackDetectPacketWrapper) ReaderReplaceable() bool {
return true
}
func (w *loopBackDetectPacketWrapper) WriterReplaceable() bool {
return true
}
func (w *loopBackDetectPacketWrapper) Upstream() any {
return w.PacketConn
}
type abstractUDPConn interface {
net.Conn
net.PacketConn
}
type loopBackDetectUDPWrapper struct {
abstractUDPConn
detector *loopBackDetector
connAddr netip.AddrPort
closeOnce sync.Once
}
func (w *loopBackDetectUDPWrapper) Close() error {
w.closeOnce.Do(func() {
w.detector.packetConnAccess.Lock()
delete(w.detector.packetConnMap, w.connAddr)
w.detector.packetConnAccess.Unlock()
})
return w.abstractUDPConn.Close()
}
func (w *loopBackDetectUDPWrapper) ReaderReplaceable() bool {
return true
}
func (w *loopBackDetectUDPWrapper) WriterReplaceable() bool {
return true
}
func (w *loopBackDetectUDPWrapper) Upstream() any {
return w.abstractUDPConn
}

View File

@@ -1,7 +1,7 @@
[Unit]
Description=sing-box service
Documentation=https://sing-box.sagernet.org
After=network.target nss-lookup.target
After=network.target nss-lookup.target network-online.target
[Service]
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_SYS_PTRACE CAP_DAC_READ_SEARCH

View File

@@ -1,7 +1,7 @@
[Unit]
Description=sing-box service
Documentation=https://sing-box.sagernet.org
After=network.target nss-lookup.target
After=network.target nss-lookup.target network-online.target
[Service]
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_SYS_PTRACE CAP_DAC_READ_SEARCH

View File

@@ -1,7 +1,7 @@
[Unit]
Description=sing-box service
Documentation=https://sing-box.sagernet.org
After=network.target nss-lookup.target
After=network.target nss-lookup.target network-online.target
[Service]
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_SYS_PTRACE CAP_DAC_READ_SEARCH

View File

@@ -72,7 +72,7 @@ func (r *abstractDefaultRule) Match(metadata *adapter.InboundContext) bool {
}
}
if len(r.sourcePortItems) > 0 && !metadata.SourceAddressMatch {
if len(r.sourcePortItems) > 0 && !metadata.SourcePortMatch {
for _, item := range r.sourcePortItems {
if item.Match(metadata) {
metadata.SourcePortMatch = true
@@ -81,7 +81,7 @@ func (r *abstractDefaultRule) Match(metadata *adapter.InboundContext) bool {
}
}
if len(r.destinationAddressItems) > 0 && !metadata.SourceAddressMatch {
if len(r.destinationAddressItems) > 0 && !metadata.DestinationAddressMatch {
for _, item := range r.destinationAddressItems {
if item.Match(metadata) {
metadata.DestinationAddressMatch = true
@@ -90,7 +90,7 @@ func (r *abstractDefaultRule) Match(metadata *adapter.InboundContext) bool {
}
}
if len(r.destinationPortItems) > 0 && !metadata.SourceAddressMatch {
if len(r.destinationPortItems) > 0 && !metadata.DestinationPortMatch {
for _, item := range r.destinationPortItems {
if item.Match(metadata) {
metadata.DestinationPortMatch = true

View File

@@ -115,7 +115,7 @@ func NewDefaultRule(router adapter.Router, logger log.ContextLogger, options opt
if len(options.SourceIPCIDR) > 0 {
item, err := NewIPCIDRItem(true, options.SourceIPCIDR)
if err != nil {
return nil, E.Cause(err, "source_ipcidr")
return nil, E.Cause(err, "source_ip_cidr")
}
rule.sourceAddressItems = append(rule.sourceAddressItems, item)
rule.allItems = append(rule.allItems, item)

View File

@@ -114,7 +114,7 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
if len(options.SourceIPCIDR) > 0 {
item, err := NewIPCIDRItem(true, options.SourceIPCIDR)
if err != nil {
return nil, E.Cause(err, "source_ipcidr")
return nil, E.Cause(err, "source_ip_cidr")
}
rule.sourceAddressItems = append(rule.sourceAddressItems, item)
rule.allItems = append(rule.allItems, item)

View File

@@ -66,7 +66,7 @@ func NewDefaultHeadlessRule(router adapter.Router, options option.DefaultHeadles
if len(options.SourceIPCIDR) > 0 {
item, err := NewIPCIDRItem(true, options.SourceIPCIDR)
if err != nil {
return nil, E.Cause(err, "source_ipcidr")
return nil, E.Cause(err, "source_ip_cidr")
}
rule.sourceAddressItems = append(rule.sourceAddressItems, item)
rule.allItems = append(rule.allItems, item)

View File

@@ -35,9 +35,9 @@ func NewIPCIDRItem(isSource bool, prefixStrings []string) (*IPCIDRItem, error) {
}
var description string
if isSource {
description = "source_ipcidr="
description = "source_ip_cidr="
} else {
description = "ipcidr="
description = "ip_cidr="
}
if dLen := len(prefixStrings); dLen == 1 {
description += prefixStrings[0]
@@ -60,9 +60,9 @@ func NewIPCIDRItem(isSource bool, prefixStrings []string) (*IPCIDRItem, error) {
func NewRawIPCIDRItem(isSource bool, ipSet *netipx.IPSet) *IPCIDRItem {
var description string
if isSource {
description = "source_ipcidr="
description = "source_ip_cidr="
} else {
description = "ipcidr="
description = "ip_cidr="
}
description += "<binary>"
return &IPCIDRItem{

View File

@@ -24,7 +24,7 @@ var tlsRegistry []func(conn net.Conn) (loaded bool, netConn net.Conn, reflectTyp
func init() {
tlsRegistry = append(tlsRegistry, func(conn net.Conn) (loaded bool, netConn net.Conn, reflectType reflect.Type, reflectPointer uintptr) {
tlsConn, loaded := conn.(*tls.Conn)
tlsConn, loaded := common.Cast[*tls.Conn](conn)
if !loaded {
return
}