Update On Wed Nov 6 19:36:39 CET 2024

This commit is contained in:
github-action[bot]
2024-11-06 19:36:40 +01:00
parent 1db417eac9
commit b0af3ca28c
352 changed files with 8514 additions and 5573 deletions

1
.github/update.log vendored
View File

@@ -816,3 +816,4 @@ Update On Sat Nov 2 19:33:00 CET 2024
Update On Sun Nov 3 19:35:10 CET 2024
Update On Mon Nov 4 19:35:56 CET 2024
Update On Tue Nov 5 19:34:18 CET 2024
Update On Wed Nov 6 19:36:29 CET 2024

View File

@@ -3,18 +3,12 @@ package outbound
import (
"context"
"errors"
"os"
"strconv"
"github.com/metacubex/mihomo/component/dialer"
"github.com/metacubex/mihomo/component/loopback"
"github.com/metacubex/mihomo/component/resolver"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/constant/features"
)
var DisableLoopBackDetector, _ = strconv.ParseBool(os.Getenv("DISABLE_LOOPBACK_DETECTOR"))
type Direct struct {
*Base
loopBack *loopback.Detector
@@ -27,10 +21,8 @@ type DirectOption struct {
// DialContext implements C.ProxyAdapter
func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) {
if !features.CMFA && !DisableLoopBackDetector {
if err := d.loopBack.CheckConn(metadata); err != nil {
return nil, err
}
if err := d.loopBack.CheckConn(metadata); err != nil {
return nil, err
}
opts = append(opts, dialer.WithResolver(resolver.DirectHostResolver))
c, err := dialer.DialContext(ctx, "tcp", metadata.RemoteAddress(), d.Base.DialOptions(opts...)...)
@@ -42,10 +34,8 @@ func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...
// ListenPacketContext implements C.ProxyAdapter
func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
if !features.CMFA && !DisableLoopBackDetector {
if err := d.loopBack.CheckPacketConn(metadata); err != nil {
return nil, err
}
if err := d.loopBack.CheckPacketConn(metadata); err != nil {
return nil, err
}
// net.UDPConn.WriteTo only working with *net.UDPAddr, so we need a net.UDPAddr
if !metadata.Resolved() {

View File

@@ -15,6 +15,7 @@ type Interface struct {
Name string
Addresses []netip.Prefix
HardwareAddr net.HardwareAddr
Flags net.Flags
}
var (
@@ -66,6 +67,7 @@ func Interfaces() (map[string]*Interface, error) {
Name: iface.Name,
Addresses: ipNets,
HardwareAddr: iface.HardwareAddr,
Flags: iface.Flags,
}
}

View File

@@ -4,14 +4,25 @@ import (
"errors"
"fmt"
"net/netip"
"os"
"strconv"
"github.com/metacubex/mihomo/common/callback"
"github.com/metacubex/mihomo/component/iface"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/constant/features"
"github.com/puzpuzpuz/xsync/v3"
)
var disableLoopBackDetector, _ = strconv.ParseBool(os.Getenv("DISABLE_LOOPBACK_DETECTOR"))
func init() {
if features.CMFA {
disableLoopBackDetector = true
}
}
var ErrReject = errors.New("reject loopback connection")
type Detector struct {
@@ -20,6 +31,9 @@ type Detector struct {
}
func NewDetector() *Detector {
if disableLoopBackDetector {
return nil
}
return &Detector{
connMap: xsync.NewMapOf[netip.AddrPort, struct{}](),
packetConnMap: xsync.NewMapOf[uint16, struct{}](),
@@ -27,6 +41,9 @@ func NewDetector() *Detector {
}
func (l *Detector) NewConn(conn C.Conn) C.Conn {
if l == nil || l.connMap == nil {
return conn
}
metadata := C.Metadata{}
if metadata.SetRemoteAddr(conn.LocalAddr()) != nil {
return conn
@@ -42,6 +59,9 @@ func (l *Detector) NewConn(conn C.Conn) C.Conn {
}
func (l *Detector) NewPacketConn(conn C.PacketConn) C.PacketConn {
if l == nil || l.packetConnMap == nil {
return conn
}
metadata := C.Metadata{}
if metadata.SetRemoteAddr(conn.LocalAddr()) != nil {
return conn
@@ -58,6 +78,9 @@ func (l *Detector) NewPacketConn(conn C.PacketConn) C.PacketConn {
}
func (l *Detector) CheckConn(metadata *C.Metadata) error {
if l == nil || l.connMap == nil {
return nil
}
connAddr := metadata.SourceAddrPort()
if !connAddr.IsValid() {
return nil
@@ -69,6 +92,9 @@ func (l *Detector) CheckConn(metadata *C.Metadata) error {
}
func (l *Detector) CheckPacketConn(metadata *C.Metadata) error {
if l == nil || l.packetConnMap == nil {
return nil
}
connAddr := metadata.SourceAddrPort()
if !connAddr.IsValid() {
return nil

View File

@@ -5,6 +5,7 @@ import (
"net"
"strings"
"github.com/metacubex/mihomo/log"
"github.com/oschwald/maxminddb-golang"
)
@@ -23,11 +24,16 @@ type ASNReader struct {
*maxminddb.Reader
}
type ASNResult struct {
type GeoLite2 struct {
AutonomousSystemNumber uint32 `maxminddb:"autonomous_system_number"`
AutonomousSystemOrganization string `maxminddb:"autonomous_system_organization"`
}
type IPInfo struct {
ASN string `maxminddb:"asn"`
Name string `maxminddb:"name"`
}
func (r IPReader) LookupCode(ipAddress net.IP) []string {
switch r.databaseType {
case typeMaxmind:
@@ -66,8 +72,18 @@ func (r IPReader) LookupCode(ipAddress net.IP) []string {
}
}
func (r ASNReader) LookupASN(ip net.IP) ASNResult {
var result ASNResult
r.Lookup(ip, &result)
return result
func (r ASNReader) LookupASN(ip net.IP) (string, string) {
switch r.Metadata.DatabaseType {
case "GeoLite2-ASN", "DBIP-ASN-Lite (compat=GeoLite2-ASN)":
var result GeoLite2
_ = r.Lookup(ip, &result)
return fmt.Sprint(result.AutonomousSystemNumber), result.AutonomousSystemOrganization
case "ipinfo generic_asn_free.mmdb":
var result IPInfo
_ = r.Lookup(ip, &result)
return result.ASN[2:], result.Name
default:
log.Warnln("Unsupported ASN type: %s", r.Metadata.DatabaseType)
}
return "", ""
}

View File

@@ -20,12 +20,12 @@ require (
github.com/metacubex/bbolt v0.0.0-20240822011022-aed6d4850399
github.com/metacubex/chacha v0.1.0
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174
github.com/metacubex/quic-go v0.48.2-0.20241105005628-a3e65bac65b2
github.com/metacubex/randv2 v0.2.0
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4
github.com/metacubex/sing-shadowsocks v0.2.8
github.com/metacubex/sing-shadowsocks2 v0.2.2
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3
github.com/metacubex/tfo-go v0.0.0-20241006021335-daedaf0ca7aa
@@ -39,7 +39,7 @@ require (
github.com/sagernet/cors v1.2.1
github.com/sagernet/fswatch v0.1.1
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
github.com/sagernet/sing v0.5.0-rc.4
github.com/sagernet/sing v0.5.0
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6
github.com/sagernet/sing-shadowtls v0.1.4
github.com/samber/lo v1.47.0
@@ -116,4 +116,4 @@ require (
golang.org/x/tools v0.24.0 // indirect
)
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20241105005934-13bf5e941908

View File

@@ -104,20 +104,20 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec h1:HxreOiFTUrJXJautEo8rnE1uKTVGY8wtZepY1Tii/Nc=
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec/go.mod h1:8BVmQ+3cxjqzWElafm24rb2Ae4jRI6vAXNXWqWjfrXw=
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174 h1:GvigRPEU+cbnzdLWne47cxLrc28Abohl3ECtVdnrbq0=
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174/go.mod h1:AiZ+UPgrkO1DTnmiAX4b+kRoV1Vfc65UkYD7RbFlIZA=
github.com/metacubex/quic-go v0.48.2-0.20241105005628-a3e65bac65b2 h1:1prpWzQnhN/LgGTMA6nz86MGcppDUOwfRkhxPOnrzAk=
github.com/metacubex/quic-go v0.48.2-0.20241105005628-a3e65bac65b2/go.mod h1:AiZ+UPgrkO1DTnmiAX4b+kRoV1Vfc65UkYD7RbFlIZA=
github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs=
github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY=
github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a h1:JuR0/7RDxQtlZp/GOzrdqNq04HplTxavPRHrek8ouJk=
github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing v0.0.0-20241105005934-13bf5e941908 h1:cZYdGEQKfLsw//TI7dk9bdplz48zitpEDbDGusB9d40=
github.com/metacubex/sing v0.0.0-20241105005934-13bf5e941908/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4 h1:HobpULaPK6OoxrHMmgcwLkwwIduXVmwdcznwUfH1GQM=
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4/go.mod h1:g7Mxj7b7zm7YVqD975mk/hSmrb0A0G4bVvIMr2MMzn8=
github.com/metacubex/sing-shadowsocks v0.2.8 h1:wIhlaigswzjPw4hej75sEvWte3QR0+AJRafgwBHO5B4=
github.com/metacubex/sing-shadowsocks v0.2.8/go.mod h1:X3x88XtJpBxG0W0/ECOJL6Ib0SJ3xdniAkU/6/RMWU0=
github.com/metacubex/sing-shadowsocks2 v0.2.2 h1:eaf42uVx4Lr21S6MDYs0ZdTvGA0GEhDpb9no4+gdXPo=
github.com/metacubex/sing-shadowsocks2 v0.2.2/go.mod h1:BhOug03a/RbI7y6hp6q+6ITM1dXjnLTmeWBHSTwvv2Q=
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c h1:qfUZ8xBrViOCZamvcC8CyV7Ii8sAUrn7RqZxFGn56tQ=
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c/go.mod h1:lCrP0AW7ieKnXG1JEeZLW+9h99QzjuOX0MfCQfz6TgE=
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98 h1:vW0QDrzUc4k1yi3A76lDW064zonPj880QFcpTD58u7A=
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98/go.mod h1:GRcrj7VnhvYFsS34cv0J2qTVm5h9DvQuGwliVyVLVvE=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 h1:OAXiCosqY8xKDp3pqTW3qbrCprZ1l6WkrXSFSCwyY4I=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY=
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 h1:xg71VmzLS6ByAzi/57phwDvjE+dLLs+ozH00k4DnOns=

View File

@@ -279,7 +279,11 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
return
}
defaultInterfaceMonitor, err = tun.NewDefaultInterfaceMonitor(networkUpdateMonitor, log.SingLogger, tun.DefaultInterfaceMonitorOptions{InterfaceFinder: interfaceFinder, OverrideAndroidVPN: true})
overrideAndroidVPN := true
if disable, _ := strconv.ParseBool(os.Getenv("DISABLE_OVERRIDE_ANDROID_VPN")); disable {
overrideAndroidVPN = false
}
defaultInterfaceMonitor, err = tun.NewDefaultInterfaceMonitor(networkUpdateMonitor, log.SingLogger, tun.DefaultInterfaceMonitorOptions{InterfaceFinder: interfaceFinder, OverrideAndroidVPN: overrideAndroidVPN})
if err != nil {
err = E.Cause(err, "create DefaultInterfaceMonitor")
return

View File

@@ -1,8 +1,6 @@
package common
import (
"strconv"
"github.com/metacubex/mihomo/component/geodata"
"github.com/metacubex/mihomo/component/mmdb"
C "github.com/metacubex/mihomo/constant"
@@ -26,17 +24,14 @@ func (a *ASN) Match(metadata *C.Metadata) (bool, string) {
return false, ""
}
result := mmdb.ASNInstance().LookupASN(ip.AsSlice())
asnNumber := strconv.FormatUint(uint64(result.AutonomousSystemNumber), 10)
ipASN := asnNumber + " " + result.AutonomousSystemOrganization
asn, aso := mmdb.ASNInstance().LookupASN(ip.AsSlice())
if a.isSourceIP {
metadata.SrcIPASN = ipASN
metadata.SrcIPASN = asn + " " + aso
} else {
metadata.DstIPASN = ipASN
metadata.DstIPASN = asn + " " + aso
}
match := a.asn == asnNumber
return match, a.adapter
return a.asn == asn, a.adapter
}
func (a *ASN) RuleType() C.RuleType {

View File

@@ -117,24 +117,19 @@ func (tt *tcpTracker) Upstream() any {
}
func parseRemoteDestination(addr net.Addr, conn C.Connection) string {
if addr == nil && conn != nil {
return conn.RemoteDestination()
}
if addrPort, err := netip.ParseAddrPort(addr.String()); err == nil && addrPort.Addr().IsValid() {
return addrPort.Addr().String()
} else {
if conn != nil {
return conn.RemoteDestination()
} else {
return ""
if addr != nil {
if addrPort, err := netip.ParseAddrPort(addr.String()); err == nil && addrPort.Addr().IsValid() {
return addrPort.Addr().String()
}
}
if conn != nil {
return conn.RemoteDestination()
}
return ""
}
func NewTCPTracker(conn C.Conn, manager *Manager, metadata *C.Metadata, rule C.Rule, uploadTotal int64, downloadTotal int64, pushToManager bool) *tcpTracker {
if conn != nil {
metadata.RemoteDst = parseRemoteDestination(conn.RemoteAddr(), conn)
}
metadata.RemoteDst = parseRemoteDestination(conn.RemoteAddr(), conn)
t := &tcpTracker{
Conn: conn,

View File

@@ -48,12 +48,12 @@ require (
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec // indirect
github.com/metacubex/mihomo v1.7.0 // indirect
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174 // indirect
github.com/metacubex/quic-go v0.48.2-0.20241105005628-a3e65bac65b2 // indirect
github.com/metacubex/randv2 v0.2.0 // indirect
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4 // indirect
github.com/metacubex/sing-shadowsocks v0.2.8 // indirect
github.com/metacubex/sing-shadowsocks2 v0.2.2 // indirect
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c // indirect
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98 // indirect
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 // indirect
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 // indirect
github.com/metacubex/tfo-go v0.0.0-20241006021335-daedaf0ca7aa // indirect
@@ -74,7 +74,7 @@ require (
github.com/sagernet/fswatch v0.1.1 // indirect
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect
github.com/sagernet/nftables v0.3.0-beta.4 // indirect
github.com/sagernet/sing v0.5.0-rc.4 // indirect
github.com/sagernet/sing v0.5.0 // indirect
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6 // indirect
github.com/sagernet/sing-shadowtls v0.1.4 // indirect
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect
@@ -111,7 +111,7 @@ require (
lukechampine.com/blake3 v1.3.0 // indirect
)
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20241105005934-13bf5e941908
replace cfa => ../../main/golang

View File

@@ -100,20 +100,20 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec h1:HxreOiFTUrJXJautEo8rnE1uKTVGY8wtZepY1Tii/Nc=
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec/go.mod h1:8BVmQ+3cxjqzWElafm24rb2Ae4jRI6vAXNXWqWjfrXw=
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174 h1:GvigRPEU+cbnzdLWne47cxLrc28Abohl3ECtVdnrbq0=
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174/go.mod h1:AiZ+UPgrkO1DTnmiAX4b+kRoV1Vfc65UkYD7RbFlIZA=
github.com/metacubex/quic-go v0.48.2-0.20241105005628-a3e65bac65b2 h1:1prpWzQnhN/LgGTMA6nz86MGcppDUOwfRkhxPOnrzAk=
github.com/metacubex/quic-go v0.48.2-0.20241105005628-a3e65bac65b2/go.mod h1:AiZ+UPgrkO1DTnmiAX4b+kRoV1Vfc65UkYD7RbFlIZA=
github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs=
github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY=
github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a h1:JuR0/7RDxQtlZp/GOzrdqNq04HplTxavPRHrek8ouJk=
github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing v0.0.0-20241105005934-13bf5e941908 h1:cZYdGEQKfLsw//TI7dk9bdplz48zitpEDbDGusB9d40=
github.com/metacubex/sing v0.0.0-20241105005934-13bf5e941908/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4 h1:HobpULaPK6OoxrHMmgcwLkwwIduXVmwdcznwUfH1GQM=
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4/go.mod h1:g7Mxj7b7zm7YVqD975mk/hSmrb0A0G4bVvIMr2MMzn8=
github.com/metacubex/sing-shadowsocks v0.2.8 h1:wIhlaigswzjPw4hej75sEvWte3QR0+AJRafgwBHO5B4=
github.com/metacubex/sing-shadowsocks v0.2.8/go.mod h1:X3x88XtJpBxG0W0/ECOJL6Ib0SJ3xdniAkU/6/RMWU0=
github.com/metacubex/sing-shadowsocks2 v0.2.2 h1:eaf42uVx4Lr21S6MDYs0ZdTvGA0GEhDpb9no4+gdXPo=
github.com/metacubex/sing-shadowsocks2 v0.2.2/go.mod h1:BhOug03a/RbI7y6hp6q+6ITM1dXjnLTmeWBHSTwvv2Q=
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c h1:qfUZ8xBrViOCZamvcC8CyV7Ii8sAUrn7RqZxFGn56tQ=
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c/go.mod h1:lCrP0AW7ieKnXG1JEeZLW+9h99QzjuOX0MfCQfz6TgE=
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98 h1:vW0QDrzUc4k1yi3A76lDW064zonPj880QFcpTD58u7A=
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98/go.mod h1:GRcrj7VnhvYFsS34cv0J2qTVm5h9DvQuGwliVyVLVvE=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 h1:OAXiCosqY8xKDp3pqTW3qbrCprZ1l6WkrXSFSCwyY4I=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY=
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 h1:xg71VmzLS6ByAzi/57phwDvjE+dLLs+ozH00k4DnOns=

View File

@@ -11,7 +11,7 @@ require (
replace github.com/metacubex/mihomo => ../../foss/golang/clash
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20241105005934-13bf5e941908
require (
github.com/3andne/restls-client-go v0.1.6 // indirect
@@ -55,12 +55,12 @@ require (
github.com/metacubex/chacha v0.1.0 // indirect
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec // indirect
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174 // indirect
github.com/metacubex/quic-go v0.48.2-0.20241105005628-a3e65bac65b2 // indirect
github.com/metacubex/randv2 v0.2.0 // indirect
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4 // indirect
github.com/metacubex/sing-shadowsocks v0.2.8 // indirect
github.com/metacubex/sing-shadowsocks2 v0.2.2 // indirect
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c // indirect
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98 // indirect
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 // indirect
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 // indirect
github.com/metacubex/tfo-go v0.0.0-20241006021335-daedaf0ca7aa // indirect
@@ -81,7 +81,7 @@ require (
github.com/sagernet/fswatch v0.1.1 // indirect
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect
github.com/sagernet/nftables v0.3.0-beta.4 // indirect
github.com/sagernet/sing v0.5.0-rc.4 // indirect
github.com/sagernet/sing v0.5.0 // indirect
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6 // indirect
github.com/sagernet/sing-shadowtls v0.1.4 // indirect
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect

View File

@@ -100,20 +100,20 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec h1:HxreOiFTUrJXJautEo8rnE1uKTVGY8wtZepY1Tii/Nc=
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec/go.mod h1:8BVmQ+3cxjqzWElafm24rb2Ae4jRI6vAXNXWqWjfrXw=
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174 h1:GvigRPEU+cbnzdLWne47cxLrc28Abohl3ECtVdnrbq0=
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174/go.mod h1:AiZ+UPgrkO1DTnmiAX4b+kRoV1Vfc65UkYD7RbFlIZA=
github.com/metacubex/quic-go v0.48.2-0.20241105005628-a3e65bac65b2 h1:1prpWzQnhN/LgGTMA6nz86MGcppDUOwfRkhxPOnrzAk=
github.com/metacubex/quic-go v0.48.2-0.20241105005628-a3e65bac65b2/go.mod h1:AiZ+UPgrkO1DTnmiAX4b+kRoV1Vfc65UkYD7RbFlIZA=
github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs=
github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY=
github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a h1:JuR0/7RDxQtlZp/GOzrdqNq04HplTxavPRHrek8ouJk=
github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing v0.0.0-20241105005934-13bf5e941908 h1:cZYdGEQKfLsw//TI7dk9bdplz48zitpEDbDGusB9d40=
github.com/metacubex/sing v0.0.0-20241105005934-13bf5e941908/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4 h1:HobpULaPK6OoxrHMmgcwLkwwIduXVmwdcznwUfH1GQM=
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4/go.mod h1:g7Mxj7b7zm7YVqD975mk/hSmrb0A0G4bVvIMr2MMzn8=
github.com/metacubex/sing-shadowsocks v0.2.8 h1:wIhlaigswzjPw4hej75sEvWte3QR0+AJRafgwBHO5B4=
github.com/metacubex/sing-shadowsocks v0.2.8/go.mod h1:X3x88XtJpBxG0W0/ECOJL6Ib0SJ3xdniAkU/6/RMWU0=
github.com/metacubex/sing-shadowsocks2 v0.2.2 h1:eaf42uVx4Lr21S6MDYs0ZdTvGA0GEhDpb9no4+gdXPo=
github.com/metacubex/sing-shadowsocks2 v0.2.2/go.mod h1:BhOug03a/RbI7y6hp6q+6ITM1dXjnLTmeWBHSTwvv2Q=
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c h1:qfUZ8xBrViOCZamvcC8CyV7Ii8sAUrn7RqZxFGn56tQ=
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c/go.mod h1:lCrP0AW7ieKnXG1JEeZLW+9h99QzjuOX0MfCQfz6TgE=
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98 h1:vW0QDrzUc4k1yi3A76lDW064zonPj880QFcpTD58u7A=
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98/go.mod h1:GRcrj7VnhvYFsS34cv0J2qTVm5h9DvQuGwliVyVLVvE=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 h1:OAXiCosqY8xKDp3pqTW3qbrCprZ1l6WkrXSFSCwyY4I=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY=
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 h1:xg71VmzLS6ByAzi/57phwDvjE+dLLs+ozH00k4DnOns=

View File

@@ -25,7 +25,7 @@ require (
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4
github.com/metacubex/sing-shadowsocks v0.2.8
github.com/metacubex/sing-shadowsocks2 v0.2.2
github.com/metacubex/sing-tun v0.2.7-0.20241105010444-9ece61968014
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3
github.com/metacubex/tfo-go v0.0.0-20241006021335-daedaf0ca7aa

View File

@@ -116,8 +116,8 @@ github.com/metacubex/sing-shadowsocks v0.2.8 h1:wIhlaigswzjPw4hej75sEvWte3QR0+AJ
github.com/metacubex/sing-shadowsocks v0.2.8/go.mod h1:X3x88XtJpBxG0W0/ECOJL6Ib0SJ3xdniAkU/6/RMWU0=
github.com/metacubex/sing-shadowsocks2 v0.2.2 h1:eaf42uVx4Lr21S6MDYs0ZdTvGA0GEhDpb9no4+gdXPo=
github.com/metacubex/sing-shadowsocks2 v0.2.2/go.mod h1:BhOug03a/RbI7y6hp6q+6ITM1dXjnLTmeWBHSTwvv2Q=
github.com/metacubex/sing-tun v0.2.7-0.20241105010444-9ece61968014 h1:5zAAcCCyuorvkXu3su4VmUkYDXOdzvRKPGEdeyc+ljY=
github.com/metacubex/sing-tun v0.2.7-0.20241105010444-9ece61968014/go.mod h1:GRcrj7VnhvYFsS34cv0J2qTVm5h9DvQuGwliVyVLVvE=
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98 h1:vW0QDrzUc4k1yi3A76lDW064zonPj880QFcpTD58u7A=
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98/go.mod h1:GRcrj7VnhvYFsS34cv0J2qTVm5h9DvQuGwliVyVLVvE=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 h1:OAXiCosqY8xKDp3pqTW3qbrCprZ1l6WkrXSFSCwyY4I=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY=
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 h1:xg71VmzLS6ByAzi/57phwDvjE+dLLs+ozH00k4DnOns=

View File

@@ -179,8 +179,9 @@ pub struct IVerge {
/// set system proxy bypass
pub system_proxy_bypass: Option<String>,
/// proxy guard duration
pub proxy_guard_duration: Option<u64>,
/// proxy guard interval
#[serde(alias = "proxy_guard_duration")]
pub proxy_guard_interval: Option<u64>,
/// theme setting
pub theme_setting: Option<IVergeTheme>,
@@ -330,7 +331,7 @@ impl IVerge {
enable_random_port: Some(false),
verge_mixed_port: Some(7890),
enable_proxy_guard: Some(false),
proxy_guard_duration: Some(30),
proxy_guard_interval: Some(30),
auto_close_connection: Some(true),
enable_builtin_enhanced: Some(true),
enable_clash_fields: Some(true),

View File

@@ -267,13 +267,13 @@ impl Sysopt {
loop {
sleep(Duration::from_secs(wait_secs)).await;
let (enable, guard, guard_duration, bypass) = {
let (enable, guard, guard_interval, bypass) = {
let verge = Config::verge();
let verge = verge.latest();
(
verge.enable_system_proxy.unwrap_or(false),
verge.enable_proxy_guard.unwrap_or(false),
verge.proxy_guard_duration.unwrap_or(10),
verge.proxy_guard_interval.unwrap_or(10),
verge.system_proxy_bypass.clone(),
)
};
@@ -284,7 +284,7 @@ impl Sysopt {
}
// update duration
wait_secs = guard_duration;
wait_secs = guard_interval;
log::debug!(target: "app", "try to guard the system proxy");

View File

@@ -23,7 +23,7 @@ export interface VergeConfig {
enable_random_port?: boolean;
verge_mixed_port?: number;
enable_proxy_guard?: boolean;
proxy_guard_duration?: number;
proxy_guard_interval?: number;
system_proxy_bypass?: string;
web_ui_list?: string[];
hotkeys?: string[];

View File

@@ -83,7 +83,7 @@ export default function ConnectionDetailDialog({
))}
<h3 className="col-span-2 py-1 pt-5 text-xl font-semibold">
{t("Meta Info")}
{t("Metadata")}
</h3>
{Object.entries(item.metadata)

View File

@@ -30,7 +30,7 @@ const TitleComp = () => {
if (port == clashConfigs?.["mixed-port"]) {
return {
label: t("Success"),
label: t("Successful"),
color: "success",
};
} else {

View File

@@ -12,7 +12,7 @@ export const NoticeProvider = () => {
}>("nyanpasu://notice-message", ({ payload }) => {
if ("ok" in payload?.set_config) {
notification({
title: t("Success"),
title: t("Successful"),
body: "Refresh Clash Config",
type: NotificationType.Success,
});

View File

@@ -283,7 +283,7 @@ export const ProfileDialog = ({
<div className="ml-2 text-red-500">{localProfileMessage}</div>
)}
<span className="px-2 text-xs">
* {t("Select file to import or leave blank to touch new one.")}
* {t("Choose file to import or leave it blank to create new one")}
</span>
</>
)}

View File

@@ -50,7 +50,7 @@ export const UpdateProviders = () => {
startIcon={<Refresh />}
onClick={handleProviderUpdate}
>
{t("Update Rules Providers All")}
{t("Update All Rules Providers")}
</LoadingButton>
);
};

View File

@@ -50,7 +50,7 @@ export const UpdateProxiesProviders = () => {
startIcon={<Refresh />}
onClick={handleProviderUpdate}
>
{t("Update Proxies Providers All")}
{t("Update All Proxies Providers")}
</LoadingButton>
);
};

View File

@@ -175,12 +175,12 @@ export const ClashCoreItem = ({
getClashCore.mutate();
message(t("Successfully update core", { core: `${data.name}` }), {
message(t("Successfully updated the core", { core: `${data.name}` }), {
kind: "info",
title: t("Success"),
title: t("Successful"),
});
} catch (e) {
message(t("Update failed", { error: `${formatError(e)}` }), {
message(t("Failed to update", { error: `${formatError(e)}` }), {
kind: "error",
title: t("Error"),
});

View File

@@ -95,7 +95,7 @@ export const SettingClashBase = () => {
{isWIN && (
<ListItem sx={{ pl: 0, pr: 0 }}>
<ListItemText primary={t("Open UWP tool")} />
<ListItemText primary={t("Open UWP Tool")} />
<Button variant="contained" onClick={clickUWP}>
{t("Open")}

View File

@@ -56,13 +56,16 @@ export const SettingClashCore = () => {
await setClashCore(core);
message(t("Successfully switch to clash core", { core: `${core}` }), {
kind: "info",
title: t("Success"),
});
message(
t("Successfully switched to the clash core", { core: `${core}` }),
{
kind: "info",
title: t("Successful"),
},
);
} catch (e) {
message(
t("Switching failed, you could see the details in the log", {
t("Failed to switch. You could see the details in the log", {
error: `${e instanceof Error ? e.message : String(e)}`,
}),
{
@@ -79,13 +82,13 @@ export const SettingClashCore = () => {
try {
await restartSidecar();
message(t("Successfully restart core"), {
message(t("Successfully restarted the core"), {
kind: "info",
title: t("Success"),
title: t("Successful"),
});
} catch (e) {
message(
t("Restart failed, full detailed please check the log") +
t("Failed to restart. You could see the details in the log") +
formatError(e),
{
kind: "error",
@@ -99,7 +102,7 @@ export const SettingClashCore = () => {
try {
await getLatestCore.mutate();
} catch (e) {
message(t("Fetch failed, please check your internet connection"), {
message(t("Failed to fetch. Please check your network connection"), {
kind: "error",
title: t("Error"),
});

View File

@@ -49,7 +49,7 @@ export const SettingClashPort = () => {
});
} finally {
message(t("After restart to take effect"), {
title: t("Success"),
title: t("Successful"),
kind: "info",
});
}

View File

@@ -130,12 +130,12 @@ export const SettingClashWeb = () => {
value={editString}
variant="outlined"
multiline
placeholder={t(`Support %host %port %secret`)}
placeholder={t(`Support %host %port, and %secret`)}
onChange={(e) => setEditString(e.target.value)}
/>
<Typography sx={{ userSelect: "text" }}>
{t("Replace host, port, secret with")}
{t("Replace host, port, and secret with")}
</Typography>
<Box display="flex" gap={1}>

View File

@@ -60,7 +60,7 @@ export const SettingNyanpasuMisc = () => {
/>
<SwitchItem
label={t("Lighten up Animation Effects")}
label={t("Lighten Up Animation Effects")}
{...createBooleanProps("lighten_animation_effects")}
/>

View File

@@ -44,8 +44,8 @@ export const SettingNyanpasuPath = () => {
await setCustomAppDir(selected);
message(t("App directory changed successfully"), {
title: t("Success"),
message(t("Successfully changed the app directory"), {
title: t("Successful"),
kind: "error",
});
@@ -53,7 +53,7 @@ export const SettingNyanpasuPath = () => {
await restartApplication();
} catch (e) {
message(t("Migration failed", { error: `${JSON.stringify(e)}` }), {
message(t("Failed to migrate", { error: `${JSON.stringify(e)}` }), {
title: t("Error"),
kind: "error",
});

View File

@@ -14,7 +14,7 @@ export const SettingSystemBehavior = () => {
<Grid container spacing={2}>
<Grid size={{ xs: 6 }}>
<PaperSwitchButton
label={t("Auto Launch")}
label={t("Auto Start")}
checked={nyanpasuConfig?.enable_auto_launch || false}
onClick={() =>
setNyanpasuConfig({

View File

@@ -102,12 +102,12 @@ export const SettingSystemProxy = () => {
/>
<NumberItem
label={t("Guard Duration")}
vaule={nyanpasuConfig?.proxy_guard_duration || 0}
label={t("Guard Interval")}
vaule={nyanpasuConfig?.proxy_guard_interval || 0}
checkEvent={(input) => input <= 0}
checkLabel={t("Dueation must be greater than 0")}
checkLabel={t("The interval must be greater than 0 second")}
onApply={(value) => {
setNyanpasuConfig({ proxy_guard_duration: value });
setNyanpasuConfig({ proxy_guard_interval: value });
}}
textFieldProps={{
inputProps: {

View File

@@ -69,15 +69,15 @@ export const SettingSystemService = () => {
} catch (e) {
const errorMessage = `${
getServiceStatus.data === "not_installed"
? t("Install failed")
: t("Uninstall failed")
? t("Failed to install")
: t("Failed to uninstall")
}: ${formatError(e)}`;
message(errorMessage, {
kind: "error",
title: t("Error"),
});
// If install failed show a prompt to user to install the service manually
// If the installation fails, prompt the user to manually install the service
promptDialog.show(
getServiceStatus.data === "not_installed" ? "install" : "uninstall",
);

View File

@@ -90,7 +90,7 @@
"Destination ASN": "Destination ASN",
"Type": "Type",
"Connection Detail": "Connection Detail",
"Meta Info": "Meta Info",
"Metadata": "Metadata",
"Remote": "Remote",
"Local": "Local",
"Remote Profile": "Remote Profile",
@@ -133,14 +133,14 @@
"System Service": "System Service",
"Service Mode": "Service Mode",
"Initiating Behavior": "Initiating Behavior",
"Auto Launch": "Auto Launch",
"Auto Start": "Auto Start",
"Silent Start": "Silent Start",
"System Proxy": "System Proxy",
"Open UWP tool": "Open UWP tool",
"Open UWP Tool": "Open UWP Tool",
"System Proxy Setting": "System Proxy Setting",
"Proxy Guard": "Proxy Guard",
"Guard Duration": "Guard Duration",
"Dueation must be greater than 0": "Dueation must be greater than 0.",
"Guard Interval": "Guard Interval",
"The interval must be greater than 0 second": "The interval must be greater than 0 second.",
"Proxy Bypass": "Proxy Bypass",
"Apply": "Apply",
"Current System Proxy": "Current System Proxy",
@@ -213,24 +213,24 @@
"Proxy Layout Column": "Proxy Layout Column",
"Default Latency Test": "Default Latency Test",
"Error": "Error",
"Success": "Success",
"Successful": "Successful",
"Occupied": "Occupied",
"Disabled": "Disabled",
"Providers": "Providers",
"Proxies Providers": "Proxies Providers",
"Rules Providers": "Rules Providers",
"Update Rules Providers All": "Update Rules Providers All",
"Update All Rules Providers": "Update All Rules Providers",
"Rule Set rules": "{{rule}} rules",
"Last Update": "Last Updated: {{fromNow}}",
"Update Rules Providers Success": "Update Rules Providers Success",
"Portable Update Error": "Portable Update is not supported, please download the latest version from the official website.",
"Successfully Updated Rules Providers": "Successfully Updated Rules Providers",
"Portable Update Error": "Portable Update is not supported. Please download the latest version from the official website.",
"Tray Proxies Selector": "Tray Proxies Selector",
"Hidden": "Hidden",
"Normal": "Normal",
"Submenu": "Submenu",
"Proxy Set proxies": "{{rule}} proxies",
"Update Proxies Providers All": "Update Rules Proxies All",
"Lighten up Animation Effects": "Lighten up Animation Effects",
"Update All Proxies Providers": "Update All Proxies Providers",
"Lighten Up Animation Effects": "Lighten Up Animation Effects",
"Subscription": "Subscription",
"FetchError": "Failed to fetch {{content}} due to network issue. Please check your network connection and try again later.",
"tun": "TUN Mode",
@@ -239,7 +239,7 @@
"Proxy Takeover Status": "Proxy Takeover Status",
"Subscription Expires In": "Expires {{time}}",
"Subscription Updated At": "Updated at {{time}}",
"Select file to import or leave blank to touch new one.": "Select file to import or leave blank to touch new one.",
"Choose file to import or leave it blank to create new one": "Choose a file to import or leave it blank to create new one.",
"updater": {
"title": "New version available",
"close": "Ignore",
@@ -251,13 +251,13 @@
"running": "Running",
"stopped_reason": "Stopped, Reason: {{reason}}",
"Current Status": "Current Status: {{status}}",
"Information: Please make sure that the Clash Nyanpasu Service is installed and enabled": "Information: Please make sure that the Clash Nyanpasu Service is installed and enabled.",
"Information: To enable service mode, make sure the Clash Nyanpasu service is installed and started": "Information: To enable service mode, make sure the Clash Nyanpasu service is installed and started.",
"install": "install",
"uninstall": "uninstall",
"start": "start",
"stop": "stop",
"Install failed": "Install failed",
"Uninstall failed": "Uninstall failed",
"Failed to install": "Failed to install",
"Failed to uninstall": "Failed to uninstall",
"service_shortcuts": {
"title": "Service Shortcuts",
"core_status": "Core Status: ",
@@ -266,22 +266,22 @@
"last_status_changed_since": "Last status changed: {{time}}"
},
"Service Manual Tips": "Service Manual Tips",
"Unable to operation the service automatically": "Unable to {{operation}} the service automatically. Please navigate to the core directory, open PowerShell (as Administrator) on Windows or a terminal emulator on macOS/Linux, and run the following commands:",
"Successfully switch to clash core": "Successfully switch to the {{core}} core.",
"Switching failed, you could see the details in the log": "Switching failed, you could see the details in the log. \nError: {{error}}",
"Successfully restart core": "Successfully restart the core.",
"Restart failed, full detailed please check the log": "Restart failed, full detailed please check the log.\n\nError:",
"Fetch failed, please check your internet connection": "Fetch failed, please check your internet connection.",
"Successfully update core": "Successfully update the {{core}} core.",
"Update failed": "Update failed. {{error}}",
"Unable to operation the service automatically": "Unable to {{operation}} the service automatically. Please navigate to the core directory, run PowerShell as administrator on Windows or a terminal emulator on macOS/Linux, and execute the following commands:",
"Successfully switched to the clash core": "Successfully switched to the {{core}} core.",
"Failed to switch. You could see the details in the log": "Failed to switch. You could see the details in the log. \nError: {{error}}",
"Successfully restarted the core": "Successfully restarted the core.",
"Failed to restart. You could see the details in the log": "Failed to restart. You could see the details in the log.\n\nError:",
"Failed to fetch. Please check your network connection": "Failed to fetch. Please check your network connection.",
"Successfully updated the core": "Successfully updated the {{core}} core.",
"Failed to update": "Failed to update. {{error}}",
"Multiple directories are not supported": "Multiple directories are not supported.",
"App directory changed successfully": "App directory changed successfully.",
"Migration failed": "Migration failed! {{error}}",
"Successfully changed the app directory": "Successfully changed the app directory.",
"Failed to migrate": "Failed to migrate. {{error}}",
"Web UI": "Web UI",
"New Item": "New Item",
"Edit Item": "Edit Item",
"Input": "Input",
"Support %host %port %secret": "Support %host, %port & %secret",
"Replace host, port, secret with": "Replace host, port & secret with:",
"Support %host %port, and %secret": "Support %host, %port, and %secret",
"Replace host, port, and secret with": "Replace host, port, and secret with:",
"Result": "Result"
}

View File

@@ -77,17 +77,17 @@
"System Service": "Системная сервиса",
"Service Mode": "Режим сервиса",
"Initiating Behavior": "Инициирующее поведение",
"Auto Launch": "Автозапуск",
"Auto Start": "Автозапуск",
"Silent Start": "Тихий запуск",
"System Proxy": "Системный прокси",
"System Proxy Setting": "Настройка системного прокси",
"Proxy Guard": "Защита прокси",
"Guard Duration": "Период защиты",
"Guard Interval": "Период защиты",
"Proxy Bypass": "Игнорирование прокси",
"Current System Proxy": "Текущий системный прокси",
"User Interface": "Пользовательский интерфейс",
"Theme Mode": "Режим темы",
"Open UWP tool": "Открыть UWP инструмент",
"Open UWP Tool": "Открыть UWP инструмент",
"Theme Blur": "Размытие темы",
"Theme Setting": "Настройка темы",
"Hotkey Setting": "Настройка клавиатурных сокращений",
@@ -140,14 +140,14 @@
"disable_tun_mode": "Отключить режим туннеля",
"Error": "Ошибка",
"Success": "Успех",
"Successful": "Успех",
"Providers": "Провайдеры",
"Rules Providers": "Провайдеры правил",
"Update Rules Providers All": "Обновить все провайдеры правил",
"Update All Rules Providers": "Обновить все провайдеры правил",
"Rule Set rules": "{{rule}} правила",
"Last Update": "Последнее обновление {{fromNow}}",
"Update Rules Providers Success": "Провайдеры правил успешно обновлены",
"Successfully Updated Rules Providers": "Провайдеры правил успешно обновлены",
"Portable Update Error": "Обновление портативной версии не поддерживается",
"Tray Proxies Selector": "Выбор прокси в трее",
@@ -162,7 +162,7 @@
"system_proxy": "Системный прокси",
"Subscription Expires In": "Подписка истекает через {{time}}",
"Subscription Updated At": "Подписка обновлена {{time}}",
"Select file to import or leave blank to touch new one.": "Выберите файл для импорта или оставьте пустым, чтобы создать новый.",
"Choose file to import or leave it blank to create new one": "Выберите файл для импорта или оставьте пустым, чтобы создать новый.",
"updater": {
"title": "Доступно обновление",
"close": "Закрыть",

View File

@@ -90,7 +90,7 @@
"Destination ASN": "目标 ASN",
"Type": "类型",
"Connection Detail": "连接详情",
"Meta Info": "元信息",
"Metadata": "元信息",
"Remote": "远程",
"Local": "本地",
"Remote Profile": "远程配置",
@@ -133,14 +133,14 @@
"System Service": "系统服务",
"Service Mode": "服务模式",
"Initiating Behavior": "启动行为",
"Auto Launch": "开机自启",
"Auto Start": "开机自启",
"Silent Start": "静默启动",
"System Proxy": "系统代理",
"Open UWP tool": "UWP 工具",
"Open UWP Tool": "UWP 工具",
"System Proxy Setting": "系统代理设置",
"Proxy Guard": "系统代理守卫",
"Guard Duration": "代理守卫间隔",
"Dueation must be greater than 0": "间隔时间必须大于 0 秒。",
"Guard Interval": "代理守卫间隔",
"The interval must be greater than 0 second": "间隔时间必须大于 0 秒。",
"Proxy Bypass": "代理绕过",
"Apply": "应用",
"Current System Proxy": "当前系统代理",
@@ -213,24 +213,24 @@
"Proxy Layout Column": "代理页布局列数",
"Default Latency Test": "默认测试链接",
"Error": "错误",
"Success": "成功",
"Successful": "成功",
"Occupied": "被占用",
"Disabled": "已禁用",
"Providers": "资源",
"Proxies Providers": "代理集",
"Rules Providers": "规则集",
"Update Rules Providers All": "全部更新",
"Update All Rules Providers": "全部更新",
"Rule Set rules": "{{rule}} 条规则",
"Last Update": "{{fromNow}}更新",
"Update Rules Providers Success": "更新规则集成功",
"Successfully Updated Rules Providers": "更新规则集成功",
"Portable Update Error": "便携版无法自动更新,请到 GitHub 下载最新版本",
"Tray Proxies Selector": "托盘代理选择",
"Hidden": "隐藏",
"Normal": "开启",
"Submenu": "子菜单",
"Proxy Set proxies": "{{rule}} 个节点",
"Update Proxies Providers All": "全部更新",
"Lighten up Animation Effects": "减轻动画效果",
"Update All Proxies Providers": "全部更新",
"Lighten Up Animation Effects": "减轻动画效果",
"Subscription": "订阅",
"FetchError": "由于网络问题,无法获取{{content}}内容。请检查网络连接或稍后再试。",
"tun": "TUN 模式",
@@ -239,7 +239,7 @@
"Proxy Takeover Status": "代理接管状态",
"Subscription Expires In": "{{time}}到期",
"Subscription Updated At": "{{time}}更新",
"Select file to import or leave blank to touch new one.": "选择文件导入或留空新建。",
"Choose file to import or leave it blank to create new one": "选择文件导入或留空新建。",
"updater": {
"title": "发现新版本",
"close": "忽略",
@@ -251,13 +251,13 @@
"running": "运行中",
"stopped_reason": "已停止,原因:{{reason}}",
"Current Status": "当前状态:{{status}}",
"Information: Please make sure that the Clash Nyanpasu Service is installed and enabled": "提示信息:请确保 Clash Nyanpasu 服务已安装并启。",
"Information: To enable service mode, make sure the Clash Nyanpasu service is installed and started": "提示信息:如需启用服务模式,请确保 Clash Nyanpasu 服务已安装并启。",
"install": "安装",
"uninstall": "卸载",
"start": "启",
"start": "启",
"stop": "停止",
"Install failed": "安装失败",
"Uninstall failed": "卸载失败",
"Failed to install": "安装失败",
"Failed to uninstall": "卸载失败",
"service_shortcuts": {
"title": "内核信息",
"core_status": "内核状态:",
@@ -266,22 +266,22 @@
"last_status_changed_since": "上次状态变更:{{time}}"
},
"Service Manual Tips": "服务提示手册",
"Unable to operation the service automatically": "无法自动{{operation}}服务。请导航到内核所在目录,在 Windows 上打开 PowerShell(以管理员身份)或在 macOS/Linux 上打开终端仿真器,然后行以下命令:",
"Successfully switch to clash core": "成功切换至 {{core}} 内核。",
"Switching failed, you could see the details in the log": "切换失败,可以在日志中查看详细信息。\n错误{{error}}",
"Successfully restart core": "重启内核成功。",
"Restart failed, full detailed please check the log": "重启失败,详细信息请检查日志。\n\n错误",
"Fetch failed, please check your internet connection": "获取更新失败,请检查你的互联网连接。",
"Successfully update core": "更新 {{core}} 内核成功。",
"Update failed": "更新失败。{{error}}",
"Unable to operation the service automatically": "无法自动{{operation}}服务。请导航到内核所在目录,在 Windows 上以管理员身份打开 PowerShell或在 macOS/Linux 上打开终端仿真器,然后行以下命令:",
"Successfully switched to the clash core": "成功切换至 {{core}} 内核。",
"Failed to switch. You could see the details in the log": "切换失败,可以在日志中查看详细信息。\n错误{{error}}",
"Successfully restarted the core": "重启内核成功。",
"Failed to restart. You could see the details in the log": "重启失败,详细信息请检查日志。\n\n错误",
"Failed to fetch. Please check your network connection": "获取更新失败,请检查你的互联网连接。",
"Successfully updated the core": "更新 {{core}} 内核成功。",
"Failed to update": "更新失败。{{error}}",
"Multiple directories are not supported": "不支持多个目录。",
"App directory changed successfully": "应用程序目录更改成功。",
"Migration failed": "迁移失败{{error}}",
"Successfully changed the app directory": "应用程序目录更改成功。",
"Failed to migrate": "迁移失败{{error}}",
"Web UI": "Web UI",
"New Item": "添加新项目",
"Edit Item": "编辑项目",
"Input": "输入",
"Support %host %port %secret": "支持使用 %host、%port 和 %secret",
"Replace host, port, secret with": "使用以下字段表示主机、端口和访问密钥:",
"Support %host %port, and %secret": "支持使用 %host、%port 和 %secret",
"Replace host, port, and secret with": "使用以下字段表示主机、端口和访问密钥:",
"Result": "结果"
}

View File

@@ -2,7 +2,7 @@
"manifest_version": 1,
"latest": {
"mihomo": "v1.18.10",
"mihomo_alpha": "alpha-a86c562",
"mihomo_alpha": "alpha-ce52c34",
"clash_rs": "v0.7.0",
"clash_premium": "2023-09-05-gdcc8d87",
"clash_rs_alpha": "0.7.0-alpha+sha.e2a4be4"
@@ -69,5 +69,5 @@
"linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf"
}
},
"updated_at": "2024-11-04T22:20:30.772Z"
"updated_at": "2024-11-05T22:20:45.824Z"
}

View File

@@ -103,12 +103,12 @@ define Package/rtl8723bu-firmware/install
endef
$(eval $(call BuildPackage,rtl8723bu-firmware))
Package/rtl8723du-firmware = $(call Package/firmware-default,RealTek RTL8723DU firmware)
define Package/rtl8723du-firmware/install
Package/rtl8723de-firmware = $(call Package/firmware-default,RealTek RTL8723DE firmware)
define Package/rtl8723de-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/rtw88
$(INSTALL_DATA) $(PKG_BUILD_DIR)/rtw88/rtw8723d_fw.bin $(1)/lib/firmware/rtw88
endef
$(eval $(call BuildPackage,rtl8723du-firmware))
$(eval $(call BuildPackage,rtl8723de-firmware))
Package/rtl8761a-firmware = $(call Package/firmware-default,RealTek RTL8761A firmware)
define Package/rtl8761a-firmware/install
@@ -141,6 +141,13 @@ define Package/rtl8821ae-firmware/install
endef
$(eval $(call BuildPackage,rtl8821ae-firmware))
Package/rtl8821au-firmware = $(call Package/firmware-default,RealTek RTL8821AU firmware)
define Package/rtl8821au-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/rtw88
$(INSTALL_DATA) $(PKG_BUILD_DIR)/rtw88/rtw8821a_fw.bin $(1)/lib/firmware/rtw88
endef
$(eval $(call BuildPackage,rtl8821au-firmware))
Package/rtl8821ce-firmware = $(call Package/firmware-default,RealTek RTL8821CE firmware)
define Package/rtl8821ce-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/rtw88
@@ -191,3 +198,10 @@ define Package/rtl8852ce-firmware/install
$(INSTALL_DATA) $(PKG_BUILD_DIR)/rtw89/rtw8852c_fw.bin $(1)/lib/firmware/rtw89
endef
$(eval $(call BuildPackage,rtl8852ce-firmware))
Package/rtl8922ae-firmware = $(call Package/firmware-default,RealTek RTL8922AE firmware)
define Package/rtl8922ae-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/rtw89
$(INSTALL_DATA) $(PKG_BUILD_DIR)/rtw89/rtw8922a_fw.bin $(1)/lib/firmware/rtw89
endef
$(eval $(call BuildPackage,rtl8922ae-firmware))

View File

@@ -8,13 +8,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=rtw88-usb
PKG_RELEASE:=2
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2024-04-10
PKG_SOURCE_DATE:=2024-11-01
PKG_SOURCE_URL:=https://github.com/lwfinger/rtw88.git
PKG_SOURCE_VERSION:=2e9f468009df592a51990d024928034e0af1c2b4
PKG_MIRROR_HASH:=684b30e58d8b990bbe141baae00c48439f45c9f39faa6f552ffb18afb6594c74
PKG_SOURCE_VERSION:=e9a6539a81a4ac1a539f510ded6a91c42efb7e2e
PKG_MIRROR_HASH:=a1d667d3bbee5a9ac197a807950cdc0f6a60828898e42ca0cfb402cf6089eb0c
PKG_BUILD_PARALLEL:=1
@@ -26,7 +26,7 @@ include $(INCLUDE_DIR)/package.mk
define KernelPackage/rtw88-default
SUBMENU:=Wireless Drivers
TITLE:=Realtek rtw88 family usb driver
DEPENDS:=+kmod-mac80211 +kmod-usb-core \
DEPENDS:=@(LINUX_6_1||LINUX_6_6) +kmod-mac80211 \
+@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT
endef
@@ -36,19 +36,33 @@ define KernelPackage/rtw88-usb
FILES:= \
$(PKG_BUILD_DIR)/rtw_core.ko \
$(PKG_BUILD_DIR)/rtw_usb.ko
DEPENDS+=+kmod-usb-core
endef
define KernelPackage/rtl8723du
$(KernelPackage/rtw88-default)
TITLE:=Realtek RTL8723DU support
DEPENDS+=+kmod-rtw88-usb +rtl8723du-firmware
DEPENDS+=+kmod-rtw88-usb +rtl8723de-firmware
FILES:= \
$(PKG_BUILD_DIR)/rtw88_8723x.ko \
$(PKG_BUILD_DIR)/rtw_8723x.ko \
$(PKG_BUILD_DIR)/rtw_8723d.ko \
$(PKG_BUILD_DIR)/rtw_8723du.ko
AUTOLOAD:=$(call AutoProbe,rtw_8723du)
endef
define KernelPackage/rtl8821au
$(KernelPackage/rtw88-default)
TITLE:=Realtek RTL8812AU/RTL8821AU support
DEPENDS+=+kmod-rtw88-usb +rtl8821au-firmware
FILES:= \
$(PKG_BUILD_DIR)/rtw_88xxa.ko \
$(PKG_BUILD_DIR)/rtw_8812a.ko \
$(PKG_BUILD_DIR)/rtw_8821a.ko \
$(PKG_BUILD_DIR)/rtw_8812au.ko \
$(PKG_BUILD_DIR)/rtw_8821au.ko
AUTOLOAD:=$(call AutoProbe,rtw_8812au rtw_8821au)
endef
define KernelPackage/rtl8821cu
$(KernelPackage/rtw88-default)
TITLE:=Realtek RTL8821CU support
@@ -99,8 +113,14 @@ define Build/Compile
modules
endef
define KernelPackage/rtl8821au/install
$(INSTALL_DIR) $(1)/lib/firmware/rtw88
$(INSTALL_DATA) $(PKG_BUILD_DIR)/firmware/rtw8812a_fw.bin $(1)/lib/firmware/rtw88
endef
$(eval $(call KernelPackage,rtw88-usb))
$(eval $(call KernelPackage,rtl8723du))
$(eval $(call KernelPackage,rtl8821au))
$(eval $(call KernelPackage,rtl8821cu))
$(eval $(call KernelPackage,rtl8822bu))
$(eval $(call KernelPackage,rtl8822cu))

View File

@@ -1,96 +0,0 @@
--- a/fw.c
+++ b/fw.c
@@ -1009,7 +1009,7 @@ static u8 rtw_get_rsvd_page_probe_req_location(struct rtw_dev *rtwdev,
if (rsvd_pkt->type != RSVD_PROBE_REQ)
continue;
if ((!ssid && !rsvd_pkt->ssid) ||
- cfg80211_ssid_eq(rsvd_pkt->ssid, ssid))
+ cfg80211_ssid_eq(rsvd_pkt->ssid, ssid))
location = rsvd_pkt->page;
}
--- a/mac.c
+++ b/mac.c
@@ -316,13 +316,6 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
rtw_write8_clr(rtwdev, REG_SYS_STATUS1 + 1, BIT(0));
}
- if (pwr_on && rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) {
- if (chip->id == RTW_CHIP_TYPE_8822C ||
- chip->id == RTW_CHIP_TYPE_8822B ||
- chip->id == RTW_CHIP_TYPE_8821C)
- rtw_write8_clr(rtwdev, REG_SYS_STATUS1 + 1, BIT(0));
- }
-
if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO)
rtw_write32(rtwdev, REG_SDIO_HIMR, imr);
@@ -956,18 +949,6 @@ static int __rtw_download_firmware_legacy(struct rtw_dev *rtwdev,
rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00);
}
- /* reset firmware if still present */
- if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B &&
- rtw_read8_mask(rtwdev, REG_MCUFW_CTRL, BIT_RAM_DL_SEL)) {
- rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00);
- }
-
- /* reset firmware if still present */
- if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B &&
- rtw_read8_mask(rtwdev, REG_MCUFW_CTRL, BIT_RAM_DL_SEL)) {
- rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00);
- }
-
en_download_firmware_legacy(rtwdev, true);
ret = download_firmware_legacy(rtwdev, fw->firmware->data, fw->firmware->size);
en_download_firmware_legacy(rtwdev, false);
--- a/main.c
+++ b/main.c
@@ -110,9 +110,7 @@ static const struct ieee80211_iface_limit rtw_iface_limits[] = {
},
{
.max = 1,
- .types = BIT(NL80211_IFTYPE_AP) |
- BIT(NL80211_IFTYPE_P2P_CLIENT) |
- BIT(NL80211_IFTYPE_P2P_GO)
+ .types = BIT(NL80211_IFTYPE_AP),
}
};
@@ -2124,11 +2122,6 @@ static int rtw_chip_efuse_info_setup(struct rtw_dev *rtwdev)
dev_warn(rtwdev->dev, "efuse MAC invalid, using random\n");
}
- if (!is_valid_ether_addr(efuse->addr)) {
- eth_random_addr(efuse->addr);
- dev_warn(rtwdev->dev, "efuse MAC invalid, using random\n");
- }
-
out_disable:
rtw_chip_efuse_disable(rtwdev);
@@ -2361,9 +2354,7 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_MESH_POINT) |
- BIT(NL80211_IFTYPE_P2P_CLIENT) |
- BIT(NL80211_IFTYPE_P2P_GO);
+ BIT(NL80211_IFTYPE_MESH_POINT);
hw->wiphy->available_antennas_tx = hal->antenna_tx;
hw->wiphy->available_antennas_rx = hal->antenna_rx;
--- a/usb.c
+++ b/usb.c
@@ -93,11 +93,6 @@ static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len)
rtwdev->chip->id == RTW_CHIP_TYPE_8821C)
rtw_usb_reg_sec(rtwdev, addr, data);
- if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C ||
- rtwdev->chip->id == RTW_CHIP_TYPE_8822B ||
- rtwdev->chip->id == RTW_CHIP_TYPE_8821C)
- rtw_usb_reg_sec(rtwdev, addr, data);
-
return le32_to_cpu(*data);
}

View File

@@ -1,432 +0,0 @@
--- a/bf.c
+++ b/bf.c
@@ -57,7 +57,7 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
}
ic_vht_cap = &hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) && !defined(BUILD_OPENWRT)
vht_cap = &sta->vht_cap;
#else
vht_cap = &sta->deflink.vht_cap;
@@ -75,7 +75,7 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
ether_addr_copy(bfee->mac_addr, bssid);
bfee->role = RTW_BFEE_MU;
bfee->p_aid = (bssid[5] << 1) | (bssid[4] >> 7);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT)
bfee->aid = vif->cfg.aid;
#else
bfee->aid = bss_conf->aid;
--- a/fw.c
+++ b/fw.c
@@ -191,7 +191,7 @@ legacy:
si->ra_report.desc_rate = rate;
si->ra_report.bit_rate = bit_rate;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) || defined(BUILD_OPENWRT)
sta->deflink.agg.max_rc_amsdu_len = get_max_amsdu_len(bit_rate);
#else
sta->max_rc_amsdu_len = get_max_amsdu_len(bit_rate);
@@ -726,7 +726,7 @@ void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) || defined(BUILD_OPENWRT)
void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
bool reset_ra_mask)
#else
@@ -735,7 +735,7 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
{
u8 h2c_pkt[H2C_PKT_SIZE] = {0};
bool disable_pt = true;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) && !defined(BUILD_OPENWRT)
bool reset_ra_mask = true;
#endif
@@ -1228,7 +1228,7 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw,
switch (rsvd_pkt->type) {
case RSVD_BEACON:
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT)
skb_new = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL, 0);
#else
skb_new = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL);
@@ -1243,7 +1243,7 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw,
break;
case RSVD_NULL:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 17)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) || defined(BUILD_OPENWRT)
skb_new = ieee80211_nullfunc_get(hw, vif, -1, false);
#else
skb_new = ieee80211_nullfunc_get(hw, vif, false);
@@ -1254,7 +1254,7 @@ static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw,
break;
case RSVD_QOS_NULL:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 17)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) || defined(BUILD_OPENWRT)
skb_new = ieee80211_nullfunc_get(hw, vif, -1, true);
#else
skb_new = ieee80211_nullfunc_get(hw, vif, true);
--- a/fw.h
+++ b/fw.h
@@ -834,7 +834,7 @@ void rtw_fw_coex_query_hid_info(struct rtw_dev *rtwdev, u8 sub_id, u8 data);
void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data);
void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) || defined(BUILD_OPENWRT)
void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
bool reset_ra_mask);
#else
--- a/mac80211.c
+++ b/mac80211.c
@@ -365,7 +365,7 @@ static void rtw_conf_tx(struct rtw_dev *rtwdev,
static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *conf,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT)
u64 changed)
#else
u32 changed)
@@ -383,7 +383,7 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_ASSOC) {
rtw_vif_assoc_changed(rtwvif, conf);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT)
if (vif->cfg.assoc) {
#else
if (conf->assoc) {
@@ -393,7 +393,7 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
rtw_fw_download_rsvd_page(rtwdev);
rtw_send_rsvd_page_h2c(rtwdev);
rtw_fw_default_port(rtwdev, rtwvif);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT)
rtw_coex_media_status_notify(rtwdev, vif->cfg.assoc);
#else
rtw_coex_media_status_notify(rtwdev, conf->assoc);
@@ -460,7 +460,7 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
mutex_unlock(&rtwdev->mutex);
}
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT)
static int rtw_ops_start_ap(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf)
@@ -481,7 +481,7 @@ static int rtw_ops_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
return 0;
}
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT)
static void rtw_ops_stop_ap(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf)
@@ -502,7 +502,7 @@ static void rtw_ops_stop_ap(struct ieee80211_hw *hw,
static int rtw_ops_conf_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT)
unsigned int link_id, u16 ac,
#else
u16 ac,
@@ -731,7 +731,7 @@ static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)
static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,14,0))
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,14,0)) || defined(BUILD_OPENWRT)
struct ieee80211_prep_tx_info *info)
#else
u16 duration)
--- a/main.c
+++ b/main.c
@@ -191,7 +191,7 @@ static void rtw_vif_watch_dog_iter(void *data, struct ieee80211_vif *vif)
struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
if (vif->type == NL80211_IFTYPE_STATION)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT)
if (vif->cfg.assoc)
#else
if (vif->bss_conf.assoc)
@@ -343,7 +343,7 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta,
if (si->mac_id >= RTW_MAX_MAC_ID_NUM)
return -ENOSPC;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT)
if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0)
#else
if (vif->type == NL80211_IFTYPE_STATION && vif->bss_conf.assoc == 0)
@@ -572,7 +572,7 @@ EXPORT_SYMBOL(rtw_dump_reg);
void rtw_vif_assoc_changed(struct rtw_vif *rtwvif,
struct ieee80211_bss_conf *conf)
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT)
struct ieee80211_vif *vif = NULL;
if (conf)
@@ -1000,7 +1000,7 @@ static void rtw_hw_config_rf_ant_num(struct rtw_dev *rtwdev, u8 hw_ant_num)
static u64 get_vht_ra_mask(struct ieee80211_sta *sta)
{
u64 ra_mask = 0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map);
#else
u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map);
@@ -1224,26 +1224,26 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
bool is_vht_enable = false;
bool is_support_sgi = false;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
if (sta->deflink.vht_cap.vht_supported) {
#else
if (sta->vht_cap.vht_supported) {
#endif
is_vht_enable = true;
ra_mask |= get_vht_ra_mask(sta);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
#else
if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
#endif
stbc_en = VHT_STBC_EN;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
#else
if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
#endif
ldpc_en = VHT_LDPC_EN;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
} else if (sta->deflink.ht_cap.ht_supported) {
ra_mask |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20) |
(sta->deflink.ht_cap.mcs.rx_mask[0] << 12);
@@ -1266,20 +1266,20 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS;
if (hal->current_band_type == RTW_BAND_5G) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4;
#else
ra_mask |= (u64)sta->supp_rates[NL80211_BAND_5GHZ] << 4;
#endif
ra_mask_bak = ra_mask;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
if (sta->deflink.vht_cap.vht_supported) {
#else
if (sta->vht_cap.vht_supported) {
#endif
ra_mask &= RA_MASK_VHT_RATES | RA_MASK_OFDM_IN_VHT;
wireless_set = WIRELESS_OFDM | WIRELESS_VHT;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
} else if (sta->deflink.ht_cap.ht_supported) {
#else
} else if (sta->ht_cap.ht_supported) {
@@ -1291,13 +1291,13 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
}
dm_info->rrsr_val_init = RRSR_INIT_5G;
} else if (hal->current_band_type == RTW_BAND_2G) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ];
#else
ra_mask |= sta->supp_rates[NL80211_BAND_2GHZ];
#endif
ra_mask_bak = ra_mask;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
if (sta->deflink.vht_cap.vht_supported) {
#else
if (sta->vht_cap.vht_supported) {
@@ -1306,7 +1306,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
RA_MASK_OFDM_IN_VHT;
wireless_set = WIRELESS_CCK | WIRELESS_OFDM |
WIRELESS_HT | WIRELESS_VHT;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
} else if (sta->deflink.ht_cap.ht_supported) {
#else
} else if (sta->ht_cap.ht_supported) {
@@ -1315,7 +1315,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
RA_MASK_OFDM_IN_HT_2G;
wireless_set = WIRELESS_CCK | WIRELESS_OFDM |
WIRELESS_HT;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
} else if (sta->deflink.supp_rates[0] <= 0xf) {
#else
} else if (sta->supp_rates[0] <= 0xf) {
@@ -1332,14 +1332,14 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
wireless_set = 0;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
switch (sta->deflink.bandwidth) {
#else
switch (sta->bandwidth) {
#endif
case IEEE80211_STA_RX_BW_80:
bw_mode = RTW_CHANNEL_WIDTH_80;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
is_support_sgi = sta->deflink.vht_cap.vht_supported &&
(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80);
#else
@@ -1349,7 +1349,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
break;
case IEEE80211_STA_RX_BW_40:
bw_mode = RTW_CHANNEL_WIDTH_40;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
is_support_sgi = sta->deflink.ht_cap.ht_supported &&
(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
#else
@@ -1359,7 +1359,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
break;
default:
bw_mode = RTW_CHANNEL_WIDTH_20;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
is_support_sgi = sta->deflink.ht_cap.ht_supported &&
(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
#else
@@ -1369,14 +1369,14 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
break;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
if (sta->deflink.vht_cap.vht_supported && ra_mask & 0xffc00000) {
#else
if (sta->vht_cap.vht_supported && ra_mask & 0xffc00000) {
#endif
tx_num = 2;
rf_type = RF_2T2R;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
} else if (sta->deflink.ht_cap.ht_supported && ra_mask & 0xfff00000) {
#else
} else if (sta->ht_cap.ht_supported && ra_mask & 0xfff00000) {
@@ -1400,7 +1400,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
si->ra_mask = ra_mask;
si->rate_id = rate_id;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) || defined(BUILD_OPENWRT)
rtw_fw_send_ra_info(rtwdev, si, reset_ra_mask);
#else
rtw_fw_send_ra_info(rtwdev, si);
@@ -1780,7 +1780,7 @@ static void rtw_vif_smps_iter(void *data, u8 *mac,
{
struct rtw_dev *rtwdev = (struct rtw_dev *)data;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT)
if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc)
#else
if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc)
@@ -1788,13 +1788,13 @@ static void rtw_vif_smps_iter(void *data, u8 *mac,
return;
if (rtwdev->hal.txrx_1ss)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT)
ieee80211_request_smps(vif, 0, IEEE80211_SMPS_STATIC);
#else
ieee80211_request_smps(vif, IEEE80211_SMPS_STATIC);
#endif
else
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT)
ieee80211_request_smps(vif, 0, IEEE80211_SMPS_OFF);
#else
ieee80211_request_smps(vif, IEEE80211_SMPS_OFF);
@@ -2516,7 +2516,7 @@ static void rtw_check_sta_active_iter(void *data, struct ieee80211_vif *vif)
if (vif->type != NL80211_IFTYPE_STATION)
return;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(BUILD_OPENWRT)
if (vif->cfg.assoc || !is_zero_ether_addr(rtwvif->bssid))
#else
if (vif->bss_conf.assoc || !is_zero_ether_addr(rtwvif->bssid))
--- a/ps.c
+++ b/ps.c
@@ -334,7 +334,7 @@ void rtw_recalc_lps(struct rtw_dev *rtwdev, struct ieee80211_vif *new_vif)
__rtw_vif_recalc_lps(&data, new_vif);
rtw_iterate_vifs(rtwdev, rtw_vif_recalc_lps_iter, &data);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || defined(BUILD_OPENWRT)
if (data.count == 1 && data.found_vif->cfg.ps) {
rtwdev->ps_enabled = true;
} else {
--- a/tx.c
+++ b/tx.c
@@ -90,7 +90,7 @@ EXPORT_SYMBOL(rtw_tx_fill_tx_desc);
static u8 get_tx_ampdu_factor(struct ieee80211_sta *sta)
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
u8 exp = sta->deflink.ht_cap.ampdu_factor;
#else
u8 exp = sta->ht_cap.ampdu_factor;
@@ -105,7 +105,7 @@ static u8 get_tx_ampdu_factor(struct ieee80211_sta *sta)
static u8 get_tx_ampdu_density(struct ieee80211_sta *sta)
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
return sta->deflink.ht_cap.ampdu_density;
#else
return sta->ht_cap.ampdu_density;
@@ -117,7 +117,7 @@ static u8 get_highest_ht_tx_rate(struct rtw_dev *rtwdev,
{
u8 rate;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
if (rtwdev->hal.rf_type == RF_2T2R && sta->deflink.ht_cap.mcs.rx_mask[1] != 0)
#else
if (rtwdev->hal.rf_type == RF_2T2R && sta->ht_cap.mcs.rx_mask[1] != 0)
@@ -136,7 +136,7 @@ static u8 get_highest_vht_tx_rate(struct rtw_dev *rtwdev,
u8 rate;
u16 tx_mcs_map;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
tx_mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.tx_mcs_map);
#else
tx_mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.tx_mcs_map);
@@ -382,7 +382,7 @@ static void rtw_tx_data_pkt_info_update(struct rtw_dev *rtwdev,
if (info->control.use_rts || skb->len > hw->wiphy->rts_threshold)
pkt_info->rts = true;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || defined(BUILD_OPENWRT)
if (sta->deflink.vht_cap.vht_supported)
rate = get_highest_vht_tx_rate(rtwdev, sta);
else if (sta->deflink.ht_cap.ht_supported)

View File

@@ -0,0 +1,11 @@
--- a/rx.c
+++ b/rx.c
@@ -176,7 +176,7 @@ void rtw_update_rx_freq_from_ie(struct r
else
goto fill_rx_status;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0)) && !defined(BUILD_OPENWRT)
channel_number = cfg80211_get_ies_channel_number(variable, ielen,
NL80211_BAND_2GHZ);
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0))

View File

@@ -1,69 +0,0 @@
--- a/Makefile
+++ b/Makefile
@@ -30,10 +30,6 @@ NO_SKIP_SIGN := y
endif
EXTRA_CFLAGS += -O2
-EXTRA_CFLAGS += -DCONFIG_RTW88_8822BE=1
-EXTRA_CFLAGS += -DCONFIG_RTW88_8821CE=1
-EXTRA_CFLAGS += -DCONFIG_RTW88_8822CE=1
-EXTRA_CFLAGS += -DCONFIG_RTW88_8723DE=1
EXTRA_CFLAGS += -DCONFIG_RTW88_DEBUG=1
EXTRA_CFLAGS += -DCONFIG_RTW88_DEBUGFS=1
#EXTRA_CFLAGS += -DCONFIG_RTW88_REGD_USER_REG_HINTS
@@ -60,9 +56,6 @@ rtw_core-objs += main.o \
obj-m += rtw_8822b.o
rtw_8822b-objs := rtw8822b.o rtw8822b_table.o
-obj-m += rtw_8822be.o
-rtw_8822be-objs := rtw8822be.o
-
obj-m += rtw_8822bu.o
rtw_8822bu-objs := rtw8822bu.o
@@ -72,9 +65,6 @@ rtw_8822bs-objs := rtw8822bs.o
obj-m += rtw_8822c.o
rtw_8822c-objs := rtw8822c.o rtw8822c_table.o
-obj-m += rtw_8822ce.o
-rtw_8822ce-objs := rtw8822ce.o
-
obj-m += rtw_8822cu.o
rtw_8822cu-objs := rtw8822cu.o
@@ -102,9 +92,6 @@ rtw_8723cs-objs := rtw8723cs.o
obj-m += rtw_8723d.o
rtw_8723d-objs := rtw8723d.o rtw8723d_table.o
-obj-m += rtw_8723de.o
-rtw_8723de-objs := rtw8723de.o
-
obj-m += rtw_8723du.o
rtw_8723du-objs := rtw8723du.o
@@ -114,15 +101,9 @@ rtw_8723ds-objs := rtw8723ds.o
obj-m += rtw_8821c.o
rtw_8821c-objs := rtw8821c.o rtw8821c_table.o
-obj-m += rtw_8821ce.o
-rtw_8821ce-objs := rtw8821ce.o
-
obj-m += rtw_8821a.o
rtw_8821a-objs := rtw8821a.o rtw8821a_table.o
-obj-m += rtw_8821ae.o
-rtw_8821ae-objs := rtw8821ae.o
-
obj-m += rtw_8821au.o
rtw_8821au-objs := rtw8821au.o
@@ -132,9 +113,6 @@ rtw_8821cs-objs := rtw8821cs.o
obj-m += rtw_8821cu.o
rtw_8821cu-objs := rtw8821cu.o
-obj-m += rtw_pci.o
-rtw_pci-objs := pci.o
-
obj-m += rtw_sdio.o
rtw_sdio-objs := sdio.o

106
mieru/apis/common/dns.go Normal file
View File

@@ -0,0 +1,106 @@
// Copyright (C) 2024 mieru authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package common
import (
"context"
"net"
"strconv"
)
// DNSResolver provides a way to look up IP addresses from host name.
type DNSResolver interface {
LookupIP(ctx context.Context, network, host string) ([]net.IP, error)
}
// Standard library Resolver implements the DNSResolver interface.
var _ DNSResolver = &net.Resolver{}
// ResolveTCPAddr returns a TCP address using the DNSResolver.
func ResolveTCPAddr(r DNSResolver, network, address string) (*net.TCPAddr, error) {
dnsQueryNetwork := "ip"
switch network {
case "tcp":
case "tcp4":
dnsQueryNetwork = "ip4"
case "tcp6":
dnsQueryNetwork = "ip6"
case "":
network = "tcp"
default:
return nil, net.UnknownNetworkError(network)
}
host, portStr, err := net.SplitHostPort(address)
if err != nil {
return nil, err
}
port, err := strconv.Atoi(portStr)
if err != nil {
return nil, err
}
if ip := net.ParseIP(host); ip != nil {
return &net.TCPAddr{IP: ip, Port: port}, nil
}
ips, err := r.LookupIP(context.Background(), dnsQueryNetwork, host)
if err != nil {
return nil, err
}
if len(ips) == 0 {
return nil, &net.AddrError{Err: "IP address not found", Addr: address}
}
return &net.TCPAddr{IP: ips[0], Port: port}, nil
}
// ResolveUDPAddr returns a UDP address using the DNSResolver.
func ResolveUDPAddr(r DNSResolver, network, address string) (*net.UDPAddr, error) {
dnsQueryNetwork := "ip"
switch network {
case "udp":
case "udp4":
dnsQueryNetwork = "ip4"
case "udp6":
dnsQueryNetwork = "ip6"
case "":
network = "udp"
default:
return nil, net.UnknownNetworkError(network)
}
host, portStr, err := net.SplitHostPort(address)
if err != nil {
return nil, err
}
port, err := strconv.Atoi(portStr)
if err != nil {
return nil, err
}
if ip := net.ParseIP(host); ip != nil {
return &net.UDPAddr{IP: ip, Port: port}, nil
}
ips, err := r.LookupIP(context.Background(), dnsQueryNetwork, host)
if err != nil {
return nil, err
}
if len(ips) == 0 {
return nil, &net.AddrError{Err: "IP address not found", Addr: address}
}
return &net.UDPAddr{IP: ips[0], Port: port}, nil
}

View File

@@ -0,0 +1,157 @@
// Copyright (C) 2024 mieru authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package common
import (
"net"
"testing"
)
func TestResolveTCPAddr(t *testing.T) {
resolver := &net.Resolver{PreferGo: true}
testcases := []struct {
name string
network string
address string
expected *net.TCPAddr
wantErr bool
}{
{
name: "localhost",
network: "tcp4",
address: "localhost:80",
expected: &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 80},
wantErr: false,
},
{
name: "ip4_address",
network: "tcp",
address: "127.0.0.1:80",
expected: &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 80},
wantErr: false,
},
{
name: "ip6_address",
network: "tcp",
address: "[::1]:80",
expected: &net.TCPAddr{IP: net.ParseIP("::1"), Port: 80},
wantErr: false,
},
{
name: "invalid_host",
network: "tcp",
address: "invalid_host:80",
wantErr: true,
},
{
name: "invalid_port",
network: "tcp",
address: "127.0.0.1:invalid_port",
wantErr: true,
},
{
name: "no_port",
network: "tcp",
address: "no_port",
wantErr: true,
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
addr, err := ResolveTCPAddr(resolver, tc.network, tc.address)
if (err != nil) != tc.wantErr {
t.Fatalf("ResolveTCPAddr() error = %v, wantErr %v", err, tc.wantErr)
}
if tc.expected != nil {
if !addr.IP.Equal(tc.expected.IP) {
t.Errorf("IP mismatch: got %v, want %v", addr.IP, tc.expected.IP)
}
if addr.Port != tc.expected.Port {
t.Errorf("Port mismatch: got %v, want %v", addr.Port, tc.expected.Port)
}
}
})
}
}
func TestResolveUDPAddr(t *testing.T) {
resolver := &net.Resolver{PreferGo: true}
testcases := []struct {
name string
network string
address string
expected *net.UDPAddr
wantErr bool
}{
{
name: "localhost",
network: "udp4",
address: "localhost:80",
expected: &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 80},
wantErr: false,
},
{
name: "ip4_address",
network: "udp",
address: "127.0.0.1:80",
expected: &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 80},
wantErr: false,
},
{
name: "ip6_address",
network: "udp",
address: "[::1]:80",
expected: &net.UDPAddr{IP: net.ParseIP("::1"), Port: 80},
wantErr: false,
},
{
name: "invalid_host",
network: "udp",
address: "invalid_host:80",
wantErr: true,
},
{
name: "invalid_port",
network: "udp",
address: "127.0.0.1:invalid_port",
wantErr: true,
},
{
name: "no_port",
network: "udp",
address: "no_port",
wantErr: true,
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
addr, err := ResolveUDPAddr(resolver, tc.network, tc.address)
if (err != nil) != tc.wantErr {
t.Fatalf("ResolveUDPAddr() error = %v, wantErr %v", err, tc.wantErr)
}
if tc.expected != nil {
if !addr.IP.Equal(tc.expected.IP) {
t.Errorf("IP mismatch: got %v, want %v", addr.IP, tc.expected.IP)
}
if addr.Port != tc.expected.Port {
t.Errorf("Port mismatch: got %v, want %v", addr.Port, tc.expected.Port)
}
}
})
}
}

View File

@@ -27,6 +27,7 @@ import (
"sync"
"time"
apicommon "github.com/enfein/mieru/v3/apis/common"
"github.com/enfein/mieru/v3/pkg/appctl/appctlpb"
"github.com/enfein/mieru/v3/pkg/cipher"
"github.com/enfein/mieru/v3/pkg/common"
@@ -48,6 +49,7 @@ type Mux struct {
underlays []Underlay
chAccept chan net.Conn
chAcceptErr chan error
resolver apicommon.DNSResolver
used bool
done chan struct{}
mu sync.Mutex
@@ -76,6 +78,7 @@ func NewMux(isClinet bool) *Mux {
underlays: make([]Underlay, 0),
chAccept: make(chan net.Conn, sessionChanCapacity),
chAcceptErr: make(chan error, 1), // non-blocking
resolver: &net.Resolver{PreferGo: true},
done: make(chan struct{}),
cleaner: time.NewTicker(idleUnderlayTickerInterval),
}
@@ -101,6 +104,42 @@ func NewMux(isClinet bool) *Mux {
return mux
}
// SetEndpoints updates the endpoints that mux is listening to.
// If mux is started and new endpoints are added, mux also starts
// to listen to those new endpoints. In that case, old endpoints
// are not impacted.
func (m *Mux) SetEndpoints(endpoints []UnderlayProperties) *Mux {
m.mu.Lock()
defer m.mu.Unlock()
new := m.newEndpoints(m.endpoints, endpoints)
if len(new) > 0 {
if m.used {
select {
case <-m.done:
log.Infof("Unable to add new endpoint after multiplexer is closed")
default:
for _, p := range new {
go m.acceptUnderlayLoop(context.Background(), p)
}
m.endpoints = endpoints
}
} else {
m.endpoints = new
}
}
log.Infof("Mux now has %d endpoints", len(m.endpoints))
return m
}
// SetResolver updates the DNS resolver used by the mux.
func (m *Mux) SetResolver(resolver apicommon.DNSResolver) *Mux {
m.mu.Lock()
defer m.mu.Unlock()
m.resolver = resolver
log.Infof("Mux DNS resolver has been updated")
return m
}
// SetClientUserNamePassword panics if the mux is already started.
func (m *Mux) SetClientUserNamePassword(username string, password []byte) *Mux {
m.mu.Lock()
@@ -151,33 +190,6 @@ func (m *Mux) SetServerUsers(users map[string]*appctlpb.User) *Mux {
return m
}
// SetEndpoints updates the endpoints that mux is listening to.
// If mux is started and new endpoints are added, mux also starts
// to listen to those new endpoints. In that case, old endpoints
// are not impacted.
func (m *Mux) SetEndpoints(endpoints []UnderlayProperties) *Mux {
m.mu.Lock()
defer m.mu.Unlock()
new := m.newEndpoints(m.endpoints, endpoints)
if len(new) > 0 {
if m.used {
select {
case <-m.done:
log.Infof("Unable to add new endpoint after multiplexer is closed")
default:
for _, p := range new {
go m.acceptUnderlayLoop(context.Background(), p)
}
m.endpoints = endpoints
}
} else {
m.endpoints = new
}
}
log.Infof("Mux now has %d endpoints", len(m.endpoints))
return m
}
func (m *Mux) Accept() (net.Conn, error) {
select {
case err := <-m.chAcceptErr:

View File

@@ -25,7 +25,7 @@ require (
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4
github.com/metacubex/sing-shadowsocks v0.2.8
github.com/metacubex/sing-shadowsocks2 v0.2.2
github.com/metacubex/sing-tun v0.2.7-0.20241105010444-9ece61968014
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3
github.com/metacubex/tfo-go v0.0.0-20241006021335-daedaf0ca7aa

View File

@@ -116,8 +116,8 @@ github.com/metacubex/sing-shadowsocks v0.2.8 h1:wIhlaigswzjPw4hej75sEvWte3QR0+AJ
github.com/metacubex/sing-shadowsocks v0.2.8/go.mod h1:X3x88XtJpBxG0W0/ECOJL6Ib0SJ3xdniAkU/6/RMWU0=
github.com/metacubex/sing-shadowsocks2 v0.2.2 h1:eaf42uVx4Lr21S6MDYs0ZdTvGA0GEhDpb9no4+gdXPo=
github.com/metacubex/sing-shadowsocks2 v0.2.2/go.mod h1:BhOug03a/RbI7y6hp6q+6ITM1dXjnLTmeWBHSTwvv2Q=
github.com/metacubex/sing-tun v0.2.7-0.20241105010444-9ece61968014 h1:5zAAcCCyuorvkXu3su4VmUkYDXOdzvRKPGEdeyc+ljY=
github.com/metacubex/sing-tun v0.2.7-0.20241105010444-9ece61968014/go.mod h1:GRcrj7VnhvYFsS34cv0J2qTVm5h9DvQuGwliVyVLVvE=
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98 h1:vW0QDrzUc4k1yi3A76lDW064zonPj880QFcpTD58u7A=
github.com/metacubex/sing-tun v0.2.7-0.20241106120309-53606a70db98/go.mod h1:GRcrj7VnhvYFsS34cv0J2qTVm5h9DvQuGwliVyVLVvE=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 h1:OAXiCosqY8xKDp3pqTW3qbrCprZ1l6WkrXSFSCwyY4I=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY=
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 h1:xg71VmzLS6ByAzi/57phwDvjE+dLLs+ozH00k4DnOns=

View File

@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=adguardhome
PKG_VERSION:=0.107.53
PKG_VERSION:=0.107.54
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/AdguardTeam/AdGuardHome/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=dd2a60ff8806d2fa39fe1c41bf3534c2231132147f23e337f98b3bd83a4be654
PKG_HASH:=2700549a8bcec151ebc25ae80c77956dda995ac3a7866aee0a187ed0b4bc39d0
PKG_BUILD_DIR:=$(BUILD_DIR)/AdGuardHome-$(PKG_VERSION)
PKG_LICENSE:=GPL-3.0-only
@@ -58,7 +58,7 @@ define Download/adguardhome-frontend
URL:=https://github.com/AdguardTeam/AdGuardHome/releases/download/v$(PKG_VERSION)/
URL_FILE:=AdGuardHome_frontend.tar.gz
FILE:=$(FRONTEND_FILE)
HASH:=69047225e2a5474e55fa56d12b71ba4e58e36b5af299f27099d216e1e7ab7f43
HASH:=2fe20a76b877aeff3b88cb454274030a9d917d6d6d7f32e573e979bfd8bbe444
endef
define Build/Prepare

View File

@@ -543,7 +543,7 @@ run_dns2socks() {
}
run_chinadns_ng() {
local _flag _listen_port _dns_local _dns_trust _no_ipv6_trust _use_direct_list _use_proxy_list _gfwlist _chnlist _default_mode _default_tag
local _flag _listen_port _dns_local _dns_trust _no_ipv6_trust _use_direct_list _use_proxy_list _gfwlist _chnlist _default_mode _default_tag _no_logic_log _tcp_node
local _extra_param=""
eval_set_val $@
@@ -554,6 +554,7 @@ run_chinadns_ng() {
_extra_param="-FLAG ${_flag} -LISTEN_PORT ${_listen_port} -DNS_LOCAL ${_dns_local} -DNS_TRUST ${_dns_trust}"
_extra_param="${_extra_param} -USE_DIRECT_LIST ${_use_direct_list} -USE_PROXY_LIST ${_use_proxy_list} -GFWLIST ${_gfwlist} -CHNLIST ${_chnlist}"
_extra_param="${_extra_param} -NO_IPV6_TRUST ${_no_ipv6_trust} -DEFAULT_MODE ${_default_mode} -DEFAULT_TAG ${_default_tag} -NFTFLAG ${nftflag}"
_extra_param="${_extra_param} -NO_LOGIC_LOG ${_no_logic_log} -TCP_NODE ${_tcp_node}"
lua $APP_PATH/helper_chinadns_add.lua ${_extra_param} > ${_CONF_FILE}
ln_run "$(first_type chinadns-ng)" chinadns-ng "${_LOG_FILE}" -C ${_CONF_FILE}
@@ -1470,6 +1471,8 @@ start_dns() {
local china_ng_listen="127.0.0.1#${china_ng_listen_port}"
[ -z "${china_ng_trust_dns}" ] && local china_ng_trust_dns=${TUN_DNS}
echolog " - ChinaDNS-NG(${china_ng_listen})直连DNS${china_ng_local_dns}可信DNS${china_ng_trust_dns}"
run_chinadns_ng \
_flag="default" \
_listen_port=${china_ng_listen_port} \
@@ -1481,9 +1484,9 @@ start_dns() {
_gfwlist=${USE_GFW_LIST} \
_chnlist=${CHN_LIST} \
_default_mode=${TCP_PROXY_MODE} \
_default_tag=$(config_t_get global chinadns_ng_default_tag smart)
echolog " - ChinaDNS-NG(${china_ng_listen})直连DNS${china_ng_local_dns}可信DNS${china_ng_trust_dns}"
_default_tag=$(config_t_get global chinadns_ng_default_tag smart) \
_no_logic_log=0 \
_tcp_node=${TCP_NODE}
USE_DEFAULT_DNS="chinadns_ng"
}
@@ -1677,7 +1680,9 @@ acl_app() {
_gfwlist=${use_gfw_list} \
_chnlist=${chn_list} \
_default_mode=${tcp_proxy_mode} \
_default_tag=${chinadns_ng_default_tag:-smart}
_default_tag=${chinadns_ng_default_tag:-smart} \
_no_logic_log=1 \
_tcp_node=${tcp_node}
use_default_dns="chinadns_ng"
}

View File

@@ -14,6 +14,8 @@ local CHNLIST = var["-CHNLIST"]
local NO_IPV6_TRUST = var["-NO_IPV6_TRUST"]
local DEFAULT_MODE = var["-DEFAULT_MODE"]
local DEFAULT_TAG = var["-DEFAULT_TAG"]
local NO_LOGIC_LOG = var["-NO_LOGIC_LOG"]
local TCP_NODE = var["-TCP_NODE"]
local NFTFLAG = var["-NFTFLAG"]
local uci = api.uci
@@ -27,6 +29,13 @@ local RULES_PATH = "/usr/share/" .. appname .. "/rules"
local config_lines = {}
local tmp_lines = {}
local function log(...)
if NO_LOGIC_LOG == "1" then
return
end
api.log(...)
end
local function is_file_nonzero(path)
if path and #path > 1 then
if sys.exec('[ -s "%s" ] && echo -n 1' % path) == "1" then
@@ -36,6 +45,13 @@ local function is_file_nonzero(path)
return nil
end
local function insert_unique(dest_table, value, lookup_table)
if not lookup_table[value] then
table.insert(dest_table, value)
lookup_table[value] = true
end
end
local function merge_array(lines1, lines2)
for i, line in ipairs(lines2) do
table.insert(lines1, #lines1 + 1, line)
@@ -60,15 +76,15 @@ config_lines = {
--始终用国内DNS解析节点域名
local file_vpslist = TMP_ACL_PATH .. "/vpslist"
if not is_file_nonzero(file_vpslist) then
local vpslist_out = io.open(file_vpslist, "w")
local f_out = io.open(file_vpslist, "w")
uci:foreach(appname, "nodes", function(t)
local address = t.address
if address == "engage.cloudflareclient.com" then return end
if datatypes.hostname(address) then
vpslist_out:write(address .. "\n")
f_out:write(address .. "\n")
end
end)
vpslist_out:close()
f_out:close()
end
if is_file_nonzero(file_vpslist) then
tmp_lines = {
@@ -78,24 +94,26 @@ if is_file_nonzero(file_vpslist) then
"group-ipset " .. setflag .. "passwall_vpslist," .. setflag .. "passwall_vpslist6"
}
merge_array(config_lines, tmp_lines)
log(string.format(" - 节点列表中的域名(vpslist)%s", DNS_LOCAL or "默认"))
end
--直连(白名单)列表
local file_direct_host = TMP_ACL_PATH .. "/direct_host"
if USE_DIRECT_LIST == "1" and not fs.access(file_direct_host) then --对自定义列表进行清洗
local direct_domain = {}
local lookup_direct_domain = {}
for line in io.lines(RULES_PATH .. "/direct_host") do
line = api.get_std_domain(line)
if line ~= "" and not line:find("#") then
table.insert(direct_domain, line)
insert_unique(direct_domain, line, lookup_direct_domain)
end
end
if #direct_domain > 0 then
local direct_out = io.open(file_direct_host, "w")
local f_out = io.open(file_direct_host, "w")
for i = 1, #direct_domain do
direct_out:write(direct_domain[i] .. "\n")
f_out:write(direct_domain[i] .. "\n")
end
direct_out:close()
f_out:close()
end
end
if USE_DIRECT_LIST == "1" and is_file_nonzero(file_direct_host) then
@@ -106,24 +124,26 @@ if USE_DIRECT_LIST == "1" and is_file_nonzero(file_direct_host) then
"group-ipset " .. setflag .. "passwall_whitelist," .. setflag .. "passwall_whitelist6"
}
merge_array(config_lines, tmp_lines)
log(string.format(" - 域名白名单(whitelist)%s", DNS_LOCAL or "默认"))
end
--代理(黑名单)列表
local file_proxy_host = TMP_ACL_PATH .. "/proxy_host"
if USE_PROXY_LIST == "1" and not fs.access(file_proxy_host) then --对自定义列表进行清洗
local proxy_domain = {}
local lookup_proxy_domain = {}
for line in io.lines(RULES_PATH .. "/proxy_host") do
line = api.get_std_domain(line)
if line ~= "" and not line:find("#") then
table.insert(proxy_domain, line)
insert_unique(proxy_domain, line, lookup_proxy_domain)
end
end
if #proxy_domain > 0 then
local proxy_out = io.open(file_proxy_host, "w")
local f_out = io.open(file_proxy_host, "w")
for i = 1, #proxy_domain do
proxy_out:write(proxy_domain[i] .. "\n")
f_out:write(proxy_domain[i] .. "\n")
end
proxy_out:close()
f_out:close()
end
end
if USE_PROXY_LIST == "1" and is_file_nonzero(file_proxy_host) then
@@ -135,6 +155,7 @@ if USE_PROXY_LIST == "1" and is_file_nonzero(file_proxy_host) then
}
merge_array(config_lines, tmp_lines)
if NO_IPV6_TRUST == "1" then table.insert(config_lines, "no-ipv6 tag:proxylist") end
log(string.format(" - 代理域名表(blacklist)%s", DNS_TRUST or "默认"))
end
--GFW列表
@@ -145,6 +166,7 @@ if GFWLIST == "1" and is_file_nonzero(RULES_PATH .. "/gfwlist") then
}
merge_array(config_lines, tmp_lines)
if NO_IPV6_TRUST == "1" then table.insert(config_lines, "no-ipv6 tag:gfw") end
log(string.format(" - 防火墙域名表(gfwlist)%s", DNS_TRUST or "默认"))
end
--中国列表
@@ -158,6 +180,7 @@ if CHNLIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then
"chnlist-first"
}
merge_array(config_lines, tmp_lines)
log(string.format(" - 中国域名表(chnroute)%s", DNS_LOCAL or "默认"))
end
--回中国模式
@@ -170,6 +193,92 @@ if CHNLIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then
}
merge_array(config_lines, tmp_lines)
if NO_IPV6_TRUST == "1" then table.insert(config_lines, "no-ipv6 tag:chn_proxy") end
log(string.format(" - 中国域名表(chnroute)%s", DNS_TRUST or "默认"))
end
end
--分流规则
if uci:get(appname, TCP_NODE, "protocol") == "_shunt" then
local white_domain = {}
local shunt_domain = {}
local lookup_white_domain = {}
local lookup_shunt_domain = {}
local file_white_host = TMP_ACL_PATH .. "/white_host"
local file_shunt_host = TMP_ACL_PATH .. "/shunt_host"
local t = uci:get_all(appname, TCP_NODE)
local default_node_id = t["default_node"] or "_direct"
uci:foreach(appname, "shunt_rules", function(s)
local _node_id = t[s[".name"]] or "nil"
if _node_id ~= "nil" and _node_id ~= "_blackhole" then
if _node_id == "_default" then
_node_id = default_node_id
end
local domain_list = s.domain_list or ""
for line in string.gmatch(domain_list, "[^\r\n]+") do
if line ~= "" and not line:find("#") and not line:find("regexp:") and not line:find("geosite:") and not line:find("ext:") then
if line:find("domain:") or line:find("full:") then
line = string.match(line, ":([^:]+)$")
end
line = api.get_std_domain(line)
if _node_id == "_direct" then
if line ~= "" and not line:find("#") then
insert_unique(white_domain, line, lookup_white_domain)
end
else
if line ~= "" and not line:find("#") then
insert_unique(shunt_domain, line, lookup_shunt_domain)
end
end
end
end
if _node_id ~= "_direct" then
log(string.format(" - Sing-Box/Xray分流规则(%s)%s", s.remarks, DNS_TRUST or "默认"))
end
end
end)
if is_file_nonzero(file_white_host) == nil then
if #white_domain > 0 then
local f_out = io.open(file_white_host, "w")
for i = 1, #white_domain do
f_out:write(white_domain[i] .. "\n")
end
f_out:close()
end
end
if is_file_nonzero(file_shunt_host) == nil then
if #shunt_domain > 0 then
local f_out = io.open(file_shunt_host, "w")
for i = 1, #shunt_domain do
f_out:write(shunt_domain[i] .. "\n")
end
f_out:close()
end
end
if is_file_nonzero(file_white_host) then
tmp_lines = {
"group whitelist",
"group-dnl " .. file_white_host,
"group-upstream " .. DNS_LOCAL,
"group-ipset " .. setflag .. "passwall_whitelist," .. setflag .. "passwall_whitelist6"
}
merge_array(config_lines, tmp_lines)
end
if is_file_nonzero(file_shunt_host) then
tmp_lines = {
"group shuntlist",
"group-dnl " .. file_shunt_host,
"group-upstream " .. DNS_TRUST,
"group-ipset " .. setflag .. "passwall_shuntlist," .. setflag .. "passwall_shuntlist6"
}
merge_array(config_lines, tmp_lines)
if NO_IPV6_TRUST == "1" then table.insert(config_lines, "no-ipv6 tag:shuntlist") end
end
end

View File

@@ -221,8 +221,8 @@ if not fs.access(CACHE_DNS_PATH) then
set_domain_ipset(address, setflag_4 .. "passwall_vpslist," .. setflag_6 .. "passwall_vpslist6")
end
end)
log(string.format(" - 节点列表中的域名(vpslist)%s", fwd_dns or "默认"))
end
log(string.format(" - 节点列表中的域名(vpslist)%s", fwd_dns or "默认"))
end
--直连(白名单)列表
@@ -242,8 +242,8 @@ if not fs.access(CACHE_DNS_PATH) then
set_domain_ipset(line, setflag_4 .. "passwall_whitelist," .. setflag_6 .. "passwall_whitelist6")
end
end
log(string.format(" - 域名白名单(whitelist)%s", fwd_dns or "默认"))
end
log(string.format(" - 域名白名单(whitelist)%s", fwd_dns or "默认"))
end
end
@@ -272,8 +272,8 @@ if not fs.access(CACHE_DNS_PATH) then
set_domain_ipset(line, ipset_flag)
end
end
log(string.format(" - 代理域名表(blacklist)%s", fwd_dns or "默认"))
end
log(string.format(" - 代理域名表(blacklist)%s", fwd_dns or "默认"))
end
end
@@ -306,8 +306,8 @@ if not fs.access(CACHE_DNS_PATH) then
set_domain_ipset(line, ipset_flag)
end
end
log(string.format(" - 防火墙域名表(gfwlist)%s", fwd_dns or "默认"))
end
log(string.format(" - 防火墙域名表(gfwlist)%s", fwd_dns or "默认"))
end
end
@@ -348,13 +348,13 @@ if not fs.access(CACHE_DNS_PATH) then
set_domain_ipset(line, ipset_flag)
end
end
log(string.format(" - 中国域名表(chnroute)%s", fwd_dns or "默认"))
end
log(string.format(" - 中国域名表(chnroute)%s", fwd_dns or "默认"))
end
end
--分流规则
if uci:get(appname, TCP_NODE, "protocol") == "_shunt" then
if uci:get(appname, TCP_NODE, "protocol") == "_shunt" and USE_DEFAULT_DNS ~= "chinadns_ng" and CHINADNS_DNS == "0" then
local t = uci:get_all(appname, TCP_NODE)
local default_node_id = t["default_node"] or "_direct"
uci:foreach(appname, "shunt_rules", function(s)
@@ -391,6 +391,7 @@ if not fs.access(CACHE_DNS_PATH) then
if line:find("domain:") or line:find("full:") then
line = string.match(line, ":([^:]+)$")
end
line = api.get_std_domain(line)
add_excluded_domain(line)
if no_ipv6 then
@@ -401,7 +402,7 @@ if not fs.access(CACHE_DNS_PATH) then
end
end
if _node_id ~= "_direct" then
log(string.format(" - V2ray/Xray分流规则(%s)%s", s.remarks, fwd_dns or "默认"))
log(string.format(" - Sing-Box/Xray分流规则(%s)%s", s.remarks, fwd_dns or "默认"))
end
end
end)

View File

@@ -745,6 +745,8 @@ add_firewall_rule() {
#分流规则的IP列表
local node_protocol=$(config_n_get $TCP_NODE protocol)
if [ "$node_protocol" = "_shunt" ]; then
USE_DIRECT_LIST = "1"
USE_BLOCK_LIST = "1"
local default_node_id=$(config_n_get $TCP_NODE default_node "_direct")
local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
for shunt_id in $shunt_ids; do

View File

@@ -830,6 +830,8 @@ add_firewall_rule() {
#分流规则的IP列表
local node_protocol=$(config_n_get $TCP_NODE protocol)
if [ "$node_protocol" = "_shunt" ]; then
USE_DIRECT_LIST = "1"
USE_BLOCK_LIST = "1"
local default_node_id=$(config_n_get $TCP_NODE default_node "_direct")
local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
for shunt_id in $shunt_ids; do

View File

@@ -345,9 +345,9 @@ dependencies = [
[[package]]
name = "bloomfilter"
version = "1.0.15"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7816eb2d70f5b74972da53075a3060ca363da702c03ccaa003e3ab32a76431a6"
checksum = "c9ee97b815938a5cbb3a0d487d8006fec4859e46c3cd9d1edb1f81090dab14ac"
dependencies = [
"bit-vec",
"getrandom",

View File

@@ -5,6 +5,7 @@
[![Build MSRV](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-msrv.yml/badge.svg)](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-msrv.yml)
[![Build Releases](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-release.yml/badge.svg?event=push)](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-release.yml)
[![Build Nightly Releases](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-nightly-release.yml/badge.svg)](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-nightly-release.yml)
[![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20shadowsocks%20Guru-006BFF)](https://gurubase.io/g/shadowsocks)
[![crates.io](https://img.shields.io/crates/v/shadowsocks-rust.svg)](https://crates.io/crates/shadowsocks-rust)
[![Release](https://img.shields.io/github/release/shadowsocks/shadowsocks-rust.svg)](https://github.com/shadowsocks/shadowsocks-rust/releases)

View File

@@ -60,7 +60,7 @@ url = "2.5"
once_cell = "1.17"
spin = { version = "0.9", features = ["std"] }
pin-project = "1.1"
bloomfilter = { version = "1.0.8", optional = true }
bloomfilter = { version = "2.0.0", optional = true }
thiserror = "1.0"
rand = { version = "0.8", optional = true }
lru_time_cache = { version = "0.11", optional = true }

View File

@@ -1,104 +0,0 @@
package adapter
import (
"context"
"net"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type ConnectionRouter interface {
RouteConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}
func NewRouteHandler(
metadata InboundContext,
router ConnectionRouter,
logger logger.ContextLogger,
) UpstreamHandlerAdapter {
return &routeHandlerWrapper{
metadata: metadata,
router: router,
logger: logger,
}
}
func NewRouteContextHandler(
router ConnectionRouter,
logger logger.ContextLogger,
) UpstreamHandlerAdapter {
return &routeContextHandlerWrapper{
router: router,
logger: logger,
}
}
var _ UpstreamHandlerAdapter = (*routeHandlerWrapper)(nil)
type routeHandlerWrapper struct {
metadata InboundContext
router ConnectionRouter
logger logger.ContextLogger
}
func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RouteConnection(ctx, conn, myMetadata)
}
func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RoutePacketConnection(ctx, conn, myMetadata)
}
func (w *routeHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}
var _ UpstreamHandlerAdapter = (*routeContextHandlerWrapper)(nil)
type routeContextHandlerWrapper struct {
router ConnectionRouter
logger logger.ContextLogger
}
func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RouteConnection(ctx, conn, *myMetadata)
}
func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RoutePacketConnection(ctx, conn, *myMetadata)
}
func (w *routeContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}

View File

@@ -6,27 +6,53 @@ import (
"github.com/sagernet/sing/common/buf"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
// Deprecated
type ConnectionHandler interface {
NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
}
type ConnectionHandlerEx interface {
NewConnectionEx(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
// Deprecated: use PacketHandlerEx instead
type PacketHandler interface {
NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata InboundContext) error
}
type PacketHandlerEx interface {
NewPacketEx(buffer *buf.Buffer, source M.Socksaddr)
}
// Deprecated: use OOBPacketHandlerEx instead
type OOBPacketHandler interface {
NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, oob []byte, metadata InboundContext) error
}
type OOBPacketHandlerEx interface {
NewPacketEx(buffer *buf.Buffer, oob []byte, source M.Socksaddr)
}
// Deprecated
type PacketConnectionHandler interface {
NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}
type PacketConnectionHandlerEx interface {
NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
type UpstreamHandlerAdapter interface {
N.TCPConnectionHandler
N.UDPConnectionHandler
E.Handler
}
type UpstreamHandlerAdapterEx interface {
N.TCPConnectionHandlerEx
N.UDPConnectionHandlerEx
}

View File

@@ -2,13 +2,12 @@ package adapter
import (
"context"
"net"
"net/netip"
"github.com/sagernet/sing-box/common/process"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type Inbound interface {
@@ -17,11 +16,19 @@ type Inbound interface {
Tag() string
}
type InjectableInbound interface {
type TCPInjectableInbound interface {
Inbound
Network() []string
NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
ConnectionHandlerEx
}
type UDPInjectableInbound interface {
Inbound
PacketConnectionHandlerEx
}
type InboundRegistry interface {
option.InboundOptionsRegistry
CreateInbound(ctx context.Context, router Router, logger log.ContextLogger, tag string, outboundType string, options any) (Inbound, error)
}
type InboundContext struct {
@@ -43,10 +50,15 @@ type InboundContext struct {
// cache
InboundDetour string
LastInbound string
OriginDestination M.Socksaddr
InboundOptions option.InboundOptions
// Deprecated: implement in rule action
InboundDetour string
LastInbound string
OriginDestination M.Socksaddr
// Deprecated
InboundOptions option.InboundOptions
UDPDisableDomainUnmapping bool
DNSServer string
DestinationAddresses []netip.Addr
SourceGeoIPCode string
GeoIPCode string

View File

@@ -0,0 +1,21 @@
package inbound
type Adapter struct {
inboundType string
inboundTag string
}
func NewAdapter(inboundType string, inboundTag string) Adapter {
return Adapter{
inboundType: inboundType,
inboundTag: inboundTag,
}
}
func (a *Adapter) Type() string {
return a.inboundType
}
func (a *Adapter) Tag() string {
return a.inboundTag
}

View File

@@ -0,0 +1,68 @@
package inbound
import (
"context"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Inbound, error)
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
registry.register(outboundType, func() any {
return new(Options)
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Inbound, error) {
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options.(*Options)))
})
}
var _ adapter.InboundRegistry = (*Registry)(nil)
type (
optionsConstructorFunc func() any
constructorFunc func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Inbound, error)
)
type Registry struct {
access sync.Mutex
optionsType map[string]optionsConstructorFunc
constructors map[string]constructorFunc
}
func NewRegistry() *Registry {
return &Registry{
optionsType: make(map[string]optionsConstructorFunc),
constructors: make(map[string]constructorFunc),
}
}
func (r *Registry) CreateOptions(outboundType string) (any, bool) {
r.access.Lock()
defer r.access.Unlock()
optionsConstructor, loaded := r.optionsType[outboundType]
if !loaded {
return nil, false
}
return optionsConstructor(), true
}
func (r *Registry) CreateInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Inbound, error) {
r.access.Lock()
defer r.access.Unlock()
constructor, loaded := r.constructors[outboundType]
if !loaded {
return nil, E.New("outbound type not found: " + outboundType)
}
return constructor(ctx, router, logger, tag, options)
}
func (r *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
r.access.Lock()
defer r.access.Unlock()
r.optionsType[outboundType] = optionsConstructor
r.constructors[outboundType] = constructor
}

View File

@@ -2,8 +2,9 @@ package adapter
import (
"context"
"net"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
N "github.com/sagernet/sing/common/network"
)
@@ -15,6 +16,9 @@ type Outbound interface {
Network() []string
Dependencies() []string
N.Dialer
NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}
type OutboundRegistry interface {
option.OutboundOptionsRegistry
CreateOutbound(ctx context.Context, router Router, logger log.ContextLogger, tag string, outboundType string, options any) (Outbound, error)
}

View File

@@ -0,0 +1,45 @@
package outbound
import (
"github.com/sagernet/sing-box/option"
)
type Adapter struct {
protocol string
network []string
tag string
dependencies []string
}
func NewAdapter(protocol string, network []string, tag string, dependencies []string) Adapter {
return Adapter{
protocol: protocol,
network: network,
tag: tag,
dependencies: dependencies,
}
}
func NewAdapterWithDialerOptions(protocol string, network []string, tag string, dialOptions option.DialerOptions) Adapter {
var dependencies []string
if dialOptions.Detour != "" {
dependencies = []string{dialOptions.Detour}
}
return NewAdapter(protocol, network, tag, dependencies)
}
func (a *Adapter) Type() string {
return a.protocol
}
func (a *Adapter) Tag() string {
return a.tag
}
func (a *Adapter) Network() []string {
return a.network
}
func (a *Adapter) Dependencies() []string {
return a.dependencies
}

View File

@@ -9,8 +9,6 @@ import (
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-dns"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
@@ -21,42 +19,6 @@ import (
N "github.com/sagernet/sing/common/network"
)
type myOutboundAdapter struct {
protocol string
network []string
router adapter.Router
logger log.ContextLogger
tag string
dependencies []string
}
func (a *myOutboundAdapter) Type() string {
return a.protocol
}
func (a *myOutboundAdapter) Tag() string {
return a.tag
}
func (a *myOutboundAdapter) Network() []string {
return a.network
}
func (a *myOutboundAdapter) Dependencies() []string {
return a.dependencies
}
func (a *myOutboundAdapter) NewError(ctx context.Context, err error) {
NewError(a.logger, ctx, err)
}
func withDialerDependency(options option.DialerOptions) []string {
if options.Detour != "" {
return []string{options.Detour}
}
return nil
}
func NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata adapter.InboundContext) error {
ctx = adapter.WithContext(ctx, &metadata)
var outConn net.Conn
@@ -69,7 +31,7 @@ func NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata a
if err != nil {
return N.ReportHandshakeFailure(conn, err)
}
err = N.ReportHandshakeSuccess(conn)
err = N.ReportConnHandshakeSuccess(conn, outConn)
if err != nil {
outConn.Close()
return err
@@ -96,7 +58,7 @@ func NewDirectConnection(ctx context.Context, router adapter.Router, this N.Dial
if err != nil {
return N.ReportHandshakeFailure(conn, err)
}
err = N.ReportHandshakeSuccess(conn)
err = N.ReportConnHandshakeSuccess(conn, outConn)
if err != nil {
outConn.Close()
return err
@@ -117,14 +79,14 @@ func NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn,
if err != nil {
return N.ReportHandshakeFailure(conn, err)
}
err = N.ReportHandshakeSuccess(conn)
err = N.ReportPacketConnHandshakeSuccess(conn, outConn)
if err != nil {
outConn.Close()
return err
}
if destinationAddress.IsValid() {
if metadata.Destination.IsFqdn() {
if metadata.InboundOptions.UDPDisableDomainUnmapping {
if metadata.UDPDisableDomainUnmapping {
outConn = bufio.NewUnidirectionalNATPacketConn(bufio.NewPacketConn(outConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), metadata.Destination)
} else {
outConn = bufio.NewNATPacketConn(bufio.NewPacketConn(outConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), metadata.Destination)
@@ -165,7 +127,7 @@ func NewDirectPacketConnection(ctx context.Context, router adapter.Router, this
if err != nil {
return N.ReportHandshakeFailure(conn, err)
}
err = N.ReportHandshakeSuccess(conn)
err = N.ReportPacketConnHandshakeSuccess(conn, outConn)
if err != nil {
outConn.Close()
return err
@@ -233,12 +195,3 @@ func CopyEarlyConn(ctx context.Context, conn net.Conn, serverConn net.Conn) erro
}
return bufio.CopyConn(ctx, conn, serverConn)
}
func NewError(logger log.ContextLogger, ctx context.Context, err error) {
common.Close(err)
if E.IsClosedOrCanceled(err) {
logger.DebugContext(ctx, "connection closed: ", err)
return
}
logger.ErrorContext(ctx, err)
}

View File

@@ -0,0 +1,68 @@
package outbound
import (
"context"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Outbound, error)
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
registry.register(outboundType, func() any {
return new(Options)
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Outbound, error) {
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options.(*Options)))
})
}
var _ adapter.OutboundRegistry = (*Registry)(nil)
type (
optionsConstructorFunc func() any
constructorFunc func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Outbound, error)
)
type Registry struct {
access sync.Mutex
optionsType map[string]optionsConstructorFunc
constructors map[string]constructorFunc
}
func NewRegistry() *Registry {
return &Registry{
optionsType: make(map[string]optionsConstructorFunc),
constructors: make(map[string]constructorFunc),
}
}
func (r *Registry) CreateOptions(outboundType string) (any, bool) {
r.access.Lock()
defer r.access.Unlock()
optionsConstructor, loaded := r.optionsType[outboundType]
if !loaded {
return nil, false
}
return optionsConstructor(), true
}
func (r *Registry) CreateOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Outbound, error) {
r.access.Lock()
defer r.access.Unlock()
constructor, loaded := r.constructors[outboundType]
if !loaded {
return nil, E.New("outbound type not found: " + outboundType)
}
return constructor(ctx, router, logger, tag, options)
}
func (r *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
r.access.Lock()
defer r.access.Unlock()
r.optionsType[outboundType] = optionsConstructor
r.constructors[outboundType] = constructor
}

View File

@@ -34,6 +34,8 @@ type Router interface {
FakeIPStore() FakeIPStore
ConnectionRouter
PreMatch(metadata InboundContext) error
ConnectionRouterEx
GeoIPReader() *geoip.Reader
LoadGeosite(code string) (Rule, error)
@@ -70,6 +72,18 @@ type Router interface {
ResetNetwork() error
}
// Deprecated: Use ConnectionRouterEx instead.
type ConnectionRouter interface {
RouteConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}
type ConnectionRouterEx interface {
ConnectionRouter
RouteConnectionEx(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
func ContextWithRouter(ctx context.Context, router Router) context.Context {
return service.ContextWith(ctx, router)
}
@@ -78,28 +92,6 @@ func RouterFromContext(ctx context.Context) Router {
return service.FromContext[Router](ctx)
}
type HeadlessRule interface {
Match(metadata *InboundContext) bool
String() string
}
type Rule interface {
HeadlessRule
Service
Type() string
UpdateGeosite() error
Outbound() string
}
type DNSRule interface {
Rule
DisableCache() bool
RewriteTTL() *uint32
ClientSubnet() *netip.Prefix
WithAddressLimit() bool
MatchAddressLimit(metadata *InboundContext) bool
}
type RuleSet interface {
Name() string
StartContext(ctx context.Context, startContext *HTTPStartContext) error

38
sing-box/adapter/rule.go Normal file
View File

@@ -0,0 +1,38 @@
package adapter
import (
C "github.com/sagernet/sing-box/constant"
)
type HeadlessRule interface {
Match(metadata *InboundContext) bool
String() string
}
type Rule interface {
HeadlessRule
Service
Type() string
UpdateGeosite() error
Action() RuleAction
}
type DNSRule interface {
Rule
WithAddressLimit() bool
MatchAddressLimit(metadata *InboundContext) bool
}
type RuleAction interface {
Type() string
String() string
}
func IsFinalAction(action RuleAction) bool {
switch action.Type() {
case C.RuleActionTypeSniff, C.RuleActionTypeResolve:
return false
default:
return true
}
}

View File

@@ -4,112 +4,165 @@ import (
"context"
"net"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type (
ConnectionHandlerFunc = func(ctx context.Context, conn net.Conn, metadata InboundContext) error
PacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
ConnectionHandlerFuncEx = func(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
PacketConnectionHandlerFuncEx = func(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
)
func NewUpstreamHandler(
func NewUpstreamHandlerEx(
metadata InboundContext,
connectionHandler ConnectionHandlerFunc,
packetHandler PacketConnectionHandlerFunc,
errorHandler E.Handler,
) UpstreamHandlerAdapter {
return &myUpstreamHandlerWrapper{
connectionHandler ConnectionHandlerFuncEx,
packetHandler PacketConnectionHandlerFuncEx,
) UpstreamHandlerAdapterEx {
return &myUpstreamHandlerWrapperEx{
metadata: metadata,
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
var _ UpstreamHandlerAdapter = (*myUpstreamHandlerWrapper)(nil)
var _ UpstreamHandlerAdapterEx = (*myUpstreamHandlerWrapperEx)(nil)
type myUpstreamHandlerWrapper struct {
type myUpstreamHandlerWrapperEx struct {
metadata InboundContext
connectionHandler ConnectionHandlerFunc
packetHandler PacketConnectionHandlerFunc
errorHandler E.Handler
connectionHandler ConnectionHandlerFuncEx
packetHandler PacketConnectionHandlerFuncEx
}
func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
func (w *myUpstreamHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
if source.IsValid() {
myMetadata.Source = source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
if destination.IsValid() {
myMetadata.Destination = destination
}
return w.connectionHandler(ctx, conn, myMetadata)
w.connectionHandler(ctx, conn, myMetadata, onClose)
}
func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
func (w *myUpstreamHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
if source.IsValid() {
myMetadata.Source = source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
if destination.IsValid() {
myMetadata.Destination = destination
}
return w.packetHandler(ctx, conn, myMetadata)
w.packetHandler(ctx, conn, myMetadata, onClose)
}
func (w *myUpstreamHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
var _ UpstreamHandlerAdapterEx = (*myUpstreamContextHandlerWrapperEx)(nil)
type myUpstreamContextHandlerWrapperEx struct {
connectionHandler ConnectionHandlerFuncEx
packetHandler PacketConnectionHandlerFuncEx
}
func UpstreamMetadata(metadata InboundContext) M.Metadata {
return M.Metadata{
Source: metadata.Source,
Destination: metadata.Destination,
}
}
type myUpstreamContextHandlerWrapper struct {
connectionHandler ConnectionHandlerFunc
packetHandler PacketConnectionHandlerFunc
errorHandler E.Handler
}
func NewUpstreamContextHandler(
connectionHandler ConnectionHandlerFunc,
packetHandler PacketConnectionHandlerFunc,
errorHandler E.Handler,
) UpstreamHandlerAdapter {
return &myUpstreamContextHandlerWrapper{
func NewUpstreamContextHandlerEx(
connectionHandler ConnectionHandlerFuncEx,
packetHandler PacketConnectionHandlerFuncEx,
) UpstreamHandlerAdapterEx {
return &myUpstreamContextHandlerWrapperEx{
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
func (w *myUpstreamContextHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
if source.IsValid() {
myMetadata.Source = source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
if destination.IsValid() {
myMetadata.Destination = destination
}
return w.connectionHandler(ctx, conn, *myMetadata)
w.connectionHandler(ctx, conn, *myMetadata, onClose)
}
func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
func (w *myUpstreamContextHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
if source.IsValid() {
myMetadata.Source = source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
if destination.IsValid() {
myMetadata.Destination = destination
}
return w.packetHandler(ctx, conn, *myMetadata)
w.packetHandler(ctx, conn, *myMetadata, onClose)
}
func (w *myUpstreamContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
func NewRouteHandlerEx(
metadata InboundContext,
router ConnectionRouterEx,
) UpstreamHandlerAdapterEx {
return &routeHandlerWrapperEx{
metadata: metadata,
router: router,
}
}
var _ UpstreamHandlerAdapterEx = (*routeHandlerWrapperEx)(nil)
type routeHandlerWrapperEx struct {
metadata InboundContext
router ConnectionRouterEx
}
func (r *routeHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
if source.IsValid() {
r.metadata.Source = source
}
if destination.IsValid() {
r.metadata.Destination = destination
}
r.router.RouteConnectionEx(ctx, conn, r.metadata, onClose)
}
func (r *routeHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
if source.IsValid() {
r.metadata.Source = source
}
if destination.IsValid() {
r.metadata.Destination = destination
}
r.router.RoutePacketConnectionEx(ctx, conn, r.metadata, onClose)
}
func NewRouteContextHandlerEx(
router ConnectionRouterEx,
) UpstreamHandlerAdapterEx {
return &routeContextHandlerWrapperEx{
router: router,
}
}
var _ UpstreamHandlerAdapterEx = (*routeContextHandlerWrapperEx)(nil)
type routeContextHandlerWrapperEx struct {
router ConnectionRouterEx
}
func (r *routeContextHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
metadata := ContextFrom(ctx)
if source.IsValid() {
metadata.Source = source
}
if destination.IsValid() {
metadata.Destination = destination
}
r.router.RouteConnectionEx(ctx, conn, *metadata, onClose)
}
func (r *routeContextHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
metadata := ContextFrom(ctx)
if source.IsValid() {
metadata.Source = source
}
if destination.IsValid() {
metadata.Destination = destination
}
r.router.RoutePacketConnectionEx(ctx, conn, *metadata, onClose)
}

View File

@@ -0,0 +1,216 @@
package adapter
import (
"context"
"net"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type (
// Deprecated
ConnectionHandlerFunc = func(ctx context.Context, conn net.Conn, metadata InboundContext) error
// Deprecated
PacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
)
// Deprecated
func NewUpstreamHandler(
metadata InboundContext,
connectionHandler ConnectionHandlerFunc,
packetHandler PacketConnectionHandlerFunc,
errorHandler E.Handler,
) UpstreamHandlerAdapter {
return &myUpstreamHandlerWrapper{
metadata: metadata,
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
var _ UpstreamHandlerAdapter = (*myUpstreamHandlerWrapper)(nil)
// Deprecated
type myUpstreamHandlerWrapper struct {
metadata InboundContext
connectionHandler ConnectionHandlerFunc
packetHandler PacketConnectionHandlerFunc
errorHandler E.Handler
}
func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.connectionHandler(ctx, conn, myMetadata)
}
func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.packetHandler(ctx, conn, myMetadata)
}
func (w *myUpstreamHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
}
// Deprecated
func UpstreamMetadata(metadata InboundContext) M.Metadata {
return M.Metadata{
Source: metadata.Source,
Destination: metadata.Destination,
}
}
// Deprecated
type myUpstreamContextHandlerWrapper struct {
connectionHandler ConnectionHandlerFunc
packetHandler PacketConnectionHandlerFunc
errorHandler E.Handler
}
// Deprecated
func NewUpstreamContextHandler(
connectionHandler ConnectionHandlerFunc,
packetHandler PacketConnectionHandlerFunc,
errorHandler E.Handler,
) UpstreamHandlerAdapter {
return &myUpstreamContextHandlerWrapper{
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.connectionHandler(ctx, conn, *myMetadata)
}
func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.packetHandler(ctx, conn, *myMetadata)
}
func (w *myUpstreamContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
}
// Deprecated: Use ConnectionRouterEx instead.
func NewRouteHandler(
metadata InboundContext,
router ConnectionRouter,
logger logger.ContextLogger,
) UpstreamHandlerAdapter {
return &routeHandlerWrapper{
metadata: metadata,
router: router,
logger: logger,
}
}
// Deprecated: Use ConnectionRouterEx instead.
func NewRouteContextHandler(
router ConnectionRouter,
logger logger.ContextLogger,
) UpstreamHandlerAdapter {
return &routeContextHandlerWrapper{
router: router,
logger: logger,
}
}
var _ UpstreamHandlerAdapter = (*routeHandlerWrapper)(nil)
// Deprecated: Use ConnectionRouterEx instead.
type routeHandlerWrapper struct {
metadata InboundContext
router ConnectionRouter
logger logger.ContextLogger
}
func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RouteConnection(ctx, conn, myMetadata)
}
func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RoutePacketConnection(ctx, conn, myMetadata)
}
func (w *routeHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}
var _ UpstreamHandlerAdapter = (*routeContextHandlerWrapper)(nil)
// Deprecated: Use ConnectionRouterEx instead.
type routeContextHandlerWrapper struct {
router ConnectionRouter
logger logger.ContextLogger
}
func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RouteConnection(ctx, conn, *myMetadata)
}
func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RoutePacketConnection(ctx, conn, *myMetadata)
}
func (w *routeContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}

View File

@@ -4,7 +4,6 @@ import (
"context"
"net"
E "github.com/sagernet/sing/common/exceptions"
N "github.com/sagernet/sing/common/network"
)
@@ -16,8 +15,7 @@ type V2RayServerTransport interface {
}
type V2RayServerTransportHandler interface {
N.TCPConnectionHandler
E.Handler
N.TCPConnectionHandlerEx
}
type V2RayClientTransport interface {

View File

@@ -14,10 +14,9 @@ import (
"github.com/sagernet/sing-box/experimental"
"github.com/sagernet/sing-box/experimental/cachefile"
"github.com/sagernet/sing-box/experimental/libbox/platform"
"github.com/sagernet/sing-box/inbound"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/outbound"
"github.com/sagernet/sing-box/protocol/direct"
"github.com/sagernet/sing-box/route"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
@@ -44,16 +43,37 @@ type Box struct {
type Options struct {
option.Options
Context context.Context
PlatformInterface platform.Interface
PlatformLogWriter log.PlatformWriter
}
func Context(ctx context.Context, inboundRegistry adapter.InboundRegistry, outboundRegistry adapter.OutboundRegistry) context.Context {
if service.FromContext[option.InboundOptionsRegistry](ctx) == nil ||
service.FromContext[adapter.InboundRegistry](ctx) == nil {
ctx = service.ContextWith[option.InboundOptionsRegistry](ctx, inboundRegistry)
ctx = service.ContextWith[adapter.InboundRegistry](ctx, inboundRegistry)
}
if service.FromContext[option.OutboundOptionsRegistry](ctx) == nil ||
service.FromContext[adapter.OutboundRegistry](ctx) == nil {
ctx = service.ContextWith[option.OutboundOptionsRegistry](ctx, outboundRegistry)
ctx = service.ContextWith[adapter.OutboundRegistry](ctx, outboundRegistry)
}
return ctx
}
func New(options Options) (*Box, error) {
createdAt := time.Now()
ctx := options.Context
if ctx == nil {
ctx = context.Background()
}
inboundRegistry := service.FromContext[adapter.InboundRegistry](ctx)
if inboundRegistry == nil {
return nil, E.New("missing inbound registry in context")
}
outboundRegistry := service.FromContext[adapter.OutboundRegistry](ctx)
if outboundRegistry == nil {
return nil, E.New("missing outbound registry in context")
}
ctx = service.ContextWithDefaultRegistry(ctx)
ctx = pause.WithDefaultManager(ctx)
experimentalOptions := common.PtrValueOrDefault(options.Experimental)
@@ -70,8 +90,9 @@ func New(options Options) (*Box, error) {
if experimentalOptions.V2RayAPI != nil && experimentalOptions.V2RayAPI.Listen != "" {
needV2RayAPI = true
}
platformInterface := service.FromContext[platform.Interface](ctx)
var defaultLogWriter io.Writer
if options.PlatformInterface != nil {
if platformInterface != nil {
defaultLogWriter = io.Discard
}
logFactory, err := log.New(log.Options{
@@ -92,64 +113,92 @@ func New(options Options) (*Box, error) {
common.PtrValueOrDefault(options.DNS),
common.PtrValueOrDefault(options.NTP),
options.Inbounds,
options.PlatformInterface,
)
if err != nil {
return nil, E.Cause(err, "parse route options")
}
//nolint:staticcheck
if len(options.LegacyInbounds) > 0 {
for _, legacyInbound := range options.LegacyInbounds {
options.Inbounds = append(options.Inbounds, option.Inbound{
Type: legacyInbound.Type,
Tag: legacyInbound.Tag,
Options: common.Must1(legacyInbound.RawOptions()),
})
}
}
inbounds := make([]adapter.Inbound, 0, len(options.Inbounds))
//nolint:staticcheck
if len(options.LegacyOutbounds) > 0 {
for _, legacyOutbound := range options.LegacyOutbounds {
options.Outbounds = append(options.Outbounds, option.Outbound{
Type: legacyOutbound.Type,
Tag: legacyOutbound.Tag,
Options: common.Must1(legacyOutbound.RawOptions()),
})
}
}
outbounds := make([]adapter.Outbound, 0, len(options.Outbounds))
for i, inboundOptions := range options.Inbounds {
var in adapter.Inbound
var currentInbound adapter.Inbound
var tag string
if inboundOptions.Tag != "" {
tag = inboundOptions.Tag
} else {
tag = F.ToString(i)
}
in, err = inbound.New(
currentInbound, err = inboundRegistry.CreateInbound(
ctx,
router,
logFactory.NewLogger(F.ToString("inbound/", inboundOptions.Type, "[", tag, "]")),
tag,
inboundOptions,
options.PlatformInterface,
inboundOptions.Type,
inboundOptions.Options,
)
if err != nil {
return nil, E.Cause(err, "parse inbound[", i, "]")
}
inbounds = append(inbounds, in)
inbounds = append(inbounds, currentInbound)
}
for i, outboundOptions := range options.Outbounds {
var out adapter.Outbound
var currentOutbound adapter.Outbound
var tag string
if outboundOptions.Tag != "" {
tag = outboundOptions.Tag
} else {
tag = F.ToString(i)
}
out, err = outbound.New(
ctx,
outboundCtx := ctx
if tag != "" {
// TODO: remove this
outboundCtx = adapter.WithContext(outboundCtx, &adapter.InboundContext{
Outbound: tag,
})
}
currentOutbound, err = outboundRegistry.CreateOutbound(
outboundCtx,
router,
logFactory.NewLogger(F.ToString("outbound/", outboundOptions.Type, "[", tag, "]")),
tag,
outboundOptions)
outboundOptions.Type,
outboundOptions.Options,
)
if err != nil {
return nil, E.Cause(err, "parse outbound[", i, "]")
}
outbounds = append(outbounds, out)
outbounds = append(outbounds, currentOutbound)
}
err = router.Initialize(inbounds, outbounds, func() adapter.Outbound {
out, oErr := outbound.New(ctx, router, logFactory.NewLogger("outbound/direct"), "direct", option.Outbound{Type: "direct", Tag: "default"})
common.Must(oErr)
outbounds = append(outbounds, out)
return out
defaultOutbound, cErr := direct.NewOutbound(ctx, router, logFactory.NewLogger("outbound/direct"), "direct", option.DirectOutboundOptions{})
common.Must(cErr)
outbounds = append(outbounds, defaultOutbound)
return defaultOutbound
})
if err != nil {
return nil, err
}
if options.PlatformInterface != nil {
err = options.PlatformInterface.Initialize(ctx, router)
if platformInterface != nil {
err = platformInterface.Initialize(ctx, router)
if err != nil {
return nil, E.Cause(err, "initialize platform interface")
}

View File

@@ -7,8 +7,9 @@ import (
"strconv"
"time"
"github.com/sagernet/sing-box"
"github.com/sagernet/sing-box/experimental/deprecated"
_ "github.com/sagernet/sing-box/include"
"github.com/sagernet/sing-box/include"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/service"
"github.com/sagernet/sing/service/filemanager"
@@ -68,4 +69,5 @@ func preRun(cmd *cobra.Command, args []string) {
configPaths = append(configPaths, "config.json")
}
globalCtx = service.ContextWith(globalCtx, deprecated.NewEnvManager(log.StdLogger()))
globalCtx = box.Context(globalCtx, include.InboundRegistry(), include.OutboundRegistry())
}

View File

@@ -38,7 +38,7 @@ func format() error {
return err
}
for _, optionsEntry := range optionsList {
optionsEntry.options, err = badjson.Omitempty(optionsEntry.options)
optionsEntry.options, err = badjson.Omitempty(globalCtx, optionsEntry.options)
if err != nil {
return err
}

View File

@@ -68,29 +68,19 @@ func merge(outputPath string) error {
}
func mergePathResources(options *option.Options) error {
for index, inbound := range options.Inbounds {
rawOptions, err := inbound.RawOptions()
if err != nil {
return err
}
if tlsOptions, containsTLSOptions := rawOptions.(option.InboundTLSOptionsWrapper); containsTLSOptions {
for _, inbound := range options.Inbounds {
if tlsOptions, containsTLSOptions := inbound.Options.(option.InboundTLSOptionsWrapper); containsTLSOptions {
tlsOptions.ReplaceInboundTLSOptions(mergeTLSInboundOptions(tlsOptions.TakeInboundTLSOptions()))
}
options.Inbounds[index] = inbound
}
for index, outbound := range options.Outbounds {
rawOptions, err := outbound.RawOptions()
if err != nil {
return err
}
for _, outbound := range options.Outbounds {
switch outbound.Type {
case C.TypeSSH:
outbound.SSHOptions = mergeSSHOutboundOptions(outbound.SSHOptions)
mergeSSHOutboundOptions(outbound.Options.(*option.SSHOutboundOptions))
}
if tlsOptions, containsTLSOptions := rawOptions.(option.OutboundTLSOptionsWrapper); containsTLSOptions {
if tlsOptions, containsTLSOptions := outbound.Options.(option.OutboundTLSOptionsWrapper); containsTLSOptions {
tlsOptions.ReplaceOutboundTLSOptions(mergeTLSOutboundOptions(tlsOptions.TakeOutboundTLSOptions()))
}
options.Outbounds[index] = outbound
}
return nil
}
@@ -138,13 +128,12 @@ func mergeTLSOutboundOptions(options *option.OutboundTLSOptions) *option.Outboun
return options
}
func mergeSSHOutboundOptions(options option.SSHOutboundOptions) option.SSHOutboundOptions {
func mergeSSHOutboundOptions(options *option.SSHOutboundOptions) {
if options.PrivateKeyPath != "" {
if content, err := os.ReadFile(os.ExpandEnv(options.PrivateKeyPath)); err == nil {
options.PrivateKey = trimStringArray(strings.Split(string(content), "\n"))
}
}
return options
}
func trimStringArray(array []string) []string {

View File

@@ -10,7 +10,7 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/route"
"github.com/sagernet/sing-box/route/rule"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/json"
@@ -84,7 +84,7 @@ func ruleSetMatch(sourcePath string, domain string) error {
}
for i, ruleOptions := range plainRuleSet.Rules {
var currentRule adapter.HeadlessRule
currentRule, err = route.NewHeadlessRule(nil, ruleOptions)
currentRule, err = rule.NewHeadlessRule(nil, ruleOptions)
if err != nil {
return E.Cause(err, "parse rule_set.rules.[", i, "]")
}

View File

@@ -57,7 +57,7 @@ func readConfigAt(path string) (*OptionsEntry, error) {
if err != nil {
return nil, E.Cause(err, "read config at ", path)
}
options, err := json.UnmarshalExtended[option.Options](configContent)
options, err := json.UnmarshalExtendedContext[option.Options](globalCtx, configContent)
if err != nil {
return nil, E.Cause(err, "decode config at ", path)
}
@@ -109,13 +109,13 @@ func readConfigAndMerge() (option.Options, error) {
}
var mergedMessage json.RawMessage
for _, options := range optionsList {
mergedMessage, err = badjson.MergeJSON(options.options.RawMessage, mergedMessage, false)
mergedMessage, err = badjson.MergeJSON(globalCtx, options.options.RawMessage, mergedMessage, false)
if err != nil {
return option.Options{}, E.Cause(err, "merge config at ", options.path)
}
}
var mergedOptions option.Options
err = mergedOptions.UnmarshalJSON(mergedMessage)
err = mergedOptions.UnmarshalJSONContext(globalCtx, mergedMessage)
if err != nil {
return option.Options{}, E.Cause(err, "unmarshal merged config")
}

View File

@@ -1,6 +1,9 @@
package main
import (
"errors"
"os"
"github.com/sagernet/sing-box"
E "github.com/sagernet/sing/common/exceptions"
N "github.com/sagernet/sing/common/network"
@@ -23,7 +26,9 @@ func init() {
func createPreStartedClient() (*box.Box, error) {
options, err := readConfigAndMerge()
if err != nil {
return nil, err
if !(errors.Is(err, os.ErrNotExist) && len(configDirectories) == 0 && len(configPaths) == 1) || configPaths[0] != "config.json" {
return nil, err
}
}
instance, err := box.New(box.Options{Options: options})
if err != nil {

View File

@@ -5,7 +5,7 @@ import (
"testing"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/route"
"github.com/sagernet/sing-box/route/rule"
"github.com/stretchr/testify/require"
)
@@ -26,7 +26,7 @@ example.arpa
`))
require.NoError(t, err)
require.Len(t, rules, 1)
rule, err := route.NewHeadlessRule(nil, rules[0])
rule, err := rule.NewHeadlessRule(nil, rules[0])
require.NoError(t, err)
matchDomain := []string{
"example.org",
@@ -85,7 +85,7 @@ func TestHosts(t *testing.T) {
`))
require.NoError(t, err)
require.Len(t, rules, 1)
rule, err := route.NewHeadlessRule(nil, rules[0])
rule, err := rule.NewHeadlessRule(nil, rules[0])
require.NoError(t, err)
matchDomain := []string{
"google.com",
@@ -115,7 +115,7 @@ www.example.org
`))
require.NoError(t, err)
require.Len(t, rules, 1)
rule, err := route.NewHeadlessRule(nil, rules[0])
rule, err := rule.NewHeadlessRule(nil, rules[0])
require.NoError(t, err)
matchDomain := []string{
"example.com",

View File

@@ -125,7 +125,7 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi
setMultiPathTCP(&dialer4)
}
if options.IsWireGuardListener {
for _, controlFn := range wgControlFns {
for _, controlFn := range WgControlFns {
listener.Control = control.Append(listener.Control, controlFn)
}
}

View File

@@ -2,8 +2,12 @@ package dialer
import (
"net"
"github.com/sagernet/sing/common/control"
)
type WireGuardListener interface {
ListenPacketCompat(network, address string) (net.PacketConn, error)
}
var WgControlFns []control.Func

View File

@@ -1,11 +0,0 @@
//go:build with_wireguard
package dialer
import (
"github.com/sagernet/wireguard-go/conn"
)
var _ WireGuardListener = (conn.Listener)(nil)
var wgControlFns = conn.ControlFns

View File

@@ -1,9 +0,0 @@
//go:build !with_wireguard
package dialer
import (
"github.com/sagernet/sing/common/control"
)
var wgControlFns []control.Func

View File

@@ -0,0 +1,136 @@
package listener
import (
"context"
"net"
"sync/atomic"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/settings"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type Listener struct {
ctx context.Context
logger logger.ContextLogger
network []string
listenOptions option.ListenOptions
connHandler adapter.ConnectionHandlerEx
packetHandler adapter.PacketHandlerEx
oobPacketHandler adapter.OOBPacketHandlerEx
threadUnsafePacketWriter bool
disablePacketOutput bool
setSystemProxy bool
systemProxySOCKS bool
tcpListener net.Listener
systemProxy settings.SystemProxy
udpConn *net.UDPConn
udpAddr M.Socksaddr
packetOutbound chan *N.PacketBuffer
packetOutboundClosed chan struct{}
shutdown atomic.Bool
}
type Options struct {
Context context.Context
Logger logger.ContextLogger
Network []string
Listen option.ListenOptions
ConnectionHandler adapter.ConnectionHandlerEx
PacketHandler adapter.PacketHandlerEx
OOBPacketHandler adapter.OOBPacketHandlerEx
ThreadUnsafePacketWriter bool
DisablePacketOutput bool
SetSystemProxy bool
SystemProxySOCKS bool
}
func New(
options Options,
) *Listener {
return &Listener{
ctx: options.Context,
logger: options.Logger,
network: options.Network,
listenOptions: options.Listen,
connHandler: options.ConnectionHandler,
packetHandler: options.PacketHandler,
oobPacketHandler: options.OOBPacketHandler,
threadUnsafePacketWriter: options.ThreadUnsafePacketWriter,
disablePacketOutput: options.DisablePacketOutput,
setSystemProxy: options.SetSystemProxy,
systemProxySOCKS: options.SystemProxySOCKS,
}
}
func (l *Listener) Start() error {
if common.Contains(l.network, N.NetworkTCP) {
_, err := l.ListenTCP()
if err != nil {
return err
}
go l.loopTCPIn()
}
if common.Contains(l.network, N.NetworkUDP) {
_, err := l.ListenUDP()
if err != nil {
return err
}
l.packetOutboundClosed = make(chan struct{})
l.packetOutbound = make(chan *N.PacketBuffer, 64)
go l.loopUDPIn()
if !l.disablePacketOutput {
go l.loopUDPOut()
}
}
if l.setSystemProxy {
listenPort := M.SocksaddrFromNet(l.tcpListener.Addr()).Port
var listenAddrString string
listenAddr := l.listenOptions.Listen.Build()
if listenAddr.IsUnspecified() {
listenAddrString = "127.0.0.1"
} else {
listenAddrString = listenAddr.String()
}
systemProxy, err := settings.NewSystemProxy(l.ctx, M.ParseSocksaddrHostPort(listenAddrString, listenPort), l.systemProxySOCKS)
if err != nil {
return E.Cause(err, "initialize system proxy")
}
err = systemProxy.Enable()
if err != nil {
return E.Cause(err, "set system proxy")
}
l.systemProxy = systemProxy
}
return nil
}
func (l *Listener) Close() error {
l.shutdown.Store(true)
var err error
if l.systemProxy != nil && l.systemProxy.IsEnabled() {
err = l.systemProxy.Disable()
}
return E.Errors(err, common.Close(
l.tcpListener,
common.PtrOrNil(l.udpConn),
))
}
func (l *Listener) TCPListener() net.Listener {
return l.tcpListener
}
func (l *Listener) UDPConn() *net.UDPConn {
return l.udpConn
}
func (l *Listener) ListenOptions() option.ListenOptions {
return l.listenOptions
}

View File

@@ -1,6 +1,6 @@
//go:build go1.21
package inbound
package listener
import "net"

View File

@@ -0,0 +1,16 @@
//go:build go1.23
package listener
import (
"net"
"time"
)
func setKeepAliveConfig(listener *net.ListenConfig, idle time.Duration, interval time.Duration) {
listener.KeepAliveConfig = net.KeepAliveConfig{
Enable: true,
Idle: idle,
Interval: interval,
}
}

View File

@@ -1,6 +1,6 @@
//go:build !go1.21
package inbound
package listener
import "net"

View File

@@ -0,0 +1,15 @@
//go:build !go1.23
package listener
import (
"net"
"time"
"github.com/sagernet/sing/common/control"
)
func setKeepAliveConfig(listener *net.ListenConfig, idle time.Duration, interval time.Duration) {
listener.KeepAlive = idle
listener.Control = control.Append(listener.Control, control.SetKeepAlivePeriod(idle, interval))
}

View File

@@ -0,0 +1,85 @@
package listener
import (
"net"
"time"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/metacubex/tfo-go"
)
func (l *Listener) ListenTCP() (net.Listener, error) {
var err error
bindAddr := M.SocksaddrFrom(l.listenOptions.Listen.Build(), l.listenOptions.ListenPort)
var tcpListener net.Listener
var listenConfig net.ListenConfig
if l.listenOptions.TCPKeepAlive >= 0 {
keepIdle := time.Duration(l.listenOptions.TCPKeepAlive)
if keepIdle == 0 {
keepIdle = C.TCPKeepAliveInitial
}
keepInterval := time.Duration(l.listenOptions.TCPKeepAliveInterval)
if keepInterval == 0 {
keepInterval = C.TCPKeepAliveInterval
}
setKeepAliveConfig(&listenConfig, keepIdle, keepInterval)
}
if l.listenOptions.TCPMultiPath {
if !go121Available {
return nil, E.New("MultiPath TCP requires go1.21, please recompile your binary.")
}
setMultiPathTCP(&listenConfig)
}
if l.listenOptions.TCPFastOpen {
var tfoConfig tfo.ListenConfig
tfoConfig.ListenConfig = listenConfig
tcpListener, err = tfoConfig.Listen(l.ctx, M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.String())
} else {
tcpListener, err = listenConfig.Listen(l.ctx, M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.String())
}
if err == nil {
l.logger.Info("tcp server started at ", tcpListener.Addr())
}
//nolint:staticcheck
if l.listenOptions.ProxyProtocol || l.listenOptions.ProxyProtocolAcceptNoHeader {
return nil, E.New("Proxy Protocol is deprecated and removed in sing-box 1.6.0")
}
l.tcpListener = tcpListener
return tcpListener, err
}
func (l *Listener) loopTCPIn() {
tcpListener := l.tcpListener
var metadata adapter.InboundContext
for {
conn, err := tcpListener.Accept()
if err != nil {
//nolint:staticcheck
if netError, isNetError := err.(net.Error); isNetError && netError.Temporary() {
l.logger.Error(err)
continue
}
if l.shutdown.Load() && E.IsClosed(err) {
return
}
l.tcpListener.Close()
l.logger.Error("tcp listener closed: ", err)
continue
}
//nolint:staticcheck
metadata.InboundDetour = l.listenOptions.Detour
//nolint:staticcheck
metadata.InboundOptions = l.listenOptions.InboundOptions
metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap()
metadata.OriginDestination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap()
ctx := log.ContextWithNewID(l.ctx)
l.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
go l.connHandler.NewConnectionEx(ctx, conn, metadata, nil)
}
}

View File

@@ -0,0 +1,154 @@
package listener
import (
"net"
"os"
"time"
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/control"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
func (l *Listener) ListenUDP() (net.PacketConn, error) {
bindAddr := M.SocksaddrFrom(l.listenOptions.Listen.Build(), l.listenOptions.ListenPort)
var lc net.ListenConfig
var udpFragment bool
if l.listenOptions.UDPFragment != nil {
udpFragment = *l.listenOptions.UDPFragment
} else {
udpFragment = l.listenOptions.UDPFragmentDefault
}
if !udpFragment {
lc.Control = control.Append(lc.Control, control.DisableUDPFragment())
}
udpConn, err := lc.ListenPacket(l.ctx, M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.String())
if err != nil {
return nil, err
}
l.udpConn = udpConn.(*net.UDPConn)
l.udpAddr = bindAddr
l.logger.Info("udp server started at ", udpConn.LocalAddr())
return udpConn, err
}
func (l *Listener) UDPAddr() M.Socksaddr {
return l.udpAddr
}
func (l *Listener) PacketWriter() N.PacketWriter {
return (*packetWriter)(l)
}
func (l *Listener) loopUDPIn() {
defer close(l.packetOutboundClosed)
var buffer *buf.Buffer
if !l.threadUnsafePacketWriter {
buffer = buf.NewPacket()
defer buffer.Release()
}
buffer.IncRef()
defer buffer.DecRef()
if l.oobPacketHandler != nil {
oob := make([]byte, 1024)
for {
if l.threadUnsafePacketWriter {
buffer = buf.NewPacket()
} else {
buffer.Reset()
}
n, oobN, _, addr, err := l.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
if err != nil {
if l.threadUnsafePacketWriter {
buffer.Release()
}
if l.shutdown.Load() && E.IsClosed(err) {
return
}
l.udpConn.Close()
l.logger.Error("udp listener closed: ", err)
return
}
buffer.Truncate(n)
l.oobPacketHandler.NewPacketEx(buffer, oob[:oobN], M.SocksaddrFromNetIP(addr).Unwrap())
}
} else {
for {
if l.threadUnsafePacketWriter {
buffer = buf.NewPacket()
} else {
buffer.Reset()
}
n, addr, err := l.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
if err != nil {
if l.threadUnsafePacketWriter {
buffer.Release()
}
if l.shutdown.Load() && E.IsClosed(err) {
return
}
l.udpConn.Close()
l.logger.Error("udp listener closed: ", err)
return
}
buffer.Truncate(n)
l.packetHandler.NewPacketEx(buffer, M.SocksaddrFromNetIP(addr).Unwrap())
}
}
}
func (l *Listener) loopUDPOut() {
for {
select {
case packet := <-l.packetOutbound:
destination := packet.Destination.AddrPort()
_, err := l.udpConn.WriteToUDPAddrPort(packet.Buffer.Bytes(), destination)
packet.Buffer.Release()
N.PutPacketBuffer(packet)
if err != nil {
if l.shutdown.Load() && E.IsClosed(err) {
return
}
l.udpConn.Close()
l.logger.Error("udp listener write back: ", destination, ": ", err)
return
}
continue
case <-l.packetOutboundClosed:
}
for {
select {
case packet := <-l.packetOutbound:
packet.Buffer.Release()
N.PutPacketBuffer(packet)
case <-time.After(time.Second):
return
}
}
}
}
type packetWriter Listener
func (w *packetWriter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
packet := N.NewPacketBuffer()
packet.Buffer = buffer
packet.Destination = destination
select {
case w.packetOutbound <- packet:
return nil
default:
buffer.Release()
N.PutPacketBuffer(packet)
if w.shutdown.Load() {
return os.ErrClosed
}
w.logger.Trace("dropped packet to ", destination)
return nil
}
}
func (w *packetWriter) WriteIsThreadUnsafe() {
}

View File

@@ -15,11 +15,11 @@ import (
)
type Router struct {
router adapter.ConnectionRouter
router adapter.ConnectionRouterEx
service *mux.Service
}
func NewRouterWithOptions(router adapter.ConnectionRouter, logger logger.ContextLogger, options option.InboundMultiplexOptions) (adapter.ConnectionRouter, error) {
func NewRouterWithOptions(router adapter.ConnectionRouterEx, logger logger.ContextLogger, options option.InboundMultiplexOptions) (adapter.ConnectionRouterEx, error) {
if !options.Enabled {
return router, nil
}
@@ -54,6 +54,7 @@ func NewRouterWithOptions(router adapter.ConnectionRouter, logger logger.Context
func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
if metadata.Destination == mux.Destination {
// TODO: check if WithContext is necessary
return r.service.NewConnection(adapter.WithContext(ctx, &metadata), conn, adapter.UpstreamMetadata(metadata))
} else {
return r.router.RouteConnection(ctx, conn, metadata)
@@ -63,3 +64,15 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
return r.router.RoutePacketConnection(ctx, conn, metadata)
}
func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
if metadata.Destination == mux.Destination {
r.service.NewConnectionEx(adapter.WithContext(ctx, &metadata), conn, metadata.Source, metadata.Destination, onClose)
return
}
r.router.RouteConnectionEx(ctx, conn, metadata, onClose)
}
func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
r.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
}

View File

@@ -1,32 +0,0 @@
package mux
import (
"context"
"net"
"github.com/sagernet/sing-box/adapter"
vmess "github.com/sagernet/sing-vmess"
"github.com/sagernet/sing/common/logger"
N "github.com/sagernet/sing/common/network"
)
type V2RayLegacyRouter struct {
router adapter.ConnectionRouter
logger logger.ContextLogger
}
func NewV2RayLegacyRouter(router adapter.ConnectionRouter, logger logger.ContextLogger) adapter.ConnectionRouter {
return &V2RayLegacyRouter{router, logger}
}
func (r *V2RayLegacyRouter) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
if metadata.Destination.Fqdn == vmess.MuxDestination.Fqdn {
r.logger.InfoContext(ctx, "inbound legacy multiplex connection")
return vmess.HandleMuxConnection(ctx, conn, adapter.NewRouteHandler(metadata, r.router, r.logger))
}
return r.router.RouteConnection(ctx, conn, metadata)
}
func (r *V2RayLegacyRouter) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
return r.router.RoutePacketConnection(ctx, conn, metadata)
}

View File

@@ -18,7 +18,7 @@ type (
PacketSniffer = func(ctx context.Context, metadata *adapter.InboundContext, packet []byte) error
)
func Skip(metadata adapter.InboundContext) bool {
func Skip(metadata *adapter.InboundContext) bool {
// skip server first protocols
switch metadata.Destination.Port {
case 25, 465, 587:

View File

@@ -13,14 +13,14 @@ import (
"github.com/sagernet/sing/common/uot"
)
var _ adapter.ConnectionRouter = (*Router)(nil)
var _ adapter.ConnectionRouterEx = (*Router)(nil)
type Router struct {
router adapter.ConnectionRouter
router adapter.ConnectionRouterEx
logger logger.ContextLogger
}
func NewRouter(router adapter.ConnectionRouter, logger logger.ContextLogger) *Router {
func NewRouter(router adapter.ConnectionRouterEx, logger logger.ContextLogger) *Router {
return &Router{router, logger}
}
@@ -51,3 +51,36 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
return r.router.RoutePacketConnection(ctx, conn, metadata)
}
func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
switch metadata.Destination.Fqdn {
case uot.MagicAddress:
request, err := uot.ReadRequest(conn)
if err != nil {
err = E.Cause(err, "UoT read request")
r.logger.ErrorContext(ctx, "process connection from ", metadata.Source, ": ", err)
N.CloseOnHandshakeFailure(conn, onClose, err)
return
}
if request.IsConnect {
r.logger.InfoContext(ctx, "inbound UoT connect connection to ", request.Destination)
} else {
r.logger.InfoContext(ctx, "inbound UoT connection to ", request.Destination)
}
metadata.Domain = metadata.Destination.Fqdn
metadata.Destination = request.Destination
r.router.RoutePacketConnectionEx(ctx, uot.NewConn(conn, *request), metadata, onClose)
return
case uot.LegacyMagicAddress:
r.logger.InfoContext(ctx, "inbound legacy UoT connection")
metadata.Domain = metadata.Destination.Fqdn
metadata.Destination = M.Socksaddr{Addr: netip.IPv4Unspecified()}
r.RoutePacketConnectionEx(ctx, uot.NewConn(conn, uot.Request{}), metadata, onClose)
return
}
r.router.RouteConnectionEx(ctx, conn, metadata, onClose)
}
func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
r.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
}

View File

@@ -22,3 +22,17 @@ const (
RuleSetVersion1 = 1 + iota
RuleSetVersion2
)
const (
RuleActionTypeRoute = "route"
RuleActionTypeDirect = "direct"
RuleActionTypeReject = "reject"
RuleActionTypeHijackDNS = "hijack-dns"
RuleActionTypeSniff = "sniff"
RuleActionTypeResolve = "resolve"
)
const (
RuleActionRejectMethodDefault = "default"
RuleActionRejectMethodDrop = "drop"
)

View File

@@ -2,6 +2,38 @@
icon: material/alert-decagram
---
#### 1.11.0-alpha.7
* Introducing rule actions **1**
* Some chaotic changes **3**
**1**:
New rule actions replace legacy inbound fields and special outbound fields,
and can be used for pre-matching **2**.
see [Rule](/configuration/route/rule/),
[Rule Action](/configuration/route/rule_action/),
[DNS Rule](/configuration/dns/rule/) and
[DNS Rule Action](/configuration/dns/rule_action/).
For migration, see
[Migrate legacy special outbounds to rule actions](/migration/#migrate-legacy-special-outbounds-to-rule-actions)
and [Migrate legacy inbound fields to rule actions](/migration/#migrate-legacy-inbound-fields-to-rule-actions).
**2**:
Similar to Surge's pre-matching.
Specifically, the new rule actions allow you to reject connections with
TCP RST (for TCP connections) and ICMP port unreachable (for UDP packets)
before connection established to improve tun's compatibility.
See [Rule Action](/configuration/route/rule_action/).
**3**:
Everything existing may be broken, please actively report problems with in beta versions.
#### 1.11.0-alpha.6
* Update quic-go to v0.48.1

View File

@@ -1,7 +1,3 @@
---
icon: material/new-box
---
!!! quote "Changes in sing-box 1.9.0"
:material-plus: [client_subnet](#client_subnet)

View File

@@ -1,7 +1,3 @@
---
icon: material/new-box
---
!!! quote "sing-box 1.9.0 中的更改"
:material-plus: [client_subnet](#client_subnet)

Some files were not shown because too many files have changed in this diff Show More