mirror of
https://github.com/bolucat/Archive.git
synced 2025-09-26 20:21:35 +08:00
Update On Sat Aug 3 20:32:16 CEST 2024
This commit is contained in:
1
.github/update.log
vendored
1
.github/update.log
vendored
@@ -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
|
||||
|
1
clash-meta/.github/workflows/build.yml
vendored
1
clash-meta/.github/workflows/build.yml
vendored
@@ -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' }}
|
||||
|
@@ -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
|
||||
|
@@ -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=
|
||||
|
1
clash-nyanpasu/.eslintignore
Normal file
1
clash-nyanpasu/.eslintignore
Normal file
@@ -0,0 +1 @@
|
||||
frontend/nyanpasu/auto-imports.d.ts
|
@@ -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",
|
||||
|
@@ -7,3 +7,4 @@ pnpm-lock.yaml
|
||||
*.lock
|
||||
*.wxs
|
||||
frontend/nyanpasu/src/router.ts
|
||||
frontend/nyanpasu/auto-imports.d.ts
|
||||
|
25
clash-nyanpasu/backend/Cargo.lock
generated
25
clash-nyanpasu/backend/Cargo.lock
generated
@@ -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",
|
||||
]
|
||||
|
@@ -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"
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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()
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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?;
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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")]
|
||||
|
92
clash-nyanpasu/backend/tauri/src/server/mod.rs
Normal file
92
clash-nyanpasu/backend/tauri/src/server/mod.rs
Normal 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
|
||||
}
|
@@ -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",
|
||||
|
@@ -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(_) => {
|
||||
|
@@ -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");
|
||||
};
|
||||
|
@@ -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 {
|
||||
|
9
clash-nyanpasu/frontend/nyanpasu/auto-imports.d.ts
vendored
Normal file
9
clash-nyanpasu/frontend/nyanpasu/auto-imports.d.ts
vendored
Normal 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"]
|
||||
}
|
@@ -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",
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
);
|
||||
}
|
@@ -78,7 +78,7 @@ export const ScriptDialog = ({
|
||||
desc: "",
|
||||
});
|
||||
}
|
||||
}, [isEdit]);
|
||||
}, [form, isEdit, profile]);
|
||||
|
||||
const [openMonaco, setOpenMonaco] = useState(false);
|
||||
|
||||
|
@@ -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>
|
||||
);
|
||||
});
|
||||
|
@@ -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", {
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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 />
|
||||
|
@@ -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"}
|
||||
|
@@ -22,6 +22,6 @@
|
||||
},
|
||||
"jsxImportSource": "@emotion/react",
|
||||
},
|
||||
"include": ["./src"],
|
||||
"include": ["./src", "./auto-imports.d.ts"],
|
||||
"references": [{ "path": "../interface/tsconfig.json" }],
|
||||
}
|
||||
|
@@ -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"] }),
|
||||
|
@@ -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",
|
||||
|
357
clash-nyanpasu/pnpm-lock.yaml
generated
357
clash-nyanpasu/pnpm-lock.yaml
generated
@@ -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
|
||||
|
@@ -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");
|
||||
|
@@ -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
|
||||
|
24
lede/package/lean/libcryptopp/patches/001-autotools.patch
Normal file
24
lede/package/lean/libcryptopp/patches/001-autotools.patch
Normal 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.
|
@@ -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
@@ -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
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -23,6 +23,6 @@
|
||||
"activeProfile": "default",
|
||||
"rpcPort": 8989,
|
||||
"socks5Port": 1080,
|
||||
"loggingLevel": "INFO",
|
||||
"loggingLevel": "TRACE",
|
||||
"socks5ListenLAN": true
|
||||
}
|
||||
|
@@ -14,6 +14,6 @@
|
||||
"advancedSettings": {
|
||||
"allowLocalDestination": true
|
||||
},
|
||||
"loggingLevel": "INFO",
|
||||
"loggingLevel": "TRACE",
|
||||
"mtu": 1400
|
||||
}
|
||||
|
1
mihomo/.github/workflows/build.yml
vendored
1
mihomo/.github/workflows/build.yml
vendored
@@ -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' }}
|
||||
|
@@ -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
|
||||
|
@@ -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=
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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,
|
||||
}
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
@@ -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=
|
||||
|
@@ -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
|
||||
)
|
||||
|
@@ -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=
|
||||
|
@@ -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)
|
||||
}
|
@@ -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)
|
||||
}
|
@@ -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
|
||||
|
@@ -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 = ' ';
|
||||
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();
|
||||
}
|
||||
});
|
@@ -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
|
||||
});
|
@@ -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
|
||||
});
|
@@ -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();
|
||||
}
|
||||
});
|
@@ -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
|
@@ -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
|
@@ -1,5 +0,0 @@
|
||||
m = Map("mosdns")
|
||||
|
||||
m:append(Template("mosdns/mosdns_log"))
|
||||
|
||||
return m
|
@@ -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
|
@@ -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
|
@@ -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%>
|
@@ -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%>
|
@@ -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%>
|
@@ -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>
|
@@ -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>
|
@@ -1 +0,0 @@
|
||||
zh-cn
|
@@ -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 "阿里云公共 DNS(223.5.5.5)"
|
||||
msgid "Aliyun Public DNS (223.6.6.6)"
|
||||
msgstr "阿里云公共 DNS(223.6.6.6)"
|
||||
|
||||
msgid "TrafficRoute Public DNS (180.184.1.1)"
|
||||
msgstr "火山引擎公共 DNS(180.184.1.1)"
|
||||
|
||||
msgid "TrafficRoute Public DNS (180.184.2.2)"
|
||||
msgstr "火山引擎公共 DNS(180.184.2.2)"
|
||||
|
||||
msgid "Xinfeng Public DNS (114.114.114.114)"
|
||||
msgstr "信风公共 DNS(114.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 服务器” 进行解析(每个域名一行,支持域名匹配规则)"
|
@@ -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'
|
||||
|
||||
|
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
|
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
|
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
|
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
|
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
|
@@ -0,0 +1,2 @@
|
||||
# MosDNS Rules
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
;;
|
||||
|
@@ -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" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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)})});
|
@@ -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"}
|
@@ -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)}}});
|
@@ -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
@@ -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")});
|
@@ -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}
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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>
|
||||
|
@@ -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
Reference in New Issue
Block a user