Update On Sat Aug 3 20:32:16 CEST 2024

This commit is contained in:
github-action[bot]
2024-08-03 20:32:16 +02:00
parent c804dc06ba
commit 8a31e512a8
122 changed files with 2408 additions and 5505 deletions

1
.github/update.log vendored
View File

@@ -722,3 +722,4 @@ Update On Tue Jul 30 20:33:50 CEST 2024
Update On Wed Jul 31 20:30:50 CEST 2024
Update On Thu Aug 1 20:31:07 CEST 2024
Update On Fri Aug 2 20:31:28 CEST 2024
Update On Sat Aug 3 20:32:05 CEST 2024

View File

@@ -155,6 +155,7 @@ jobs:
echo "BUILDTIME=$(date)" >> $GITHUB_ENV
echo "CGO_ENABLED=0" >> $GITHUB_ENV
echo "BUILDTAG=-extldflags --static" >> $GITHUB_ENV
echo "GOTOOLCHAIN=local" >> $GITHUB_ENV
- name: Setup NDK
if: ${{ matrix.jobs.goos == 'android' }}

View File

@@ -7,20 +7,20 @@ require (
github.com/bahlo/generic-list-go v0.2.0
github.com/cilium/ebpf v0.12.3
github.com/coreos/go-iptables v0.7.0
github.com/dlclark/regexp2 v1.11.0
github.com/go-chi/chi/v5 v5.0.14
github.com/dlclark/regexp2 v1.11.2
github.com/go-chi/chi/v5 v5.1.0
github.com/go-chi/cors v1.2.1
github.com/go-chi/render v1.0.3
github.com/gobwas/ws v1.4.0
github.com/gofrs/uuid/v5 v5.2.0
github.com/insomniacslk/dhcp v0.0.0-20240529192340-51bc6136a0a6
github.com/insomniacslk/dhcp v0.0.0-20240710054256-ddd8a41251c9
github.com/klauspost/compress v1.17.9
github.com/klauspost/cpuid/v2 v2.2.8
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40
github.com/mdlayher/netlink v1.7.2
github.com/metacubex/chacha v0.1.0
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759
github.com/metacubex/quic-go v0.45.1-0.20240610004319-163fee60637e
github.com/metacubex/quic-go v0.45.1-0.20240803003931-60a15f6efd94
github.com/metacubex/randv2 v0.2.0
github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72
github.com/metacubex/sing-shadowsocks v0.2.7
@@ -34,7 +34,7 @@ require (
github.com/mroth/weightedrand/v2 v2.1.0
github.com/openacid/low v0.1.21
github.com/oschwald/maxminddb-golang v1.12.0
github.com/puzpuzpuz/xsync/v3 v3.2.0
github.com/puzpuzpuz/xsync/v3 v3.4.0
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
github.com/sagernet/fswatch v0.1.1
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
@@ -42,7 +42,7 @@ require (
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6
github.com/sagernet/sing-shadowtls v0.1.4
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e
github.com/samber/lo v1.39.0
github.com/samber/lo v1.46.0
github.com/shirou/gopsutil/v3 v3.24.5
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.9.0
@@ -50,9 +50,9 @@ require (
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7
go.uber.org/automaxprocs v1.5.3
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto v0.24.0
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
golang.org/x/net v0.26.0
golang.org/x/crypto v0.25.0
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
golang.org/x/net v0.27.0
golang.org/x/sync v0.7.0
golang.org/x/sys v0.22.0
google.golang.org/protobuf v1.34.2
@@ -107,10 +107,10 @@ require (
github.com/yusufpapurcu/wmi v1.2.4 // indirect
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect
go.uber.org/mock v0.4.0 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/mod v0.19.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.22.0 // indirect
golang.org/x/tools v0.23.0 // indirect
)
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240724044459-6f3cf5896297

View File

@@ -26,8 +26,8 @@ github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFE
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dlclark/regexp2 v1.11.2 h1:/u628IuisSTwri5/UKloiIsH8+qF2Pu7xEQX+yIKg68=
github.com/dlclark/regexp2 v1.11.2/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/ericlagergren/aegis v0.0.0-20230312195928-b4ce538b56f9 h1:/5RkVc9Rc81XmMyVqawCiDyrBHZbLAZgTTCqou4mwj8=
github.com/ericlagergren/aegis v0.0.0-20230312195928-b4ce538b56f9/go.mod h1:hkIFzoiIPZYxdFOOLyDho59b7SrDfo+w3h+yWdlg45I=
github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 h1:8j2RH289RJplhA6WfdaPqzg1MjH2K8wX5e0uhAxrw2g=
@@ -42,8 +42,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
github.com/go-chi/chi/v5 v5.0.14 h1:PyEwo2Vudraa0x/Wl6eDRRW2NXBvekgfxyydcM0WGE0=
github.com/go-chi/chi/v5 v5.0.14/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
@@ -75,8 +75,8 @@ github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/insomniacslk/dhcp v0.0.0-20240529192340-51bc6136a0a6 h1:dh8D8FksyMhD64mRMbUhZHWYJfNoNMCxfVq6eexleMw=
github.com/insomniacslk/dhcp v0.0.0-20240529192340-51bc6136a0a6/go.mod h1:KclMyHxX06VrVr0DJmeFSUb1ankt7xTfoOA35pCkoic=
github.com/insomniacslk/dhcp v0.0.0-20240710054256-ddd8a41251c9 h1:LZJWucZz7ztCqY6Jsu7N9g124iJ2kt/O62j3+UchZFg=
github.com/insomniacslk/dhcp v0.0.0-20240710054256-ddd8a41251c9/go.mod h1:KclMyHxX06VrVr0DJmeFSUb1ankt7xTfoOA35pCkoic=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
@@ -103,8 +103,8 @@ 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.45.1-0.20240610004319-163fee60637e h1:bLYn3GuRvWDcBDAkIv5kUYIhzHwafDVq635BuybnKqI=
github.com/metacubex/quic-go v0.45.1-0.20240610004319-163fee60637e/go.mod h1:Yza2H7Ax1rxWPUcJx0vW+oAt9EsPuSiyQFhFabUPzwU=
github.com/metacubex/quic-go v0.45.1-0.20240803003931-60a15f6efd94 h1:wlhwgxRzPLH8Ce0VME35iD2sr7jY2gFrL299/T4C2Sg=
github.com/metacubex/quic-go v0.45.1-0.20240803003931-60a15f6efd94/go.mod h1:Yza2H7Ax1rxWPUcJx0vW+oAt9EsPuSiyQFhFabUPzwU=
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-20240724044459-6f3cf5896297 h1:YG/JkwGPbca5rUtEMHIu8ZuqzR7BSVm1iqY8hNoMeMA=
@@ -149,8 +149,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/puzpuzpuz/xsync/v3 v3.2.0 h1:9AzuUeF88YC5bK8u2vEG1Fpvu4wgpM1wfPIExfaaDxQ=
github.com/puzpuzpuz/xsync/v3 v3.2.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4=
github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs=
@@ -172,8 +172,8 @@ github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxe
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo=
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e h1:iGH0RMv2FzELOFNFQtvsxH7NPmlo7X5JizEK51UCojo=
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e/go.mod h1:YbL4TKHRR6APYQv3U2RGfwLDpPYSyWz6oUlpISBEzBE=
github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ=
github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
@@ -226,18 +226,18 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
@@ -259,15 +259,15 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=

View File

@@ -0,0 +1 @@
frontend/nyanpasu/auto-imports.d.ts

View File

@@ -18,6 +18,7 @@ module.exports = {
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
"@typescript-eslint/no-unused-vars": "warn",
"@typescript-eslint/no-explicit-any": "warn",
"react/jsx-no-undef": "off",
"react/react-in-jsx-scope": "off",
"@typescript-eslint/no-namespace": "off",
"react-compiler/react-compiler": "error",

View File

@@ -7,3 +7,4 @@ pnpm-lock.yaml
*.lock
*.wxs
frontend/nyanpasu/src/router.ts
frontend/nyanpasu/auto-imports.d.ts

View File

@@ -642,6 +642,15 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bindgen"
version = "0.69.4"
@@ -1193,10 +1202,13 @@ dependencies = [
"async-trait",
"atomic_enum",
"auto-launch",
"axum",
"backon",
"base64 0.22.1",
"bincode",
"boa_engine",
"boa_utils",
"bytes",
"chrono",
"clap",
"cocoa 0.25.0",
@@ -1223,6 +1235,7 @@ dependencies = [
"indexmap 2.3.0",
"log",
"md-5",
"mime",
"mlua",
"nanoid",
"num_cpus",
@@ -1249,6 +1262,7 @@ dependencies = [
"serde",
"serde_json",
"serde_yaml 0.9.34+deprecated",
"sha2 0.10.8",
"simd-json",
"single-instance",
"sysinfo",
@@ -3892,7 +3906,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
dependencies = [
"cfg-if",
"windows-targets 0.48.5",
"windows-targets 0.52.6",
]
[[package]]
@@ -5727,9 +5741,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.10.5"
version = "1.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
dependencies = [
"aho-corasick",
"memchr",
@@ -7160,12 +7174,13 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.10.1"
version = "3.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53"
dependencies = [
"cfg-if",
"fastrand 2.1.0",
"once_cell",
"rustix 0.38.34",
"windows-sys 0.52.0",
]

View File

@@ -59,6 +59,10 @@ tauri = { version = "1.5.4", features = [
] }
window-vibrancy = { version = "0.5.0" }
window-shadows = { version = "0.2.2" }
axum = "0.7"
mime = "0.3"
bincode = "1"
bytes = { version = "1", features = ["serde"] }
wry = { version = "0.24.6" }
semver = "1.0"
zip = "2.0.0"
@@ -126,7 +130,7 @@ mlua = { version = "0.9", features = [
"vendored",
] }
enumflags2 = "0.7"
sha2 = "0.10"
[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.25.0"
objc = "0.2.7"

View File

@@ -2,6 +2,7 @@ use crate::utils::{dirs, help};
use anyhow::Result;
// use log::LevelFilter;
use enumflags2::bitflags;
use semver::Op;
use serde::{Deserialize, Serialize};
mod clash_strategy;
pub mod logging;
@@ -99,6 +100,25 @@ pub enum ProxiesSelectorMode {
Submenu,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Default)]
#[serde(rename_all = "snake_case")]
pub enum TunStack {
System,
#[default]
Gvisor,
Mixed,
}
impl AsRef<str> for TunStack {
fn as_ref(&self) -> &str {
match self {
TunStack::System => "system",
TunStack::Gvisor => "gvisor",
TunStack::Mixed => "mixed",
}
}
}
/// ### `verge.yaml` schema
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct IVerge {
@@ -210,6 +230,12 @@ pub struct IVerge {
/// 是否启用代理托盘选择
pub clash_tray_selector: Option<ProxiesSelectorMode>,
pub always_on_top: Option<bool>,
/// Tun 堆栈选择
/// TODO: 弃用此字段,转移到 clash config 里
pub tun_stack: Option<TunStack>,
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
@@ -305,6 +331,7 @@ impl IVerge {
enable_auto_check_update: Some(true),
clash_tray_selector: Some(ProxiesSelectorMode::default()),
enable_service_mode: Some(false),
always_on_top: Some(false),
..Self::default()
}
}
@@ -364,5 +391,7 @@ impl IVerge {
patch!(window_size_state);
patch!(clash_strategy);
patch!(clash_tray_selector);
patch!(tun_stack);
patch!(always_on_top);
}
}

View File

@@ -27,9 +27,7 @@ pub async fn init_service() {
..
}) = control::status().await
{
if !enable_service {
control::stop_service().await.unwrap();
} else {
if enable_service {
ipc::spawn_health_check()
}
}

View File

@@ -1,6 +1,9 @@
use serde_yaml::{Mapping, Value};
use crate::config::{nyanpasu::ClashCore, Config};
use crate::config::{
nyanpasu::{ClashCore, TunStack},
Config,
};
macro_rules! revise {
($map: expr, $key: expr, $val: expr) => {
@@ -43,7 +46,17 @@ pub fn use_tun(mut config: Mapping, enable: bool) -> Mapping {
if core == ClashCore::ClashRs {
append!(tun_val, "device-id", "dev://utun1989");
} else {
append!(tun_val, "stack", "gvisor");
let mut tun_stack = {
*Config::verge()
.latest()
.tun_stack
.as_ref()
.unwrap_or(&TunStack::default())
};
if core == ClashCore::ClashPremium && tun_stack == TunStack::Mixed {
tun_stack = TunStack::Gvisor;
}
append!(tun_val, "stack", AsRef::<str>::as_ref(&tun_stack));
append!(tun_val, "dns-hijack", vec!["any:53"]);
append!(tun_val, "auto-route", true);
append!(tun_val, "auto-detect-interface", true);

View File

@@ -6,7 +6,7 @@
//!
use crate::{
config::*,
core::*,
core::{service::ipc::get_ipc_state, *},
log_err,
utils::{self, help::get_clash_external_port, resolve},
};
@@ -283,21 +283,15 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
let enable_tray_selector = patch.clash_tray_selector;
let res = || async move {
#[cfg(target_os = "windows")]
{
let service_mode = patch.enable_service_mode;
let service_mode = patch.enable_service_mode;
let ipc_state = get_ipc_state();
if service_mode.is_some() && ipc_state.is_connected() {
log::debug!(target: "app", "change service mode to {}", service_mode.unwrap());
if service_mode.is_some() {
log::debug!(target: "app", "change service mode to {}", service_mode.unwrap());
Config::generate().await?;
CoreManager::global().run_core().await?;
} else if tun_mode.is_some() {
update_core_config().await?;
}
Config::generate().await?;
CoreManager::global().run_core().await?;
}
#[cfg(not(target_os = "windows"))]
if tun_mode.is_some() {
update_core_config().await?;
}

View File

@@ -15,6 +15,7 @@ use anyhow::{Context, Result};
use chrono::Local;
use indexmap::IndexMap;
use log::debug;
use profile::item_type::ProfileItemType;
use serde_yaml::Mapping;
use std::collections::VecDeque;
use sysproxy::Sysproxy;
@@ -102,10 +103,36 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult {
/// 修改某个profile item的
#[tauri::command]
pub fn patch_profile(index: String, profile: ProfileItem) -> CmdResult {
pub async fn patch_profile(index: String, profile: ProfileItem) -> CmdResult {
tracing::debug!("patch profile: {index} with {profile:?}");
wrap_err!(Config::profiles().data().patch_item(index, profile))?;
wrap_err!(Config::profiles().data().patch_item(index.clone(), profile))?;
ProfilesJobGuard::global().lock().refresh();
let need_update = {
let profiles = Config::profiles();
let profiles = profiles.latest();
match (&profiles.chain, &profiles.current) {
(Some(chains), _) if chains.contains(&index) => true,
(_, Some(current_chain)) if current_chain == &index => true,
(_, Some(current_chain)) => match profiles.get_item(current_chain) {
Ok(item) => item
.chains
.as_ref()
.map_or(false, |chain| chain.contains(&index)),
Err(_) => false,
},
_ => false,
}
};
if need_update {
match CoreManager::global().update_config().await {
Ok(_) => {
handle::Handle::refresh_clash();
}
Err(err) => {
log::error!(target: "app", "{err}");
}
}
}
Ok(())
}
@@ -131,7 +158,14 @@ pub fn read_profile_file(index: String) -> CmdResult<String> {
let profiles = Config::profiles();
let profiles = profiles.latest();
let item = wrap_err!(profiles.get_item(&index))?;
let data = wrap_err!(item.read_file())?;
let data = match item.r#type.as_ref().unwrap_or(&ProfileItemType::Local) {
ProfileItemType::Local | ProfileItemType::Remote => {
let raw = wrap_err!(item.read_file())?;
let data = wrap_err!(serde_yaml::from_str::<Mapping>(&raw))?;
wrap_err!(serde_yaml::to_string(&data).context("failed to convert yaml to string"))?
}
_ => wrap_err!(item.read_file())?,
};
Ok(data)
}
@@ -450,6 +484,11 @@ pub fn restart_application(app_handle: tauri::AppHandle) -> CmdResult {
Ok(())
}
#[tauri::command]
pub fn get_server_port() -> CmdResult<u16> {
Ok(*crate::server::SERVER_PORT)
}
#[cfg(not(windows))]
#[tauri::command]
pub async fn set_custom_app_dir(_path: String) -> CmdResult {
@@ -488,17 +527,56 @@ pub mod service {
#[tauri::command]
pub async fn start_service() -> CmdResult {
wrap_err!(service::control::start_service().await)
let res = wrap_err!(service::control::start_service().await);
let enabled_service = {
*crate::config::Config::verge()
.latest()
.enable_service_mode
.as_ref()
.unwrap_or(&false)
};
if enabled_service {
if let Err(e) = crate::core::CoreManager::global().run_core().await {
log::error!(target: "app", "{e}");
}
}
res
}
#[tauri::command]
pub async fn stop_service() -> CmdResult {
wrap_err!(service::control::stop_service().await)
let res = wrap_err!(service::control::stop_service().await);
let enabled_service = {
*crate::config::Config::verge()
.latest()
.enable_service_mode
.as_ref()
.unwrap_or(&false)
};
if enabled_service {
if let Err(e) = crate::core::CoreManager::global().run_core().await {
log::error!(target: "app", "{e}");
}
}
res
}
#[tauri::command]
pub async fn restart_service() -> CmdResult {
wrap_err!(service::control::restart_service().await)
let res = wrap_err!(service::control::restart_service().await);
let enabled_service = {
*crate::config::Config::verge()
.latest()
.enable_service_mode
.as_ref()
.unwrap_or(&false)
};
if enabled_service {
if let Err(e) = crate::core::CoreManager::global().run_core().await {
log::error!(target: "app", "{e}");
}
}
res
}
}

View File

@@ -19,6 +19,7 @@ mod core;
mod enhance;
mod feat;
mod ipc;
mod server;
mod utils;
use crate::{
config::Config,
@@ -67,6 +68,16 @@ fn main() -> std::io::Result<()> {
#[cfg(not(feature = "verge-dev"))]
tauri_plugin_deep_link::prepare("moe.elaina.clash.nyanpasu");
// Custom scheme check
#[cfg(not(target_os = "macos"))]
// on macos the plugin handles this (macos doesn't use cli args for the url)
let custom_schema = match std::env::args().nth(1) {
Some(url) => url::Url::parse(&url).ok(),
None => None,
};
#[cfg(target_os = "macos")]
let custom_schema: Option<url::Url> = None;
// 单例检测
let single_instance_result = utils::init::check_singleton();
@@ -77,14 +88,16 @@ fn main() -> std::io::Result<()> {
};
rust_i18n::set_locale(locale);
if let Err(e) = init::run_pending_migrations() {
utils::dialog::panic_dialog(
&format!(
"Failed to finish migration event: {}\nYou can see the detailed information at migration.log in your local data dir.\nYou're supposed to submit it as the attachment of new issue.",
e,
)
);
std::process::exit(1);
if single_instance_result.is_ok() {
if let Err(e) = init::run_pending_migrations() {
utils::dialog::panic_dialog(
&format!(
"Failed to finish migration event: {}\nYou can see the detailed information at migration.log in your local data dir.\nYou're supposed to submit it as the attachment of new issue.",
e,
)
);
std::process::exit(1);
}
}
crate::log_err!(init::init_config());
@@ -101,7 +114,9 @@ fn main() -> std::io::Result<()> {
rust_i18n::set_locale(verge.as_str());
// show a dialog to print the single instance error
let _singleton = single_instance_result.unwrap(); // hold the guard until the end of the program
if custom_schema.is_none() {
let _singleton = single_instance_result.unwrap(); // hold the guard until the end of the program
}
#[allow(unused_mut)]
let mut builder = tauri::Builder::default()
@@ -112,7 +127,7 @@ fn main() -> std::io::Result<()> {
let handle = app.handle().clone();
// For start new app from schema
#[cfg(not(target_os = "macos"))]
if let Some(url) = std::env::args().nth(1) {
if let Some(url) = custom_schema {
log::info!(target: "app", "started with schema");
if Config::verge().data().enable_silent_start.unwrap_or(true) {
resolve::create_window(&handle.clone());
@@ -128,7 +143,7 @@ fn main() -> std::io::Result<()> {
.unwrap();
});
}
// This operation should terminate the app if app is called by custom scheme and this instance is not the primary instance
log_err!(tauri_plugin_deep_link::register(
&["clash-nyanpasu", "clash"],
move |request| {
@@ -137,6 +152,13 @@ fn main() -> std::io::Result<()> {
handle.emit_all("scheme-request-received", request).unwrap();
}
));
std::thread::spawn(move || {
nyanpasu_utils::runtime::block_on(async move {
server::run(*server::SERVER_PORT)
.await
.expect("failed to start server");
});
});
Ok(())
})
.on_system_tray_event(core::tray::Tray::on_system_tray_event)
@@ -202,6 +224,7 @@ fn main() -> std::io::Result<()> {
ipc::update_proxy_provider,
ipc::restart_application,
ipc::collect_envs,
ipc::get_server_port,
]);
#[cfg(target_os = "macos")]

View File

@@ -0,0 +1,92 @@
pub(crate) use crate::utils::candy::get_reqwest_client;
use anyhow::{anyhow, Result};
use axum::{
body::Body,
extract::Query,
http::{Response, StatusCode},
routing::get,
Router,
};
use base64::{prelude::BASE64_STANDARD, Engine};
use bytes::Bytes;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use std::borrow::Cow;
use tracing_attributes::instrument;
use url::Url;
pub static SERVER_PORT: Lazy<u16> = Lazy::new(|| port_scanner::request_open_port().unwrap());
#[derive(Deserialize)]
struct CacheIcon {
/// should be encoded as base64
url: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
struct CacheFile<'n> {
mime: Cow<'n, str>,
bytes: Bytes,
}
async fn cache_icon_inner<'n>(url: &str) -> Result<CacheFile<'n>> {
let url = BASE64_STANDARD.decode(url)?;
let url = String::from_utf8_lossy(&url);
let url = Url::parse(&url)?;
// get filename
let hash = Sha256::digest(url.as_str().as_bytes());
let cache_dir = crate::utils::dirs::cache_dir()?.join("icons");
if !cache_dir.exists() {
std::fs::create_dir_all(&cache_dir)?;
}
let cache_file = cache_dir.join(format!("{:x}.bin", hash));
if cache_file.exists() {
let cache_file = tokio::fs::read(cache_file).await?;
let cache_file: CacheFile = bincode::deserialize(&cache_file)?;
return Ok(cache_file);
}
let client = get_reqwest_client()?;
let response = client.get(url).send().await?.error_for_status()?;
let mime = response
.headers()
.get("content-type")
.ok_or(anyhow!("no content-type"))?
.to_str()?
.to_string();
let bytes = response.bytes().await?;
let data = CacheFile {
mime: Cow::Owned(mime),
bytes,
};
tokio::fs::write(cache_file, bincode::serialize(&data)?).await?;
Ok(data)
}
async fn cache_icon(query: Query<CacheIcon>) -> Response<Body> {
match cache_icon_inner(&query.url).await {
Ok(data) => {
let mut response = Response::new(Body::from(data.bytes));
response
.headers_mut()
.insert("content-type", data.mime.parse().unwrap());
response
}
Err(e) => {
let mut response = Response::new(Body::from(e.to_string()));
*response.status_mut() = StatusCode::BAD_REQUEST;
response
}
}
}
#[instrument]
pub async fn run(port: u16) -> std::io::Result<()> {
let app = Router::new().route("/cache/icon", get(cache_icon));
let listener = tokio::net::TcpListener::bind(format!("127.0.0.1:{port}")).await?;
tracing::debug!(
"internal http server listening on {}",
listener.local_addr()?
);
axum::serve(listener, app).await
}

View File

@@ -194,18 +194,18 @@ pub fn app_resources_dir() -> Result<PathBuf> {
}
/// Cache dir, it safe to clean up
pub fn cache_dir() -> Result<PathBuf> {
let mut dir = dirs::cache_dir()
.ok_or(anyhow::anyhow!("failed to get the cache dir"))?
.join(APP_DIR_PLACEHOLDER.as_ref());
if cfg!(windows) {
dir.push("cache");
}
if !dir.exists() {
fs::create_dir_all(&dir)?;
}
Ok(dir)
}
// pub fn cache_dir() -> Result<PathBuf> {
// let mut dir = dirs::cache_dir()
// .ok_or(anyhow::anyhow!("failed to get the cache dir"))?
// .join(APP_DIR_PLACEHOLDER.as_ref());
// if cfg!(windows) {
// dir.push("cache");
// }
// if !dir.exists() {
// fs::create_dir_all(&dir)?;
// }
// Ok(dir)
// }
/// App install dir, sidecars should placed here
pub fn app_install_dir() -> Result<PathBuf> {
@@ -247,6 +247,10 @@ pub fn clash_pid_path() -> Result<PathBuf> {
Ok(app_data_dir()?.join("clash.pid"))
}
pub fn cache_dir() -> Result<PathBuf> {
Ok(app_data_dir()?.join("cache"))
}
#[cfg(windows)]
#[deprecated(
since = "1.6.0",

View File

@@ -150,6 +150,14 @@ pub fn create_window(app_handle: &AppHandle) {
return;
}
let always_on_top = {
*Config::verge()
.latest()
.always_on_top
.as_ref()
.unwrap_or(&false)
};
let mut builder = tauri::window::WindowBuilder::new(
app_handle,
"main".to_string(),
@@ -157,7 +165,9 @@ pub fn create_window(app_handle: &AppHandle) {
)
.title("Clash Nyanpasu")
.fullscreen(false)
.always_on_top(always_on_top)
.min_inner_size(600.0, 520.0);
let win_state = &Config::verge().latest().window_size_state.clone();
match win_state {
Some(_) => {

View File

@@ -203,3 +203,11 @@ export const save_window_size_state = async () => {
export const collect_envs = async () => {
return await invoke<EnvInfos>("collect_envs");
};
export const getRuntimeYaml = async () => {
return await invoke<string>("get_runtime_yaml");
};
export const getServerPort = async () => {
return await invoke<number>("get_server_port");
};

View File

@@ -45,6 +45,8 @@ export interface VergeConfig {
clash_strategy?: {
external_controller_port_strategy: "fixed" | "random" | "allow_fallback";
};
tun_stack?: "system" | "gvisor" | "mixed";
always_on_top?: boolean;
}
export interface ClashInfo {

View File

@@ -0,0 +1,9 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
export {}
declare global {
const IconMdiTextBoxCheckOutline: (typeof import("~icons/mdi/text-box-check-outline.jsx"))["default"]
}

View File

@@ -48,6 +48,7 @@
"devDependencies": {
"@emotion/babel-plugin": "11.12.0",
"@emotion/react": "11.13.0",
"@iconify/json": "2.2.233",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"@vitejs/plugin-react": "4.3.1",
@@ -56,6 +57,8 @@
"sass": "1.77.8",
"shiki": "1.12.1",
"tailwindcss-textshadow": "2.1.3",
"unplugin-auto-import": "0.18.2",
"unplugin-icons": "0.19.1",
"vite": "5.3.5",
"vite-plugin-monaco-editor": "1.1.3",
"vite-plugin-sass-dts": "1.3.25",

View File

@@ -1,3 +1,4 @@
import { useMemoizedFn } from "ahooks";
import { debounce } from "lodash-es";
import { useEffect, useState } from "react";
import { classNames } from "@/utils";
@@ -7,9 +8,11 @@ import {
CropSquareRounded,
FilterNoneRounded,
HorizontalRuleRounded,
PushPin,
PushPinOutlined,
} from "@mui/icons-material";
import { alpha, Button, ButtonProps, useTheme } from "@mui/material";
import { save_window_size_state } from "@nyanpasu/interface";
import { save_window_size_state, useNyanpasu } from "@nyanpasu/interface";
import { platform, type Platform } from "@tauri-apps/api/os";
import { appWindow } from "@tauri-apps/api/window";
@@ -29,6 +32,7 @@ const CtrlButton = (props: ButtonProps) => {
};
export const LayoutControl = ({ className }: { className?: string }) => {
const { nyanpasuConfig, setNyanpasuConfig } = useNyanpasu();
const [isMaximized, setIsMaximized] = useState(false);
const [platfrom, setPlatform] = useState<Platform>("win32");
@@ -46,6 +50,12 @@ export const LayoutControl = ({ className }: { className?: string }) => {
}
};
const toggleAlwaysOnTop = useMemoizedFn(async () => {
const isAlwaysOnTop = !!nyanpasuConfig?.always_on_top;
await setNyanpasuConfig({ always_on_top: !isAlwaysOnTop });
await appWindow.setAlwaysOnTop(!isAlwaysOnTop);
});
useEffect(() => {
// Update the maximized state
updateMaximized();
@@ -67,6 +77,17 @@ export const LayoutControl = ({ className }: { className?: string }) => {
return (
<div className={classNames("flex gap-1", className)} data-tauri-drag-region>
<CtrlButton onClick={toggleAlwaysOnTop}>
{nyanpasuConfig?.always_on_top ? (
<PushPin fontSize="small" style={{ transform: "rotate(15deg)" }} />
) : (
<PushPinOutlined
fontSize="small"
style={{ transform: "rotate(15deg)" }}
/>
)}
</CtrlButton>
<CtrlButton onClick={() => appWindow.minimize()}>
<HorizontalRuleRounded fontSize="small" />
</CtrlButton>

View File

@@ -0,0 +1,83 @@
import { useAtomValue } from "jotai";
import { useEffect, useRef } from "react";
import { useTranslation } from "react-i18next";
import useSWR from "swr";
import { monaco } from "@/services/monaco";
import { themeMode } from "@/store";
import { getRuntimeYaml, useClash } from "@nyanpasu/interface";
import { BaseDialog } from "@nyanpasu/ui";
export type RuntimeConfigDiffDialogProps = {
open: boolean;
onClose: () => void;
};
export default function RuntimeConfigDiffDialog({
open,
onClose,
}: RuntimeConfigDiffDialogProps) {
const { t } = useTranslation();
const { getProfiles, getProfileFile } = useClash();
const currentProfileUid = getProfiles.data?.current;
const mode = useAtomValue(themeMode);
const {
data: runtimeConfig,
isLoading: isLoadingRuntimeConfig,
error: errorRuntimeConfig,
} = useSWR(open ? "/getRuntimeConfigYaml" : null, getRuntimeYaml);
const {
data: profileConfig,
isLoading: isLoadingProfileConfig,
error: errorProfileConfig,
} = useSWR(
open ? `/readProfileFile?uid=${currentProfileUid}` : null,
async (key) => {
const url = new URL(key, window.location.origin);
return await getProfileFile(url.searchParams.get("uid")!);
},
{
revalidateOnFocus: true,
refreshInterval: 0,
},
);
const monacoRef = useRef<typeof monaco | null>(null);
const editorRef = useRef<monaco.editor.IStandaloneDiffEditor | null>(null);
const domRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (open && runtimeConfig && profileConfig) {
console.log("init monaco");
const run = async () => {
const { monaco } = await import("@/services/monaco");
monacoRef.current = monaco;
console.log(domRef.current);
editorRef.current = monaco.editor.createDiffEditor(domRef.current!, {
theme: mode === "light" ? "vs" : "vs-dark",
minimap: { enabled: false },
automaticLayout: true,
readOnly: true,
});
editorRef.current.setModel({
original: monaco.editor.createModel(profileConfig, "yaml"),
modified: monaco.editor.createModel(runtimeConfig, "yaml"),
});
};
run().catch(console.error);
}
return () => {
monacoRef.current = null;
editorRef.current?.dispose();
};
}, [mode, open, runtimeConfig, profileConfig]);
console.log(currentProfileUid);
if (!currentProfileUid) {
return null;
}
return (
<BaseDialog title={t("Runtime Config")} open={open} onClose={onClose}>
<div className="xs:w-[95vw] h-full w-[80vw] px-4">
<div ref={domRef} className="h-[75vh] w-full" />
</div>
</BaseDialog>
);
}

View File

@@ -78,7 +78,7 @@ export const ScriptDialog = ({
desc: "",
});
}
}, [isEdit]);
}, [form, isEdit, profile]);
const [openMonaco, setOpenMonaco] = useState(false);

View File

@@ -1,5 +1,6 @@
import { useAtom } from "jotai";
import { memo } from "react";
import { memo, useMemo } from "react";
import useSWR from "swr";
import { Virtualizer } from "virtua";
import { proxyGroupAtom } from "@/store";
import {
@@ -9,16 +10,30 @@ import {
ListItemIcon,
ListItemText,
} from "@mui/material";
import { useClashCore } from "@nyanpasu/interface";
import { getServerPort, useClashCore } from "@nyanpasu/interface";
const IconRender = memo(function IconRender({ icon }: { icon: string }) {
const {
data: serverPort,
isLoading,
error,
} = useSWR("/getServerPort", getServerPort);
const src = icon.trim().startsWith("<svg")
? `data:image/svg+xml;base64,${btoa(icon)}`
: icon;
const cachedUrl = useMemo(() => {
if (!src.startsWith("http")) {
return src;
}
return `http://localhost:${serverPort}/cache/icon?url=${btoa(src)}`;
}, [src, serverPort]);
console.log(serverPort, isLoading, error);
if (isLoading || error) {
return null;
}
return (
<ListItemIcon>
<img className="h-11 w-11" src={src} />
<img className="h-11 w-11" src={cachedUrl} />
</ListItemIcon>
);
});

View File

@@ -1,8 +1,10 @@
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { useCoreType } from "@/hooks/use-store";
import getSystem from "@/utils/get-system";
import { message } from "@/utils/notification";
import { Button, List, ListItem, ListItemText } from "@mui/material";
import { pullupUWPTool } from "@nyanpasu/interface";
import { pullupUWPTool, useNyanpasu, VergeConfig } from "@nyanpasu/interface";
import { BaseCard, MenuItem, SwitchItem } from "@nyanpasu/ui";
import { clash } from "./modules";
@@ -13,8 +15,8 @@ const isWIN = getSystem() === "windows";
export const SettingClashBase = () => {
const { t } = useTranslation();
// const [coreType] = useCoreType();
const [coreType] = useCoreType();
const { nyanpasuConfig, setNyanpasuConfig } = useNyanpasu();
const clickUWP = async () => {
try {
await pullupUWPTool();
@@ -26,6 +28,23 @@ export const SettingClashBase = () => {
}
};
const tunStackOptions = useMemo(() => {
const options: {
[key: string]: string;
} = {
system: "System",
gvisor: "gVisor",
mixed: "Mixed",
};
if (coreType === "clash") {
delete options.mixed;
}
return options;
}, [coreType]);
const tunStackSelected = useMemo(() => {
const stack = nyanpasuConfig?.tun_stack || "gvisor";
return stack in tunStackOptions ? stack : "gvisor";
}, [nyanpasuConfig?.tun_stack, tunStackOptions]);
return (
<BaseCard label={t("Clash Setting")}>
<List disablePadding>
@@ -36,6 +55,22 @@ export const SettingClashBase = () => {
<SwitchItem label={t("IPv6")} {...createBooleanProps("ipv6")} />
{coreType !== "clash-rs" && (
<MenuItem
label={t("Tun Stack")}
options={tunStackOptions}
selected={tunStackSelected}
onSelected={(value) => {
const payload = {
tun_stack: value as NonNullable<VergeConfig["tun_stack"]>,
} as Partial<VergeConfig>;
if (nyanpasuConfig?.enable_tun_mode) {
payload.enable_tun_mode = true; // just to reload clash config
}
setNyanpasuConfig(payload);
}}
/>
)}
<MenuItem
label={t("Log Level")}
{...createMenuProps("log-level", {

View File

@@ -5,7 +5,12 @@ import { useTranslation } from "react-i18next";
import { message } from "@/utils/notification";
import LoadingButton from "@mui/lab/LoadingButton";
import { Box, List, ListItem } from "@mui/material";
import { ClashCore, useClash, useNyanpasu } from "@nyanpasu/interface";
import {
ClashCore,
useClash,
useNyanpasu,
VergeConfig,
} from "@nyanpasu/interface";
import { BaseCard, ExpandMore } from "@nyanpasu/ui";
import { ClashCoreItem } from "./modules/clash-core";
@@ -107,7 +112,7 @@ export const SettingClashCore = () => {
});
const handleUpdateCore = useLockFn(
async (core: Required<IVergeConfig>["clash_core"]) => {
async (core: Required<VergeConfig>["clash_core"]) => {
try {
loading.mask = true;

View File

@@ -32,7 +32,14 @@ export default function App() {
const isDrawer = useMemo(() => Boolean(column === 1), [column]);
return (
<SWRConfig value={{ errorRetryCount: 3 }}>
<SWRConfig
value={{
errorRetryCount: 5,
revalidateOnMount: true,
revalidateOnFocus: true,
refreshInterval: 5000,
}}
>
<CssVarsProvider theme={theme}>
<ThemeModeProvider />
<LogProvider />

View File

@@ -1,4 +1,5 @@
import { useAtom } from "jotai";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import {
atomChainsSelected,
@@ -8,10 +9,11 @@ import NewProfileButton from "@/components/profiles/new-profile-button";
import ProfileItem from "@/components/profiles/profile-item";
import ProfileSide from "@/components/profiles/profile-side";
import { QuickImport } from "@/components/profiles/quick-import";
import RuntimeConfigDiffDialog from "@/components/profiles/runtime-config-diff-dialog";
import { filterProfiles } from "@/components/profiles/utils";
import { Public } from "@mui/icons-material";
import Masonry from "@mui/lab/Masonry";
import { Button } from "@mui/material";
import { Button, IconButton } from "@mui/material";
import { Profile, useClash } from "@nyanpasu/interface";
import { SidePage } from "@nyanpasu/ui";
@@ -46,12 +48,25 @@ export const ProfilePage = () => {
setGlobalChain(false);
};
const [runtimeConfigViewerOpen, setRuntimeConfigViewerOpen] = useState(false);
console.log(runtimeConfigViewerOpen);
return (
<SidePage
title={t("Profiles")}
flexReverse
header={
<div>
<RuntimeConfigDiffDialog
open={runtimeConfigViewerOpen}
onClose={() => setRuntimeConfigViewerOpen(false)}
/>
<IconButton
onClick={() => {
setRuntimeConfigViewerOpen(true);
}}
>
<IconMdiTextBoxCheckOutline />
</IconButton>
<Button
size="small"
variant={globalChain ? "contained" : "outlined"}

View File

@@ -22,6 +22,6 @@
},
"jsxImportSource": "@emotion/react",
},
"include": ["./src"],
"include": ["./src", "./auto-imports.d.ts"],
"references": [{ "path": "../interface/tsconfig.json" }],
}

View File

@@ -1,4 +1,7 @@
import path from "node:path";
import AutoImport from "unplugin-auto-import/vite";
import IconsResolver from "unplugin-icons/resolver";
import Icons from "unplugin-icons/vite";
import { defineConfig } from "vite";
import monaco from "vite-plugin-monaco-editor";
import sassDts from "vite-plugin-sass-dts";
@@ -50,6 +53,17 @@ export default defineConfig(({ command }) => {
// plugins: ["@emotion/babel-plugin"],
// },
}),
AutoImport({
resolvers: [
IconsResolver({
prefix: "Icon",
extension: "jsx",
}),
],
}),
Icons({
compiler: "jsx", // or 'solid'
}),
generouted(),
sassDts({ esmExport: true }),
monaco({ languageWorkers: ["editorWorkerService", "typescript"] }),

View File

@@ -59,7 +59,7 @@
"@types/node": "20.14.14",
"@typescript-eslint/eslint-plugin": "8.0.0",
"@typescript-eslint/parser": "8.0.0",
"autoprefixer": "10.4.19",
"autoprefixer": "10.4.20",
"conventional-changelog-conventionalcommits": "8.0.0",
"cross-env": "7.0.3",
"dedent": "1.5.3",

View File

@@ -50,8 +50,8 @@ importers:
specifier: 8.0.0
version: 8.0.0(eslint@8.57.0)(typescript@5.5.4)
autoprefixer:
specifier: 10.4.19
version: 10.4.19(postcss@8.4.40)
specifier: 10.4.20
version: 10.4.20(postcss@8.4.40)
conventional-changelog-conventionalcommits:
specifier: 8.0.0
version: 8.0.0
@@ -297,6 +297,9 @@ importers:
'@emotion/react':
specifier: 11.13.0
version: 11.13.0(react@19.0.0-rc-df783f9ea1-20240708)(types-react@19.0.0-rc.1)
'@iconify/json':
specifier: 2.2.233
version: 2.2.233
'@types/react':
specifier: npm:types-react@rc
version: types-react@19.0.0-rc.1
@@ -321,6 +324,12 @@ importers:
tailwindcss-textshadow:
specifier: 2.1.3
version: 2.1.3
unplugin-auto-import:
specifier: 0.18.2
version: 0.18.2(rollup@4.17.2)
unplugin-icons:
specifier: 0.19.1
version: 0.19.1(@svgr/core@8.1.0(typescript@5.5.4))
vite:
specifier: 5.3.5
version: 5.3.5(@types/node@20.14.14)(less@4.2.0)(sass@1.77.8)(stylus@0.62.0)
@@ -472,6 +481,15 @@ packages:
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'}
'@antfu/install-pkg@0.1.1':
resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==}
'@antfu/install-pkg@0.3.3':
resolution: {integrity: sha512-nHHsk3NXQ6xkCfiRRC8Nfrg8pU5kkr3P3Y9s9dKqiuRmBD0Yap7fymNDjGFKeWhZQHqqbCS5CfeMy9wtExM24w==}
'@antfu/utils@0.7.10':
resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
'@babel/code-frame@7.24.2':
resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==}
engines: {node: '>=6.9.0'}
@@ -1198,6 +1216,15 @@ packages:
'@vue/compiler-sfc':
optional: true
'@iconify/json@2.2.233':
resolution: {integrity: sha512-i0URcf6w1TxEQixrYi/hBLdY3ArglF0uOx7pwqaNN5oGW82+G6ojWXeHXekntLxH7EpaXTNQ5bo6CJCbU3fpdQ==}
'@iconify/types@2.0.0':
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
'@iconify/utils@2.1.29':
resolution: {integrity: sha512-wCcTsmlJvTi1VWBgcJ7HeuWlh7gLGWY7L9HmbgMfjOfsoo7DADemB2Nqnrw1KvCdEAxLL5wTMBAOP5BesFrtng==}
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
@@ -1218,12 +1245,16 @@ packages:
resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
engines: {node: '>=6.0.0'}
'@jridgewell/sourcemap-codec@1.4.15':
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
'@jridgewell/sourcemap-codec@1.5.0':
resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
'@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
'@jsdevtools/ez-spawn@3.0.4':
resolution: {integrity: sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==}
engines: {node: '>=10'}
'@juggle/resize-observer@3.4.0':
resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==}
@@ -2315,6 +2346,11 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
acorn@8.12.1:
resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
engines: {node: '>=0.4.0'}
hasBin: true
adm-zip@0.5.14:
resolution: {integrity: sha512-DnyqqifT4Jrcvb8USYjp6FHtBpEIz1mnXu6pTRHZ0RL69LbQYiO+0lDFg5+OKA7U29oWSs3a/i8fhn8ZcceIWg==}
engines: {node: '>=12.0'}
@@ -2442,8 +2478,8 @@ packages:
asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
autoprefixer@10.4.19:
resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==}
autoprefixer@10.4.20:
resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==}
engines: {node: ^10 || ^12 || >=14}
hasBin: true
peerDependencies:
@@ -2515,6 +2551,11 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
browserslist@4.23.3:
resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
buffer-crc32@0.2.13:
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
@@ -2548,6 +2589,9 @@ packages:
resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
engines: {node: '>= 0.4'}
call-me-maybe@1.0.2:
resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==}
callsites@3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
@@ -2567,6 +2611,9 @@ packages:
caniuse-lite@1.0.30001616:
resolution: {integrity: sha512-RHVYKov7IcdNjVHJFNY/78RdG4oGVjbayxv8u5IO74Wv7Hlq4PnJE6mo/OjFijjVFNy5ijnCt6H3IIo4t+wfEw==}
caniuse-lite@1.0.30001646:
resolution: {integrity: sha512-dRg00gudiBDDTmUhClSdv3hqRfpbOnU28IpI1T6PBTLWa+kOj0681C8uML3PifYfREuBrVjDGhL3adYpBT6spw==}
capture-stack-trace@1.0.2:
resolution: {integrity: sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==}
engines: {node: '>=0.10.0'}
@@ -2707,6 +2754,9 @@ packages:
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
confbox@0.1.7:
resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==}
configstore@3.1.5:
resolution: {integrity: sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA==}
engines: {node: '>=4'}
@@ -2998,15 +3048,6 @@ packages:
supports-color:
optional: true
debug@4.3.5:
resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
debug@4.3.6:
resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==}
engines: {node: '>=6.0'}
@@ -3159,6 +3200,9 @@ packages:
electron-to-chromium@1.4.758:
resolution: {integrity: sha512-/o9x6TCdrYZBMdGeTifAP3wlF/gVT+TtWJe3BSmtNh92Mw81U9hrYwW9OAGUh+sEOX/yz5e34sksqRruZbjYrw==}
electron-to-chromium@1.5.4:
resolution: {integrity: sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==}
electron@23.3.13:
resolution: {integrity: sha512-BaXtHEb+KYKLouUXlUVDa/lj9pj4F5kiE0kwFdJV84Y2EU7euIDgPthfKtchhr5MVHmjtavRMIV/zAwEiSQ9rQ==}
engines: {node: '>= 12.20.55'}
@@ -3419,6 +3463,9 @@ packages:
estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
@@ -4231,6 +4278,9 @@ packages:
known-css-properties@0.34.0:
resolution: {integrity: sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==}
kolorist@1.8.0:
resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
latest-version@3.1.0:
resolution: {integrity: sha512-Be1YRHWWlZaSsrz2U+VInk+tO0EwLIyV+23RhWLINJYwg/UIikxjlj3MhH37/6/EDCAusjajvMkMMUXRaMWl/w==}
engines: {node: '>=4'}
@@ -4264,6 +4314,10 @@ packages:
resolution: {integrity: sha512-irTfvpib/rNiD637xeevjO2l3Z5loZmuaRi0L0YE5LfijwVY96oyVn0DFD3o/teAok7nfobMG1THvvcHh/BP6g==}
engines: {node: '>=18.0.0'}
local-pkg@0.5.0:
resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==}
engines: {node: '>=14'}
locate-path@6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
@@ -4349,6 +4403,9 @@ packages:
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
magic-string@0.30.11:
resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==}
make-dir@1.3.0:
resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==}
engines: {node: '>=4'}
@@ -4530,6 +4587,10 @@ packages:
resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==}
engines: {node: '>=16 || 14 >=14.17'}
minimatch@9.0.5:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
@@ -4546,6 +4607,9 @@ packages:
engines: {node: '>=10'}
hasBin: true
mlly@1.7.1:
resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==}
monaco-editor@0.50.0:
resolution: {integrity: sha512-8CclLCmrRRh+sul7C08BmPBP3P8wVWfBHomsTcndxg5NRCEPfu/mc2AGU8k37ajjDVXcXFc12ORAMUkmk+lkFA==}
@@ -4618,6 +4682,9 @@ packages:
node-releases@2.0.14:
resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
node-releases@2.0.18:
resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
@@ -4821,6 +4888,9 @@ packages:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
pathe@1.1.2:
resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
pend@1.2.0:
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
@@ -4859,6 +4929,9 @@ packages:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
pkg-types@1.1.3:
resolution: {integrity: sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==}
possible-typed-array-names@1.0.0:
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
engines: {node: '>= 0.4'}
@@ -5391,6 +5464,9 @@ packages:
resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==}
engines: {node: '>=0.10.0'}
scule@1.3.0:
resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
semver-compare@1.0.0:
resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==}
@@ -5606,6 +5682,9 @@ packages:
resolution: {integrity: sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==}
engines: {node: '>=14.16'}
strip-literal@2.1.0:
resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==}
style-to-object@1.0.6:
resolution: {integrity: sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==}
@@ -5821,6 +5900,10 @@ packages:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
type-detect@4.1.0:
resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==}
engines: {node: '>=4'}
type-fest@0.13.1:
resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
engines: {node: '>=10'}
@@ -5891,6 +5974,9 @@ packages:
unified@11.0.4:
resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==}
unimport@3.9.1:
resolution: {integrity: sha512-4gtacoNH6YPx2Aa5Xfyrf8pU2RdXjWUACb/eF7bH1AcZtqs+6ijbNB0M3BPENbtVjnCcg8tw9UJ1jQGbCzKA6g==}
unique-string@1.0.0:
resolution: {integrity: sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==}
engines: {node: '>=4'}
@@ -5930,6 +6016,42 @@ packages:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
engines: {node: '>= 10.0.0'}
unplugin-auto-import@0.18.2:
resolution: {integrity: sha512-Dwb3rAic75harVBrVjwiq6H24PT+nBq2dpxV5BH8NNI6sDFaTytvP+iyo4xy7prQbR3r5K6nMs4f5Wp9PE4g8A==}
engines: {node: '>=14'}
peerDependencies:
'@nuxt/kit': ^3.2.2
'@vueuse/core': '*'
peerDependenciesMeta:
'@nuxt/kit':
optional: true
'@vueuse/core':
optional: true
unplugin-icons@0.19.1:
resolution: {integrity: sha512-a5I+wSOO5lsgc4dB2nEFaSZ4eEgQvSSR8tSR2jT69nTKiVmcK+PPU633zn2FyRf9i6vLapUiQ28GQStfzGURdg==}
peerDependencies:
'@svgr/core': '>=7.0.0'
'@svgx/core': ^1.0.1
'@vue/compiler-sfc': ^3.0.2 || ^2.7.0
vue-template-compiler: ^2.6.12
vue-template-es2015-compiler: ^1.9.0
peerDependenciesMeta:
'@svgr/core':
optional: true
'@svgx/core':
optional: true
'@vue/compiler-sfc':
optional: true
vue-template-compiler:
optional: true
vue-template-es2015-compiler:
optional: true
unplugin@1.12.0:
resolution: {integrity: sha512-KeczzHl2sATPQUx1gzo+EnUkmN4VmGBYRRVOZSGvGITE9rGHRDGqft6ONceP3vgXcyJ2XjX5axG5jMWUwNCYLw==}
engines: {node: '>=14.0.0'}
unzip-response@2.0.1:
resolution: {integrity: sha512-N0XH6lqDtFH84JxptQoZYmloF4nzrQqqrAymNj+/gW60AO2AZgOcf4O/nUXJcYfyQkqvMo9lSupBZmmgvuVXlw==}
engines: {node: '>=4'}
@@ -5940,6 +6062,12 @@ packages:
peerDependencies:
browserslist: '>= 4.21.0'
update-browserslist-db@1.1.0:
resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==}
hasBin: true
peerDependencies:
browserslist: '>= 4.21.0'
update-notifier@2.5.0:
resolution: {integrity: sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==}
engines: {node: '>=4'}
@@ -6061,6 +6189,13 @@ packages:
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
engines: {node: '>= 8'}
webpack-sources@3.2.3:
resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
engines: {node: '>=10.13.0'}
webpack-virtual-modules@0.6.2:
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
websocket@1.0.35:
resolution: {integrity: sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q==}
engines: {node: '>=4.0.0'}
@@ -6223,6 +6358,17 @@ snapshots:
'@jridgewell/gen-mapping': 0.3.5
'@jridgewell/trace-mapping': 0.3.25
'@antfu/install-pkg@0.1.1':
dependencies:
execa: 5.1.1
find-up: 5.0.0
'@antfu/install-pkg@0.3.3':
dependencies:
'@jsdevtools/ez-spawn': 3.0.4
'@antfu/utils@0.7.10': {}
'@babel/code-frame@7.24.2':
dependencies:
'@babel/highlight': 7.24.5
@@ -6248,7 +6394,7 @@ snapshots:
'@babel/traverse': 7.24.5
'@babel/types': 7.24.5
convert-source-map: 2.0.0
debug: 4.3.5
debug: 4.3.6
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
@@ -6470,7 +6616,7 @@ snapshots:
'@babel/helper-split-export-declaration': 7.24.5
'@babel/parser': 7.24.5
'@babel/types': 7.24.5
debug: 4.3.5
debug: 4.3.6
globals: 11.12.0
transitivePeerDependencies:
- supports-color
@@ -6901,7 +7047,7 @@ snapshots:
'@eslint/eslintrc@2.1.4':
dependencies:
ajv: 6.12.6
debug: 4.3.5
debug: 4.3.6
espree: 9.6.1
globals: 13.24.0
ignore: 5.3.1
@@ -6949,7 +7095,7 @@ snapshots:
'@humanwhocodes/config-array@0.11.14':
dependencies:
'@humanwhocodes/object-schema': 2.0.3
debug: 4.3.5
debug: 4.3.6
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
@@ -6970,6 +7116,25 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@iconify/json@2.2.233':
dependencies:
'@iconify/types': 2.0.0
pathe: 1.1.2
'@iconify/types@2.0.0': {}
'@iconify/utils@2.1.29':
dependencies:
'@antfu/install-pkg': 0.1.1
'@antfu/utils': 0.7.10
'@iconify/types': 2.0.0
debug: 4.3.6
kolorist: 1.8.0
local-pkg: 0.5.0
mlly: 1.7.1
transitivePeerDependencies:
- supports-color
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
@@ -6986,19 +7151,26 @@ snapshots:
'@jridgewell/gen-mapping@0.3.5':
dependencies:
'@jridgewell/set-array': 1.2.1
'@jridgewell/sourcemap-codec': 1.4.15
'@jridgewell/sourcemap-codec': 1.5.0
'@jridgewell/trace-mapping': 0.3.25
'@jridgewell/resolve-uri@3.1.2': {}
'@jridgewell/set-array@1.2.1': {}
'@jridgewell/sourcemap-codec@1.4.15': {}
'@jridgewell/sourcemap-codec@1.5.0': {}
'@jridgewell/trace-mapping@0.3.25':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.4.15
'@jridgewell/sourcemap-codec': 1.5.0
'@jsdevtools/ez-spawn@3.0.4':
dependencies:
call-me-maybe: 1.0.2
cross-spawn: 7.0.3
string-argv: 0.3.2
type-detect: 4.1.0
'@juggle/resize-observer@3.4.0': {}
@@ -8018,7 +8190,7 @@ snapshots:
debug: 4.3.6
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.4
minimatch: 9.0.5
semver: 7.6.1
ts-api-utils: 1.3.0(typescript@5.5.4)
optionalDependencies:
@@ -8083,11 +8255,13 @@ snapshots:
acorn@8.11.3: {}
acorn@8.12.1: {}
adm-zip@0.5.14: {}
agent-base@7.1.1:
dependencies:
debug: 4.3.5
debug: 4.3.6
transitivePeerDependencies:
- supports-color
@@ -8249,10 +8423,10 @@ snapshots:
asynckit@0.4.0: {}
autoprefixer@10.4.19(postcss@8.4.40):
autoprefixer@10.4.20(postcss@8.4.40):
dependencies:
browserslist: 4.23.0
caniuse-lite: 1.0.30001616
browserslist: 4.23.3
caniuse-lite: 1.0.30001646
fraction.js: 4.3.7
normalize-range: 0.1.2
picocolors: 1.0.1
@@ -8338,6 +8512,13 @@ snapshots:
node-releases: 2.0.14
update-browserslist-db: 1.0.15(browserslist@4.23.0)
browserslist@4.23.3:
dependencies:
caniuse-lite: 1.0.30001646
electron-to-chromium: 1.5.4
node-releases: 2.0.18
update-browserslist-db: 1.1.0(browserslist@4.23.3)
buffer-crc32@0.2.13: {}
buffer@6.0.3:
@@ -8377,6 +8558,8 @@ snapshots:
get-intrinsic: 1.2.4
set-function-length: 1.2.2
call-me-maybe@1.0.2: {}
callsites@3.1.0: {}
camelcase-css@2.0.1: {}
@@ -8387,6 +8570,8 @@ snapshots:
caniuse-lite@1.0.30001616: {}
caniuse-lite@1.0.30001646: {}
capture-stack-trace@1.0.2: {}
ccount@2.0.1: {}
@@ -8513,6 +8698,8 @@ snapshots:
concat-map@0.0.1: {}
confbox@0.1.7: {}
configstore@3.1.5:
dependencies:
dot-prop: 4.2.1
@@ -8818,10 +9005,6 @@ snapshots:
dependencies:
ms: 2.1.2
debug@4.3.5:
dependencies:
ms: 2.1.2
debug@4.3.6:
dependencies:
ms: 2.1.2
@@ -8974,6 +9157,8 @@ snapshots:
electron-to-chromium@1.4.758: {}
electron-to-chromium@1.5.4: {}
electron@23.3.13:
dependencies:
'@electron/get': 2.0.3
@@ -9399,6 +9584,10 @@ snapshots:
estree-walker@2.0.2: {}
estree-walker@3.0.3:
dependencies:
'@types/estree': 1.0.5
esutils@2.0.3: {}
event-emitter@0.3.5:
@@ -9648,7 +9837,7 @@ snapshots:
dependencies:
foreground-child: 3.1.1
jackspeak: 2.3.6
minimatch: 9.0.4
minimatch: 9.0.5
minipass: 7.1.2
path-scurry: 1.10.2
@@ -10216,6 +10405,8 @@ snapshots:
known-css-properties@0.34.0: {}
kolorist@1.8.0: {}
latest-version@3.1.0:
dependencies:
package-json: 4.0.1
@@ -10269,6 +10460,11 @@ snapshots:
rfdc: 1.3.1
wrap-ansi: 9.0.0
local-pkg@0.5.0:
dependencies:
mlly: 1.7.1
pkg-types: 1.1.3
locate-path@6.0.0:
dependencies:
p-locate: 5.0.0
@@ -10340,6 +10536,10 @@ snapshots:
dependencies:
yallist: 3.1.1
magic-string@0.30.11:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
make-dir@1.3.0:
dependencies:
pify: 3.0.0
@@ -10637,6 +10837,10 @@ snapshots:
dependencies:
brace-expansion: 2.0.1
minimatch@9.0.5:
dependencies:
brace-expansion: 2.0.1
minimist@1.2.8: {}
minipass@7.1.2: {}
@@ -10648,6 +10852,13 @@ snapshots:
mkdirp@3.0.1: {}
mlly@1.7.1:
dependencies:
acorn: 8.12.1
pathe: 1.1.2
pkg-types: 1.1.3
ufo: 1.5.3
monaco-editor@0.50.0: {}
ms@2.0.0: {}
@@ -10712,6 +10923,8 @@ snapshots:
node-releases@2.0.14: {}
node-releases@2.0.18: {}
normalize-path@3.0.0: {}
normalize-range@0.1.2: {}
@@ -10920,6 +11133,8 @@ snapshots:
path-type@4.0.0: {}
pathe@1.1.2: {}
pend@1.2.0: {}
picocolors@0.2.1: {}
@@ -10941,6 +11156,12 @@ snapshots:
pirates@4.0.6: {}
pkg-types@1.1.3:
dependencies:
confbox: 0.1.7
mlly: 1.7.1
pathe: 1.1.2
possible-typed-array-names@1.0.0: {}
postcss-functions@3.0.0:
@@ -11458,6 +11679,8 @@ snapshots:
screenfull@5.2.0: {}
scule@1.3.0: {}
semver-compare@1.0.0:
optional: true
@@ -11673,6 +11896,10 @@ snapshots:
strip-json-comments@5.0.1: {}
strip-literal@2.1.0:
dependencies:
js-tokens: 9.0.0
style-to-object@1.0.6:
dependencies:
inline-style-parser: 0.2.3
@@ -11765,7 +11992,7 @@ snapshots:
stylus@0.62.0:
dependencies:
'@adobe/css-tools': 4.3.3
debug: 4.3.4
debug: 4.3.6
glob: 7.2.3
sax: 1.3.0
source-map: 0.7.4
@@ -11991,6 +12218,8 @@ snapshots:
dependencies:
prelude-ls: 1.2.1
type-detect@4.1.0: {}
type-fest@0.13.1:
optional: true
@@ -12096,6 +12325,24 @@ snapshots:
trough: 2.2.0
vfile: 6.0.1
unimport@3.9.1(rollup@4.17.2):
dependencies:
'@rollup/pluginutils': 5.1.0(rollup@4.17.2)
acorn: 8.12.1
escape-string-regexp: 5.0.0
estree-walker: 3.0.3
fast-glob: 3.3.2
local-pkg: 0.5.0
magic-string: 0.30.11
mlly: 1.7.1
pathe: 1.1.2
pkg-types: 1.1.3
scule: 1.3.0
strip-literal: 2.1.0
unplugin: 1.12.0
transitivePeerDependencies:
- rollup
unique-string@1.0.0:
dependencies:
crypto-random-string: 1.0.0
@@ -12138,6 +12385,40 @@ snapshots:
universalify@2.0.1: {}
unplugin-auto-import@0.18.2(rollup@4.17.2):
dependencies:
'@antfu/utils': 0.7.10
'@rollup/pluginutils': 5.1.0(rollup@4.17.2)
fast-glob: 3.3.2
local-pkg: 0.5.0
magic-string: 0.30.11
minimatch: 9.0.5
unimport: 3.9.1(rollup@4.17.2)
unplugin: 1.12.0
transitivePeerDependencies:
- rollup
unplugin-icons@0.19.1(@svgr/core@8.1.0(typescript@5.5.4)):
dependencies:
'@antfu/install-pkg': 0.3.3
'@antfu/utils': 0.7.10
'@iconify/utils': 2.1.29
debug: 4.3.6
kolorist: 1.8.0
local-pkg: 0.5.0
unplugin: 1.12.0
optionalDependencies:
'@svgr/core': 8.1.0(typescript@5.5.4)
transitivePeerDependencies:
- supports-color
unplugin@1.12.0:
dependencies:
acorn: 8.12.1
chokidar: 3.6.0
webpack-sources: 3.2.3
webpack-virtual-modules: 0.6.2
unzip-response@2.0.1: {}
update-browserslist-db@1.0.15(browserslist@4.23.0):
@@ -12146,6 +12427,12 @@ snapshots:
escalade: 3.1.2
picocolors: 1.0.1
update-browserslist-db@1.1.0(browserslist@4.23.3):
dependencies:
browserslist: 4.23.3
escalade: 3.1.2
picocolors: 1.0.1
update-notifier@2.5.0:
dependencies:
boxen: 1.3.0
@@ -12255,6 +12542,10 @@ snapshots:
web-streams-polyfill@3.3.3: {}
webpack-sources@3.2.3: {}
webpack-virtual-modules@0.6.2: {}
websocket@1.0.35:
dependencies:
bufferutil: 4.0.8

View File

@@ -26,6 +26,7 @@ async function resolvePortable() {
zip.addLocalFile(path.join(releaseDir, "clash.exe"));
zip.addLocalFile(path.join(releaseDir, "mihomo.exe"));
zip.addLocalFile(path.join(releaseDir, "mihomo-alpha.exe"));
zip.addLocalFile(path.join(releaseDir, "nyanpasu-service.exe"));
zip.addLocalFile(path.join(releaseDir, "clash-rs.exe"));
zip.addLocalFolder(path.join(releaseDir, "resources"), "resources");
zip.addLocalFolder(configDir, ".config");

View File

@@ -13,7 +13,7 @@ PKG_VERSION:=8.5.0
PKG_RELEASE:=1
PKG_SOURCE:=cryptopp$(subst .,,$(PKG_VERSION)).zip
PKG_SOURCE_URL:=https://www.cryptopp.com/
PKG_SOURCE_URL:=https://github.com/weidai11/cryptopp/releases/download/CRYPTOPP_$(subst .,_,$(PKG_VERSION))/
PKG_HASH:=95fc50d59488ebf61a735cce2b2ec2c2561fc682077c7b496273d65a1ed93d9e
PKG_FIXUP:=autoreconf
@@ -38,9 +38,19 @@ define Package/libcryptopp/description
use of templates and abstract base classes.
endef
PKG_BUILD_FILE:=cryptopp-autotools$(subst .,,$(PKG_VERSION)).zip
define Download/autotools
URL:=https://github.com/noloader/cryptopp-autotools/releases/download/CRYPTOPP_$(subst .,_,$(PKG_VERSION))/
FILE:=$(PKG_BUILD_FILE)
HASH:=91e06c53b517753f0ba02b92bb259e0ee929ebc6ad4f8b5c190d39ba407d3fbe
endef
$(eval $(call Download,autotools))
define Build/Prepare
$(Build/Prepare/Default)
$(PKG_UNPACK)
unzip -q -d $(PKG_BUILD_DIR) $(DL_DIR)/$(PKG_BUILD_FILE)
cd $(PKG_BUILD_DIR); rm -f GNUmakefile GNUmakefile-cross
$(Build/Patch)
endef
define Build/InstallDev

View File

@@ -0,0 +1,24 @@
--- a/Makefile.am
+++ b/Makefile.am
@@ -458,14 +458,13 @@ testvector_FILES = \
TestVectors/lea.txt TestVectors/sosemanuk.txt \
TestVectors/mars.txt TestVectors/speck.txt \
TestVectors/nr.txt TestVectors/tea.txt \
- TestVectors/ocb.txt TestVectors/threefish.txt \
- TestVectors/panama.txt TestVectors/ttmac.txt \
- TestVectors/poly1305aes.txt TestVectors/vmac.txt \
- TestVectors/poly1305_tls.txt TestVectors/wake.txt \
- TestVectors/rabbit.txt TestVectors/whrlpool.txt \
- TestVectors/Readme.txt TestVectors/xchacha.txt \
- TestVectors/rsa_oaep.txt TestVectors/xts.txt \
- TestVectors/rsa_pkcs1_1_5.txt
+ TestVectors/panama.txt TestVectors/threefish.txt \
+ TestVectors/poly1305aes.txt TestVectors/ttmac.txt \
+ TestVectors/poly1305_tls.txt TestVectors/vmac.txt \
+ TestVectors/rabbit.txt TestVectors/wake.txt \
+ TestVectors/Readme.txt TestVectors/whrlpool.txt \
+ TestVectors/rsa_oaep.txt TestVectors/xchacha.txt \
+ TestVectors/rsa_pkcs1_1_5.txt TestVectors/xts.txt
# Create with 'ls TestPrograms/test_*.cxx'. These files do not get installed.
# They exist so the feature tests can be run from the configure directory.

View File

@@ -1,592 +0,0 @@
## Makefile.am - Autotools configuration file for Crypto++.
## written and placed in public domain by Jeffrey Walton.
## based on Debian Makefile.am by László Böszörményi.
##
## The GNUmakefile can generate the list of lib headers, lib sources,
## test headers and test sources. Generate the list of files with
## 'make sources'. Remove the SIMD files for libothers_la_SOURCES.
## Thanks to steeldriver on U&L.SE for help with the sed.
##
## make sources | sed 's|cryptlib.cpp cpu.cpp integer.cpp ||g' | \
## sed -e 's|[[:alnum:]]*_simd.cpp ||g' | \
## sed -e 's|[[:alnum:]]*_sse.cpp ||g' | \
## sed -e 's|[[:alnum:]]*_avx.cpp ||g' | \
## sed -e 's|[[:alnum:]]*_armv4.cpp ||g' | \
## sed -e 's|ppc_power[[:alnum:]]*.cpp ||g' | \
## fold -s -w 72
##
## The command `make sources | sed ... | fold` will create the source file
## list that can be used with `libothers_la_SOURCES` below.
##
## The list of header files can be built with 'make sources', too.
##
## make sources | sed -e 's|[[:alnum:]]*_armv4.h ||g' \
## fold -s -w 72
##
## Note: configure.ac deletes GNUmakefile. You can get it back with:
##
## git checkout GNUmakefile
##
## Automake does not support "specific flags for certain source files"
## natively, so we hack it. The hack include building 20 or so
## libraries and then combining them into an archive or shared object.
## Also see https://lists.gnu.org/archive/html/automake/2017-11/msg00000.html
## https://www.gnu.org/software/automake/manual/html_node/Per_002dObject-Flags.html.
##
## Visit the link below for the original Debian Autotools files
## https://sources.debian.net/src/libcrypto++/5.6.4-8/debian/autotools/
##
## TODO:
##
## - Figure out how to include TestPrograms/ in the dist tarball
## TestPrograms/ is unique because it is included in dist tarball but not installed
##
## - Figure out what's going on with DragonFly and dependencies
##
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4
AM_DEFAULT_SOURCE_EXT = .cpp
## libcryptopp.la is created from disjoint libraries due to object file
## ordering and per-object file flags requirements. libcryptopp.la is
## named as the primary library, and the object files with special needs
## are listed as EXTRA_LTLIBRARIES. Also see
## https://lists.gnu.org/archive/html/automake/2017-11/msg00000.html.
lib_LTLIBRARIES = \
libcryptopp.la
EXTRA_LTLIBRARIES = \
libcryptlib.la \
libcpu.la \
libinteger.la \
libaria_simd.la \
libblake2s_simd.la \
libblake2b_simd.la \
libchacha_simd.la \
libchacha_avx.la \
libcham_simd.la \
libcrc_simd.la \
libdonna_sse.la \
libgcm_simd.la \
libgf2n_simd.la \
libkeccak_simd.la \
liblea_simd.la \
libneon_simd.la \
libppc_simd.la \
libppc_power7.la \
libppc_power8.la \
libppc_power9.la \
librijndael_simd.la \
libsha_simd.la \
libshacal2_simd.la \
libsimon128_simd.la \
libspeck128_simd.la \
libsm4_simd.la \
libsse_simd.la
## ARMv7-a AES and SHA by Andy Polyakov
if CRYPTOGAMS_ARM_SOURCES
EXTRA_LTLIBRARIES += libaes_armv4.la
EXTRA_LTLIBRARIES += libsha1_armv4.la
EXTRA_LTLIBRARIES += libsha256_armv4.la
EXTRA_LTLIBRARIES += libsha512_armv4.la
endif
## The remainder of the source files
EXTRA_LTLIBRARIES += libothers.la
## libcryptopp_la_SOURCES is empty because we need to create the library
## artifact from disjoint libraries due to object file ordering and
## per-object file flags requriements. Actually, the adhoc.cpp file is
## due to an automake issue of assuming C sources when the list is empty.
## https://lists.gnu.org/archive/html/automake/2017-11/msg00000.html.
libcryptopp_la_SOURCES = \
adhoc.cpp
## Don't use EXTRA_ prefix for libcryptopp_la_LIBADD. It breaks Solaris.
libcryptopp_la_LIBADD = \
$(libcryptlib_la_OBJECTS) \
$(libcpu_la_OBJECTS) \
$(libinteger_la_OBJECTS) \
$(libaria_simd_la_OBJECTS) \
$(libblake2s_simd_la_OBJECTS) \
$(libblake2b_simd_la_OBJECTS) \
$(libchacha_simd_la_OBJECTS) \
$(libchacha_avx_la_OBJECTS) \
$(libcham_simd_la_OBJECTS) \
$(libcrc_simd_la_OBJECTS) \
$(libdonna_sse_la_OBJECTS) \
$(libgcm_simd_la_OBJECTS) \
$(libgf2n_simd_la_OBJECTS) \
$(libkeccak_simd_la_OBJECTS) \
$(liblea_simd_la_OBJECTS) \
$(libneon_simd_la_OBJECTS) \
$(libppc_simd_la_OBJECTS) \
$(libppc_power7_la_OBJECTS) \
$(libppc_power8_la_OBJECTS) \
$(libppc_power9_la_OBJECTS) \
$(librijndael_simd_la_OBJECTS) \
$(libsha_simd_la_OBJECTS) \
$(libshacal2_simd_la_OBJECTS) \
$(libsimon128_simd_la_OBJECTS) \
$(libspeck128_simd_la_OBJECTS) \
$(libsm4_simd_la_OBJECTS) \
$(libsse_simd_la_OBJECTS)
## ARMv7-a AES and SHA by Andy Polyakov
if CRYPTOGAMS_ARM_SOURCES
libcryptopp_la_LIBADD += $(libaes_armv4_la_OBJECTS)
libcryptopp_la_LIBADD += $(libsha1_armv4_la_OBJECTS)
libcryptopp_la_LIBADD += $(libsha256_armv4_la_OBJECTS)
libcryptopp_la_LIBADD += $(libsha512_armv4_la_OBJECTS)
endif
## cpufeatures library on Android
if ANDROID_CPU_FEATURES
libcryptopp_la_LIBADD += $(libcpu_features_la_OBJECTS)
endif
## The remainder of the object files
libcryptopp_la_LIBADD += $(libothers_la_OBJECTS)
## Don't use EXTRA_ prefix for libcryptopp_la_DEPENDENCIES. It breaks Solaris.
libcryptopp_la_DEPENDENCIES = \
$(libcryptlib_la_OBJECTS) \
$(libcpu_la_OBJECTS) \
$(libinteger_la_OBJECTS) \
$(libaria_simd_la_OBJECTS) \
$(libblake2s_simd_la_OBJECTS) \
$(libblake2b_simd_la_OBJECTS) \
$(libchacha_simd_la_OBJECTS) \
$(libchacha_avx_la_OBJECTS) \
$(libcham_simd_la_OBJECTS) \
$(libcrc_simd_la_OBJECTS) \
$(libdonna_sse_la_OBJECTS) \
$(libkeccak_simd_la_OBJECTS) \
$(liblea_simd_la_OBJECTS) \
$(libgcm_simd_la_OBJECTS) \
$(libgf2n_simd_la_OBJECTS) \
$(libneon_simd_la_OBJECTS) \
$(libppc_simd_la_OBJECTS) \
$(libppc_power7_la_OBJECTS) \
$(libppc_power8_la_OBJECTS) \
$(libppc_power9_la_OBJECTS) \
$(librijndael_simd_la_OBJECTS) \
$(libsha_simd_la_OBJECTS) \
$(libshacal2_simd_la_OBJECTS) \
$(libsimon128_simd_la_OBJECTS) \
$(libspeck128_simd_la_OBJECTS) \
$(libsm4_simd_la_OBJECTS) \
$(libsse_simd_la_OBJECTS)
## ARMv7-a AES and SHA by Andy Polyakov
if CRYPTOGAMS_ARM_SOURCES
libcryptopp_la_DEPENDENCIES += $(libaes_armv4_la_OBJECTS)
libcryptopp_la_DEPENDENCIES += $(libsha1_armv4_la_OBJECTS)
libcryptopp_la_DEPENDENCIES += $(libsha256_armv4_la_OBJECTS)
libcryptopp_la_DEPENDENCIES += $(libsha512_armv4_la_OBJECTS)
endif
## cpufeatures library on Android
if ANDROID_CPU_FEATURES
libcryptopp_la_DEPENDENCIES += $(libcpu_features_la_OBJECTS)
endif
## The remainder of the object files
libcryptopp_la_DEPENDENCIES += $(libothers_la_OBJECTS)
## Man, did Autotools fuck this up royally...
## https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
libcryptopp_la_LDFLAGS = $(AM_LDFLAGS) -release 8.5.0 -version-info 8:5
## Source files with special needs
libcryptlib_la_SOURCES = cryptlib.cpp
libcryptlib_la_CXXFLAGS = $(AM_CXXFLAGS)
libcpu_la_SOURCES = cpu.cpp
libcpu_la_CXXFLAGS = $(AM_CXXFLAGS)
libinteger_la_SOURCES = integer.cpp
libinteger_la_CXXFLAGS = $(AM_CXXFLAGS)
libaria_simd_la_SOURCES = aria_simd.cpp
libaria_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_ARIA_FLAG)
libblake2s_simd_la_SOURCES = blake2s_simd.cpp
libblake2s_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_BLAKE2S_FLAG)
libblake2b_simd_la_SOURCES = blake2b_simd.cpp
libblake2b_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_BLAKE2B_FLAG)
libchacha_simd_la_SOURCES = chacha_simd.cpp
libchacha_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_CHACHA_FLAG)
libchacha_avx_la_SOURCES = chacha_avx.cpp
libchacha_avx_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_CHACHA_AVX2_FLAG)
libcham_simd_la_SOURCES = cham_simd.cpp
libcham_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_CHAM_FLAG)
libcrc_simd_la_SOURCES = crc_simd.cpp
libcrc_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_CRC_FLAG)
libdonna_sse_la_SOURCES = donna_sse.cpp
libdonna_sse_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_DONNA_FLAG)
libgcm_simd_la_SOURCES = gcm_simd.cpp
libgcm_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_GCM_FLAG)
libgf2n_simd_la_SOURCES = gf2n_simd.cpp
libgf2n_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_GF2N_FLAG)
libkeccak_simd_la_SOURCES = keccak_simd.cpp
libkeccak_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_KECCAK_FLAG)
liblea_simd_la_SOURCES = lea_simd.cpp
liblea_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_LEA_FLAG)
libneon_simd_la_SOURCES = neon_simd.cpp
libneon_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_NEON_FLAG)
libppc_simd_la_SOURCES = ppc_simd.cpp
libppc_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_ALTIVEC_FLAG)
libppc_power7_la_SOURCES = ppc_power7.cpp
libppc_power7_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_POWER7_FLAG)
libppc_power8_la_SOURCES = ppc_power8.cpp
libppc_power8_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_POWER8_FLAG)
# Do not use CRYPTOPP_POWER9_FLAG. See https://github.com/weidai11/cryptopp/issues/986
libppc_power9_la_SOURCES = ppc_power9.cpp
# libppc_power9_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_POWER9_FLAG)
libppc_power9_la_CXXFLAGS = $(AM_CXXFLAGS)
librijndael_simd_la_SOURCES = rijndael_simd.cpp
librijndael_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_AES_FLAG)
libsha_simd_la_SOURCES = sha_simd.cpp
libsha_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_SHA_FLAG)
libshacal2_simd_la_SOURCES = shacal2_simd.cpp
libshacal2_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_SHA_FLAG)
libsimon128_simd_la_SOURCES = simon128_simd.cpp
libsimon128_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_SIMON128_FLAG)
libspeck128_simd_la_SOURCES = speck128_simd.cpp
libspeck128_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_SPECK128_FLAG)
libsm4_simd_la_SOURCES = sm4_simd.cpp
libsm4_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_SM4_FLAG)
libsse_simd_la_SOURCES = sse_simd.cpp
libsse_simd_la_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTOPP_SSE2_FLAG)
## ARMv7-a AES and SHA by Andy Polyakov
## Also see https://stackoverflow.com/q/51575580/608639
if CRYPTOGAMS_ARM_SOURCES
libaes_armv4_la_SOURCES = aes_armv4.S
libsha1_armv4_la_SOURCES = sha1_armv4.S
libsha256_armv4_la_SOURCES = sha256_armv4.S
libsha512_armv4_la_SOURCES = sha512_armv4.S
libaes_armv4_la_CCASFLAGS = $(AM_CXXFLAGS) $(CRYPTOPGAMS_ARMV4_THUMB_FLAG)
libsha1_armv4_la_CCASFLAGS = $(AM_CXXFLAGS) $(CRYPTOPGAMS_ARMV4_FLAG)
libsha256_armv4_la_CCASFLAGS = $(AM_CXXFLAGS) $(CRYPTOPGAMS_ARMV4_FLAG)
libsha512_armv4_la_CCASFLAGS = $(AM_CXXFLAGS) $(CRYPTOPGAMS_ARMV4_FLAG)
endif
## cpufeatures library on Android
if ANDROID_CPU_FEATURES
libcpu_features_la_SOURCES = cpu-features.c
endif
# This is the list of remaining sources files that don't need special order
# and don't need special flags. It is formed by removing cryptlib.cpp,
# cpu.cpp, integer.cpp, *_avx.cpp and *_simd.cpp files. It is sorted in
# alphabetical order for deterministic builds.
# To build this list, see the head notes.
libothers_la_SOURCES = \
3way.cpp adler32.cpp algebra.cpp algparam.cpp allocate.cpp arc4.cpp \
aria.cpp ariatab.cpp asn.cpp authenc.cpp base32.cpp base64.cpp \
basecode.cpp bfinit.cpp blake2.cpp blowfish.cpp blumshub.cpp \
camellia.cpp cast.cpp casts.cpp cbcmac.cpp ccm.cpp chacha.cpp \
chachapoly.cpp cham.cpp channels.cpp cmac.cpp crc.cpp darn.cpp \
default.cpp des.cpp dessp.cpp dh.cpp dh2.cpp dll.cpp donna_32.cpp \
donna_64.cpp dsa.cpp eax.cpp ec2n.cpp eccrypto.cpp ecp.cpp elgamal.cpp \
emsa2.cpp eprecomp.cpp esign.cpp files.cpp filters.cpp fips140.cpp \
fipstest.cpp gcm.cpp gf256.cpp gf2_32.cpp gf2n.cpp gfpcrypt.cpp \
gost.cpp gzip.cpp hc128.cpp hc256.cpp hex.cpp hight.cpp hmac.cpp \
hrtimer.cpp ida.cpp idea.cpp iterhash.cpp kalyna.cpp kalynatab.cpp \
keccak.cpp keccak_core.cpp lea.cpp luc.cpp mars.cpp marss.cpp md2.cpp \
md4.cpp md5.cpp misc.cpp modes.cpp mqueue.cpp mqv.cpp nbtheory.cpp \
oaep.cpp osrng.cpp padlkrng.cpp panama.cpp pkcspad.cpp poly1305.cpp \
polynomi.cpp pssr.cpp pubkey.cpp queue.cpp rabbit.cpp rabin.cpp \
randpool.cpp rc2.cpp rc5.cpp rc6.cpp rdrand.cpp rdtables.cpp \
rijndael.cpp ripemd.cpp rng.cpp rsa.cpp rw.cpp safer.cpp salsa.cpp \
scrypt.cpp seal.cpp seed.cpp serpent.cpp sha.cpp sha3.cpp shacal2.cpp \
shake.cpp shark.cpp sharkbox.cpp simeck.cpp simon.cpp skipjack.cpp \
sm3.cpp sm4.cpp sosemanuk.cpp speck.cpp square.cpp squaretb.cpp \
strciphr.cpp tea.cpp tftables.cpp threefish.cpp tiger.cpp tigertab.cpp \
ttmac.cpp tweetnacl.cpp twofish.cpp vmac.cpp wake.cpp whrlpool.cpp \
xed25519.cpp xtr.cpp xtrcrypt.cpp xts.cpp zdeflate.cpp zinflate.cpp \
zlib.cpp
# To build this list, see the head notes.
pkginclude_HEADERS = \
3way.h adler32.h adv_simd.h aes.h algebra.h algparam.h allocate.h \
arc4.h argnames.h aria.h arm_simd.h asn.h authenc.h base32.h base64.h \
basecode.h blake2.h blowfish.h blumshub.h camellia.h cast.h cbcmac.h \
ccm.h chacha.h chachapoly.h cham.h channels.h cmac.h config.h \
config_align.h config_asm.h config_cpu.h config_cxx.h config_dll.h \
config_int.h config_misc.h config_ns.h config_os.h config_ver.h cpu.h \
crc.h cryptlib.h darn.h default.h des.h dh.h dh2.h dll.h dmac.h donna.h \
donna_32.h donna_64.h donna_sse.h drbg.h dsa.h eax.h ec2n.h eccrypto.h \
ecp.h ecpoint.h elgamal.h emsa2.h eprecomp.h esign.h fhmqv.h files.h \
filters.h fips140.h fltrimpl.h gcm.h gf256.h gf2_32.h gf2n.h gfpcrypt.h \
gost.h gzip.h hashfwd.h hc128.h hc256.h hex.h hight.h hkdf.h hmac.h \
hmqv.h hrtimer.h ida.h idea.h integer.h iterhash.h kalyna.h keccak.h \
lea.h local.h lubyrack.h luc.h mars.h md2.h md4.h md5.h mdc.h \
mersenne.h misc.h modarith.h modes.h modexppc.h mqueue.h mqv.h \
naclite.h nbtheory.h nr.h oaep.h oids.h osrng.h ossig.h padlkrng.h \
panama.h pch.h pkcspad.h poly1305.h polynomi.h ppc_simd.h pssr.h \
pubkey.h pwdbased.h queue.h rabbit.h rabin.h randpool.h rc2.h rc5.h \
rc6.h rdrand.h rijndael.h ripemd.h rng.h rsa.h rw.h safer.h salsa.h \
scrypt.h seal.h secblock.h secblockfwd.h seckey.h seed.h serpent.h \
serpentp.h sha.h sha3.h shacal2.h shake.h shark.h simeck.h simon.h \
simple.h siphash.h skipjack.h sm3.h sm4.h smartptr.h sosemanuk.h \
speck.h square.h stdcpp.h strciphr.h tea.h threefish.h tiger.h trap.h \
trunhash.h ttmac.h tweetnacl.h twofish.h vmac.h wake.h whrlpool.h \
words.h xed25519.h xtr.h xtrcrypt.h xts.h zdeflate.h zinflate.h zlib.h
noinst_HEADERS = \
local.h \
bench.h \
factory.h \
resource.h \
validate.h \
aes_armv4.h \
sha1_armv4.h \
sha256_armv4.h \
sha512_armv4.h
bin_PROGRAMS = cryptest$(EXEEXT)
cryptest_CXXFLAGS = $(AM_CXXFLAGS) $(CRYPTEST_CXXFLAGS) -DCRYPTOPP_DATA_DIR='"${pkgdatadir}/"'
cryptest_SOURCES = \
test.cpp bench1.cpp bench2.cpp bench3.cpp datatest.cpp \
dlltest.cpp fipsalgt.cpp validat0.cpp validat1.cpp validat2.cpp \
validat3.cpp validat4.cpp validat5.cpp validat6.cpp validat7.cpp \
validat8.cpp validat9.cpp validat10.cpp regtest1.cpp regtest2.cpp \
regtest3.cpp regtest4.cpp
nodist_cryptest_SOURCES = adhoc.cpp
cryptest_LDADD = $(lib_LTLIBRARIES)
CLEANFILES = adhoc.cpp
## Copy the TestVectors/ and TestData/ to ${pkgdatadir}.
## TestPrograms/ is included in the tarball but not installed.
## https://www.gnu.org/software/automake/manual/html_node/Data.html
# Create with 'ls TestData/*.dat'. These files get installed.
testdata_FILES = \
TestData/3desval.dat TestData/fhmqv160.dat TestData/rc2val.dat \
TestData/3wayval.dat TestData/fhmqv256.dat TestData/rc5val.dat \
TestData/aria.dat TestData/fhmqv384.dat TestData/rc6val.dat \
TestData/camellia.dat TestData/fhmqv512.dat TestData/rijndael.dat \
TestData/cast128v.dat TestData/gostval.dat TestData/rsa1024.dat \
TestData/cast256v.dat TestData/hmqv160.dat TestData/rsa2048a.dat \
TestData/defdmac1.bin TestData/hmqv256.dat TestData/rsa2048.dat \
TestData/defdmac2.bin TestData/hmqv384.dat TestData/rsa400pb.dat \
TestData/descert.dat TestData/hmqv512.dat TestData/rsa400pv.dat \
TestData/dh1024.dat TestData/ideaval.dat TestData/rsa512a.dat \
TestData/dh2048.dat TestData/luc1024.dat TestData/rw1024.dat \
TestData/dlie1024.dat TestData/luc2048.dat TestData/rw2048.dat \
TestData/dlie2048.dat TestData/lucc1024.dat TestData/saferval.dat \
TestData/dsa1024b.dat TestData/lucc512.dat TestData/serpentv.dat \
TestData/dsa1024.dat TestData/lucd1024.dat TestData/shacal2v.dat \
TestData/dsa512.dat TestData/lucd512.dat TestData/sharkval.dat \
TestData/ecies_p160.dat TestData/lucs1024.dat TestData/skipjack.dat \
TestData/ecies_t163.dat TestData/lucs512.dat TestData/squareva.dat \
TestData/ed25519.dat TestData/marsval.dat TestData/twofishv.dat \
TestData/ed25519v0.dat TestData/mqv1024.dat TestData/usage.dat \
TestData/ed25519v1.dat TestData/mqv2048.dat TestData/x25519.dat \
TestData/elgc1024.dat TestData/nr1024.dat TestData/x25519v0.dat \
TestData/esig1023.dat TestData/nr2048.dat TestData/x25519v1.dat \
TestData/esig1536.dat TestData/rabi1024.dat TestData/xtrdh171.dat \
TestData/esig2046.dat TestData/rabi2048.dat TestData/xtrdh342.dat
# Create with 'ls TestVectors/*.txt'. These files get installed.
testvector_FILES = \
TestVectors/aead.txt TestVectors/rsa_pss.txt \
TestVectors/aes.txt TestVectors/rw.txt \
TestVectors/all.txt TestVectors/salsa.txt \
TestVectors/aria.txt TestVectors/seal.txt \
TestVectors/blake2b.txt TestVectors/seed.txt \
TestVectors/blake2s.txt TestVectors/sha1_160_fips_180.txt \
TestVectors/blake2.txt TestVectors/sha1_fips_180.txt \
TestVectors/camellia.txt TestVectors/sha2_224_fips_180.txt \
TestVectors/ccm.txt TestVectors/sha2_256_fips_180.txt \
TestVectors/chacha20poly1305.txt TestVectors/sha2_384_fips_180.txt \
TestVectors/chacha_tls.txt TestVectors/sha2_512_fips_180.txt \
TestVectors/chacha.txt TestVectors/sha2_fips_180.txt \
TestVectors/cham.txt TestVectors/sha2.txt \
TestVectors/cmac.txt TestVectors/sha3_224_fips_202.txt \
TestVectors/dlies.txt TestVectors/sha3_256_fips_202.txt \
TestVectors/dsa_1363.txt TestVectors/sha3_384_fips_202.txt \
TestVectors/dsa_rfc6979.txt TestVectors/sha3_512_fips_202.txt \
TestVectors/dsa.txt TestVectors/sha3_fips_202.txt \
TestVectors/eax.txt TestVectors/sha3.txt \
TestVectors/esign.txt TestVectors/shacal2.txt \
TestVectors/gcm.txt TestVectors/shake.txt \
TestVectors/hc128.txt TestVectors/sha.txt \
TestVectors/hc256.txt TestVectors/simeck.txt \
TestVectors/hight.txt TestVectors/simon.txt \
TestVectors/hkdf.txt TestVectors/siphash.txt \
TestVectors/hmac.txt TestVectors/skipjack.txt \
TestVectors/kalyna.txt TestVectors/sm3.txt \
TestVectors/keccak.txt TestVectors/sm4.txt \
TestVectors/lea.txt TestVectors/sosemanuk.txt \
TestVectors/mars.txt TestVectors/speck.txt \
TestVectors/nr.txt TestVectors/tea.txt \
TestVectors/panama.txt TestVectors/threefish.txt \
TestVectors/poly1305aes.txt TestVectors/ttmac.txt \
TestVectors/poly1305_tls.txt TestVectors/vmac.txt \
TestVectors/rabbit.txt TestVectors/wake.txt \
TestVectors/Readme.txt TestVectors/whrlpool.txt \
TestVectors/rsa_oaep.txt TestVectors/xchacha.txt \
TestVectors/rsa_pkcs1_1_5.txt TestVectors/xts.txt
# Create with 'ls TestPrograms/test_*.cxx'. These files do not get installed.
# They exist so the feature tests can be run from the configure directory.
testprogs_FILES= \
TestPrograms/test_32bit.cxx
TestPrograms/test_64bit.cxx
TestPrograms/test_arm_acle_header.cxx
TestPrograms/test_arm_aes.cxx
TestPrograms/test_arm_asimd.cxx
TestPrograms/test_arm_crc.cxx
TestPrograms/test_arm_neon.cxx
TestPrograms/test_arm_neon_header.cxx
TestPrograms/test_arm_pmull.cxx
TestPrograms/test_arm_sha1.cxx
TestPrograms/test_arm_sha256.cxx
TestPrograms/test_arm_sha3.cxx
TestPrograms/test_arm_sha512.cxx
TestPrograms/test_arm_sm3.cxx
TestPrograms/test_arm_sm4.cxx
TestPrograms/test_asm_mixed.cxx
TestPrograms/test_cxx11_alignas.cxx
TestPrograms/test_cxx11_alignof.cxx
TestPrograms/test_cxx11_assert.cxx
TestPrograms/test_cxx11_atomic.cxx
TestPrograms/test_cxx11_auto.cxx
TestPrograms/test_cxx11_constexpr.cxx
TestPrograms/test_cxx11.cxx
TestPrograms/test_cxx11_deletefn.cxx
TestPrograms/test_cxx11_enumtype.cxx
TestPrograms/test_cxx11_initializer.cxx
TestPrograms/test_cxx11_lambda.cxx
TestPrograms/test_cxx11_noexcept.cxx
TestPrograms/test_cxx11_nullptr.cxx
TestPrograms/test_cxx11_staticinit.cxx
TestPrograms/test_cxx11_sync.cxx
TestPrograms/test_cxx11_vartemplates.cxx
TestPrograms/test_cxx14.cxx
TestPrograms/test_cxx17_assert.cxx
TestPrograms/test_cxx17.cxx
TestPrograms/test_cxx17_exceptions.cxx
TestPrograms/test_cxx98_exception.cxx
TestPrograms/test_cxx.cxx
TestPrograms/test_glibc.cxx
TestPrograms/test_newlib.cxx
TestPrograms/test_ppc_aes.cxx
TestPrograms/test_ppc_altivec.cxx
TestPrograms/test_ppc_power7.cxx
TestPrograms/test_ppc_power8.cxx
TestPrograms/test_ppc_power9.cxx
TestPrograms/test_ppc_sha.cxx
TestPrograms/test_ppc_vmull.cxx
TestPrograms/test_pthreads.cxx
TestPrograms/test_x86_aes.cxx
TestPrograms/test_x86_avx2.cxx
TestPrograms/test_x86_avx512.cxx
TestPrograms/test_x86_avx.cxx
TestPrograms/test_x86_clmul.cxx
TestPrograms/test_x86_cpuid.cxx
TestPrograms/test_x86_rdrand.cxx
TestPrograms/test_x86_rdseed.cxx
TestPrograms/test_x86_sha.cxx
TestPrograms/test_x86_sse2.cxx
TestPrograms/test_x86_sse3.cxx
TestPrograms/test_x86_sse41.cxx
TestPrograms/test_x86_sse42.cxx
TestPrograms/test_x86_ssse3.cxx
TestPrograms/test_x86_via_aes.cxx
TestPrograms/test_x86_via_rng.cxx
TestPrograms/test_x86_via_sha.cxx
nobase_dist_pkgdata_DATA = \
$(testdata_FILES) \
$(testvector_FILES)
# Can't seem to get this to work, despite the fiddling attempts.
# https://www.gnu.org/software/automake/manual/html_node/Uniform.html and
# https://www.gnu.org/software/automake/manual/html_node/Program-and-Library-Variables.html
#nobase_noinst_data_DATA = \
# $(testprogs_FILES)
# Workaround Automake bug. We can't seem to include the TestProgram/ data
# in the tarball without installation using their Uniform Naming Scheme
# https://www.gnu.org/software/automake/manual/html_node/Uniform.html and
# https://www.gnu.org/software/automake/manual/html_node/Program-and-Library-Variables.html
dist-hook:
chmod -R u+w $(distdir)
cp -r TestPrograms/ $(distdir)
rm -f $(distdir)/TestPrograms/dump2def.cxx
## Automake bug workaround. If libcryptopp_la_SOURCES is an empty list, Automake assumes
## C source files and drives link through the C compiler. We provide the empty adhoc.cpp
## to get things back on course, so adhoc.cpp must always be copied.
adhoc.cpp:
cp adhoc.cpp.proto adhoc.cpp
touch adhoc.cpp
## Remove doc directory if present
distclean-local:
-rm -rf html-docs doxyfile.stamp
## Automake does not properly uninstall the library test data and vectors
uninstall-hook:
-rm -rf ${pkgdatadir}
-rm -rf ${pkghtmldir}
## Doxygen is available but not built by default
## TODO: copy docs to ${pkghtmldir} if built
if CRYPTOPP_DOXYGEN_AVAILABLE
## PHONY targets. Automake can only handle one of them...
.PHONY: doc docs html htmldoc checkout reset
doc docs html htmldoc:
$(DOXYGEN) Doxyfile -d CRYPTOPP_DOXYGEN_PROCESSING
endif
# Restore GNUmakefile
checkout:
git checkout master -f
# Restore GNUmakefile
reset:
git reset --hard HEAD

File diff suppressed because it is too large Load Diff

View File

@@ -1,31 +0,0 @@
## libcryptopp.pc.in - Autotools package configuration file for Crypto++.
## written and placed in public domain by Jeffrey Walton.
## based on Debian package configuration by László Böszörményi.
##
## libdir=@libdir@ is not working as expected for Fedora, Solaris,
## and other 64-bit OSes that use library directories like /lib64,
## /usr/lib64, /lib/amd64 and friends. Also see:
## * https://stackoverflow.com/q/47124066/608639
## * https://stackoverflow.com/q/46847939/608639 and
## * https://bugzilla.redhat.com/show_bug.cgi?id=1510073.
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: @PACKAGE_NAME@
Description: free C++ class library of cryptographic schemes
Authors: originally written by Wei Dai
Maintainers: the Crypto++ community
URL: @PACKAGE_URL@
Version: @PACKAGE_VERSION@
Bug-Report: @PACKAGE_BUGREPORT@
Requires:
## These flags are mostly broken. We cannot record user choices,
## and then have user programs use the same flags later.
## https://lists.freedesktop.org/archives/pkg-config/2017-November/001087.html
Cflags: -I${includedir}
Libs: -L${libdir} -lcryptopp

View File

@@ -16,6 +16,7 @@
package congestion
import (
"fmt"
mrand "math/rand"
"sync"
"time"
@@ -60,13 +61,13 @@ const (
)
const (
timeFormat = "15:04:05.999"
maxDatagramSize = 1500
// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
// Does not inflate the pacing rate.
//
// We use TCP initial CWND specified in RFC 6928.
defaultMinimumCongestionWindow = 10 * maxDatagramSize
defaultMinimumCongestionWindow = 16 * maxDatagramSize
defaultInitialCongestionWindow = 32 * maxDatagramSize
@@ -121,16 +122,24 @@ type AckedPacketInfo struct {
ReceiveTimestamp time.Time
}
func (i AckedPacketInfo) String() string {
return fmt.Sprintf("AckedPacketInfo{PacketNumber=%d, BytesAcked=%d, ReceiveTimestamp=%s}", i.PacketNumber, i.BytesAcked, i.ReceiveTimestamp.Format(timeFormat))
}
type LostPacketInfo struct {
PacketNumber int64
BytesLost int64
}
func (i LostPacketInfo) String() string {
return fmt.Sprintf("LostPacketInfo{PacketNumber=%d, BytesLost=%d}", i.PacketNumber, i.BytesLost)
}
type BBRSender struct {
mu sync.Mutex
// Additional context of this BBRSender. Used in the log.
logContext string
loggingContext string
rttStats *RTTStats
@@ -290,10 +299,9 @@ type BBRSender struct {
minRTTSinceLastProbeRTT time.Duration
}
func NewBBRSender(logContext string) *BBRSender {
return &BBRSender{
logContext: logContext,
rttStats: NewRTTStats(),
func NewBBRSender(loggingContext string, rttStats *RTTStats) *BBRSender {
s := &BBRSender{
loggingContext: loggingContext,
mode: modeStartUp,
sampler: NewBandwidthSampler(),
maxBandwidth: NewWindowedFilter(bandwidthFilterWindowSize, 0, MaxFilter[int64]),
@@ -312,6 +320,12 @@ func NewBBRSender(logContext string) *BBRSender {
initialConservationInStartup: stateConservation,
minRTTSinceLastProbeRTT: infDuration,
}
if rttStats != nil {
s.rttStats = rttStats
} else {
s.rttStats = NewRTTStats()
}
return s
}
func (b *BBRSender) SetInitialCongestionWindowInPackets(congestionWindow int64) {
@@ -326,6 +340,10 @@ func (b *BBRSender) InSlowStart() bool {
}
func (b *BBRSender) OnPacketSent(sentTime time.Time, bytesInFlight int64, packetNumber int64, bytes int64, hasRetransmittableData bool) {
if log.IsLevelEnabled(log.TraceLevel) {
log.Tracef("[BBRSender %s] OnPacketSent(bytesInFlight=%d, packetNumber=%d, bytes=%d)", b.loggingContext, bytesInFlight, packetNumber, bytes)
}
b.mu.Lock()
defer b.mu.Unlock()
@@ -390,6 +408,17 @@ func (b *BBRSender) AdjustNetworkParameters(bandwidth int64, rtt time.Duration)
}
func (b *BBRSender) OnCongestionEvent(priorInFlight int64, eventTime time.Time, ackedPackets []AckedPacketInfo, lostPackets []LostPacketInfo) {
for _, ack := range ackedPackets {
if log.IsLevelEnabled(log.TraceLevel) {
log.Tracef("[BBRSender %s] OnCongestionEvent(priorInFlight=%d, ackedPacket=%v)", b.loggingContext, priorInFlight, ack)
}
}
for _, lost := range lostPackets {
if log.IsLevelEnabled(log.TraceLevel) {
log.Tracef("[BBRSender %s] OnCongestionEvent(priorInFlight=%d, lostPacket=%v)", b.loggingContext, priorInFlight, lost)
}
}
b.mu.Lock()
defer b.mu.Unlock()
@@ -535,10 +564,10 @@ func (b *BBRSender) UpdateBandwidthAndMinRTT(now time.Time, ackedPackets []Acked
for _, acked := range ackedPackets {
bandwidthSample := b.sampler.OnPacketAcknowledged(now, acked.PacketNumber)
if log.IsLevelEnabled(log.TraceLevel) {
log.Tracef("[BBRSender %s] Acknowledged packet %d produced %v", b.logContext, acked.PacketNumber, bandwidthSample)
log.Tracef("[BBRSender %s] Acknowledged packet %d produced %v", b.loggingContext, acked.PacketNumber, bandwidthSample)
}
if bandwidthSample.bandwidth < 0 {
log.Debugf("[BBRSender %s] Acknowledged packet %d produced negative bandwidth %d B/s. Sample is dropped.", b.logContext, acked.PacketNumber, bandwidthSample.bandwidth)
log.Debugf("[BBRSender %s] Acknowledged packet %d produced negative bandwidth %d B/s. Sample is dropped.", b.loggingContext, acked.PacketNumber, bandwidthSample.bandwidth)
continue
}
b.lastSampleIsAppLimited = bandwidthSample.isAppLimited

View File

@@ -133,7 +133,7 @@ func TestBBRSender(t *testing.T) {
s := &sender{
ctx: ctx,
rwc: e1,
bbr: congestion.NewBBRSender("Test"),
bbr: congestion.NewBBRSender("Test", nil),
}
r := &receiver{
ctx: ctx,

View File

@@ -109,9 +109,10 @@ type Session struct {
uploadBytes metrics.Metric // number of bytes from client to server, only used by server
downloadBytes metrics.Metric // number of bytes from server to client, only used by server
rttStat *congestion.RTTStats
sendAlgorithm *congestion.CubicSendAlgorithm
remoteWindowSize uint16
rttStat *congestion.RTTStats
legacysendAlgorithm *congestion.CubicSendAlgorithm
sendAlgorithm *congestion.BBRSender
remoteWindowSize uint16
wg sync.WaitGroup
rLock sync.Mutex
@@ -129,29 +130,30 @@ func NewSession(id uint32, isClient bool, mtu int) *Session {
rttStat.SetMaxAckDelay(outputLoopInterval)
rttStat.SetRTOMultiplier(txTimeoutBackOff)
return &Session{
conn: nil,
block: nil,
id: id,
isClient: isClient,
mtu: mtu,
state: sessionInit,
status: statusOK,
ready: make(chan struct{}),
done: make(chan struct{}),
readDeadline: time.Time{},
writeDeadline: time.Time{},
inputErr: make(chan error, 2), // allow nested
outputErr: make(chan error, 2), // allow nested
sendQueue: newSegmentTree(segmentTreeCapacity),
sendBuf: newSegmentTree(segmentTreeCapacity),
recvBuf: newSegmentTree(segmentTreeCapacity),
recvQueue: newSegmentTree(segmentTreeCapacity),
recvChan: make(chan *segment, segmentChanCapacity),
lastRXTime: time.Now(),
lastTXTime: time.Now(),
rttStat: rttStat,
sendAlgorithm: congestion.NewCubicSendAlgorithm(minWindowSize, maxWindowSize),
remoteWindowSize: minWindowSize,
conn: nil,
block: nil,
id: id,
isClient: isClient,
mtu: mtu,
state: sessionInit,
status: statusOK,
ready: make(chan struct{}),
done: make(chan struct{}),
readDeadline: time.Time{},
writeDeadline: time.Time{},
inputErr: make(chan error, 2), // allow nested
outputErr: make(chan error, 2), // allow nested
sendQueue: newSegmentTree(segmentTreeCapacity),
sendBuf: newSegmentTree(segmentTreeCapacity),
recvBuf: newSegmentTree(segmentTreeCapacity),
recvQueue: newSegmentTree(segmentTreeCapacity),
recvChan: make(chan *segment, segmentChanCapacity),
lastRXTime: time.Now(),
lastTXTime: time.Now(),
rttStat: rttStat,
legacysendAlgorithm: congestion.NewCubicSendAlgorithm(minWindowSize, maxWindowSize),
sendAlgorithm: congestion.NewBBRSender(fmt.Sprintf("%d", id), rttStat),
remoteWindowSize: minWindowSize,
}
}
@@ -508,7 +510,7 @@ func (s *Session) writeChunk(b []byte) (n int, err error) {
sessionID: s.id,
seq: s.nextSend,
unAckSeq: s.nextRecv,
windowSize: uint16(mathext.Max(0, int(s.sendAlgorithm.CongestionWindowSize())-s.recvBuf.Len())),
windowSize: uint16(mathext.Max(0, int(s.legacysendAlgorithm.CongestionWindowSize())-s.recvBuf.Len())),
fragment: uint8(i),
payloadLen: uint16(partLen),
},
@@ -598,7 +600,9 @@ func (s *Session) runOutputLoop(ctx context.Context) error {
// Resend segments in sendBuf.
// To avoid deadlock, session can't be closed inside Ascend().
var bytesInFlight int64
s.sendBuf.Ascend(func(iter *segment) bool {
bytesInFlight += int64(udpOverhead + len(iter.payload))
if iter.txCount >= txCountLimit {
err := fmt.Errorf("too many retransmission of %v", iter)
log.Debugf("%v is unhealthy: %v", s, err)
@@ -635,22 +639,14 @@ func (s *Session) runOutputLoop(ctx context.Context) error {
s.Close()
}
if hasLoss || hasTimeout {
s.sendAlgorithm.OnLoss() // OnTimeout() is too aggressive.
s.legacysendAlgorithm.OnLoss() // OnTimeout() is too aggressive.
}
// Send new segments in sendQueue.
segmentMoved := 0
if s.sendQueue.Len() > 0 {
maxSegmentToMove := mathext.Min(s.sendQueue.Len(), s.sendBuf.Remaining())
maxSegmentToMove = mathext.Min(maxSegmentToMove, int(s.sendAlgorithm.CongestionWindowSize())-s.sendBuf.Len())
maxSegmentToMove = mathext.Min(maxSegmentToMove, int(s.remoteWindowSize))
for {
seg, deleted := s.sendQueue.DeleteMinIf(func(iter *segment) bool {
if segmentMoved >= maxSegmentToMove {
return false
}
segmentMoved++
return true
return s.sendAlgorithm.CanSend(bytesInFlight)
})
if !deleted {
break
@@ -669,6 +665,18 @@ func (s *Session) runOutputLoop(ctx context.Context) error {
s.outputErr <- err
s.Close()
break
} else {
seq, err := seg.Seq()
if err != nil {
err = fmt.Errorf("failed to get sequence number from %v: %w", seg, err)
log.Debugf("%v %v", s, err)
s.outputErr <- err
s.Close()
break
}
newBytesInFlight := int64(udpOverhead + len(seg.payload))
s.sendAlgorithm.OnPacketSent(time.Now(), bytesInFlight, int64(seq), newBytesInFlight, true)
bytesInFlight += newBytesInFlight
}
}
}
@@ -688,7 +696,7 @@ func (s *Session) runOutputLoop(ctx context.Context) error {
sessionID: s.id,
seq: uint32(mathext.Max(0, int(s.nextSend)-1)),
unAckSeq: s.nextRecv,
windowSize: uint16(mathext.Max(0, int(s.sendAlgorithm.CongestionWindowSize())-s.recvBuf.Len())),
windowSize: uint16(mathext.Max(0, int(s.legacysendAlgorithm.CongestionWindowSize())-s.recvBuf.Len())),
},
transport: s.conn.TransportProtocol(),
}
@@ -697,6 +705,17 @@ func (s *Session) runOutputLoop(ctx context.Context) error {
log.Debugf("%v %v", s, err)
s.outputErr <- err
s.Close()
} else {
seq, err := ackSeg.Seq()
if err != nil {
err = fmt.Errorf("failed to get sequence number from %v: %w", ackSeg, err)
log.Debugf("%v %v", s, err)
s.outputErr <- err
s.Close()
}
newBytesInFlight := int64(udpOverhead + len(ackSeg.payload))
s.sendAlgorithm.OnPacketSent(time.Now(), bytesInFlight, int64(seq), newBytesInFlight, true)
bytesInFlight += newBytesInFlight
}
s.ackOnDataRecv.Store(false)
}
@@ -751,9 +770,15 @@ func (s *Session) inputData(seg *segment) error {
s.recvQueue.InsertBlocking(seg)
case util.UDPTransport:
// Delete all previous acknowledged segments from sendBuf.
var priorInFlight int64
s.sendBuf.Ascend(func(iter *segment) bool {
priorInFlight += int64(udpOverhead + len(iter.payload))
return true
})
das, ok := seg.metadata.(*dataAckStruct)
if ok {
unAckSeq := das.unAckSeq
ackedPackets := make([]congestion.AckedPacketInfo, 0)
for {
seg2, deleted := s.sendBuf.DeleteMinIf(func(iter *segment) bool {
seq, _ := iter.Seq()
@@ -763,7 +788,16 @@ func (s *Session) inputData(seg *segment) error {
break
}
s.rttStat.UpdateRTT(time.Since(seg2.txTime))
s.sendAlgorithm.OnAck()
s.legacysendAlgorithm.OnAck()
seq, _ := seg2.Seq()
ackedPackets = append(ackedPackets, congestion.AckedPacketInfo{
PacketNumber: int64(seq),
BytesAcked: int64(udpOverhead + len(seg2.payload)),
ReceiveTimestamp: time.Now(),
})
}
if len(ackedPackets) > 0 {
s.sendAlgorithm.OnCongestionEvent(priorInFlight, time.Now(), ackedPackets, nil)
}
s.remoteWindowSize = das.windowSize
}
@@ -848,8 +882,14 @@ func (s *Session) inputAck(seg *segment) error {
return nil
case util.UDPTransport:
// Delete all previous acknowledged segments from sendBuf.
var priorInFlight int64
s.sendBuf.Ascend(func(iter *segment) bool {
priorInFlight += int64(udpOverhead + len(iter.payload))
return true
})
das := seg.metadata.(*dataAckStruct)
unAckSeq := das.unAckSeq
ackedPackets := make([]congestion.AckedPacketInfo, 0)
for {
seg2, deleted := s.sendBuf.DeleteMinIf(func(iter *segment) bool {
seq, _ := iter.Seq()
@@ -859,7 +899,16 @@ func (s *Session) inputAck(seg *segment) error {
break
}
s.rttStat.UpdateRTT(time.Since(seg2.txTime))
s.sendAlgorithm.OnAck()
s.legacysendAlgorithm.OnAck()
seq, _ := seg2.Seq()
ackedPackets = append(ackedPackets, congestion.AckedPacketInfo{
PacketNumber: int64(seq),
BytesAcked: int64(udpOverhead + len(seg2.payload)),
ReceiveTimestamp: time.Now(),
})
}
if len(ackedPackets) > 0 {
s.sendAlgorithm.OnCongestionEvent(priorInFlight, time.Now(), ackedPackets, nil)
}
s.remoteWindowSize = das.windowSize

View File

@@ -23,6 +23,6 @@
"activeProfile": "default",
"rpcPort": 8989,
"socks5Port": 1080,
"loggingLevel": "INFO",
"loggingLevel": "TRACE",
"socks5ListenLAN": true
}

View File

@@ -14,6 +14,6 @@
"advancedSettings": {
"allowLocalDestination": true
},
"loggingLevel": "INFO",
"loggingLevel": "TRACE",
"mtu": 1400
}

View File

@@ -155,6 +155,7 @@ jobs:
echo "BUILDTIME=$(date)" >> $GITHUB_ENV
echo "CGO_ENABLED=0" >> $GITHUB_ENV
echo "BUILDTAG=-extldflags --static" >> $GITHUB_ENV
echo "GOTOOLCHAIN=local" >> $GITHUB_ENV
- name: Setup NDK
if: ${{ matrix.jobs.goos == 'android' }}

View File

@@ -7,20 +7,20 @@ require (
github.com/bahlo/generic-list-go v0.2.0
github.com/cilium/ebpf v0.12.3
github.com/coreos/go-iptables v0.7.0
github.com/dlclark/regexp2 v1.11.0
github.com/go-chi/chi/v5 v5.0.14
github.com/dlclark/regexp2 v1.11.2
github.com/go-chi/chi/v5 v5.1.0
github.com/go-chi/cors v1.2.1
github.com/go-chi/render v1.0.3
github.com/gobwas/ws v1.4.0
github.com/gofrs/uuid/v5 v5.2.0
github.com/insomniacslk/dhcp v0.0.0-20240529192340-51bc6136a0a6
github.com/insomniacslk/dhcp v0.0.0-20240710054256-ddd8a41251c9
github.com/klauspost/compress v1.17.9
github.com/klauspost/cpuid/v2 v2.2.8
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40
github.com/mdlayher/netlink v1.7.2
github.com/metacubex/chacha v0.1.0
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759
github.com/metacubex/quic-go v0.45.1-0.20240610004319-163fee60637e
github.com/metacubex/quic-go v0.45.1-0.20240803003931-60a15f6efd94
github.com/metacubex/randv2 v0.2.0
github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72
github.com/metacubex/sing-shadowsocks v0.2.7
@@ -34,7 +34,7 @@ require (
github.com/mroth/weightedrand/v2 v2.1.0
github.com/openacid/low v0.1.21
github.com/oschwald/maxminddb-golang v1.12.0
github.com/puzpuzpuz/xsync/v3 v3.2.0
github.com/puzpuzpuz/xsync/v3 v3.4.0
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
github.com/sagernet/fswatch v0.1.1
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
@@ -42,7 +42,7 @@ require (
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6
github.com/sagernet/sing-shadowtls v0.1.4
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e
github.com/samber/lo v1.39.0
github.com/samber/lo v1.46.0
github.com/shirou/gopsutil/v3 v3.24.5
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.9.0
@@ -50,9 +50,9 @@ require (
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7
go.uber.org/automaxprocs v1.5.3
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto v0.24.0
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
golang.org/x/net v0.26.0
golang.org/x/crypto v0.25.0
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
golang.org/x/net v0.27.0
golang.org/x/sync v0.7.0
golang.org/x/sys v0.22.0
google.golang.org/protobuf v1.34.2
@@ -107,10 +107,10 @@ require (
github.com/yusufpapurcu/wmi v1.2.4 // indirect
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect
go.uber.org/mock v0.4.0 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/mod v0.19.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.22.0 // indirect
golang.org/x/tools v0.23.0 // indirect
)
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240724044459-6f3cf5896297

View File

@@ -26,8 +26,8 @@ github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFE
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dlclark/regexp2 v1.11.2 h1:/u628IuisSTwri5/UKloiIsH8+qF2Pu7xEQX+yIKg68=
github.com/dlclark/regexp2 v1.11.2/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/ericlagergren/aegis v0.0.0-20230312195928-b4ce538b56f9 h1:/5RkVc9Rc81XmMyVqawCiDyrBHZbLAZgTTCqou4mwj8=
github.com/ericlagergren/aegis v0.0.0-20230312195928-b4ce538b56f9/go.mod h1:hkIFzoiIPZYxdFOOLyDho59b7SrDfo+w3h+yWdlg45I=
github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 h1:8j2RH289RJplhA6WfdaPqzg1MjH2K8wX5e0uhAxrw2g=
@@ -42,8 +42,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
github.com/go-chi/chi/v5 v5.0.14 h1:PyEwo2Vudraa0x/Wl6eDRRW2NXBvekgfxyydcM0WGE0=
github.com/go-chi/chi/v5 v5.0.14/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
@@ -75,8 +75,8 @@ github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/insomniacslk/dhcp v0.0.0-20240529192340-51bc6136a0a6 h1:dh8D8FksyMhD64mRMbUhZHWYJfNoNMCxfVq6eexleMw=
github.com/insomniacslk/dhcp v0.0.0-20240529192340-51bc6136a0a6/go.mod h1:KclMyHxX06VrVr0DJmeFSUb1ankt7xTfoOA35pCkoic=
github.com/insomniacslk/dhcp v0.0.0-20240710054256-ddd8a41251c9 h1:LZJWucZz7ztCqY6Jsu7N9g124iJ2kt/O62j3+UchZFg=
github.com/insomniacslk/dhcp v0.0.0-20240710054256-ddd8a41251c9/go.mod h1:KclMyHxX06VrVr0DJmeFSUb1ankt7xTfoOA35pCkoic=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
@@ -103,8 +103,8 @@ 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.45.1-0.20240610004319-163fee60637e h1:bLYn3GuRvWDcBDAkIv5kUYIhzHwafDVq635BuybnKqI=
github.com/metacubex/quic-go v0.45.1-0.20240610004319-163fee60637e/go.mod h1:Yza2H7Ax1rxWPUcJx0vW+oAt9EsPuSiyQFhFabUPzwU=
github.com/metacubex/quic-go v0.45.1-0.20240803003931-60a15f6efd94 h1:wlhwgxRzPLH8Ce0VME35iD2sr7jY2gFrL299/T4C2Sg=
github.com/metacubex/quic-go v0.45.1-0.20240803003931-60a15f6efd94/go.mod h1:Yza2H7Ax1rxWPUcJx0vW+oAt9EsPuSiyQFhFabUPzwU=
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-20240724044459-6f3cf5896297 h1:YG/JkwGPbca5rUtEMHIu8ZuqzR7BSVm1iqY8hNoMeMA=
@@ -149,8 +149,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/puzpuzpuz/xsync/v3 v3.2.0 h1:9AzuUeF88YC5bK8u2vEG1Fpvu4wgpM1wfPIExfaaDxQ=
github.com/puzpuzpuz/xsync/v3 v3.2.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4=
github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs=
@@ -172,8 +172,8 @@ github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxe
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo=
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e h1:iGH0RMv2FzELOFNFQtvsxH7NPmlo7X5JizEK51UCojo=
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e/go.mod h1:YbL4TKHRR6APYQv3U2RGfwLDpPYSyWz6oUlpISBEzBE=
github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ=
github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
@@ -226,18 +226,18 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
@@ -259,15 +259,15 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=

View File

@@ -260,9 +260,9 @@ function connect_status()
local socks_port = uci:get(appname, "@global[0]", "tcp_node_socks_port")
if enabled ~= 0 then
if (chn_list == "proxy" and gfw_list == 0 and proxy_mode ~= "proxy" and baidu ~= nil) or (chn_list == 0 and gfw_list == 0 and proxy_mode == "proxy") then
url = "--socks5 127.0.0.1:" .. socks_port .. " " .. url
url = "-x socks5h://127.0.0.1:" .. socks_port .. " " .. url
elseif baidu == nil then
url = "--socks5 127.0.0.1:" .. socks_port .. " " .. url
url = "-x socks5h://127.0.0.1:" .. socks_port .. " " .. url
end
end
local result = luci.sys.exec('curl --connect-timeout 3 -o /dev/null -I -sk -w "%{http_code}:%{time_appconnect}" ' .. url)

View File

@@ -1338,15 +1338,18 @@ stop_crontab() {
start_dns() {
echolog "DNS域名解析"
local china_ng_local_dns=${LOCAL_DNS}
local direct_dns_mode=$(config_t_get global direct_dns_mode "auto")
case "$direct_dns_mode" in
udp)
LOCAL_DNS=$(config_t_get global direct_dns_udp 223.5.5.5 | sed 's/:/#/g')
china_ng_local_dns=${LOCAL_DNS}
;;
tcp)
LOCAL_DNS="127.0.0.1#${dns_listen_port}"
dns_listen_port=$(expr $dns_listen_port + 1)
local DIRECT_DNS=$(config_t_get global direct_dns_tcp 223.5.5.5 | sed 's/:/#/g')
china_ng_local_dns="tcp://${DIRECT_DNS}"
ln_run "$(first_type dns2tcp)" dns2tcp "/dev/null" -L "${LOCAL_DNS}" -R "$(get_first_dns DIRECT_DNS 53)" -v
echolog " - dns2tcp(${LOCAL_DNS}) -> tcp://$(get_first_dns DIRECT_DNS 53 | sed 's/#/:/g')"
echolog " * 请确保上游直连 DNS 支持 TCP 查询。"
@@ -1357,11 +1360,12 @@ start_dns() {
local cdns_listen_port=${dns_listen_port}
dns_listen_port=$(expr $dns_listen_port + 1)
local DIRECT_DNS=$(config_t_get global direct_dns_dot "tls://dot.pub@1.12.12.12")
china_ng_local_dns=${DIRECT_DNS}
ln_run "$(first_type chinadns-ng)" chinadns-ng "/dev/null" -b 127.0.0.1 -l ${cdns_listen_port} -c ${DIRECT_DNS} -d chn
echolog " - ChinaDNS-NG(${LOCAL_DNS}) -> ${DIRECT_DNS}"
echolog " * 请确保上游直连 DNS 支持 DoT 查询。"
else
echolog " - 你的ChinaDNS-NG版本不支持DoT直连DNS将使用默认UDP地址。"
echolog " - 你的ChinaDNS-NG版本不支持DoT直连DNS将使用默认地址。"
fi
;;
auto)
@@ -1478,8 +1482,6 @@ start_dns() {
if [ $(check_ver "$chinadns_ng_now" "$chinadns_ng_min") = 1 ]; then
echolog " * 注意:当前 ChinaDNS-NG 版本为[ $chinadns_ng_now ],请更新到[ $chinadns_ng_min ]或以上版本,否则 DNS 有可能无法正常工作!"
fi
local china_ng_local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n2 | awk -v prefix="udp://" '{ for (i=1; i<=NF; i++) print prefix $i }') | tr " " ",")
[ "$FILTER_PROXY_IPV6" = "1" ] && DNSMASQ_FILTER_PROXY_IPV6=0
[ -z "${china_ng_listen_port}" ] && local china_ng_listen_port=$(expr $dns_listen_port + 1)
@@ -1659,7 +1661,22 @@ acl_app() {
[ "$filter_proxy_ipv6" = "1" ] && dnsmasq_filter_proxy_ipv6=0
chinadns_port=$(expr $chinadns_port + 1)
_china_ng_listen="127.0.0.1#${chinadns_port}"
_chinadns_local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n2 | awk -v prefix="udp://" '{ for (i=1; i<=NF; i++) print prefix $i }') | tr " " ",")
_chinadns_local_dns=${LOCAL_DNS}
_direct_dns_mode=$(config_t_get global direct_dns_mode "auto")
case "${_direct_dns_mode}" in
udp)
_chinadns_local_dns=$(config_t_get global direct_dns_udp 223.5.5.5 | sed 's/:/#/g')
;;
tcp)
_chinadns_local_dns="tcp://$(config_t_get global direct_dns_tcp 223.5.5.5 | sed 's/:/#/g')"
;;
dot)
if [ "$(chinadns-ng -V | grep -i wolfssl)" != "nil" ]; then
_chinadns_local_dns=$(config_t_get global direct_dns_dot "tls://dot.pub@1.12.12.12")
fi
;;
esac
run_chinadns_ng \
_flag="$sid" \
@@ -1812,7 +1829,7 @@ acl_app() {
[ -n "$redirect_dns_port" ] && echo "${redirect_dns_port}" > $TMP_ACL_PATH/$sid/var_redirect_dns_port
unset enabled sid remarks sources use_global_config tcp_node udp_node use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode filter_proxy_ipv6 dns_mode remote_dns v2ray_dns_mode remote_dns_doh dns_client_ip
unset _ip _mac _iprange _ipset _ip_or_mac rule_list tcp_port udp_port config_file _extra_param
unset _china_ng_listen _chinadns_local_dns chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6
unset _china_ng_listen _chinadns_local_dns _direct_dns_mode chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6
unset redirect_dns_port
done
unset socks_port redir_port dns_port dnsmasq_port chinadns_port

View File

@@ -266,8 +266,18 @@ namespace Ryujinx.UI.App.Common
public bool TryGetApplicationsFromFile(string applicationPath, out List<ApplicationData> applications)
{
applications = [];
long fileSize;
long fileSize = new FileInfo(applicationPath).Length;
try
{
fileSize = new FileInfo(applicationPath).Length;
}
catch (FileNotFoundException)
{
Logger.Warning?.Print(LogClass.Application, $"The file was not found: '{applicationPath}'");
return false;
}
BlitStruct<ApplicationControlProperty> controlHolder = new(1);
@@ -502,7 +512,13 @@ namespace Ryujinx.UI.App.Common
try
{
IEnumerable<string> files = Directory.EnumerateFiles(appDir, "*", SearchOption.AllDirectories).Where(file =>
EnumerationOptions options = new()
{
RecurseSubdirectories = true,
IgnoreInaccessible = false,
};
IEnumerable<string> files = Directory.EnumerateFiles(appDir, "*", options).Where(file =>
{
return
(Path.GetExtension(file).ToLower() is ".nsp" && ConfigurationState.Instance.UI.ShownFileTypes.NSP.Value) ||
@@ -521,14 +537,18 @@ namespace Ryujinx.UI.App.Common
}
var fileInfo = new FileInfo(app);
string extension = fileInfo.Extension.ToLower();
if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden) && extension is ".nsp" or ".pfs0" or ".xci" or ".nca" or ".nro" or ".nso")
try
{
var fullPath = fileInfo.ResolveLinkTarget(true)?.FullName ?? fileInfo.FullName;
applicationPaths.Add(fullPath);
numApplicationsFound++;
}
catch (IOException exception)
{
Logger.Warning?.Print(LogClass.Application, $"Failed to resolve the full path to file: \"{app}\" Error: {exception}");
}
}
}
catch (UnauthorizedAccessException)

View File

@@ -53,8 +53,11 @@ use super::{
target_os = "freebsd"
))]
pub struct BatchSendMessage<'a> {
/// Optional target address
pub addr: Option<SocketAddr>,
/// Data to be transmitted
pub data: &'a [IoSlice<'a>],
/// Output result. The number of bytes sent by `batch_send`
pub data_len: usize,
}
@@ -67,8 +70,11 @@ pub struct BatchSendMessage<'a> {
target_os = "freebsd"
))]
pub struct BatchRecvMessage<'a> {
/// Peer address
pub addr: SocketAddr,
/// Data buffer for receiving
pub data: &'a mut [IoSliceMut<'a>],
/// Output result. The number of bytes received by `batch_recv`
pub data_len: usize,
}

View File

@@ -222,7 +222,7 @@ impl ProxySocket {
.map_err(Into::into)
}
/// Send a UDP packet to addr through proxy
/// Send a UDP packet to addr through proxy with `ControlData`
pub async fn send_with_ctrl(
&self,
addr: &Address,
@@ -261,11 +261,19 @@ impl ProxySocket {
}
/// poll family functions
/// the send_timeout is ignored.
///
/// Send a UDP packet to addr through proxy
///
/// NOTE: the `send_timeout` is ignored.
pub fn poll_send(&self, addr: &Address, payload: &[u8], cx: &mut Context<'_>) -> Poll<ProxySocketResult<usize>> {
self.poll_send_with_ctrl(addr, &DEFAULT_SOCKET_CONTROL, payload, cx)
}
/// poll family functions
///
/// Send a UDP packet to addr through proxy with `ControlData`
///
/// NOTE: the `send_timeout` is ignored.
pub fn poll_send_with_ctrl(
&self,
addr: &Address,
@@ -299,6 +307,11 @@ impl ProxySocket {
}
}
/// poll family functions
///
/// Send a UDP packet to addr through proxy `target`
///
/// NOTE: the `send_timeout` is ignored.
pub fn poll_send_to(
&self,
target: SocketAddr,
@@ -309,6 +322,11 @@ impl ProxySocket {
self.poll_send_to_with_ctrl(target, addr, &DEFAULT_SOCKET_CONTROL, payload, cx)
}
/// poll family functions
///
/// Send a UDP packet to addr through proxy `target` with `ControlData`
///
/// NOTE: the `send_timeout` is ignored.
pub fn poll_send_to_with_ctrl(
&self,
target: SocketAddr,
@@ -341,11 +359,14 @@ impl ProxySocket {
}
}
/// poll family functions
///
/// Check if socket is ready to `send`, or writable.
pub fn poll_send_ready(&self, cx: &mut Context<'_>) -> Poll<ProxySocketResult<()>> {
self.socket.poll_send_ready(cx).map_err(|x| x.into())
}
/// Send a UDP packet to target from proxy
/// Send a UDP packet to target through proxy `target`
pub async fn send_to<A: ToSocketAddrs>(
&self,
target: A,
@@ -357,7 +378,7 @@ impl ProxySocket {
.map_err(Into::into)
}
/// Send a UDP packet to target from proxy
/// Send a UDP packet to target through proxy `target`
pub async fn send_to_with_ctrl<A: ToSocketAddrs>(
&self,
target: A,

View File

@@ -24,7 +24,7 @@ require (
github.com/sagernet/fswatch v0.1.1
github.com/sagernet/gomobile v0.1.3
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f
github.com/sagernet/quic-go v0.45.1-beta.2
github.com/sagernet/quic-go v0.45.2-beta.1
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.5.0-alpha.14
github.com/sagernet/sing-dns v0.3.0-beta.14

View File

@@ -110,8 +110,8 @@ github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZN
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=
github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8=
github.com/sagernet/quic-go v0.45.1-beta.2 h1:zkEeCbhdFFkrxKcuIRBtXNKci/1t2J/39QSG/sPvlmc=
github.com/sagernet/quic-go v0.45.1-beta.2/go.mod h1:+N3FqM9DAzOWfe64uxXuBejVJwX7DeW7BslzLO6N/xI=
github.com/sagernet/quic-go v0.45.2-beta.1 h1:Gu/vYzKZI7EZItGSkCnatod8c32Nq1hzM5jqCYuc3aY=
github.com/sagernet/quic-go v0.45.2-beta.1/go.mod h1:+N3FqM9DAzOWfe64uxXuBejVJwX7DeW7BslzLO6N/xI=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=

View File

@@ -9,26 +9,25 @@ replace github.com/sagernet/sing-box => ../
require (
github.com/docker/docker v24.0.7+incompatible
github.com/docker/go-connections v0.4.0
github.com/gofrs/uuid/v5 v5.0.0
github.com/sagernet/quic-go v0.40.0
github.com/sagernet/sing v0.2.20-0.20231212123824-8836b6754226
github.com/sagernet/sing-dns v0.1.11
github.com/sagernet/sing-quic v0.1.6-0.20231207143711-eb3cbf9ed054
github.com/sagernet/sing-shadowsocks v0.2.6
github.com/sagernet/sing-shadowsocks2 v0.1.6-0.20231207143709-50439739601a
github.com/gofrs/uuid/v5 v5.2.0
github.com/sagernet/quic-go v0.45.1-beta.2
github.com/sagernet/sing v0.4.2
github.com/sagernet/sing-dns v0.2.3
github.com/sagernet/sing-quic v0.2.0-beta.12
github.com/sagernet/sing-shadowsocks v0.2.7
github.com/sagernet/sing-shadowsocks2 v0.2.0
github.com/spyzhov/ajson v0.9.0
github.com/stretchr/testify v1.8.4
github.com/stretchr/testify v1.9.0
go.uber.org/goleak v1.3.0
golang.org/x/net v0.19.0
golang.org/x/net v0.25.0
)
require (
berty.tech/go-libtor v1.0.385 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ajg/form v1.5.1 // indirect
github.com/andybalholm/brotli v1.0.6 // indirect
github.com/caddyserver/certmagic v0.20.0 // indirect
github.com/cloudflare/circl v1.3.6 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/cretz/bine v0.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/distribution/reference v0.5.0 // indirect
@@ -36,28 +35,23 @@ require (
github.com/docker/go-units v0.5.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gaukas/godicttls v0.0.4 // indirect
github.com/go-chi/chi/v5 v5.0.10 // indirect
github.com/go-chi/cors v1.2.1 // indirect
github.com/go-chi/render v1.0.3 // indirect
github.com/go-chi/chi/v5 v5.0.12 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 // indirect
github.com/josharian/native v1.1.0 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/libdns/alidns v1.0.3 // indirect
github.com/libdns/cloudflare v0.1.0 // indirect
github.com/libdns/libdns v0.2.1 // indirect
github.com/libdns/cloudflare v0.1.1 // indirect
github.com/libdns/libdns v0.2.2 // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
github.com/mholt/acmez v1.2.0 // indirect
github.com/miekg/dns v1.1.57 // indirect
github.com/miekg/dns v1.1.59 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/onsi/ginkgo/v2 v2.9.7 // indirect
@@ -65,43 +59,41 @@ require (
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/oschwald/maxminddb-golang v1.12.0 // indirect
github.com/pierrec/lz4/v4 v4.1.14 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a // indirect
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1 // indirect
github.com/sagernet/gvisor v0.0.0-20231209105102-8d27a30e436e // indirect
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f // indirect
github.com/sagernet/netlink v0.0.0-20240523065131-45e60152f9ba // indirect
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
github.com/sagernet/sing-mux v0.1.6-0.20231208180947-9053c29513a2 // indirect
github.com/sagernet/sing-mux v0.2.0 // indirect
github.com/sagernet/sing-shadowtls v0.1.4 // indirect
github.com/sagernet/sing-tun v0.1.24-0.20231212060935-6a1419aeae11 // indirect
github.com/sagernet/sing-vmess v0.1.8 // indirect
github.com/sagernet/sing-tun v0.3.2 // indirect
github.com/sagernet/sing-vmess v0.1.12 // indirect
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect
github.com/sagernet/tfo-go v0.0.0-20231209031829-7b5343ac1dc6 // indirect
github.com/sagernet/utls v1.5.4 // indirect
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e // indirect
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8 // indirect
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 // indirect
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 // indirect
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0 // indirect
go.uber.org/zap v1.27.0 // indirect
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
golang.org/x/crypto v0.16.0 // indirect
golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.16.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/grpc v1.63.2 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.1 // indirect
lukechampine.com/blake3 v1.2.1 // indirect
lukechampine.com/blake3 v1.3.0 // indirect
)

View File

@@ -3,14 +3,12 @@ berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+f
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc=
github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
github.com/cloudflare/circl v1.3.6 h1:/xbKIqSHbZXHwkhbrhrt2YOHIwYJlXH94E3tI/gDlUg=
github.com/cloudflare/circl v1.3.6/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cretz/bine v0.1.0/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw=
github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo=
github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbetI=
@@ -31,12 +29,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
@@ -46,26 +40,18 @@ github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/gofrs/uuid/v5 v5.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM=
github.com/gofrs/uuid/v5 v5.2.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a h1:fEBsGL/sjAuJrgah5XqmmYsTLzJp/TO9Lhy39gkverk=
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA=
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI=
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
@@ -76,17 +62,17 @@ github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZY
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/libdns/alidns v1.0.3 h1:LFHuGnbseq5+HCeGa1aW8awyX/4M2psB9962fdD2+yQ=
github.com/libdns/alidns v1.0.3/go.mod h1:e18uAG6GanfRhcJj6/tps2rCMzQJaYVcGKT+ELjdjGE=
github.com/libdns/cloudflare v0.1.0 h1:93WkJaGaiXCe353LHEP36kAWCUw0YjFqwhkBkU2/iic=
github.com/libdns/cloudflare v0.1.0/go.mod h1:a44IP6J1YH6nvcNl1PverfJviADgXUnsozR3a7vBKN8=
github.com/libdns/cloudflare v0.1.1 h1:FVPfWwP8zZCqj268LZjmkDleXlHPlFU9KC4OJ3yn054=
github.com/libdns/cloudflare v0.1.1/go.mod h1:9VK91idpOjg6v7/WbjkEW49bSCxj00ALesIFDhJ8PBU=
github.com/libdns/libdns v0.2.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
@@ -103,8 +89,6 @@ github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrB
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs=
github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY=
github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -117,55 +101,51 @@ github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a h1:+NkI2670SQpQWvkk
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM=
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1 h1:YbmpqPQEMdlk9oFSKYWRqVuu9qzNiOayIonKmv1gCXY=
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1/go.mod h1:J2yAxTFPDjrDPhuAi9aWFz2L3ox9it4qAluBBbN0H5k=
github.com/sagernet/gvisor v0.0.0-20231209105102-8d27a30e436e h1:DOkjByVeAR56dkszjnMZke4wr7yM/1xHaJF3G9olkEE=
github.com/sagernet/gvisor v0.0.0-20231209105102-8d27a30e436e/go.mod h1:fLxq/gtp0qzkaEwywlRRiGmjOK5ES/xUzyIKIFP2Asw=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/quic-go v0.40.0 h1:DvQNPb72lzvNQDe9tcUyHTw8eRv6PLtM2mNYmdlzUMo=
github.com/sagernet/quic-go v0.40.0/go.mod h1:VqtdhlbkeeG5Okhb3eDMb/9o0EoglReHunNT9ukrJAI=
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f h1:NkhuupzH5ch7b/Y/6ZHJWrnNLoiNnSJaow6DPb8VW2I=
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f/go.mod h1:KXmw+ouSJNOsuRpg4wgwwCQuunrGz4yoAqQjsLjc6N0=
github.com/sagernet/netlink v0.0.0-20240523065131-45e60152f9ba h1:EY5AS7CCtfmARNv2zXUOrsEMPFDGYxaw65JzA2p51Vk=
github.com/sagernet/netlink v0.0.0-20240523065131-45e60152f9ba/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/quic-go v0.45.1-beta.2 h1:zkEeCbhdFFkrxKcuIRBtXNKci/1t2J/39QSG/sPvlmc=
github.com/sagernet/quic-go v0.45.1-beta.2/go.mod h1:+N3FqM9DAzOWfe64uxXuBejVJwX7DeW7BslzLO6N/xI=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
github.com/sagernet/sing v0.2.20-0.20231212123824-8836b6754226 h1:rcII71ho6F/7Nyx7n2kESLcnvNMdcU4i8ZUGF2Fi7yA=
github.com/sagernet/sing v0.2.20-0.20231212123824-8836b6754226/go.mod h1:Ce5LNojQOgOiWhiD8pPD6E9H7e2KgtOe3Zxx4Ou5u80=
github.com/sagernet/sing-dns v0.1.11 h1:PPrMCVVrAeR3f5X23I+cmvacXJ+kzuyAsBiWyUKhGSE=
github.com/sagernet/sing-dns v0.1.11/go.mod h1:zJ/YjnYB61SYE+ubMcMqVdpaSvsyQ2iShQGO3vuLvvE=
github.com/sagernet/sing-mux v0.1.6-0.20231208180947-9053c29513a2 h1:rRlYQPbMKmzKX+43XC04gEQvxc45/AxfteRWfcl2/rw=
github.com/sagernet/sing-mux v0.1.6-0.20231208180947-9053c29513a2/go.mod h1:IdSrwwqBeJTrjLZJRFXE+F8mYXNI/rPAjzlgTFuEVmo=
github.com/sagernet/sing-quic v0.1.6-0.20231207143711-eb3cbf9ed054 h1:Ed7FskwQcep5oQ+QahgVK0F6jPPSV8Nqwjr9MwGatMU=
github.com/sagernet/sing-quic v0.1.6-0.20231207143711-eb3cbf9ed054/go.mod h1:u758WWv3G1OITG365CYblL0NfAruFL1PpLD9DUVTv1o=
github.com/sagernet/sing-shadowsocks v0.2.6 h1:xr7ylAS/q1cQYS8oxKKajhuQcchd5VJJ4K4UZrrpp0s=
github.com/sagernet/sing-shadowsocks v0.2.6/go.mod h1:j2YZBIpWIuElPFL/5sJAj470bcn/3QQ5lxZUNKLDNAM=
github.com/sagernet/sing-shadowsocks2 v0.1.6-0.20231207143709-50439739601a h1:uYIKfpE1/EJpa+1Bja7b006VixeRuVduOpeuesMk2lU=
github.com/sagernet/sing-shadowsocks2 v0.1.6-0.20231207143709-50439739601a/go.mod h1:pjeylQ4ApvpEH7B4PUBrdyJf4xmQkg8BaIzT5fI2fR0=
github.com/sagernet/sing v0.4.2 h1:jzGNJdZVRI0xlAfFugsIQUPvyB9SuWvbJK7zQCXc4QM=
github.com/sagernet/sing v0.4.2/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls=
github.com/sagernet/sing-dns v0.2.3 h1:YzeBUn2tR38F7HtvGEQ0kLRLmZWMEgi/+7wqa4Twb1k=
github.com/sagernet/sing-dns v0.2.3/go.mod h1:BJpJv6XLnrUbSyIntOT6DG9FW0f4fETmPAHvNjOprLg=
github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo=
github.com/sagernet/sing-mux v0.2.0/go.mod h1:khzr9AOPocLa+g53dBplwNDz4gdsyx/YM3swtAhlkHQ=
github.com/sagernet/sing-quic v0.2.0-beta.12 h1:BhvA5mmrDFEyDUQB5eeu+9UhF+ieyuNJ5Rsb0dAG3QY=
github.com/sagernet/sing-quic v0.2.0-beta.12/go.mod h1:YVpLfVi8BvYM7NMrjmnvcRm3E8iMETf1gFQmTQDN9jI=
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg=
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
github.com/sagernet/sing-tun v0.1.24-0.20231212060935-6a1419aeae11 h1:crTOVPJGOGWOW+Q2a0FQiiS/G2+W6uCLKtOofFMisQc=
github.com/sagernet/sing-tun v0.1.24-0.20231212060935-6a1419aeae11/go.mod h1:DgXPnBqtqWrZj37Mun/W61dW0Q56eLqTZYhcuNLaCtY=
github.com/sagernet/sing-vmess v0.1.8 h1:XVWad1RpTy9b5tPxdm5MCU8cGfrTGdR8qCq6HV2aCNc=
github.com/sagernet/sing-vmess v0.1.8/go.mod h1:vhx32UNzTDUkNwOyIjcZQohre1CaytquC5mPplId8uA=
github.com/sagernet/sing-tun v0.3.2 h1:z0bLUT/YXH9RrJS9DsIpB0Bb9afl2hVJOmHd0zA3HJY=
github.com/sagernet/sing-tun v0.3.2/go.mod h1:DxLIyhjWU/HwGYoX0vNGg2c5QgTQIakphU1MuERR5tQ=
github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg=
github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I=
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo=
github.com/sagernet/tfo-go v0.0.0-20231209031829-7b5343ac1dc6 h1:z3SJQhVyU63FT26Wn/UByW6b7q8QKB0ZkPqsyqcz2PI=
github.com/sagernet/tfo-go v0.0.0-20231209031829-7b5343ac1dc6/go.mod h1:73xRZuxwkFk4aiLw28hG8W6o9cr2UPrGL9pdY2UTbvY=
github.com/sagernet/utls v1.5.4 h1:KmsEGbB2dKUtCNC+44NwAdNAqnqQ6GA4pTO0Yik56co=
github.com/sagernet/utls v1.5.4/go.mod h1:CTGxPWExIloRipK3XFpYv0OVyhO8kk3XCGW/ieyTh1s=
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e h1:iGH0RMv2FzELOFNFQtvsxH7NPmlo7X5JizEK51UCojo=
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e/go.mod h1:YbL4TKHRR6APYQv3U2RGfwLDpPYSyWz6oUlpISBEzBE=
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8 h1:R0OMYAScomNAVpTfbHFpxqJpvwuhxSRi+g6z7gZhABs=
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8/go.mod h1:K4J7/npM+VAMUeUmTa2JaA02JmyheP0GpRBOUvn3ecc=
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc=
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA=
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 h1:rc/CcqLH3lh8n+csdOuDfP+NuykE0U6AeYSJJHKDgSg=
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9/go.mod h1:a/83NAfUXvEuLpmxDssAXxgUgrEy12MId3Wd7OTs76s=
github.com/spyzhov/ajson v0.9.0 h1:tF46gJGOenYVj+k9K1U1XpCxVWhmiyY5PsVCAs1+OJ0=
github.com/spyzhov/ajson v0.9.0/go.mod h1:a6oSw0MMb7Z5aD2tPoPO+jq11ETKgXUr2XktHdT8Wt8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA=
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -180,8 +160,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -189,26 +169,27 @@ golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaE
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No=
golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY=
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -216,40 +197,37 @@ golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@@ -257,5 +235,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=

View File

@@ -1,354 +0,0 @@
package main
import (
"net/netip"
"testing"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/transport/vless"
)
func TestVLESSVisionReality(t *testing.T) {
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
userUUID := newUUID()
startInstance(t, option.Options{
Inbounds: []option.Inbound{
{
Type: C.TypeMixed,
Tag: "mixed-in",
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: clientPort,
},
},
},
{
Type: C.TypeVLESS,
VLESSOptions: option.VLESSInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: serverPort,
},
Users: []option.VLESSUser{
{
Name: "sekai",
UUID: userUUID.String(),
Flow: vless.FlowVision,
},
},
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
TLS: &option.InboundTLSOptions{
Enabled: true,
ServerName: "google.com",
Reality: &option.InboundRealityOptions{
Enabled: true,
Handshake: option.InboundRealityHandshakeOptions{
ServerOptions: option.ServerOptions{
Server: "google.com",
ServerPort: 443,
},
},
ShortID: []string{"0123456789abcdef"},
PrivateKey: "UuMBgl7MXTPx9inmQp2UC7Jcnwc6XYbwDNebonM-FCc",
},
},
},
},
},
{
Type: C.TypeTrojan,
Tag: "trojan",
TrojanOptions: option.TrojanInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: otherPort,
},
Users: []option.TrojanUser{
{
Name: "sekai",
Password: userUUID.String(),
},
},
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
TLS: &option.InboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
KeyPath: keyPem,
},
},
},
},
},
Outbounds: []option.Outbound{
{
Type: C.TypeDirect,
},
{
Type: C.TypeTrojan,
Tag: "trojan-out",
TrojanOptions: option.TrojanOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: otherPort,
},
Password: userUUID.String(),
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
TLS: &option.OutboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
},
},
DialerOptions: option.DialerOptions{
Detour: "vless-out",
},
},
},
{
Type: C.TypeVLESS,
Tag: "vless-out",
VLESSOptions: option.VLESSOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: serverPort,
},
UUID: userUUID.String(),
Flow: vless.FlowVision,
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
TLS: &option.OutboundTLSOptions{
Enabled: true,
ServerName: "google.com",
Reality: &option.OutboundRealityOptions{
Enabled: true,
ShortID: "0123456789abcdef",
PublicKey: "jNXHt1yRo0vDuchQlIP6Z0ZvjT3KtzVI-T4E7RoLJS0",
},
UTLS: &option.OutboundUTLSOptions{
Enabled: true,
},
},
},
},
},
},
Route: &option.RouteOptions{
Rules: []option.Rule{
{
DefaultOptions: option.DefaultRule{
Inbound: []string{"mixed-in"},
Outbound: "trojan-out",
},
},
},
},
})
testSuit(t, clientPort, testPort)
}
func TestVLESSVisionRealityPlain(t *testing.T) {
userUUID := newUUID()
startInstance(t, option.Options{
Inbounds: []option.Inbound{
{
Type: C.TypeMixed,
Tag: "mixed-in",
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: clientPort,
},
},
},
{
Type: C.TypeVLESS,
VLESSOptions: option.VLESSInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: serverPort,
},
Users: []option.VLESSUser{
{
Name: "sekai",
UUID: userUUID.String(),
Flow: vless.FlowVision,
},
},
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
TLS: &option.InboundTLSOptions{
Enabled: true,
ServerName: "google.com",
Reality: &option.InboundRealityOptions{
Enabled: true,
Handshake: option.InboundRealityHandshakeOptions{
ServerOptions: option.ServerOptions{
Server: "google.com",
ServerPort: 443,
},
},
ShortID: []string{"0123456789abcdef"},
PrivateKey: "UuMBgl7MXTPx9inmQp2UC7Jcnwc6XYbwDNebonM-FCc",
},
},
},
},
},
},
Outbounds: []option.Outbound{
{
Type: C.TypeDirect,
},
{
Type: C.TypeVLESS,
Tag: "vless-out",
VLESSOptions: option.VLESSOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: serverPort,
},
UUID: userUUID.String(),
Flow: vless.FlowVision,
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
TLS: &option.OutboundTLSOptions{
Enabled: true,
ServerName: "google.com",
Reality: &option.OutboundRealityOptions{
Enabled: true,
ShortID: "0123456789abcdef",
PublicKey: "jNXHt1yRo0vDuchQlIP6Z0ZvjT3KtzVI-T4E7RoLJS0",
},
UTLS: &option.OutboundUTLSOptions{
Enabled: true,
},
},
},
},
},
},
Route: &option.RouteOptions{
Rules: []option.Rule{
{
DefaultOptions: option.DefaultRule{
Inbound: []string{"mixed-in"},
Outbound: "vless-out",
},
},
},
},
})
testSuit(t, clientPort, testPort)
}
func TestVLESSRealityTransport(t *testing.T) {
t.Run("grpc", func(t *testing.T) {
testVLESSRealityTransport(t, &option.V2RayTransportOptions{
Type: C.V2RayTransportTypeGRPC,
})
})
t.Run("websocket", func(t *testing.T) {
testVLESSRealityTransport(t, &option.V2RayTransportOptions{
Type: C.V2RayTransportTypeWebsocket,
})
})
t.Run("h2", func(t *testing.T) {
testVLESSRealityTransport(t, &option.V2RayTransportOptions{
Type: C.V2RayTransportTypeHTTP,
})
})
}
func testVLESSRealityTransport(t *testing.T, transport *option.V2RayTransportOptions) {
userUUID := newUUID()
startInstance(t, option.Options{
Inbounds: []option.Inbound{
{
Type: C.TypeMixed,
Tag: "mixed-in",
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: clientPort,
},
},
},
{
Type: C.TypeVLESS,
VLESSOptions: option.VLESSInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: serverPort,
},
Users: []option.VLESSUser{
{
Name: "sekai",
UUID: userUUID.String(),
},
},
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
TLS: &option.InboundTLSOptions{
Enabled: true,
ServerName: "google.com",
Reality: &option.InboundRealityOptions{
Enabled: true,
Handshake: option.InboundRealityHandshakeOptions{
ServerOptions: option.ServerOptions{
Server: "google.com",
ServerPort: 443,
},
},
ShortID: []string{"0123456789abcdef"},
PrivateKey: "UuMBgl7MXTPx9inmQp2UC7Jcnwc6XYbwDNebonM-FCc",
},
},
},
Transport: transport,
},
},
},
Outbounds: []option.Outbound{
{
Type: C.TypeDirect,
},
{
Type: C.TypeVLESS,
Tag: "vless-out",
VLESSOptions: option.VLESSOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: serverPort,
},
UUID: userUUID.String(),
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
TLS: &option.OutboundTLSOptions{
Enabled: true,
ServerName: "google.com",
Reality: &option.OutboundRealityOptions{
Enabled: true,
ShortID: "0123456789abcdef",
PublicKey: "jNXHt1yRo0vDuchQlIP6Z0ZvjT3KtzVI-T4E7RoLJS0",
},
UTLS: &option.OutboundUTLSOptions{
Enabled: true,
},
},
},
Transport: transport,
},
},
},
Route: &option.RouteOptions{
Rules: []option.Rule{
{
DefaultOptions: option.DefaultRule{
Inbound: []string{"mixed-in"},
Outbound: "vless-out",
},
},
},
},
})
testSuit(t, clientPort, testPort)
}

View File

@@ -1,559 +0,0 @@
package main
import (
"net/netip"
"os"
"testing"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/transport/vless"
"github.com/gofrs/uuid/v5"
"github.com/spyzhov/ajson"
"github.com/stretchr/testify/require"
)
func TestVLESS(t *testing.T) {
content, err := os.ReadFile("config/vless-server.json")
require.NoError(t, err)
config, err := ajson.Unmarshal(content)
require.NoError(t, err)
user := newUUID()
inbound := config.MustKey("inbounds").MustIndex(0)
inbound.MustKey("port").SetNumeric(float64(serverPort))
inbound.MustKey("settings").MustKey("clients").MustIndex(0).MustKey("id").SetString(user.String())
content, err = ajson.Marshal(config)
require.NoError(t, err)
startDockerContainer(t, DockerOptions{
Image: ImageV2RayCore,
Ports: []uint16{serverPort},
EntryPoint: "v2ray",
Cmd: []string{"run"},
Stdin: content,
})
startInstance(t, option.Options{
Inbounds: []option.Inbound{
{
Type: C.TypeMixed,
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: clientPort,
},
},
},
},
Outbounds: []option.Outbound{
{
Type: C.TypeVLESS,
VLESSOptions: option.VLESSOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: serverPort,
},
UUID: user.String(),
},
},
},
})
testTCP(t, clientPort, testPort)
}
func TestVLESSXRay(t *testing.T) {
t.Run("origin", func(t *testing.T) {
testVLESSXrayOutbound(t, "", "")
})
t.Run("xudp", func(t *testing.T) {
testVLESSXrayOutbound(t, "xudp", "")
})
t.Run("vision", func(t *testing.T) {
testVLESSXrayOutbound(t, "xudp", vless.FlowVision)
})
}
func testVLESSXrayOutbound(t *testing.T, packetEncoding string, flow string) {
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
content, err := os.ReadFile("config/vless-tls-server.json")
require.NoError(t, err)
config, err := ajson.Unmarshal(content)
require.NoError(t, err)
userID := newUUID()
inbound := config.MustKey("inbounds").MustIndex(0)
inbound.MustKey("port").SetNumeric(float64(serverPort))
user := inbound.MustKey("settings").MustKey("clients").MustIndex(0)
user.MustKey("id").SetString(userID.String())
user.MustKey("flow").SetString(flow)
content, err = ajson.Marshal(config)
require.NoError(t, err)
startDockerContainer(t, DockerOptions{
Image: ImageXRayCore,
Ports: []uint16{serverPort},
EntryPoint: "xray",
Stdin: content,
Bind: map[string]string{
certPem: "/path/to/certificate.crt",
keyPem: "/path/to/private.key",
},
})
startInstance(t, option.Options{
Inbounds: []option.Inbound{
{
Type: C.TypeMixed,
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: clientPort,
},
},
},
{
Type: C.TypeTrojan,
Tag: "trojan",
TrojanOptions: option.TrojanInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: otherPort,
},
Users: []option.TrojanUser{
{
Name: "sekai",
Password: userID.String(),
},
},
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
TLS: &option.InboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
KeyPath: keyPem,
},
},
},
},
},
Outbounds: []option.Outbound{
{
Type: C.TypeTrojan,
TrojanOptions: option.TrojanOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "host.docker.internal",
ServerPort: otherPort,
},
Password: userID.String(),
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
TLS: &option.OutboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
},
},
DialerOptions: option.DialerOptions{
Detour: "vless",
},
},
},
{
Type: C.TypeVLESS,
Tag: "vless",
VLESSOptions: option.VLESSOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: serverPort,
},
UUID: userID.String(),
Flow: flow,
PacketEncoding: &packetEncoding,
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
TLS: &option.OutboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
},
},
},
},
{
Type: C.TypeDirect,
Tag: "direct",
},
},
Route: &option.RouteOptions{
Rules: []option.Rule{
{
DefaultOptions: option.DefaultRule{
Inbound: []string{"trojan"},
Outbound: "direct",
},
},
},
},
})
testSuit(t, clientPort, testPort)
}
func TestVLESSSelf(t *testing.T) {
t.Run("origin", func(t *testing.T) {
testVLESSSelf(t, "")
})
t.Run("vision", func(t *testing.T) {
testVLESSSelf(t, vless.FlowVision)
})
t.Run("vision-tls", func(t *testing.T) {
testVLESSSelfTLS(t, vless.FlowVision)
})
}
func testVLESSSelf(t *testing.T, flow string) {
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
userUUID := newUUID()
startInstance(t, option.Options{
Inbounds: []option.Inbound{
{
Type: C.TypeMixed,
Tag: "mixed-in",
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: clientPort,
},
},
},
{
Type: C.TypeVLESS,
VLESSOptions: option.VLESSInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: serverPort,
},
Users: []option.VLESSUser{
{
Name: "sekai",
UUID: userUUID.String(),
Flow: flow,
},
},
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
TLS: &option.InboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
KeyPath: keyPem,
},
},
},
},
},
Outbounds: []option.Outbound{
{
Type: C.TypeDirect,
},
{
Type: C.TypeVLESS,
Tag: "vless-out",
VLESSOptions: option.VLESSOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: serverPort,
},
UUID: userUUID.String(),
Flow: flow,
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
TLS: &option.OutboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
},
},
},
},
},
Route: &option.RouteOptions{
Rules: []option.Rule{
{
DefaultOptions: option.DefaultRule{
Inbound: []string{"mixed-in"},
Outbound: "vless-out",
},
},
},
},
})
testSuit(t, clientPort, testPort)
}
func testVLESSSelfTLS(t *testing.T, flow string) {
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
userUUID := newUUID()
startInstance(t, option.Options{
Inbounds: []option.Inbound{
{
Type: C.TypeMixed,
Tag: "mixed-in",
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: clientPort,
},
},
},
{
Type: C.TypeVLESS,
VLESSOptions: option.VLESSInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: serverPort,
},
Users: []option.VLESSUser{
{
Name: "sekai",
UUID: userUUID.String(),
Flow: flow,
},
},
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
TLS: &option.InboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
KeyPath: keyPem,
},
},
},
},
{
Type: C.TypeTrojan,
Tag: "trojan",
TrojanOptions: option.TrojanInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: otherPort,
},
Users: []option.TrojanUser{
{
Name: "sekai",
Password: userUUID.String(),
},
},
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
TLS: &option.InboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
KeyPath: keyPem,
},
},
},
},
},
Outbounds: []option.Outbound{
{
Type: C.TypeDirect,
},
{
Type: C.TypeTrojan,
Tag: "trojan-out",
TrojanOptions: option.TrojanOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: otherPort,
},
Password: userUUID.String(),
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
TLS: &option.OutboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
},
},
DialerOptions: option.DialerOptions{
Detour: "vless-out",
},
},
},
{
Type: C.TypeVLESS,
Tag: "vless-out",
VLESSOptions: option.VLESSOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: serverPort,
},
UUID: userUUID.String(),
Flow: flow,
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
TLS: &option.OutboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
},
},
},
},
},
Route: &option.RouteOptions{
Rules: []option.Rule{
{
DefaultOptions: option.DefaultRule{
Inbound: []string{"mixed-in"},
Outbound: "trojan-out",
},
},
},
},
})
testSuit(t, clientPort, testPort)
}
func TestVLESSXrayInbound(t *testing.T) {
testVLESSXrayInbound(t, vless.FlowVision)
}
func testVLESSXrayInbound(t *testing.T, flow string) {
userId, err := uuid.DefaultGenerator.NewV4()
require.NoError(t, err)
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startInstance(t, option.Options{
Inbounds: []option.Inbound{
{
Type: C.TypeVLESS,
VLESSOptions: option.VLESSInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: serverPort,
},
Users: []option.VLESSUser{
{
Name: "sekai",
UUID: userId.String(),
Flow: flow,
},
},
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
TLS: &option.InboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
KeyPath: keyPem,
},
},
},
},
{
Type: C.TypeTrojan,
Tag: "trojan",
TrojanOptions: option.TrojanInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: otherPort,
},
Users: []option.TrojanUser{
{
Name: "sekai",
Password: userId.String(),
},
},
InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
TLS: &option.InboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
KeyPath: keyPem,
},
},
},
},
},
})
startInstance(t, option.Options{
Inbounds: []option.Inbound{
{
Type: C.TypeMixed,
Tag: "mixed-in",
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: otherClientPort,
},
},
},
},
Outbounds: []option.Outbound{
{
Type: C.TypeTrojan,
Tag: "trojan-out",
TrojanOptions: option.TrojanOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: otherPort,
},
Password: userId.String(),
OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
TLS: &option.OutboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
},
},
DialerOptions: option.DialerOptions{
Detour: "vless-out",
},
},
},
{
Type: C.TypeSOCKS,
Tag: "vless-out",
SocksOptions: option.SocksOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: clientPort,
},
},
},
},
})
content, err := os.ReadFile("config/vless-tls-client.json")
require.NoError(t, err)
config, err := ajson.Unmarshal(content)
require.NoError(t, err)
config.MustKey("inbounds").MustIndex(0).MustKey("port").SetNumeric(float64(clientPort))
outbound := config.MustKey("outbounds").MustIndex(0)
settings := outbound.MustKey("settings").MustKey("vnext").MustIndex(0)
settings.MustKey("port").SetNumeric(float64(serverPort))
user := settings.MustKey("users").MustIndex(0)
user.MustKey("id").SetString(userId.String())
user.MustKey("flow").SetString(flow)
content, err = ajson.Marshal(config)
require.NoError(t, err)
content, err = ajson.Marshal(config)
require.NoError(t, err)
startDockerContainer(t, DockerOptions{
Image: ImageXRayCore,
Ports: []uint16{clientPort},
EntryPoint: "xray",
Stdin: content,
Bind: map[string]string{
certPem: "/path/to/certificate.crt",
keyPem: "/path/to/private.key",
},
})
testTCP(t, otherClientPort, testPort)
}

View File

@@ -1,12 +1,14 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-mosdns
PKG_VERSION:=1.5.23
PKG_VERSION:=1.6.0
PKG_RELEASE:=1
LUCI_TITLE:=LuCI Support for mosdns
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+mosdns +jsonfilter +luci-compat +curl +v2ray-geoip +v2ray-geosite +v2dat
LUCI_DEPENDS:=+mosdns +jsonfilter +curl +v2ray-geoip +v2ray-geosite +v2dat
PKG_MAINTAINER:=sbwml <admin@cooluc.com>
define Package/$(PKG_NAME)/conffiles
/etc/config/mosdns

View File

@@ -0,0 +1,359 @@
'use strict';
'require form';
'require fs';
'require poll';
'require rpc';
'require uci';
'require ui';
'require view';
var callServiceList = rpc.declare({
object: 'service',
method: 'list',
params: ['name'],
expect: { '': {} }
});
function getServiceStatus() {
return L.resolveDefault(callServiceList('mosdns'), {}).then(function (res) {
var isRunning = false;
try {
isRunning = res['mosdns']['instances']['mosdns']['running'];
} catch (e) { }
return isRunning;
});
}
function renderStatus(isRunning) {
var spanTemp = '<em><span style="color:%s"><strong>%s %s</strong></span></em>';
var renderHTML;
if (isRunning) {
renderHTML = spanTemp.format('green', _('MosDNS'), _('RUNNING'));
} else {
renderHTML = spanTemp.format('red', _('MosDNS'), _('NOT RUNNING'));
}
return renderHTML;
}
return view.extend({
handleFlushCache: function (m, section_id, ev) {
return fs.exec('/usr/share/mosdns/mosdns.sh', ['flush'])
.then(function (lazy_cache) {
var res = lazy_cache.code;
if (res === 0) {
ui.addNotification(null, E('p', _('Flushing DNS Cache Success.')), 'info');
} else {
ui.addNotification(null, E('p', _('Flushing DNS Cache Failed, Please check if MosDNS is running.')), 'error');
}
});
},
render: function () {
var m, s, o;
m = new form.Map('mosdns', _('MosDNS'),
_('MosDNS is a plugin-based DNS forwarder/traffic splitter.'));
s = m.section(form.TypedSection);
s.anonymous = true;
s.render = function () {
poll.add(function () {
return L.resolveDefault(getServiceStatus()).then(function (res) {
var view = document.getElementById('service_status');
view.innerHTML = renderStatus(res);
});
});
return E('div', { class: 'cbi-section', id: 'status_bar' }, [
E('p', { id: 'service_status' }, _('Collecting data...'))
]);
}
s = m.section(form.NamedSection, 'config', 'mosdns');
s.tab('basic', _('Basic Options'));
s.tab("advanced", _("Advanced Options"));
s.tab("cloudflare", _("Cloudflare Options"));
s.tab("api", _("API Options"));
s.tab('geodata', _('GeoData Export'));
/* basic */
o = s.taboption('basic', form.Flag, 'enabled', _('Enabled'));
o.default = o.disabled;
o.rmempty = false;
o = s.taboption('basic', form.ListValue, 'configfile', _('Config File'));
o.value('/var/etc/mosdns.json', _('Default Config'));
o.value('/etc/mosdns/config_custom.yaml', _('Custom Config'));
o.default = '/var/etc/mosdns.json';
o = s.taboption('basic', form.Value, 'listen_port', _('Listen port'));
o.default = '5335';
o.datatype = 'port';
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('basic', form.ListValue, 'log_level', _('Log Level'));
o.value('debug', _('Debug'));
o.value('info', _('Info'));
o.value('warn', _('Warning'));
o.value('error', _('Error'));
o.default = 'info';
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('basic', form.Value, 'log_file', _('Log File'));
o.placeholder = '/var/log/mosdns.log';
o.default = '/var/log/mosdns.log';
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('basic', form.Flag, 'redirect', _('DNS Forward'), _('Forward Dnsmasq Domain Name resolution requests to MosDNS'));
o.default = false;
o = s.taboption('basic', form.Flag, 'prefer_ipv4', _('Remote DNS prefer IPv4'),
_('IPv4 is preferred for Remote / Streaming Media DNS resolution of dual-stack addresses, and is not affected when the destination is IPv6 only'));
o.depends('configfile', '/var/etc/mosdns.json');
o.default = false;
o = s.taboption('basic', form.Flag, 'custom_local_dns', _('Custom China DNS'), _('Follow WAN interface DNS if not enabled'));
o.depends('configfile', '/var/etc/mosdns.json');
o.default = false;
o = s.taboption('basic', form.Flag, 'apple_optimization', _('Apple domains optimization'),
_('For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses'));
o.depends('custom_local_dns', '1');
o.default = false;
o = s.taboption('basic', form.DynamicList, 'local_dns', _('China DNS server'));
o.value('119.29.29.29', _('Tencent Public DNS (119.29.29.29)'));
o.value('119.28.28.28', _('Tencent Public DNS (119.28.28.28)'));
o.value('223.5.5.5', _('Aliyun Public DNS (223.5.5.5)'));
o.value('223.6.6.6', _('Aliyun Public DNS (223.6.6.6)'));
o.value('180.184.1.1', _('TrafficRoute Public DNS (180.184.1.1)'));
o.value('180.184.2.2', _('TrafficRoute Public DNS (180.184.2.2)'));
o.value('114.114.114.114', _('Xinfeng Public DNS (114.114.114.114)'));
o.value('114.114.115.115', _('Xinfeng Public DNS (114.114.115.115)'));
o.value('180.76.76.76', _('Baidu Public DNS (180.76.76.76)'));
o.value('https://doh.pub/dns-query', _('Tencent Public DNS (DNS over HTTPS)'));
o.value('quic://dns.alidns.com', _('Aliyun Public DNS (DNS over QUIC)'));
o.value('https://dns.alidns.com/dns-query', _('Aliyun Public DNS (DNS over HTTPS)'));
o.value('h3://dns.alidns.com/dns-query', _('Aliyun Public DNS (DNS over HTTPS/3)'));
o.value('https://doh.360.cn/dns-query', _('360 Public DNS (DNS over HTTPS)'));
o.default = '119.29.29.29';
o.depends('custom_local_dns', '1');
o = s.taboption('basic', form.DynamicList, 'remote_dns', _('Remote DNS server'));
o.value('tls://1.1.1.1', _('CloudFlare Public DNS (1.1.1.1)'));
o.value('tls://1.0.0.1', _('CloudFlare Public DNS (1.0.0.1)'));
o.value('tls://8.8.8.8', _('Google Public DNS (8.8.8.8)'));
o.value('tls://8.8.4.4', _('Google Public DNS (8.8.4.4)'));
o.value('tls://9.9.9.9', _('Quad9 Public DNS (9.9.9.9)'));
o.value('tls://149.112.112.112', _('Quad9 Public DNS (149.112.112.112)'));
o.value('tls://208.67.222.222', _('Cisco Public DNS (208.67.222.222)'));
o.value('tls://208.67.220.220', _('Cisco Public DNS (208.67.220.220)'));
o.default = 'tls://8.8.8.8';
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('basic', form.Flag, 'custom_stream_media_dns', _('Custom Stream Media DNS'),
_('Netflix, Disney+, Hulu and streaming media rules list will use this DNS'));
o.depends('configfile', '/var/etc/mosdns.json');
o.default = false;
o = s.taboption('basic', form.DynamicList, 'stream_media_dns', _('Streaming Media DNS server'));
o.value('tls://1.1.1.1', _('CloudFlare Public DNS (1.1.1.1)'));
o.value('tls://1.0.0.1', _('CloudFlare Public DNS (1.0.0.1)'));
o.value('tls://8.8.8.8', _('Google Public DNS (8.8.8.8)'));
o.value('tls://8.8.4.4', _('Google Public DNS (8.8.4.4)'));
o.value('tls://9.9.9.9', _('Quad9 Public DNS (9.9.9.9)'));
o.value('tls://149.112.112.112', _('Quad9 Public DNS (149.112.112.112)'));
o.value('tls://208.67.222.222', _('Cisco Public DNS (208.67.222.222)'));
o.value('tls://208.67.220.220', _('Cisco Public DNS (208.67.220.220)'));
o.default = 'tls://8.8.8.8';
o.depends('custom_stream_media_dns', '1');
o = s.taboption('basic', form.ListValue, 'bootstrap_dns', _('Bootstrap DNS servers'),
_('Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT resolvers you specify as upstreams'));
o.value('119.29.29.29', _('Tencent Public DNS (119.29.29.29)'));
o.value('119.28.28.28', _('Tencent Public DNS (119.28.28.28)'));
o.value('223.5.5.5', _('Aliyun Public DNS (223.5.5.5)'));
o.value('223.6.6.6', _('Aliyun Public DNS (223.6.6.6)'));
o.value('114.114.114.114', _('Xinfeng Public DNS (114.114.114.114)'));
o.value('114.114.115.115', _('Xinfeng Public DNS (114.114.115.115)'));
o.value('180.76.76.76', _('Baidu Public DNS (180.76.76.76)'));
o.value('8.8.8.8', _('Google Public DNS (8.8.8.8)'));
o.value('1.1.1.1', _('CloudFlare Public DNS (1.1.1.1)'));
o.default = '119.29.29.29';
o.depends('configfile', '/var/etc/mosdns.json');
/* advanced */
o = s.taboption('advanced', form.Value, 'concurrent', _('Concurrent'),
_('DNS query request concurrency, The number of upstream DNS servers that are allowed to initiate requests at the same time'));
o.datatype = 'and(uinteger,min(1),max(3))';
o.default = '2';
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('advanced', form.Value, 'idle_timeout', _('Idle Timeout'),
_('DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)'))
o.datatype = 'and(uinteger,min(1))';
o.default = '30';
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('advanced', form.Flag, 'enable_pipeline', _('TCP/DoT Connection Multiplexing'),
_('Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode'))
o.rmempty = false;
o.default = false;
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('advanced', form.Flag, 'insecure_skip_verify', _('Disable TLS Certificate'),
_('Disable TLS Servers certificate validation, Can be useful if system CA certificate expires or the system time is out of order'));
o.rmempty = false;
o.default = false;
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('advanced', form.Flag, 'enable_ecs_remote',
_('Enable EDNS client subnet'));
o.rmempty = false;
o.default = false;
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('advanced', form.Value, 'remote_ecs_ip', _('IP Address'),
_('Please provide the IP address you use when accessing foreign websites. This IP subnet (0/24) will be used as the ECS address for Remote / Streaming Media DNS requests') +
_('This feature is typically used when using a self-built DNS server as an Remote / Streaming Media DNS upstream (requires support from the upstream server)'));
o.datatype = 'ipaddr';
o.depends('enable_ecs_remote', '1');
o = s.taboption('advanced', form.Flag, 'dns_leak', _('Prevent DNS Leaks'),
_('Enable this option fallback policy forces forwarding to remote DNS'));
o.rmempty = false;
o.default = false;
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('advanced', form.Flag, 'cache', _('Enable DNS Cache'));
o.rmempty = false;
o.default = false;
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('advanced', form.Value, 'cache_size', _('DNS Cache Size'),
_('DNS cache size (in piece). To disable caching, please set to 0.'));
o.datatype = 'and(uinteger,min(0))';
o.default = 8000;
o.depends('cache', '1');
o = s.taboption('advanced', form.Value, 'lazy_cache_ttl', _('Lazy Cache TTL'),
_('Lazy cache survival time (in second). To disable Lazy Cache, please set to 0.'));
o.datatype = 'and(uinteger,min(0))';
o.default = 86400;
o.depends('cache', '1');
o = s.taboption('advanced', form.Flag, 'dump_file', _('Cache Dump'),
_('Save the cache locally and reload the cache dump on the next startup'));
o.rmempty = false;
o.default = false;
o.depends('cache', '1');
o = s.taboption('advanced', form.Value, 'dump_interval',
_('Auto Save Cache Interval'));
o.datatype = 'and(uinteger,min(0))';
o.default = 3600;
o.depends('dump_file', '1');
o = s.taboption('advanced', form.Value, 'minimal_ttl', _('Minimum TTL'),
_('Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating no modification'));
o.datatype = 'and(uinteger,min(0),max(604800))';
o.default = 0;
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('advanced', form.Value, 'maximum_ttl', _('Maximum TTL'),
_('Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating no modification'));
o.datatype = 'and(uinteger,min(0),max(604800))';
o.default = 0;
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('advanced', form.Flag, 'adblock', _('Enable DNS ADblock'));
o.depends('configfile', '/var/etc/mosdns.json');
o.default = false;
o = s.taboption('advanced', form.DynamicList, 'ad_source', _('ADblock Source'),
_('When using custom rule sources, please use rule types supported by MosDNS (domain lists).') +
'<br>' +
_('Support for local files, such as: file:///var/mosdns/example.txt'));
o.depends('adblock', '1');
o.default = 'geosite.dat';
o.value('geosite.dat', 'v2ray-geosite');
o.value('https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt', 'anti-AD')
o.value('https://raw.githubusercontent.com/Cats-Team/AdRules/main/mosdns_adrules.txt', 'Cats-Team/AdRules')
o.value('https://raw.githubusercontent.com/neodevpro/neodevhost/master/domain', 'NEO DEV HOST')
/* cloudflare */
o = s.taboption('cloudflare', form.Flag, 'cloudflare', _('Enabled'),
_('Match the parsing result with the Cloudflare IP ranges, and when there is a successful match, \
use the \'Custom IP\' as the parsing result (experimental feature)'));
o.rmempty = false;
o.default = false;
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('cloudflare', form.DynamicList, 'cloudflare_ip', _('Custom IP'));
o.datatype = 'ipaddr';
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('cloudflare', form.TextValue, '_cloudflare',
_('Cloudflare IP Ranges'),
_('IPv4 CIDR: <a href="https://www.cloudflare.com/ips-v4" target="_blank">https://www.cloudflare.com/ips-v4</a> <br /> IPv6 CIDR: <a href="https://www.cloudflare.com/ips-v6" target="_blank">https://www.cloudflare.com/ips-v6</a>'));
o.rows = 15;
o.depends('configfile', '/var/etc/mosdns.json');
o.cfgvalue = function (section_id) {
return fs.trimmed('/etc/mosdns/rule/cloudflare-cidr.txt');
};
o.write = function (section_id, formvalue) {
return fs.write('/etc/mosdns/rule/cloudflare-cidr.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
.then(function (i) {
return fs.exec('/etc/init.d/mosdns', ['restart']);
});
};
/* api */
o = s.taboption('api', form.Value, 'listen_port_api', _('API Listen port'));
o.datatype = 'and(port,min(1))';
o.default = 9091;
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('api', form.Button, '_flush_cache', null,
_('Flushing DNS Cache will clear any IP addresses or DNS records from MosDNS cache.'));
o.title = '&#160;';
o.inputtitle = _('Flush DNS Cache');
o.inputstyle = 'apply';
o.onclick = L.bind(this.handleFlushCache, this, m);
o.depends('cache', '1');
/* configuration */
o = s.taboption('basic', form.TextValue, '_custom', _('Configuration Editor'),
_('This is the content of the file \'/etc/mosdns/config_custom.yaml\' from which your MosDNS configuration will be generated. \
Only accepts configuration content in yaml format.'));
o.rows = 25;
o.depends('configfile', '/etc/mosdns/config_custom.yaml');
o.cfgvalue = function (section_id) {
return fs.trimmed('/etc/mosdns/config_custom.yaml');
};
o.write = function (section_id, formvalue) {
return fs.write('/etc/mosdns/config_custom.yaml', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
.then(function (i) {
ui.addNotification(null, E('p', _('Configuration have been saved.')), 'info');
return fs.exec('/etc/init.d/mosdns', ['restart']);
})
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
};
o = s.taboption('geodata', form.DynamicList, 'geosite_tags', _('GeoSite Tags'),
_('Enter the GeoSite.dat category to be exported, Allow add multiple tags'),
_('Export directory: /var/mosdns'));
o.depends('configfile', '/etc/mosdns/config_custom.yaml');
o = s.taboption('geodata', form.DynamicList, 'geoip_tags', _('GeoIP Tags'),
_('Enter the GeoIP.dat category to be exported, Allow add multiple tags'),
_('Export directory: /var/mosdns'));
o.depends('configfile', '/etc/mosdns/config_custom.yaml');
return m.render();
}
});

View File

@@ -0,0 +1,77 @@
'use strict';
'require dom';
'require fs';
'require poll';
'require view';
function pollLog(e) {
return Promise.all([
fs.exec_direct('/usr/share/mosdns/mosdns.sh', ['printlog']).then(function (res) {
return res.trim().split(/\n/).join('\n')
}),
]).then(function (data) {
var logTextarea = E('textarea', { 'class': 'cbi-input-textarea', 'wrap': 'off', 'readonly': 'readonly', 'style': 'width: calc(100% - 20px);height: 645px;margin: 10px;overflow-y: scroll;' }, [
data[0] || _('No log data.')
]);
// Store the current scroll position
var storedScrollTop = e.querySelector('textarea') ? e.querySelector('textarea').scrollTop : null;
dom.content(e, logTextarea);
// If the storedScrollTop is not null, it means we have a previous scroll position
if (storedScrollTop !== null) {
logTextarea.scrollTop = storedScrollTop;
}
// Add event listener to save the scroll position when scrolling stops
var timer;
logTextarea.addEventListener('scroll', function () {
clearTimeout(timer);
timer = setTimeout(function () {
storeScrollPosition(logTextarea.scrollTop);
}, 150);
});
function storeScrollPosition(scrollPos) {
localStorage.setItem("scrollPosition", JSON.stringify({ "log": scrollPos }));
}
});
};
return view.extend({
handleCleanLogs: function () {
return fs.exec('/usr/share/mosdns/mosdns.sh', ['cleanlog'])
.catch(function (e) { ui.addNotification(null, E('p', e.message)) });
},
render: function () {
var log_textarea = E('div', { 'id': 'log_textarea' },
E('img', {
'src': L.resource(['icons/loading.gif']),
'alt': _('Loading'),
'style': 'vertical-align:middle'
}, _('Collecting data...'))
);
poll.add(pollLog.bind(this, log_textarea));
var clear_logs_button = E('input', { 'class': 'btn cbi-button-action', 'type': 'button', 'style': 'margin-left: 10px; margin-top: 10px;', 'value': _('Clear logs') });
clear_logs_button.addEventListener('click', this.handleCleanLogs.bind(this));
return E([
E('div', { 'class': 'cbi-map' }, [
E('h2', { 'name': 'content' }, '%s - %s'.format(_('MosDNS'), _('Log Data'))),
E('div', { 'class': 'cbi-section' }, [
clear_logs_button,
log_textarea,
E('div', { 'style': 'text-align:right' },
E('small', {}, _('Refresh every %s seconds.').format(L.env.pollinterval))
)
])])
]);
},
handleSave: null,
handleSaveApply: null,
handleReset: null
});

View File

@@ -0,0 +1,251 @@
'use strict';
'require form';
'require fs';
'require ui';
'require view';
return view.extend({
render: function () {
var m, s, o;
m = new form.Map("mosdns", _("Rule Settings"),
_('The list of rules only apply to \'Default Config\' profiles.'));
s = m.section(form.TypedSection);
s.anonymous = true;
s.sortable = true;
s.tab('whitelist', _('White Lists'));
s.tab('blocklist', _('Block Lists'));
s.tab('greylist', _('Grey Lists'));
s.tab('ddnslist', _('DDNS Lists'));
s.tab('hostslist', _('Hosts'));
s.tab('redirectlist', _('Redirect'));
s.tab('localptrlist', _('Block PTR'));
s.tab('streamingmedialist', _('Streaming Media'));
o = s.taboption('whitelist', form.TextValue, '_whitelist',
null,
'<font color=\'red\'>'
+ _('Added domain names always permit resolution using \'local DNS\' with the highest priority (one domain per line, supports domain matching rules).')
+ '</font>'
);
o.rows = 25;
o.cfgvalue = function (section_id) {
return fs.trimmed('/etc/mosdns/rule/whitelist.txt').catch(function (e) {
return "";
});
};
o.write = function (section_id, formvalue) {
return this.cfgvalue(section_id).then(function (value) {
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/whitelist.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
.then(function (i) {
ui.addNotification(null, E('p', _('Rules have been saved.')), 'info');
})
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o = s.taboption('blocklist', form.TextValue, '_blocklist',
null,
'<font color=\'red\'>'
+ _('Added domain names will block DNS resolution (one domain per line, supports domain matching rules).')
+ '</font>'
);
o.rows = 25;
o.cfgvalue = function (section_id) {
return fs.trimmed('/etc/mosdns/rule/blocklist.txt').catch(function (e) {
return "";
});
};
o.write = function (section_id, formvalue) {
return this.cfgvalue(section_id).then(function (value) {
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/blocklist.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
.then(function (i) {
ui.addNotification(null, E('p', _('Rules have been saved.')), 'info');
})
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o = s.taboption('greylist', form.TextValue, '_greylist',
null,
'<font color=\'red\'>'
+ _('Added domain names will always use \'Remote DNS\' for resolution (one domain per line, supports domain matching rules).')
+ '</font>'
);
o.rows = 25;
o.cfgvalue = function (section_id) {
return fs.trimmed('/etc/mosdns/rule/greylist.txt').catch(function (e) {
return "";
});
};
o.write = function (section_id, formvalue) {
return this.cfgvalue(section_id).then(function (value) {
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/greylist.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
.then(function (i) {
ui.addNotification(null, E('p', _('Rules have been saved.')), 'info');
})
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o = s.taboption('ddnslist', form.TextValue, '_ddnslist',
null,
'<font color=\'red\'>'
+ _('Added domain names will always use \'Local DNS\' for resolution, with a forced TTL of 5 seconds, and results will not be cached (one domain per line, supports domain matching rules).')
+ '</font>'
);
o.rows = 25;
o.cfgvalue = function (section_id) {
return fs.trimmed('/etc/mosdns/rule/ddnslist.txt').catch(function (e) {
return "";
});
};
o.write = function (section_id, formvalue) {
return this.cfgvalue(section_id).then(function (value) {
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/ddnslist.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
.then(function (i) {
ui.addNotification(null, E('p', _('Rules have been saved.')), 'info');
})
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o = s.taboption('hostslist', form.TextValue, '_hostslist',
null,
'<font color=\'red\'>'
+ _('Custom Hosts rewrite, for example: baidu.com 10.0.0.1 (one rule per line, supports domain matching rules).')
+ '</font>'
);
o.rows = 25;
o.cfgvalue = function (section_id) {
return fs.trimmed('/etc/mosdns/rule/hosts.txt').catch(function (e) {
return "";
});
};
o.write = function (section_id, formvalue) {
return this.cfgvalue(section_id).then(function (value) {
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/hosts.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
.then(function (i) {
ui.addNotification(null, E('p', _('Rules have been saved.')), 'info');
})
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o = s.taboption('redirectlist', form.TextValue, '_redirectlist',
null,
'<font color=\'red\'>'
+ _('Redirecting requests for domain names. Request domain A, but return records for domain B, for example: baidu.com qq.com (one rule per line).')
+ '</font>'
);
o.rows = 25;
o.cfgvalue = function (section_id) {
return fs.trimmed('/etc/mosdns/rule/redirect.txt').catch(function (e) {
return "";
});
};
o.write = function (section_id, formvalue) {
return this.cfgvalue(section_id).then(function (value) {
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/redirect.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
.then(function (i) {
ui.addNotification(null, E('p', _('Rules have been saved.')), 'info');
})
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o = s.taboption('localptrlist', form.TextValue, '_localptrlist',
null,
'<font color=\'red\'>'
+ _('Added domain names will block PTR requests (one domain per line, supports domain matching rules).')
+ '</font>'
);
o.rows = 25;
o.cfgvalue = function (section_id) {
return fs.trimmed('/etc/mosdns/rule/local-ptr.txt').catch(function (e) {
return "";
});
};
o.write = function (section_id, formvalue) {
return this.cfgvalue(section_id).then(function (value) {
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/local-ptr.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
.then(function (i) {
ui.addNotification(null, E('p', _('Rules have been saved.')), 'info');
})
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o = s.taboption('streamingmedialist', form.TextValue, '_streamingmedialist',
null,
'<font color=\'red\'>'
+ _('When enabling \'Custom Stream Media DNS\', added domains will always use the \'Streaming Media DNS server\' for resolution (one domain per line, supports domain matching rules).')
+ '</font>'
);
o.rows = 25;
o.cfgvalue = function (section_id) {
return fs.trimmed('/etc/mosdns/rule/streaming.txt').catch(function (e) {
return "";
});
};
o.write = function (section_id, formvalue) {
return this.cfgvalue(section_id).then(function (value) {
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/streaming.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
.then(function (i) {
ui.addNotification(null, E('p', _('Rules have been saved.')), 'info');
})
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
return m.render();
},
handleSaveApply: function (ev) {
onclick = L.bind(this.handleSave, this, m);
return fs.exec('/etc/init.d/mosdns', ['restart']);
},
handleReset: null
});

View File

@@ -0,0 +1,65 @@
'use strict';
'require form';
'require fs';
'require ui';
'require view';
return view.extend({
handleUpdate: function (m, section_id, ev) {
return fs.exec('/usr/share/mosdns/mosdns.sh', ['geodata'])
.then(function (i) {
var res = i.code;
if (res === 0) {
ui.addNotification(null, E('p', _('Update success')), 'info');
} else {
ui.addNotification(null, E('p', i.stderr + '<br />' + i.stdout), 'warn');
ui.addNotification(null, E('p', _('Update failed, Please check the network status')), 'error');
}
});
},
render: function () {
var m, s, o;
m = new form.Map('mosdns', _('Update GeoIP & GeoSite databases'),
_('Automatically update GeoIP and GeoSite databases as well as ad filtering rules through scheduled tasks.'));
s = m.section(form.TypedSection);
s.anonymous = true;
o = s.option(form.Flag, 'geo_auto_update', _('Enable Auto Database Update'));
o.rmempty = false;
o = s.option(form.ListValue, 'geo_update_week_time', _('Update Cycle'));
o.value('*', _('Every Day'));
o.value('1', _('Every Monday'));
o.value('2', _('Every Tuesday'));
o.value('3', _('Every Wednesday'));
o.value('4', _('Every Thursday'));
o.value('5', _('Every Friday'));
o.value('6', _('Every Saturday'));
o.value('7', _('Every Sunday'));
o.default = 3;
o = s.option(form.ListValue, 'geo_update_day_time', _('Update Time'));
for (let t = 0; t < 24; t++) {
o.value(t, t + ':00');
};
o.default = 3;
o = s.option(form.Value, 'github_proxy', _('GitHub Proxy'),
_('Update data files with GitHub Proxy, leave blank to disable proxy downloads.'));
o.value('https://hub.gitmirror.com', _('https://hub.gitmirror.com'));
o.rmempty = true;
o.default = '';
o = s.option(form.Button, '_udpate', null,
_('Check And Update GeoData.'));
o.title = _('Database Update');
o.inputtitle = _('Check And Update');
o.inputstyle = 'apply';
o.onclick = L.bind(this.handleUpdate, this, m);
return m.render();
}
});

View File

@@ -1,53 +0,0 @@
local sys = require "luci.sys"
local http = require "luci.http"
module("luci.controller.mosdns", package.seeall)
function index()
if not nixio.fs.access("/etc/config/mosdns") then
return
end
local page = entry({"admin", "services", "mosdns"}, alias("admin", "services", "mosdns", "basic"), _("MosDNS"), 30)
page.dependent = true
page.acl_depends = { "luci-app-mosdns" }
entry({"admin", "services", "mosdns", "basic"}, cbi("mosdns/basic"), _("Basic Setting"), 1).leaf = true
entry({"admin", "services", "mosdns", "rule_list"}, cbi("mosdns/rule_list"), _("Rule List"), 2).leaf = true
entry({"admin", "services", "mosdns", "update"}, cbi("mosdns/update"), _("Geodata Update"), 3).leaf = true
entry({"admin", "services", "mosdns", "log"}, cbi("mosdns/log"), _("Logs"), 4).leaf = true
entry({"admin", "services", "mosdns", "status"}, call("act_status")).leaf = true
entry({"admin", "services", "mosdns", "get_log"}, call("get_log")).leaf = true
entry({"admin", "services", "mosdns", "clear_log"}, call("clear_log")).leaf = true
entry({"admin", "services", "mosdns", "geo_update"}, call("geo_update")).leaf = true
entry({"admin", "services", "mosdns", "flush_cache"}, call("flush_cache")).leaf = true
end
function act_status()
local e = {}
e.running = sys.call("pgrep -f mosdns >/dev/null") == 0
http.prepare_content("application/json")
http.write_json(e)
end
function get_log()
http.write(sys.exec("cat $(/usr/share/mosdns/mosdns.sh logfile)"))
end
function clear_log()
sys.call("cat /dev/null > $(/usr/share/mosdns/mosdns.sh logfile)")
end
function geo_update()
local e = {}
e.updating = sys.call("/usr/share/mosdns/mosdns.sh geodata >/dev/null") == 0
http.prepare_content("application/json")
http.write_json(e)
end
function flush_cache()
local e = {}
e.flushing = sys.call("/usr/share/mosdns/mosdns.sh flush >/dev/null") == 0
http.prepare_content("application/json")
http.write_json(e)
end

View File

@@ -1,264 +0,0 @@
local fs = require "nixio.fs"
local sys = require "luci.sys"
if fs.access("/usr/bin/mosdns") then
mosdns_version = sys.exec("/usr/share/mosdns/mosdns.sh version")
else
mosdns_version = "Unknown Version"
end
m = Map("mosdns")
m.title = translate("MosDNS") .. " " .. mosdns_version
m.description = translate("MosDNS is a plugin-based DNS forwarder/traffic splitter.")
m:section(SimpleSection).template = "mosdns/mosdns_status"
s = m:section(TypedSection, "mosdns")
s.addremove = false
s.anonymous = true
s:tab("basic", translate("Basic Options"))
o = s:taboption("basic", Flag, "enabled", translate("Enabled"))
o.rmempty = false
o = s:taboption("basic", ListValue, "configfile", translate("Config File"))
o:value("/var/etc/mosdns.json", translate("Default Config"))
o:value("/etc/mosdns/config_custom.yaml", translate("Custom Config"))
o.default = "/var/etc/mosdns.json"
o = s:taboption("basic", Value, "listen_port", translate("Listen port"))
o.datatype = "and(port,min(1))"
o.default = 5335
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("basic", ListValue, "log_level", translate("Log Level"))
o:value("debug", translate("Debug"))
o:value("info", translate("Info"))
o:value("warn", translate("Warning"))
o:value("error", translate("Error"))
o.default = "info"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("basic", Value, "log_file", translate("Log File"))
o.placeholder = "/var/log/mosdns.log"
o.default = "/var/log/mosdns.log"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("basic", Flag, "redirect", translate("DNS Forward"), translate("Forward Dnsmasq Domain Name resolution requests to MosDNS"))
o.default = true
o = s:taboption("basic", Flag, "prefer_ipv4", translate("Remote DNS prefer IPv4"), translate("IPv4 is preferred for Remote / Streaming Media DNS resolution of dual-stack addresses, and is not affected when the destination is IPv6 only"))
o:depends( "configfile", "/var/etc/mosdns.json")
o.default = true
o = s:taboption("basic", Flag, "custom_local_dns", translate("Custom China DNS"), translate("Follow WAN interface DNS if not enabled"))
o:depends( "configfile", "/var/etc/mosdns.json")
o.default = false
o = s:taboption("basic", Flag, "apple_optimization", translate("Apple domains optimization"), translate("For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses"))
o:depends("custom_local_dns", "1")
o.default = false
o = s:taboption("basic", DynamicList, "local_dns", translate("China DNS server"))
o:value("119.29.29.29", translate("Tencent Public DNS (119.29.29.29)"))
o:value("119.28.28.28", translate("Tencent Public DNS (119.28.28.28)"))
o:value("223.5.5.5", translate("Aliyun Public DNS (223.5.5.5)"))
o:value("223.6.6.6", translate("Aliyun Public DNS (223.6.6.6)"))
o:value("114.114.114.114", translate("Xinfeng Public DNS (114.114.114.114)"))
o:value("114.114.115.115", translate("Xinfeng Public DNS (114.114.115.115)"))
o:value("180.76.76.76", translate("Baidu Public DNS (180.76.76.76)"))
o:value("https://doh.pub/dns-query", translate("Tencent Public DNS (DNS over HTTPS)"))
o:value("quic://dns.alidns.com", translate("Aliyun Public DNS (DNS over QUIC)"))
o:value("https://dns.alidns.com/dns-query", translate("Aliyun Public DNS (DNS over HTTPS)"))
o:value("h3://dns.alidns.com/dns-query", translate("Aliyun Public DNS (DNS over HTTPS/3)"))
o:value("https://doh.360.cn/dns-query", translate("360 Public DNS (DNS over HTTPS)"))
o:depends("custom_local_dns", "1")
o = s:taboption("basic", DynamicList, "remote_dns", translate("Remote DNS server"))
o:value("tls://1.1.1.1", translate("CloudFlare Public DNS (1.1.1.1)"))
o:value("tls://1.0.0.1", translate("CloudFlare Public DNS (1.0.0.1)"))
o:value("tls://8.8.8.8", translate("Google Public DNS (8.8.8.8)"))
o:value("tls://8.8.4.4", translate("Google Public DNS (8.8.4.4)"))
o:value("tls://9.9.9.9", translate("Quad9 Public DNS (9.9.9.9)"))
o:value("tls://149.112.112.112", translate("Quad9 Public DNS (149.112.112.112)"))
o:value("tls://208.67.222.222", translate("Cisco Public DNS (208.67.222.222)"))
o:value("tls://208.67.220.220", translate("Cisco Public DNS (208.67.220.220)"))
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("basic", Flag, "custom_stream_media_dns", translate("Custom Stream Media DNS"), translate("Netflix, Disney+, Hulu and streaming media rules list will use this DNS"))
o:depends( "configfile", "/var/etc/mosdns.json")
o.default = false
o = s:taboption("basic", DynamicList, "stream_media_dns", translate("Streaming Media DNS server"))
o:value("tls://1.1.1.1", translate("CloudFlare Public DNS (1.1.1.1)"))
o:value("tls://1.0.0.1", translate("CloudFlare Public DNS (1.0.0.1)"))
o:value("tls://8.8.8.8", translate("Google Public DNS (8.8.8.8)"))
o:value("tls://8.8.4.4", translate("Google Public DNS (8.8.4.4)"))
o:value("tls://9.9.9.9", translate("Quad9 Public DNS (9.9.9.9)"))
o:value("tls://149.112.112.112", translate("Quad9 Public DNS (149.112.112.112)"))
o:value("tls://208.67.222.222", translate("Cisco Public DNS (208.67.222.222)"))
o:value("tls://208.67.220.220", translate("Cisco Public DNS (208.67.220.220)"))
o.default = "tls://8.8.8.8"
o:depends("custom_stream_media_dns", "1")
o = s:taboption("basic", ListValue, "bootstrap_dns", translate("Bootstrap DNS servers"), translate("Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT resolvers you specify as upstreams"))
o:value("119.29.29.29", translate("Tencent Public DNS (119.29.29.29)"))
o:value("119.28.28.28", translate("Tencent Public DNS (119.28.28.28)"))
o:value("223.5.5.5", translate("Aliyun Public DNS (223.5.5.5)"))
o:value("223.6.6.6", translate("Aliyun Public DNS (223.6.6.6)"))
o:value("114.114.114.114", translate("Xinfeng Public DNS (114.114.114.114)"))
o:value("114.114.115.115", translate("Xinfeng Public DNS (114.114.115.115)"))
o:value("180.76.76.76", translate("Baidu Public DNS (180.76.76.76)"))
o:value("8.8.8.8", translate("Google Public DNS (8.8.8.8)"))
o:value("1.1.1.1", translate("CloudFlare Public DNS (1.1.1.1)"))
o.default = "119.29.29.29"
o:depends("configfile", "/var/etc/mosdns.json")
s:tab("advanced", translate("Advanced Options"))
o = s:taboption("advanced", Value, "concurrent", translate("Concurrent"), translate("DNS query request concurrency, The number of upstream DNS servers that are allowed to initiate requests at the same time"))
o.datatype = "and(uinteger,min(1),max(3))"
o.default = "2"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Value, "idle_timeout", translate("Idle Timeout"), translate("DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)"))
o.datatype = "and(uinteger,min(1))"
o.default = "30"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Flag, "enable_pipeline", translate("TCP/DoT Connection Multiplexing"), translate("Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode"))
o.rmempty = false
o.default = false
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Flag, "insecure_skip_verify", translate("Disable TLS Certificate"), translate("Disable TLS Servers certificate validation, Can be useful if system CA certificate expires or the system time is out of order"))
o.rmempty = false
o.default = false
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Flag, "enable_ecs_remote", translate("Enable EDNS client subnet"))
o.rmempty = false
o.default = false
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Value, "remote_ecs_ip", translate("IP Address"), translate("Please provide the IP address you use when accessing foreign websites. This IP subnet (0/24) will be used as the ECS address for Remote / Streaming Media DNS requests") .. '<br />' .. translate("This feature is typically used when using a self-built DNS server as an Remote / Streaming Media DNS upstream (requires support from the upstream server)"))
o.datatype = "ipaddr"
o:depends("enable_ecs_remote", "1")
o = s:taboption("advanced", Flag, "dns_leak", translate("Prevent DNS Leaks"), translate("Enable this option fallback policy forces forwarding to remote DNS"))
o.rmempty = false
o.default = false
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Flag, "cache", translate("Enable DNS Cache"))
o.rmempty = false
o.default = false
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Value, "cache_size", translate("DNS Cache Size"), translate("DNS cache size (in piece)."))
o.datatype = "and(uinteger,min(0))"
o.default = "8000"
o:depends("cache", "1")
o = s:taboption("advanced", Value, "lazy_cache_ttl", translate("Lazy Cache TTL"), translate("Lazy cache survival time (in second). To disable Lazy Cache, please set to 0."))
o.datatype = "and(uinteger,min(0))"
o.default = "86400"
o:depends("cache", "1")
o = s:taboption("advanced", Flag, "dump_file", translate("Cache Dump"), translate("Save the cache locally and reload the cache dump on the next startup"))
o.rmempty = false
o.default = false
o:depends("cache", "1")
o = s:taboption("advanced", Value, "dump_interval", translate("Auto Save Cache Interval"))
o.datatype = "and(uinteger,min(0))"
o.default = "3600"
o:depends("dump_file", "1")
o = s:taboption("advanced", Value, "minimal_ttl", translate("Minimum TTL"), translate("Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating no modification"))
o.datatype = "and(uinteger,min(0),max(604800))"
o.default = "0"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Value, "maximum_ttl", translate("Maximum TTL"), translate("Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating no modification"))
o.datatype = "and(uinteger,min(0),max(604800))"
o.default = "0"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Flag, "adblock", translate("Enable DNS ADblock"))
o:depends("configfile", "/var/etc/mosdns.json")
o.default = false
o = s:taboption("advanced", DynamicList, "ad_source", translate("ADblock Source"), translate("When using custom rule sources, please use rule types supported by MosDNS (domain lists).") .. '<br />' .. translate("Support for local files, such as: file:///var/mosdns/example.txt"))
o:depends("adblock", "1")
o.default = "geosite.dat"
o:value("geosite.dat", "v2ray-geosite")
o:value("https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt", "anti-AD")
o:value("https://raw.githubusercontent.com/Cats-Team/AdRules/main/mosdns_adrules.txt", "Cats-Team/AdRules")
o:value("https://raw.githubusercontent.com/neodevpro/neodevhost/master/domain", "NEO DEV HOST")
o = s:taboption("basic", Button, "_reload", translate("Restart-Service"), translate("Restart the MosDNS process to take effect of new configuration"))
o.write = function()
sys.exec("/etc/init.d/mosdns reload")
end
o:depends("configfile", "/etc/mosdns/config_custom.yaml")
o = s:taboption("basic", TextValue, "config_custom", translate("Configuration Editor"))
o.template = "cbi/tvalue"
o.rows = 25
o:depends("configfile", "/etc/mosdns/config_custom.yaml")
function o.cfgvalue(self, section)
return fs.readfile("/etc/mosdns/config_custom.yaml")
end
function o.write(self, section, value)
value = value:gsub("\r\n?", "\n")
fs.writefile("/etc/mosdns/config_custom.yaml", value)
end
-- codemirror
o = s:taboption("basic", DummyValue, "")
o.template = "mosdns/mosdns_editor"
s:tab("cloudflare", translate("Cloudflare Options"))
o = s:taboption("cloudflare", Flag, "cloudflare", translate("Enabled"), translate("Match the parsing result with the Cloudflare IP ranges, and when there is a successful match, use the 'Custom IP' as the parsing result (experimental feature)"))
o.rmempty = false
o.default = false
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("cloudflare", DynamicList, "cloudflare_ip", translate("Custom IP"))
o.datatype = "ipaddr"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("cloudflare", TextValue, "cloudflare_cidr", translate("Cloudflare IP Ranges"))
o.description = translate("IPv4 CIDR") .. [[<a href="https://www.cloudflare.com/ips-v4" target="_blank">https://www.cloudflare.com/ips-v4</a>]] .. '<br />' .. translate("IPv6 CIDR") .. [[<a href="https://www.cloudflare.com/ips-v6" target="_blank">https://www.cloudflare.com/ips-v6</a>]]
o.template = "cbi/tvalue"
o.rows = 15
o:depends("configfile", "/var/etc/mosdns.json")
function o.cfgvalue(self, section)
return fs.readfile("/etc/mosdns/rule/cloudflare-cidr.txt")
end
function o.write(self, section, value)
value = value:gsub("\r\n?", "\n")
fs.writefile("/etc/mosdns/rule/cloudflare-cidr.txt", value)
end
s:tab("api", translate("API Options"))
o = s:taboption("api", Value, "listen_port_api", translate("API Listen port"))
o.datatype = "and(port,min(1))"
o.default = 9091
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("api", Button, "flush_cache", translate("Flush Cache"), translate("Flushing Cache will clear any IP addresses or DNS records from MosDNS cache"))
o.rawhtml = true
o.template = "mosdns/mosdns_flush_cache"
o:depends("configfile", "/var/etc/mosdns.json")
s:tab("geodata", translate("GeoData Export"))
o = s:taboption("geodata", DynamicList, "geosite_tags", translate("GeoSite Tags"), translate("Enter the GeoSite.dat category to be exported, Allow add multiple tags") .. '<br />' .. translate("Export directory: /var/mosdns"))
o:depends("configfile", "/etc/mosdns/config_custom.yaml")
o = s:taboption("geodata", DynamicList, "geoip_tags", translate("GeoIP Tags"), translate("Enter the GeoIP.dat category to be exported, Allow add multiple tags") .. '<br />' .. translate("Export directory: /var/mosdns"))
o:depends("configfile", "/etc/mosdns/config_custom.yaml")
return m

View File

@@ -1,5 +0,0 @@
m = Map("mosdns")
m:append(Template("mosdns/mosdns_log"))
return m

View File

@@ -1,111 +0,0 @@
local datatypes = require "luci.cbi.datatypes"
local white_list_file = "/etc/mosdns/rule/whitelist.txt"
local block_list_file = "/etc/mosdns/rule/blocklist.txt"
local grey_list_file = "/etc/mosdns/rule/greylist.txt"
local hosts_list_file = "/etc/mosdns/rule/hosts.txt"
local redirect_list_file = "/etc/mosdns/rule/redirect.txt"
local local_ptr_file = "/etc/mosdns/rule/local-ptr.txt"
local ddns_list_file = "/etc/mosdns/rule/ddnslist.txt"
local streaming_media_list_file = "/etc/mosdns/rule/streaming.txt"
m = Map("mosdns")
s = m:section(TypedSection, "mosdns", translate("Rule Settings"))
s.anonymous = true
s:tab("white_list", translate("White Lists"))
s:tab("block_list", translate("Block Lists"))
s:tab("grey_list", translate("Grey Lists"))
s:tab("ddns_list", translate("DDNS Lists"))
s:tab("hosts_list", translate("Hosts"))
s:tab("redirect_list", translate("Redirect"))
s:tab("local_ptr_list", translate("Block PTR"))
s:tab("streaming_media_list", translate("Streaming Media"))
o = s:taboption("white_list", TextValue, "whitelist", "", "<font color='red'>" .. translate("These domain names allow DNS resolution with the highest priority. Please input the domain names of websites, every line can input only one website domain. For example: hm.baidu.com.") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(white_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(white_list_file , value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(white_list_file , "") end
o.validate = function(self, value)
return value
end
o = s:taboption("block_list", TextValue, "blocklist", "", "<font color='red'>" .. translate("These domains are blocked from DNS resolution. Please input the domain names of websites, every line can input only one website domain. For example: baidu.com.") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(block_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(block_list_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(block_list_file, "") end
o.validate = function(self, value)
return value
end
o = s:taboption("grey_list", TextValue, "greylist", "", "<font color='red'>" .. translate("These domains are always resolved using remote DNS. Please input the domain names of websites, every line can input only one website domain. For example: google.com.") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(grey_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(grey_list_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(grey_list_file, "") end
o.validate = function(self, value)
return value
end
o = s:taboption("ddns_list", TextValue, "ddns", "", "<font color='red'>" .. translate("These domains are always resolved using local DNS. And force TTL 5 seconds, DNS resolution results will not enter the cache. For example: myddns.example.com.") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(ddns_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(ddns_list_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(ddns_list_file, "") end
o.validate = function(self, value)
return value
end
o = s:taboption("hosts_list", TextValue, "hosts", "", "<font color='red'>" .. translate("Hosts For example: baidu.com 10.0.0.1") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(hosts_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(hosts_list_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(hosts_list_file, "") end
o.validate = function(self, value)
return value
end
o = s:taboption("redirect_list", TextValue, "redirect", "", "<font color='red'>" .. translate("The domain name to redirect the request to. Requests domain A, but returns records for domain B. example: a.com b.com") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(redirect_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(redirect_list_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(redirect_list_file, "") end
o.validate = function(self, value)
return value
end
o = s:taboption("local_ptr_list", TextValue, "local_ptr", "", "<font color='red'>" .. translate("These domains are blocked from PTR requests") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(local_ptr_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(local_ptr_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(local_ptr_file, "") end
o.validate = function(self, value)
return value
end
o = s:taboption("streaming_media_list", TextValue, "streaming_media", "", "<font color='red'>" .. translate("These domains are always resolved using Streaming Media DNS. Please input the domain names of websites, every line can input only one website domain. For example: netflix.com.") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(streaming_media_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(streaming_media_list_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(streaming_media_list_file, "") end
o.validate = function(self, value)
return value
end
local apply = luci.http.formvalue("cbi.apply")
if apply then
luci.sys.exec("/etc/init.d/mosdns reload")
end
return m

View File

@@ -1,37 +0,0 @@
m = Map("mosdns")
s = m:section(TypedSection, "mosdns", translate("Update GeoIP & GeoSite dat"))
s.addremove = false
s.anonymous = true
o = s:option(Flag, "geo_auto_update", translate("Enable Auto Database Update"))
o.rmempty = false
o = s:option(ListValue, "geo_update_week_time", translate("Update Cycle"))
o:value("*", translate("Every Day"))
o:value("1", translate("Every Monday"))
o:value("2", translate("Every Tuesday"))
o:value("3", translate("Every Wednesday"))
o:value("4", translate("Every Thursday"))
o:value("5", translate("Every Friday"))
o:value("6", translate("Every Saturday"))
o:value("7", translate("Every Sunday"))
o.default = "3"
o = s:option(ListValue, "geo_update_day_time", translate("Update Time"))
for t = 0, 23 do
o:value(t, t..":00")
end
default = 3
o = s:option(Value, "github_proxy", translate("GitHub Proxy"), translate("Update data files with GitHub Proxy, leave blank to disable proxy downloads."))
o:value("https://hub.gitmirror.com", translate("https://hub.gitmirror.com"))
o:value("https://ghps.cc", translate("https://ghps.cc"))
o.rmempty = true
o.default = ""
o = s:option(Button, "geo_update_database", translate("Database Update"))
o.rawhtml = true
o.template = "mosdns/mosdns_geo_update"
return m

View File

@@ -1,21 +0,0 @@
<%+cbi/valueheader%>
<script src="/luci-static/resources/mosdns/lib/codemirror.js"></script>
<script src="/luci-static/resources/mosdns/addon/fold/foldcode.js"></script>
<script src="/luci-static/resources/mosdns/addon/fold/foldgutter.js"></script>
<script src="/luci-static/resources/mosdns/addon/fold/indent-fold.js"></script>
<script src="/luci-static/resources/mosdns/mode/yaml/yaml.js"></script>
<link rel="stylesheet" href="/luci-static/resources/mosdns/addon/fold/foldgutter.css" />
<link rel="stylesheet" href="/luci-static/resources/mosdns/lib/codemirror.css" />
<link rel="stylesheet" href="/luci-static/resources/mosdns/theme/dracula.css" />
<script type="text/javascript">//<![CDATA[
var editor = CodeMirror.fromTextArea(document.getElementById("cbid.mosdns.config.config_custom"), {
mode: "text/yaml",
styleActiveLine: true,
lineNumbers: true,
theme: "dracula",
lineWrapping: true,
matchBrackets: true
}
);//]]>
</script>
<%+cbi/valuefooter%>

View File

@@ -1,34 +0,0 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function flush_cache(btn, dataname)
{
btn.disabled = true;
btn.value = '<%:Flushing...%> ';
st=dataname;
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "mosdns", "flush_cache")%>',
{ set:st },
function(x,data)
{
var tb = document.getElementById(dataname+'-status');
if (tb)
{
switch (data.flushing)
{
case true:
tb.innerHTML = "<font color='green'>" + "<%:Flushing Success%>" + "</font>";
break;
case false:
tb.innerHTML = "<font color='red'>" + "<%:Flushing Failed, Please check if MosDNS is enabled%>" + "</font>";
break;
}
}
btn.disabled = false;
btn.value = '<%:Flush Cache%>';
}
);
return false;
}
//]]></script>
<input type="button" class="btn cbi-button-action" value="<%:Flush Cache%>" onclick="return flush_cache(this,'<%=self.option%>')" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%>

View File

@@ -1,34 +0,0 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function update_data(btn, dataname)
{
btn.disabled = true;
btn.value = '<%:Updating...%> ';
st=dataname;
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "mosdns", "geo_update")%>',
{ set:st },
function(x,data)
{
var tb = document.getElementById(dataname+'-status');
if (tb)
{
switch (data.updating)
{
case true:
tb.innerHTML = "<font color='green'>" + "<%:Update success%>" + "</font>";
break;
case false:
tb.innerHTML = "<font color='red'>" + "<%:Update failed, Please check the network status%>" + "</font>";
break;
}
}
btn.disabled = false;
btn.value = '<%:Check And Update%>';
}
);
return false;
}
//]]></script>
<input type="button" class="btn cbi-button-action" value="<%:Check And Update%>" onclick="return update_data(this,'<%=self.option%>')" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%>

View File

@@ -1,33 +0,0 @@
<script type="text/javascript">
//<![CDATA[
function clear_log(btn) {
XHR.get('<%=url([[admin]], [[services]], [[mosdns]], [[clear_log]])%>', null,
function(x, data) {
if(x && x.status == 200) {
var log_textarea = document.getElementById('log_textarea');
log_textarea.innerHTML = "";
log_textarea.scrollTop = log_textarea.scrollHeight;
}
location.reload();
}
);
}
var scrolled = false;
XHR.poll(2, '<%=url([[admin]], [[services]], [[mosdns]], [[get_log]])%>', null,
function(x, data) {
if(x && x.status == 200) {
var log_textarea = document.getElementById('log_textarea');
log_textarea.innerHTML = x.responseText;
if (!scrolled) {
log_textarea.scrollTop = log_textarea.scrollHeight;
scrolled = true;
}
}
}
);
//]]>
</script>
<fieldset class="cbi-section" id="_log_fieldset">
<input class="btn cbi-button-action" type="button" onclick="clear_log()" value="<%:Clear logs%>" style="margin-left: 10px; margin-top: 10px;">
<textarea id="log_textarea" class="cbi-input-textarea" style="width: calc(100% - 20px); height: 645px; margin: 10px;" data-update="change" rows="5" wrap="off" readonly="readonly"></textarea>
</fieldset>

View File

@@ -1,28 +0,0 @@
<script type="text/javascript">
//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[mosdns]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('mosdns_status');
if (data && tb) {
if (data.running) {
var links = '<em><b style=color:green>MosDNS <%:RUNNING%></b></em>';
tb.innerHTML = links;
} else {
tb.innerHTML = '<em><b style=color:red>MosDNS <%:NOT RUNNING%></b></em>';
}
}
}
);
//]]>
</script>
<style>
.mar-10 {
margin-left: 50px;
margin-right: 10px;
}
</style>
<fieldset class="cbi-section">
<p id="mosdns_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>

View File

@@ -1 +0,0 @@
zh-cn

View File

@@ -1,3 +1,19 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Project-Id-Version: PACKAGE VERSION\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: zh_Hans\n"
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "MosDNS"
msgstr "MosDNS"
msgid "MosDNS is a plugin-based DNS forwarder/traffic splitter."
msgstr "MosDNS 是一个插件化的 DNS 转发/分流器。"
msgid "Basic Setting"
msgstr "基本设置"
@@ -13,9 +29,6 @@ msgstr "Cloudflare 选项"
msgid "API Options"
msgstr "API 选项"
msgid "MosDNS is a plugin-based DNS forwarder/traffic splitter."
msgstr "MosDNS 是一个插件化的 DNS 转发/分流器。"
msgid "RUNNING"
msgstr "运行中"
@@ -34,20 +47,17 @@ msgstr "监听端口"
msgid "API Listen port"
msgstr "API 监听端口"
msgid "Flush Cache"
msgstr "刷新缓存"
msgid "Flush DNS Cache"
msgstr "刷新 DNS 缓存"
msgid "Flushing Cache will clear any IP addresses or DNS records from MosDNS cache"
msgstr "刷新缓存会清空 MosDNS 所有 IP 地址和 DNS 解析缓存"
msgid "Flushing DNS Cache will clear any IP addresses or DNS records from MosDNS cache."
msgstr "刷新 DNS 缓存会清空 MosDNS 所有 IP 地址和 DNS 解析缓存"
msgid "Flushing..."
msgstr "正在刷新..."
msgid "Flushing DNS Cache Success."
msgstr "刷新 DNS 缓存成功"
msgid "Flushing Success"
msgstr "刷新成功"
msgid "Flushing Failed, Please check if MosDNS is enabled"
msgstr "刷新失败,请检查 MosDNS 是否已启用"
msgid "Flushing DNS Cache Failed, Please check if MosDNS is running."
msgstr "刷新 DNS 缓存失败,请检查 MosDNS 状态是否在运行中。"
msgid "Match the parsing result with the Cloudflare IP ranges, and when there is a successful match, use the 'Custom IP' as the parsing result (experimental feature)"
msgstr "将解析结果与 Cloudflare IP 范围进行匹配,当匹配成功时,使用 “自选 IP” 作为解析结果(实验性功能)"
@@ -79,21 +89,27 @@ msgstr "使用自定义规则来源时,请使用 MosDNS 支持的规则类型
msgid "Support for local files, such as: file:///var/mosdns/example.txt"
msgstr "支持本地文件例如file:///var/mosdns/example.txt"
msgid "Restart-Service"
msgstr "重启服务"
msgid "Restart the MosDNS process to take effect of new configuration"
msgstr "重启 MosDNS 进程使新配置文件生效"
msgid "Configuration Editor"
msgstr "配置编辑器"
msgid "Edit the MosDNS custom configuration file."
msgstr "编辑 MosDNS 自定义配置文件。"
msgid "Configuration have been saved."
msgstr "配置已保存。"
msgid "This is the content of the file '/etc/mosdns/config_custom.yaml' from which your MosDNS configuration will be generated. Only accepts configuration content in yaml format."
msgstr "这是文件 “/etc/mosdns/config_custom.yaml” 的内容,您的 MosDNS 配置将从此文件生成。仅接受 yaml 格式的配置内容。"
msgid "Geodata Update"
msgstr "更新数据库"
msgid "Update GeoIP & GeoSite dat"
msgid "Update GeoIP & GeoSite databases"
msgstr "更新广告规则、GeoIP & GeoSite 数据库"
msgid "Automatically update GeoIP and GeoSite databases as well as ad filtering rules through scheduled tasks."
msgstr "通过定时任务自动更新 GeoIP 和 GeoSite 数据库以及广告过滤规则。"
msgid "Update Time"
msgstr "更新时间"
@@ -133,15 +149,15 @@ msgstr "通过 GitHub 代理更新数据文件,留空则禁用代理下载。"
msgid "Database Update"
msgstr "数据库更新"
msgid "Check And Update GeoData."
msgstr "检查并更新 GeoData 数据库。"
msgid "Check And Update"
msgstr "检查并更新"
msgid "Enable Auto Database Update"
msgstr "启用自动更新"
msgid "Updating..."
msgstr "正在更新..."
msgid "Update success"
msgstr "更新成功"
@@ -202,6 +218,12 @@ msgstr "阿里云公共 DNS223.5.5.5"
msgid "Aliyun Public DNS (223.6.6.6)"
msgstr "阿里云公共 DNS223.6.6.6"
msgid "TrafficRoute Public DNS (180.184.1.1)"
msgstr "火山引擎公共 DNS180.184.1.1"
msgid "TrafficRoute Public DNS (180.184.2.2)"
msgstr "火山引擎公共 DNS180.184.2.2"
msgid "Xinfeng Public DNS (114.114.114.114)"
msgstr "信风公共 DNS114.114.114.114"
@@ -334,52 +356,67 @@ msgstr "日志"
msgid "Clear logs"
msgstr "清空日志"
msgid "Rule List"
msgid "Log Data"
msgstr "日志数据"
msgid "No log data."
msgstr "无日志数据。"
msgid "Refresh every %s seconds."
msgstr "每 %s 秒刷新。"
msgid "Rules"
msgstr "规则列表"
msgid "Rule Settings"
msgstr "自定义规则列表"
msgid "<br>The list of rules only apply to 'Default Config' profiles."
msgstr "<br>规则列表仅适用于 “内置预设” 配置文件"
msgid "Rules have been saved."
msgstr "规则已保存"
msgid "Unable to save contents: %s"
msgstr "无法保存内容:%s"
msgid "The list of rules only apply to 'Default Config' profiles."
msgstr "规则列表仅适用于 “内置预设” 配置文件。"
msgid "White Lists"
msgstr "白名单"
msgid "These domain names allow DNS resolution with the highest priority. Please input the domain names of websites, every line can input only one website domain. For example: hm.baidu.com."
msgid "Added domain names always permit resolution using 'local DNS' with the highest priority (one domain per line, supports domain matching rules)."
msgstr "加入的域名始终允许使用 “本地 DNS” 进行解析,且优先级最高(每个域名一行,支持域名匹配规则)"
msgid "Block Lists"
msgstr "黑名单"
msgid "These domains are blocked from DNS resolution. Please input the domain names of websites, every line can input only one website domain. For example: baidu.com."
msgid "Added domain names will block DNS resolution (one domain per line, supports domain matching rules)."
msgstr "加入的域名将屏蔽 DNS 解析(每个域名一行,支持域名匹配规则)"
msgid "Grey Lists"
msgstr "灰名单"
msgid "These domains are always resolved using remote DNS. Please input the domain names of websites, every line can input only one website domain. For example: google.com."
msgid "Added domain names will always use 'Remote DNS' for resolution (one domain per line, supports domain matching rules)."
msgstr "加入的域名始终使用 “远程 DNS” 进行解析(每个域名一行,支持域名匹配规则)"
msgid "DDNS Lists"
msgstr "DDNS 域名"
msgid "These domains are always resolved using local DNS. And force TTL 5 seconds, DNS resolution results will not enter the cache. For example: myddns.example.com."
msgid "Added domain names will always use 'Local DNS' for resolution, with a forced TTL of 5 seconds, and results will not be cached (one domain per line, supports domain matching rules)."
msgstr "加入的域名始终使用 “本地 DNS” 进行解析,并且强制 TTL 5 秒,解析结果不会进入缓存(每个域名一行,支持域名匹配规则)"
msgid "Hosts For example: baidu.com 10.0.0.1"
msgid "Custom Hosts rewrite, for example: baidu.com 10.0.0.1 (one rule per line, supports domain matching rules)."
msgstr "自定义 Hosts 重写baidu.com 10.0.0.1(每个规则一行,支持域名匹配规则)"
msgid "Redirect"
msgstr "重定向"
msgid "The domain name to redirect the request to. Requests domain A, but returns records for domain B. example: a.com b.com"
msgid "Redirecting requests for domain names. Request domain A, but return records for domain B, for example: baidu.com qq.com (one rule per line)."
msgstr "重定向请求的域名。请求域名 A但返回域名 B 的记录baidu.com qq.com每个规则一行"
msgid "Block PTR"
msgstr "PTR 黑名单"
msgid "These domains are blocked from PTR requests"
msgid "Added domain names will block PTR requests (one domain per line, supports domain matching rules)."
msgstr "加入的域名将阻止 PTR 请求(每个域名一行,支持域名匹配规则)"
msgid "GeoData Export"
@@ -412,5 +449,5 @@ msgstr "自定义 Netflix、Disney+、Hulu 以及 “流媒体” 规则列表
msgid "Streaming Media"
msgstr "流媒体"
msgid "These domains are always resolved using Streaming Media DNS. Please input the domain names of websites, every line can input only one website domain. For example: netflix.com."
msgid "When enabling 'Custom Stream Media DNS', added domains will always use the 'Streaming Media DNS server' for resolution (one domain per line, supports domain matching rules)."
msgstr "启用 “自定义流媒体 DNS” 时,加入的域名始终使用 “流媒体 DNS 服务器” 进行解析(每个域名一行,支持域名匹配规则)"

View File

@@ -5,25 +5,25 @@ config mosdns 'config'
option geo_auto_update '0'
option geo_update_week_time '*'
option geo_update_day_time '2'
option redirect '1'
option prefer_ipv4 '1'
option adblock '0'
option configfile '/var/etc/mosdns.json'
option log_level 'info'
option log_file '/var/log/mosdns.log'
option cache '0'
option concurrent '1'
option cache '1'
option concurrent '2'
option idle_timeout '30'
option minimal_ttl '0'
option maximum_ttl '0'
option custom_local_dns '0'
option enable_pipeline '0'
option enable_pipeline '1'
option insecure_skip_verify '0'
option dns_leak '0'
option cloudflare '0'
option listen_port_api '9091'
option custom_stream_media_dns '0'
option bootstrap_dns '119.29.29.29'
list remote_dns 'tls://8.8.8.8'
list remote_dns 'tls://1.1.1.1'
option redirect '1'
option prefer_ipv4 '1'
option enable_ecs_remote '0'
option cache_size '8000'
option lazy_cache_ttl '86400'
option dump_file '0'

View File

@@ -0,0 +1,2 @@
# MosDNS Rules

View File

@@ -0,0 +1,2 @@
# MosDNS Rules

View File

@@ -0,0 +1,2 @@
# MosDNS Rules

View File

@@ -0,0 +1,2 @@
# MosDNS Rules

View File

@@ -0,0 +1,2 @@
# MosDNS Rules

View File

@@ -0,0 +1,2 @@
# MosDNS Rules

View File

@@ -1,11 +1,2 @@
domain:bing.com
domain:live.com
domain:msn.com
domain:ntp.org
domain:office.com
domain:qlogo.cn
domain:qq.com
domain:redhat.com
keyword:douyin
keyword:microsoft
keyword:windows
# MosDNS Rules

View File

@@ -0,0 +1,45 @@
{
"admin/services/mosdns": {
"title": "MosDNS",
"order": 30,
"action": {
"type": "firstchild"
},
"depends": {
"acl": [ "luci-app-mosdns" ],
"uci": { "mosdns": true }
}
},
"admin/services/mosdns/basic": {
"title": "Basic Setting",
"order": 10,
"action": {
"type": "view",
"path": "mosdns/basic"
}
},
"admin/services/mosdns/rules": {
"title": "Rules",
"order": 15,
"action": {
"type": "view",
"path": "mosdns/rules"
}
},
"admin/services/mosdns/update": {
"title": "Geodata Update",
"order": 20,
"action": {
"type": "view",
"path": "mosdns/update"
}
},
"admin/services/mosdns/logs": {
"title": "Logs",
"order": 25,
"action": {
"type": "view",
"path": "mosdns/logs"
}
}
}

View File

@@ -2,7 +2,7 @@
script_action=${1}
logfile_path() (
logfile_path() {
configfile=$(uci -q get mosdns.config.configfile)
if [ "$configfile" = "/var/etc/mosdns.json" ]; then
uci -q get mosdns.config.log_file
@@ -10,7 +10,15 @@ logfile_path() (
[ ! -f /etc/mosdns/config_custom.yaml ] && exit 1
awk '/^log:/{f=1;next}f==1{if($0~/file:/){print;exit}if($0~/^[^ ]/)exit}' /etc/mosdns/config_custom.yaml | grep -Eo "/[^'\"]+"
fi
)
}
print_logfile() {
cat $(logfile_path);
}
clean_logfile() {
true > $(logfile_path);
}
interface_dns() (
if [ "$(uci -q get mosdns.config.custom_local_dns)" = 1 ]; then
@@ -76,12 +84,12 @@ adlist_update() {
else
mirror=""
fi
echo -e "\e[1;32mDownloading $mirror$url\e[0m"
echo -e "Downloading $mirror$url"
curl --connect-timeout 5 -m 90 --ipv4 -kfSLo "$AD_TMPDIR/$filename" "$mirror$url"
fi
done
if [ $? -ne 0 ]; then
echo -e "\e[1;31mRules download failed.\e[0m"
echo -e "\e[1;31mRules download failed."
rm -rf "$AD_TMPDIR" "$lock_file"
exit 1
else
@@ -98,29 +106,29 @@ geodat_update() (
TMPDIR=$(mktemp -d) || exit 1
[ -n "$(uci -q get mosdns.config.github_proxy)" ] && mirror="$(uci -q get mosdns.config.github_proxy)/"
# geoip.dat - cn-private
echo -e "\e[1;32mDownloading "$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip-only-cn-private.dat\e[0m"
echo -e "Downloading "$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip-only-cn-private.dat"
curl --connect-timeout 5 -m 60 --ipv4 -kfSLo "$TMPDIR/geoip.dat" ""$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip-only-cn-private.dat"
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
# checksum - geoip.dat
echo -e "\e[1;32mDownloading "$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip-only-cn-private.dat.sha256sum\e[0m"
echo -e "Downloading "$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip-only-cn-private.dat.sha256sum"
curl --connect-timeout 5 -m 10 --ipv4 -kfSLo "$TMPDIR/geoip.dat.sha256sum" ""$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip-only-cn-private.dat.sha256sum"
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
if [ "$(sha256sum "$TMPDIR/geoip.dat" | awk '{print $1}')" != "$(cat "$TMPDIR/geoip.dat.sha256sum" | awk '{print $1}')" ]; then
echo -e "\e[1;31mgeoip.dat checksum error\e[0m"
echo -e "\e[1;31mgeoip.dat checksum error"
rm -rf "$TMPDIR"
exit 1
fi
# geosite.dat
echo -e "\e[1;32mDownloading "$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat\e[0m"
echo -e "Downloading "$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
curl --connect-timeout 5 -m 120 --ipv4 -kfSLo "$TMPDIR/geosite.dat" ""$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
# checksum - geosite.dat
echo -e "\e[1;32mDownloading "$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat.sha256sum\e[0m"
echo -e "Downloading "$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat.sha256sum"
curl --connect-timeout 5 -m 10 --ipv4 -kfSLo "$TMPDIR/geosite.dat.sha256sum" ""$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat.sha256sum"
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
if [ "$(sha256sum "$TMPDIR/geosite.dat" | awk '{print $1}')" != "$(cat "$TMPDIR/geosite.dat.sha256sum" | awk '{print $1}')" ]; then
echo -e "\e[1;31mgeosite.dat checksum error\e[0m"
echo -e "\e[1;31mgeosite.dat checksum error"
rm -rf "$TMPDIR"
exit 1
fi
@@ -150,8 +158,8 @@ v2dat_dump() {
# default config
v2dat unpack geoip -o /var/mosdns -f cn $v2dat_dir/geoip.dat
v2dat unpack geosite -o /var/mosdns -f cn -f apple -f 'geolocation-!cn' $v2dat_dir/geosite.dat
[ "$adblock" -eq 1 ] && [ $(echo $ad_source | grep -c geosite.dat) -ge '1' ] && v2dat unpack geosite -o /var/mosdns -f category-ads-all $v2dat_dir/geosite.dat
[ "$streaming_media" -eq 1 ] && v2dat unpack geosite -o /var/mosdns -f netflix -f disney -f hulu $v2dat_dir/geosite.dat || \
[ "$adblock" = 1 ] && [ $(echo $ad_source | grep -c geosite.dat) -ge '1' ] && v2dat unpack geosite -o /var/mosdns -f category-ads-all $v2dat_dir/geosite.dat
[ "$streaming_media" = 1 ] && v2dat unpack geosite -o /var/mosdns -f netflix -f disney -f hulu $v2dat_dir/geosite.dat || \
touch /var/mosdns/geosite_disney.txt ; touch /var/mosdns/geosite_netflix.txt ; touch /var/mosdns/geosite_hulu.txt
else
# custom config
@@ -186,6 +194,12 @@ case $script_action in
"v2dat_dump")
v2dat_dump
;;
"printlog")
print_logfile
;;
"cleanlog")
clean_logfile
;;
"version")
mosdns version
;;

View File

@@ -2,10 +2,44 @@
"luci-app-mosdns": {
"description": "Grant UCI access for luci-app-mosdns",
"read": {
"file": {
"/etc/init.d/mosdns": [ "exec" ],
"/etc/mosdns/config_custom.yaml": [ "read" ],
"/etc/mosdns/rule/blocklist.txt": [ "read" ],
"/etc/mosdns/rule/cloudflare-cidr.txt": [ "read" ],
"/etc/mosdns/rule/ddnslist.txt": [ "read" ],
"/etc/mosdns/rule/greylist.txt": [ "read" ],
"/etc/mosdns/rule/hosts.txt": [ "read" ],
"/etc/mosdns/rule/local-ptr.txt": [ "read" ],
"/etc/mosdns/rule/redirect.txt": [ "read" ],
"/etc/mosdns/rule/streaming.txt": [ "read" ],
"/etc/mosdns/rule/whitelist.txt": [ "read" ],
"/usr/share/mosdns/mosdns.sh": [ "exec" ]
},
"ubus": {
"file": [ "read" ],
"luci": [ "getConntrackHelpers" ]
},
"uci": [ "mosdns" ]
},
"write": {
"file": {
"/etc/mosdns/config_custom.yaml": [ "write" ],
"/etc/mosdns/rule/blocklist.txt": [ "write" ],
"/etc/mosdns/rule/cloudflare-cidr.txt": [ "write" ],
"/etc/mosdns/rule/ddnslist.txt": [ "write" ],
"/etc/mosdns/rule/greylist.txt": [ "write" ],
"/etc/mosdns/rule/hosts.txt": [ "write" ],
"/etc/mosdns/rule/local-ptr.txt": [ "write" ],
"/etc/mosdns/rule/redirect.txt": [ "write" ],
"/etc/mosdns/rule/streaming.txt": [ "write" ],
"/etc/mosdns/rule/whitelist.txt": [ "write" ]
},
"ubus": {
"file": [ "write" ]
},
"uci": [ "mosdns" ]
}
}
}

View File

@@ -1 +0,0 @@
!function(n){"object"==typeof exports&&"object"==typeof module?n(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],n):n(CodeMirror)}(function(n){"use strict";function e(e,o,i,t){if(i&&i.call){var l=i;i=null}else l=r(e,i,"rangeFinder");"number"==typeof o&&(o=n.Pos(o,0));var f=r(e,i,"minFoldSize");function d(n){var r=l(e,o);if(!r||r.to.line-r.from.line<f)return null;for(var i=e.findMarksAt(r.from),d=0;d<i.length;++d)if(i[d].__isFold&&"fold"!==t){if(!n)return null;r.cleared=!0,i[d].clear()}return r}var u=d(!0);if(r(e,i,"scanUp"))for(;!u&&o.line>e.firstLine();)o=n.Pos(o.line-1,0),u=d(!1);if(u&&!u.cleared&&"unfold"!==t){var a=function(n,e){var o=r(n,e,"widget");if("string"==typeof o){var i=document.createTextNode(o);(o=document.createElement("span")).appendChild(i),o.className="CodeMirror-foldmarker"}else o&&(o=o.cloneNode(!0));return o}(e,i);n.on(a,"mousedown",function(e){c.clear(),n.e_preventDefault(e)});var c=e.markText(u.from,u.to,{replacedWith:a,clearOnEnter:r(e,i,"clearOnEnter"),__isFold:!0});c.on("clear",function(o,r){n.signal(e,"unfold",e,o,r)}),n.signal(e,"fold",e,u.from,u.to)}}n.newFoldFunction=function(n,o){return function(r,i){e(r,i,{rangeFinder:n,widget:o})}},n.defineExtension("foldCode",function(n,o,r){e(this,n,o,r)}),n.defineExtension("isFolded",function(n){for(var e=this.findMarksAt(n),o=0;o<e.length;++o)if(e[o].__isFold)return!0}),n.commands.toggleFold=function(n){n.foldCode(n.getCursor())},n.commands.fold=function(n){n.foldCode(n.getCursor(),null,"fold")},n.commands.unfold=function(n){n.foldCode(n.getCursor(),null,"unfold")},n.commands.foldAll=function(e){e.operation(function(){for(var o=e.firstLine(),r=e.lastLine();o<=r;o++)e.foldCode(n.Pos(o,0),null,"fold")})},n.commands.unfoldAll=function(e){e.operation(function(){for(var o=e.firstLine(),r=e.lastLine();o<=r;o++)e.foldCode(n.Pos(o,0),null,"unfold")})},n.registerHelper("fold","combine",function(){var n=Array.prototype.slice.call(arguments,0);return function(e,o){for(var r=0;r<n.length;++r){var i=n[r](e,o);if(i)return i}}}),n.registerHelper("fold","auto",function(n,e){for(var o=n.getHelpers(e,"fold"),r=0;r<o.length;r++){var i=o[r](n,e);if(i)return i}});var o={rangeFinder:n.fold.auto,widget:"↔",minFoldSize:0,scanUp:!1,clearOnEnter:!0};function r(n,e,r){if(e&&void 0!==e[r])return e[r];var i=n.options.foldOptions;return i&&void 0!==i[r]?i[r]:o[r]}n.defineOption("foldOptions",null),n.defineExtension("foldOption",function(n,e){return r(this,n,e)})});

View File

@@ -1 +0,0 @@
.CodeMirror-foldmarker{color:blue;text-shadow:#b9f 1px 1px 2px,#b9f -1px -1px 2px,#b9f 1px -1px 2px,#b9f -1px 1px 2px;font-family:arial;line-height:.3;cursor:pointer}.CodeMirror-foldgutter{width:.7em}.CodeMirror-foldgutter-open,.CodeMirror-foldgutter-folded{cursor:pointer}.CodeMirror-foldgutter-open:after{content:"\25BE"}.CodeMirror-foldgutter-folded:after{content:"\25B8"}

View File

@@ -1 +0,0 @@
!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror"),require("./foldcode")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","./foldcode"],t):t(CodeMirror)}(function(t){"use strict";t.defineOption("foldGutter",!1,function(o,e,r){r&&r!=t.Init&&(o.clearGutter(o.state.foldGutter.options.gutter),o.state.foldGutter=null,o.off("gutterClick",a),o.off("changes",d),o.off("viewportChange",u),o.off("fold",l),o.off("unfold",l),o.off("swapDoc",d)),e&&(o.state.foldGutter=new function(t){this.options=t,this.from=this.to=0}(function(t){!0===t&&(t={});null==t.gutter&&(t.gutter="CodeMirror-foldgutter");null==t.indicatorOpen&&(t.indicatorOpen="CodeMirror-foldgutter-open");null==t.indicatorFolded&&(t.indicatorFolded="CodeMirror-foldgutter-folded");return t}(e)),f(o),o.on("gutterClick",a),o.on("changes",d),o.on("viewportChange",u),o.on("fold",l),o.on("unfold",l),o.on("swapDoc",d))});var o=t.Pos;function e(t,e){for(var r=t.findMarks(o(e,0),o(e+1,0)),n=0;n<r.length;++n)if(r[n].__isFold){var i=r[n].find(-1);if(i&&i.line===e)return r[n]}}function r(t){if("string"==typeof t){var o=document.createElement("div");return o.className=t+" CodeMirror-guttermarker-subtle",o}return t.cloneNode(!0)}function n(t,n,f){var a=t.state.foldGutter.options,d=n-1,u=t.foldOption(a,"minFoldSize"),l=t.foldOption(a,"rangeFinder"),c="string"==typeof a.indicatorFolded&&i(a.indicatorFolded),s="string"==typeof a.indicatorOpen&&i(a.indicatorOpen);t.eachLine(n,f,function(n){++d;var i=null,f=n.gutterMarkers;if(f&&(f=f[a.gutter]),e(t,d)){if(c&&f&&c.test(f.className))return;i=r(a.indicatorFolded)}else{var p=o(d,0),m=l&&l(t,p);if(m&&m.to.line-m.from.line>=u){if(s&&f&&s.test(f.className))return;i=r(a.indicatorOpen)}}(i||f)&&t.setGutterMarker(n,a.gutter,i)})}function i(t){return new RegExp("(^|\\s)"+t+"(?:$|\\s)\\s*")}function f(t){var o=t.getViewport(),e=t.state.foldGutter;e&&(t.operation(function(){n(t,o.from,o.to)}),e.from=o.from,e.to=o.to)}function a(t,r,n){var i=t.state.foldGutter;if(i){var f=i.options;if(n==f.gutter){var a=e(t,r);a?a.clear():t.foldCode(o(r,0),f)}}}function d(t){var o=t.state.foldGutter;if(o){var e=o.options;o.from=o.to=0,clearTimeout(o.changeUpdate),o.changeUpdate=setTimeout(function(){f(t)},e.foldOnChangeTimeSpan||600)}}function u(t){var o=t.state.foldGutter;if(o){var e=o.options;clearTimeout(o.changeUpdate),o.changeUpdate=setTimeout(function(){var e=t.getViewport();o.from==o.to||e.from-o.to>20||o.from-e.to>20?f(t):t.operation(function(){e.from<o.from&&(n(t,e.from,o.from),o.from=e.from),e.to>o.to&&(n(t,o.to,e.to),o.to=e.to)})},e.updateViewportTimeSpan||400)}}function l(t,o){var e=t.state.foldGutter;if(e){var r=o.line;r>=e.from&&r<e.to&&n(t,r,r+1)}}});

View File

@@ -1 +0,0 @@
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";function n(n,t){var i=n.getLine(t),o=i.search(/\S/);return-1==o||/\bcomment\b/.test(n.getTokenTypeAt(e.Pos(t,o+1)))?-1:e.countColumn(i,null,n.getOption("tabSize"))}e.registerHelper("fold","indent",function(t,i){var o=n(t,i.line);if(!(o<0)){for(var r=null,l=i.line+1,f=t.lastLine();l<=f;++l){var u=n(t,l);if(-1==u);else{if(!(u>o))break;r=l}}return r?{from:e.Pos(i.line,t.getLine(i.line).length),to:e.Pos(r,t.getLine(r).length)}:void 0}})});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";e.defineMode("yaml",function(){var e=new RegExp("\\b(("+["true","false","on","off","yes","no"].join(")|(")+"))$","i");return{token:function(i,t){var r=i.peek(),n=t.escaped;if(t.escaped=!1,"#"==r&&(0==i.pos||/\s/.test(i.string.charAt(i.pos-1))))return i.skipToEnd(),"comment";if(i.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))return"string";if(t.literal&&i.indentation()>t.keyCol)return i.skipToEnd(),"string";if(t.literal&&(t.literal=!1),i.sol()){if(t.keyCol=0,t.pair=!1,t.pairStart=!1,i.match(/---/))return"def";if(i.match(/\.\.\./))return"def";if(i.match(/\s*-\s+/))return"meta"}if(i.match(/^(\{|\}|\[|\])/))return"{"==r?t.inlinePairs++:"}"==r?t.inlinePairs--:"["==r?t.inlineList++:t.inlineList--,"meta";if(t.inlineList>0&&!n&&","==r)return i.next(),"meta";if(t.inlinePairs>0&&!n&&","==r)return t.keyCol=0,t.pair=!1,t.pairStart=!1,i.next(),"meta";if(t.pairStart){if(i.match(/^\s*(\||\>)\s*/))return t.literal=!0,"meta";if(i.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i))return"variable-2";if(0==t.inlinePairs&&i.match(/^\s*-?[0-9\.\,]+\s?$/))return"number";if(t.inlinePairs>0&&i.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/))return"number";if(i.match(e))return"keyword"}return!t.pair&&i.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)?(t.pair=!0,t.keyCol=i.indentation(),"atom"):t.pair&&i.match(/^:\s*/)?(t.pairStart=!0,"meta"):(t.pairStart=!1,t.escaped="\\"==r,i.next(),null)},startState:function(){return{pair:!1,pairStart:!1,keyCol:0,inlinePairs:0,inlineList:0,literal:!1,escaped:!1}},lineComment:"#",fold:"indent"}}),e.defineMIME("text/x-yaml","yaml"),e.defineMIME("text/yaml","yaml")});

View File

@@ -1 +0,0 @@
.cm-s-dracula.CodeMirror,.cm-s-dracula .CodeMirror-gutters{background-color:#282a36 !important;color:#f8f8f2 !important;border:0}.cm-s-dracula .CodeMirror-gutters{color:#282a36}.cm-s-dracula .CodeMirror-cursor{border-left:solid thin #f8f8f0}.cm-s-dracula .CodeMirror-linenumber{color:#6d8a88}.cm-s-dracula .CodeMirror-selected{background:rgba(255,255,255,0.10)}.cm-s-dracula .CodeMirror-line::selection,.cm-s-dracula .CodeMirror-line>span::selection,.cm-s-dracula .CodeMirror-line>span>span::selection{background:rgba(255,255,255,0.10)}.cm-s-dracula .CodeMirror-line::-moz-selection,.cm-s-dracula .CodeMirror-line>span::-moz-selection,.cm-s-dracula .CodeMirror-line>span>span::-moz-selection{background:rgba(255,255,255,0.10)}.cm-s-dracula span.cm-comment{color:#6272a4}.cm-s-dracula span.cm-string,.cm-s-dracula span.cm-string-2{color:#f1fa8c}.cm-s-dracula span.cm-number{color:#bd93f9}.cm-s-dracula span.cm-variable{color:#50fa7b}.cm-s-dracula span.cm-variable-2{color:white}.cm-s-dracula span.cm-def{color:#50fa7b}.cm-s-dracula span.cm-operator{color:#ff79c6}.cm-s-dracula span.cm-keyword{color:#ff79c6}.cm-s-dracula span.cm-atom{color:#bd93f9}.cm-s-dracula span.cm-meta{color:#f8f8f2}.cm-s-dracula span.cm-tag{color:#ff79c6}.cm-s-dracula span.cm-attribute{color:#50fa7b}.cm-s-dracula span.cm-qualifier{color:#50fa7b}.cm-s-dracula span.cm-property{color:#66d9ef}.cm-s-dracula span.cm-builtin{color:#50fa7b}.cm-s-dracula span.cm-variable-3,.cm-s-dracula span.cm-type{color:#ffb86c}.cm-s-dracula .CodeMirror-activeline-background{background:rgba(255,255,255,0.1)}.cm-s-dracula .CodeMirror-matchingbracket{text-decoration:underline;color:white !important}

View File

@@ -260,9 +260,9 @@ function connect_status()
local socks_port = uci:get(appname, "@global[0]", "tcp_node_socks_port")
if enabled ~= 0 then
if (chn_list == "proxy" and gfw_list == 0 and proxy_mode ~= "proxy" and baidu ~= nil) or (chn_list == 0 and gfw_list == 0 and proxy_mode == "proxy") then
url = "--socks5 127.0.0.1:" .. socks_port .. " " .. url
url = "-x socks5h://127.0.0.1:" .. socks_port .. " " .. url
elseif baidu == nil then
url = "--socks5 127.0.0.1:" .. socks_port .. " " .. url
url = "-x socks5h://127.0.0.1:" .. socks_port .. " " .. url
end
end
local result = luci.sys.exec('curl --connect-timeout 3 -o /dev/null -I -sk -w "%{http_code}:%{time_appconnect}" ' .. url)

View File

@@ -1338,15 +1338,18 @@ stop_crontab() {
start_dns() {
echolog "DNS域名解析"
local china_ng_local_dns=${LOCAL_DNS}
local direct_dns_mode=$(config_t_get global direct_dns_mode "auto")
case "$direct_dns_mode" in
udp)
LOCAL_DNS=$(config_t_get global direct_dns_udp 223.5.5.5 | sed 's/:/#/g')
china_ng_local_dns=${LOCAL_DNS}
;;
tcp)
LOCAL_DNS="127.0.0.1#${dns_listen_port}"
dns_listen_port=$(expr $dns_listen_port + 1)
local DIRECT_DNS=$(config_t_get global direct_dns_tcp 223.5.5.5 | sed 's/:/#/g')
china_ng_local_dns="tcp://${DIRECT_DNS}"
ln_run "$(first_type dns2tcp)" dns2tcp "/dev/null" -L "${LOCAL_DNS}" -R "$(get_first_dns DIRECT_DNS 53)" -v
echolog " - dns2tcp(${LOCAL_DNS}) -> tcp://$(get_first_dns DIRECT_DNS 53 | sed 's/#/:/g')"
echolog " * 请确保上游直连 DNS 支持 TCP 查询。"
@@ -1357,11 +1360,12 @@ start_dns() {
local cdns_listen_port=${dns_listen_port}
dns_listen_port=$(expr $dns_listen_port + 1)
local DIRECT_DNS=$(config_t_get global direct_dns_dot "tls://dot.pub@1.12.12.12")
china_ng_local_dns=${DIRECT_DNS}
ln_run "$(first_type chinadns-ng)" chinadns-ng "/dev/null" -b 127.0.0.1 -l ${cdns_listen_port} -c ${DIRECT_DNS} -d chn
echolog " - ChinaDNS-NG(${LOCAL_DNS}) -> ${DIRECT_DNS}"
echolog " * 请确保上游直连 DNS 支持 DoT 查询。"
else
echolog " - 你的ChinaDNS-NG版本不支持DoT直连DNS将使用默认UDP地址。"
echolog " - 你的ChinaDNS-NG版本不支持DoT直连DNS将使用默认地址。"
fi
;;
auto)
@@ -1478,8 +1482,6 @@ start_dns() {
if [ $(check_ver "$chinadns_ng_now" "$chinadns_ng_min") = 1 ]; then
echolog " * 注意:当前 ChinaDNS-NG 版本为[ $chinadns_ng_now ],请更新到[ $chinadns_ng_min ]或以上版本,否则 DNS 有可能无法正常工作!"
fi
local china_ng_local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n2 | awk -v prefix="udp://" '{ for (i=1; i<=NF; i++) print prefix $i }') | tr " " ",")
[ "$FILTER_PROXY_IPV6" = "1" ] && DNSMASQ_FILTER_PROXY_IPV6=0
[ -z "${china_ng_listen_port}" ] && local china_ng_listen_port=$(expr $dns_listen_port + 1)
@@ -1659,7 +1661,22 @@ acl_app() {
[ "$filter_proxy_ipv6" = "1" ] && dnsmasq_filter_proxy_ipv6=0
chinadns_port=$(expr $chinadns_port + 1)
_china_ng_listen="127.0.0.1#${chinadns_port}"
_chinadns_local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n2 | awk -v prefix="udp://" '{ for (i=1; i<=NF; i++) print prefix $i }') | tr " " ",")
_chinadns_local_dns=${LOCAL_DNS}
_direct_dns_mode=$(config_t_get global direct_dns_mode "auto")
case "${_direct_dns_mode}" in
udp)
_chinadns_local_dns=$(config_t_get global direct_dns_udp 223.5.5.5 | sed 's/:/#/g')
;;
tcp)
_chinadns_local_dns="tcp://$(config_t_get global direct_dns_tcp 223.5.5.5 | sed 's/:/#/g')"
;;
dot)
if [ "$(chinadns-ng -V | grep -i wolfssl)" != "nil" ]; then
_chinadns_local_dns=$(config_t_get global direct_dns_dot "tls://dot.pub@1.12.12.12")
fi
;;
esac
run_chinadns_ng \
_flag="$sid" \
@@ -1812,7 +1829,7 @@ acl_app() {
[ -n "$redirect_dns_port" ] && echo "${redirect_dns_port}" > $TMP_ACL_PATH/$sid/var_redirect_dns_port
unset enabled sid remarks sources use_global_config tcp_node udp_node use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode filter_proxy_ipv6 dns_mode remote_dns v2ray_dns_mode remote_dns_doh dns_client_ip
unset _ip _mac _iprange _ipset _ip_or_mac rule_list tcp_port udp_port config_file _extra_param
unset _china_ng_listen _chinadns_local_dns chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6
unset _china_ng_listen _chinadns_local_dns _direct_dns_mode chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6
unset redirect_dns_port
done
unset socks_port redir_port dns_port dnsmasq_port chinadns_port

View File

@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=naiveproxy
PKG_VERSION:=127.0.6533.64-1
PKG_VERSION:=127.0.6533.64-2
PKG_RELEASE:=1
# intel 80386 & riscv64 & cortex-a76
@@ -20,47 +20,47 @@ else ifeq ($(ARCH_PREBUILT),riscv64_riscv64)
endif
ifeq ($(ARCH_PACKAGES),aarch64_cortex-a53)
PKG_HASH:=76d6bf0891d72f2083f497aba44e9e7eb86ad420b5556a5c01857cfafb567b18
PKG_HASH:=856451a837422d3cce314859ed929912071321de04cbe044bd7f82de972bb670
else ifeq ($(ARCH_PACKAGES),aarch64_cortex-a72)
PKG_HASH:=5e1ec15ec4fb1145a64f5befb18c49b9b970438bba57dd8d5c6a9043803bcf8d
PKG_HASH:=dcd1a9a981a082805cdba714ffafce1ad5d6146951a92761bfc8c5157b2152cd
else ifeq ($(ARCH_PACKAGES),aarch64_generic)
PKG_HASH:=864deabbb035a4ec7df589b796bfa2838c5ebaebdb2d91df0a900a8a239d760f
PKG_HASH:=a228558aa327c450e8631a8f855669f18801ea17f5efb1c32eced495e5b84597
else ifeq ($(ARCH_PACKAGES),arm_arm1176jzf-s_vfp)
PKG_HASH:=9b6f8e8ccf771305f722bad7d8454464f7fd993a62f9c4a4c187767eb3e61605
PKG_HASH:=7f90787828eb2bb2a957e70da4f9e500b4abd1bf7a9ff6ef2636a004e5314a2f
else ifeq ($(ARCH_PACKAGES),arm_arm926ej-s)
PKG_HASH:=d9fb0c29f7c6b79afc0375751859b0db673d3355c0a5a69762f763de5d54b38e
PKG_HASH:=80fb0562a279659ff0811cee441e319587505bbc06ad4b271f4d1fefa1c7f672
else ifeq ($(ARCH_PACKAGES),arm_cortex-a15_neon-vfpv4)
PKG_HASH:=964a92e915220963a94a6556db96a09c903fc3dfd4e6b2ae1a837f5b24a63945
PKG_HASH:=0d378b74c59025973c2f9e8577bc514be6601fc191c3cbbbabad427793fc4df9
else ifeq ($(ARCH_PACKAGES),arm_cortex-a5_vfpv4)
PKG_HASH:=04deb25636983504a593d5c1627d1d336672afccf3c8dd75e7919e77171a9ab2
PKG_HASH:=72433296d6417ee0edce2246e4c107f71253b1b2dd6cd6cf89da8e462a381a05
else ifeq ($(ARCH_PACKAGES),arm_cortex-a7)
PKG_HASH:=868ac8c97f6e8a7b4097e1a20b46c723a1caa31508e3844d470b38f820ef5976
PKG_HASH:=553e36d2eb3afe2618b4af9e8d5f19aae1fe3bff867b10d1406b4a204f647fe9
else ifeq ($(ARCH_PACKAGES),arm_cortex-a7_neon-vfpv4)
PKG_HASH:=ddb14e435dc396c5228647bc15fb2e3cbd49a15a5fc2c280a11417b0ad0d37c9
PKG_HASH:=5edce6d98dc6d631708db4cbe64a811b423a4cd3c9d3a017cd0f9ee128dcff12
else ifeq ($(ARCH_PACKAGES),arm_cortex-a7_vfpv4)
PKG_HASH:=fc7a83ab309dcdf7f3ea2ed44ad9a37b3efedfb850372042bb8853e3b3bb784d
PKG_HASH:=0bb1dc4c539bd4268dcb640a413413772a866724d7f1aa73cac3de82314dcc5b
else ifeq ($(ARCH_PACKAGES),arm_cortex-a8_vfpv3)
PKG_HASH:=5eb32a09c30a7932bfe20bca6226d459eef7517796ea38065446b2bbaee8e0cc
PKG_HASH:=7acec9e59793201243f6c76ee0ab1def62ca8ee539207f55830cd8a1585ed294
else ifeq ($(ARCH_PACKAGES),arm_cortex-a9)
PKG_HASH:=197b1bd818f6cfd349f2077a408d2186ef430b762a65fbb6c2846599497895b7
PKG_HASH:=aba4212b3e2af6e248ebbda90b43d55ea9a9448c3f578b6c9545027a1c54c111
else ifeq ($(ARCH_PACKAGES),arm_cortex-a9_neon)
PKG_HASH:=a5f8461fa6b11fa9a53f8c41b450aed7cec8bcd0e690bc2316ec868cbf8b565a
PKG_HASH:=70845dcd459834822a3bc8e68f2d19ee230f6768d20c79ffcc443a19b6334e6b
else ifeq ($(ARCH_PACKAGES),arm_cortex-a9_vfpv3-d16)
PKG_HASH:=09077a6318039baff022fb673a94cbce3a270338213bc0c063e9c0da168c2982
PKG_HASH:=e8d5501614d880c490cb6c0ad6d831c248de2668e07b7c98ee79c2f2f719fe19
else ifeq ($(ARCH_PACKAGES),arm_mpcore)
PKG_HASH:=eeada4b34728c5052a75abb2e55a5f0a45b66f6d220483e1c4407adb0a4eb55e
PKG_HASH:=a132692b8ac678ff6d40cb22767da80ef83b7f6c4f81242d8f033721d33ecc83
else ifeq ($(ARCH_PACKAGES),arm_xscale)
PKG_HASH:=b5fdde4063613c7209e45fcea0c70a447f31569a916780ab1738011819d37a13
PKG_HASH:=e0f10115b225bdffbdcbc550bc2baeeb1ea9e174926430ef848c5b767cefdc78
else ifeq ($(ARCH_PACKAGES),mipsel_24kc)
PKG_HASH:=49c6722aeb41994fa919f52cfb36a80354862673837879d2432d08f8d55ba182
PKG_HASH:=ccd2421d48ddcfc29633fe2059e0bb62a8dc7550de4d70892c50b898bab4dcc4
else ifeq ($(ARCH_PACKAGES),mipsel_mips32)
PKG_HASH:=da35f403614f3aab9b6252fad490cf1e3cbb79ea97cfd9a047cecde5787bd9a5
PKG_HASH:=606b82c1bdaa84ec80be074b0551f12b79f36cf13be90e481da947397096632b
else ifeq ($(ARCH_PACKAGES),riscv64)
PKG_HASH:=2cb07b68527032329ded3ab3ccbe66930cd6b7bd523787e90305a5476594a41f
PKG_HASH:=f2784f78ef577e41cb71cdb1e0cd59d05b5215e9ff99384835b51fa2017ea029
else ifeq ($(ARCH_PACKAGES),x86)
PKG_HASH:=2010757b3555ae78a529f5b2261edf339bb5052b543558423444c133c34107d6
PKG_HASH:=afc71f4e0a45e5103e54ecc18a8c43e3d2b016c9a1d3113b3e483573e556171b
else ifeq ($(ARCH_PACKAGES),x86_64)
PKG_HASH:=3a0d15a8fa4c15a4f55f80367a30b1621cbb2ed2be826e9f3a5360ffef08552e
PKG_HASH:=315a2321655f2d3dd8a54f5538e52b3d21d15df0d09e66c2b1f6afb83f427eb8
else
PKG_HASH:=dummy
endif

View File

@@ -9,9 +9,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.27.2" />
<PackageReference Include="Grpc.Net.Client" Version="2.63.0" />
<PackageReference Include="Grpc.Tools" Version="2.64.0">
<PackageReference Include="Google.Protobuf" Version="3.27.3" />
<PackageReference Include="Grpc.Net.Client" Version="2.65.0" />
<PackageReference Include="Grpc.Tools" Version="2.65.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -1,9 +1,9 @@
<Application
x:Class="v2rayN.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
ShutdownMode="OnExplicitShutdown"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
@@ -62,11 +62,9 @@
</Style>
<Style TargetType="{x:Type TextElement}">
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="Foreground" Value="{DynamicResource MaterialDesignBody}" />
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="Foreground" Value="{DynamicResource MaterialDesignBody}" />
</Style>
<Style x:Key="lvItemSelected" TargetType="{x:Type ListViewItem}">
<Setter Property="Margin" Value="2" />

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