mirror of
https://github.com/bolucat/Archive.git
synced 2025-09-27 04:30:12 +08:00
Update On Wed Nov 6 19:36:39 CET 2024
This commit is contained in:
1
.github/update.log
vendored
1
.github/update.log
vendored
@@ -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
|
||||
|
@@ -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() {
|
||||
|
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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 "", ""
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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=
|
||||
|
@@ -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
|
||||
|
@@ -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 {
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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=
|
||||
|
@@ -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
|
||||
|
@@ -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=
|
||||
|
@@ -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
|
||||
|
@@ -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=
|
||||
|
@@ -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),
|
||||
|
@@ -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");
|
||||
|
||||
|
@@ -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[];
|
||||
|
@@ -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)
|
||||
|
@@ -30,7 +30,7 @@ const TitleComp = () => {
|
||||
|
||||
if (port == clashConfigs?.["mixed-port"]) {
|
||||
return {
|
||||
label: t("Success"),
|
||||
label: t("Successful"),
|
||||
color: "success",
|
||||
};
|
||||
} else {
|
||||
|
@@ -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,
|
||||
});
|
||||
|
@@ -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>
|
||||
</>
|
||||
)}
|
||||
|
@@ -50,7 +50,7 @@ export const UpdateProviders = () => {
|
||||
startIcon={<Refresh />}
|
||||
onClick={handleProviderUpdate}
|
||||
>
|
||||
{t("Update Rules Providers All")}
|
||||
{t("Update All Rules Providers")}
|
||||
</LoadingButton>
|
||||
);
|
||||
};
|
||||
|
@@ -50,7 +50,7 @@ export const UpdateProxiesProviders = () => {
|
||||
startIcon={<Refresh />}
|
||||
onClick={handleProviderUpdate}
|
||||
>
|
||||
{t("Update Proxies Providers All")}
|
||||
{t("Update All Proxies Providers")}
|
||||
</LoadingButton>
|
||||
);
|
||||
};
|
||||
|
@@ -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"),
|
||||
});
|
||||
|
@@ -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")}
|
||||
|
@@ -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"),
|
||||
});
|
||||
|
@@ -49,7 +49,7 @@ export const SettingClashPort = () => {
|
||||
});
|
||||
} finally {
|
||||
message(t("After restart to take effect"), {
|
||||
title: t("Success"),
|
||||
title: t("Successful"),
|
||||
kind: "info",
|
||||
});
|
||||
}
|
||||
|
@@ -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}>
|
||||
|
@@ -60,7 +60,7 @@ export const SettingNyanpasuMisc = () => {
|
||||
/>
|
||||
|
||||
<SwitchItem
|
||||
label={t("Lighten up Animation Effects")}
|
||||
label={t("Lighten Up Animation Effects")}
|
||||
{...createBooleanProps("lighten_animation_effects")}
|
||||
/>
|
||||
|
||||
|
@@ -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",
|
||||
});
|
||||
|
@@ -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({
|
||||
|
@@ -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: {
|
||||
|
@@ -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",
|
||||
);
|
||||
|
@@ -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"
|
||||
}
|
||||
|
@@ -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": "Закрыть",
|
||||
|
@@ -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": "结果"
|
||||
}
|
||||
|
@@ -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"
|
||||
}
|
||||
|
@@ -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))
|
||||
|
@@ -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))
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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)
|
11
lede/package/kernel/rtw88-usb/patches/101-wireless-6.6.patch
Normal file
11
lede/package/kernel/rtw88-usb/patches/101-wireless-6.6.patch
Normal 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))
|
@@ -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
106
mieru/apis/common/dns.go
Normal 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
|
||||
}
|
157
mieru/apis/common/dns_test.go
Normal file
157
mieru/apis/common/dns_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
@@ -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=
|
||||
|
@@ -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
|
||||
|
@@ -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"
|
||||
}
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
4
shadowsocks-rust/Cargo.lock
generated
4
shadowsocks-rust/Cargo.lock
generated
@@ -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",
|
||||
|
@@ -5,6 +5,7 @@
|
||||
[](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-msrv.yml)
|
||||
[](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-release.yml)
|
||||
[](https://github.com/shadowsocks/shadowsocks-rust/actions/workflows/build-nightly-release.yml)
|
||||
[](https://gurubase.io/g/shadowsocks)
|
||||
|
||||
[](https://crates.io/crates/shadowsocks-rust)
|
||||
[](https://github.com/shadowsocks/shadowsocks-rust/releases)
|
||||
|
@@ -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 }
|
||||
|
@@ -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)
|
||||
}
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
|
21
sing-box/adapter/inbound/adapter.go
Normal file
21
sing-box/adapter/inbound/adapter.go
Normal 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
|
||||
}
|
68
sing-box/adapter/inbound/registry.go
Normal file
68
sing-box/adapter/inbound/registry.go
Normal 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
|
||||
}
|
@@ -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)
|
||||
}
|
||||
|
45
sing-box/adapter/outbound/adapter.go
Normal file
45
sing-box/adapter/outbound/adapter.go
Normal 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
|
||||
}
|
@@ -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)
|
||||
}
|
68
sing-box/adapter/outbound/registry.go
Normal file
68
sing-box/adapter/outbound/registry.go
Normal 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
|
||||
}
|
@@ -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
38
sing-box/adapter/rule.go
Normal 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
|
||||
}
|
||||
}
|
@@ -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)
|
||||
}
|
||||
|
216
sing-box/adapter/upstream_legacy.go
Normal file
216
sing-box/adapter/upstream_legacy.go
Normal 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)
|
||||
}
|
@@ -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 {
|
||||
|
@@ -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")
|
||||
}
|
||||
|
@@ -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())
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -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, "]")
|
||||
}
|
||||
|
@@ -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")
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -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",
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
@@ -1,9 +0,0 @@
|
||||
//go:build !with_wireguard
|
||||
|
||||
package dialer
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing/common/control"
|
||||
)
|
||||
|
||||
var wgControlFns []control.Func
|
136
sing-box/common/listener/listener.go
Normal file
136
sing-box/common/listener/listener.go
Normal 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
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
//go:build go1.21
|
||||
|
||||
package inbound
|
||||
package listener
|
||||
|
||||
import "net"
|
||||
|
16
sing-box/common/listener/listener_go123.go
Normal file
16
sing-box/common/listener/listener_go123.go
Normal 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,
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
//go:build !go1.21
|
||||
|
||||
package inbound
|
||||
package listener
|
||||
|
||||
import "net"
|
||||
|
15
sing-box/common/listener/listener_nongo123.go
Normal file
15
sing-box/common/listener/listener_nongo123.go
Normal 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))
|
||||
}
|
85
sing-box/common/listener/listener_tcp.go
Normal file
85
sing-box/common/listener/listener_tcp.go
Normal 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)
|
||||
}
|
||||
}
|
154
sing-box/common/listener/listener_udp.go
Normal file
154
sing-box/common/listener/listener_udp.go
Normal 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() {
|
||||
}
|
@@ -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)
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
@@ -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:
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -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"
|
||||
)
|
||||
|
@@ -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
|
||||
|
@@ -1,7 +1,3 @@
|
||||
---
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! quote "Changes in sing-box 1.9.0"
|
||||
|
||||
:material-plus: [client_subnet](#client_subnet)
|
||||
|
@@ -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
Reference in New Issue
Block a user