Update On Sat May 4 20:29:57 CEST 2024
1
.github/update.log
vendored
@@ -636,3 +636,4 @@ Update On Tue Apr 30 20:31:38 CEST 2024
|
||||
Update On Wed May 1 20:30:48 CEST 2024
|
||||
Update On Thu May 2 20:28:05 CEST 2024
|
||||
Update On Fri May 3 20:27:51 CEST 2024
|
||||
Update On Sat May 4 20:29:46 CEST 2024
|
||||
|
@@ -238,6 +238,24 @@ func (blk *BrookLink) CreateExchanger(network, src string, dstb []byte, tcptimeo
|
||||
}
|
||||
return sc, rc, nil
|
||||
}
|
||||
if blk.V.Get("udpoverstream") == "true" {
|
||||
rc, err := QUICDialTCP(src, socks5.ToAddress(dstb[0], dstb[1:len(dstb)-2], dstb[len(dstb)-2:]), blk.Address, blk.Tc, tcptimeout)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
var sc Exchanger
|
||||
if blk.V.Get("withoutBrookProtocol") != "true" {
|
||||
sc, err = NewStreamClient("udp", blk.Password, src, rc, tcptimeout, dstb)
|
||||
}
|
||||
if blk.V.Get("withoutBrookProtocol") == "true" {
|
||||
sc, err = NewSimpleStreamClient("udp", blk.Password, src, rc, tcptimeout, dstb)
|
||||
}
|
||||
if err != nil {
|
||||
rc.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
return sc, rc, nil
|
||||
}
|
||||
rc, err := QUICDialUDP(src, socks5.ToAddress(dstb[0], dstb[1:len(dstb)-2], dstb[len(dstb)-2:]), blk.Address, blk.Tc, udptimeout)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@@ -74,7 +74,7 @@ func main() {
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "tag",
|
||||
Usage: "Tag can be used to the process, will be append into log or serverLog, such as: 'key1:value1'",
|
||||
Usage: "Tag can be used to the process, will be append into log or serverLog, such as: 'key1:value1'. All tags will also be appended as query parameters one by one to the userAPI",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "dialWithDNS",
|
||||
@@ -1583,6 +1583,10 @@ func main() {
|
||||
Name: "udpovertcp",
|
||||
Usage: "When server is brook server, UDP over TCP",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "udpoverstream",
|
||||
Usage: "When server is brook quicserver, UDP over Stream. Note: only brook CLI and tun2brook suppport for now",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "address",
|
||||
Usage: "When server is brook wsserver or brook wssserver or brook quicserver, specify address instead of resolving addresses from host, such as 1.2.3.4:443",
|
||||
@@ -1613,11 +1617,11 @@ func main() {
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "fragment",
|
||||
Usage: "When server is brook wssserver, split the ClientHello into multiple fragments and then send them one by one with delays (millisecond). The format is min_length:max_length:min_delay:max_delay, cannot be zero, such as 50:100:10:50, Note that: This is an experimental feature, currently only supported by the brook CLI and tun2brook",
|
||||
Usage: "When server is brook wssserver, split the ClientHello into multiple fragments and then send them one by one with delays (millisecond). The format is min_length:max_length:min_delay:max_delay, cannot be zero, such as 50:100:10:50",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "token",
|
||||
Usage: "A token represents a user's identity. A string encoded in hexadecimal. Server needs to have --userAPI enabled. Note that: Only supported by the brook GUI and tun2brook",
|
||||
Usage: "A token represents a user's identity. A string encoded in hexadecimal. Server needs to have --userAPI enabled. Note that: Only supported by the brook GUI(except for OpenWrt) and tun2brook",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "example",
|
||||
@@ -1656,6 +1660,9 @@ func main() {
|
||||
if c.Bool("udpovertcp") {
|
||||
v.Set("udpovertcp", "true")
|
||||
}
|
||||
if c.Bool("udpoverstream") {
|
||||
v.Set("udpoverstream", "true")
|
||||
}
|
||||
if c.String("address") != "" {
|
||||
v.Set("address", c.String("address"))
|
||||
}
|
||||
@@ -2735,11 +2742,11 @@ func main() {
|
||||
if ip == nil {
|
||||
return errors.New(c.String("ip") + " is not IP")
|
||||
}
|
||||
b := iploc.Country(ip)
|
||||
if b == nil {
|
||||
s := iploc.Country(ip)
|
||||
if s == "" {
|
||||
return errors.New(c.String("ip") + " unknown")
|
||||
}
|
||||
fmt.Println(string(b))
|
||||
fmt.Println(s)
|
||||
return nil
|
||||
},
|
||||
},
|
||||
|
@@ -6,7 +6,7 @@ echo '<!--G-R3M673HK5V-->' >> ../readme.md
|
||||
echo 'A cross-platform programmable network tool.' >> ../readme.md
|
||||
echo '' >> ../readme.md
|
||||
echo '# Sponsor' >> ../readme.md
|
||||
echo '**❤️ [Shiliew - China Optimized Network App](https://www.txthinking.com/shiliew.html)**' >> ../readme.md
|
||||
echo '**❤️ [Shiliew - A network app designed for those who value their time](https://www.txthinking.com/shiliew.html)**' >> ../readme.md
|
||||
|
||||
cat getting-started.md >> ../readme.md
|
||||
cat gui.md >> ../readme.md
|
||||
@@ -16,7 +16,6 @@ echo '# CLI Documentation' >> ../readme.md
|
||||
jb '$1`brook mdpage`.split("\n").filter(v=>!v.startsWith("[")).join("\n").replace("```\n```", "```\nbrook --help\n```").split("\n").forEach(v=> echo(v.startsWith("**") && !v.startsWith("**Usage") ? "- "+v : v))' >> ../readme.md
|
||||
|
||||
cat example.md >> ../readme.md
|
||||
cat diagram.md >> ../readme.md
|
||||
|
||||
markdown ../readme.md ./index.html
|
||||
|
||||
|
@@ -1,40 +0,0 @@
|
||||
# Diagram
|
||||
|
||||
> Maybe outdated
|
||||
|
||||
## overview
|
||||
|
||||

|
||||
|
||||
## withoutBrookProtocol
|
||||
|
||||

|
||||
|
||||
## relayoverbrook
|
||||
|
||||

|
||||
|
||||
## dnsserveroverbrook
|
||||
|
||||

|
||||
|
||||
## relay
|
||||
|
||||

|
||||
|
||||
## dnsserver
|
||||
|
||||

|
||||
|
||||
## tproxy
|
||||
|
||||

|
||||
|
||||
## gui
|
||||
|
||||

|
||||
|
||||
## script
|
||||
|
||||

|
||||
|
@@ -27,6 +27,6 @@
|
||||
| [Socks5 Configurator](https://chromewebstore.google.com/detail/socks5-configurator/hnpgnjkeaobghpjjhaiemlahikgmnghb) | If you prefer CLI brook client |
|
||||
| [IPvBar](https://chromewebstore.google.com/detail/ipvbar/nepjlegfiihpkcdhlmaebfdfppckonlj) | See domain, IP and country in browser |
|
||||
| [TxThinking SSH](https://www.txthinking.com/ssh.html) | A SSH Terminal |
|
||||
| [brook-manager](https://github.com/txthinking/brook-manager) | Brook Manager is a Brook management system for medium to large merchants |
|
||||
| [brook-dashboard](https://github.com/txthinkinginc/brook-dashboard) | A Brook User System |
|
||||
| [TxThinking](https://www.txthinking.com) | Everything |
|
||||
|
||||
|
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 44 KiB |
@@ -1,845 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" d2Version="v0.3.0" preserveAspectRatio="xMinYMin meet" viewBox="0 0 711 968"><svg id="d2-svg" class="d2-3723677766" width="711" height="968" viewBox="-101 -101 711 968"><rect x="-101.000000" y="-101.000000" width="711.000000" height="968.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
|
||||
.d2-3723677766 .text {
|
||||
font-family: "d2-3723677766-font-regular";
|
||||
}
|
||||
@font-face {
|
||||
font-family: d2-3723677766-font-regular;
|
||||
src: url("data:application/font-woff;base64,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");
|
||||
}
|
||||
.d2-3723677766 .text-bold {
|
||||
font-family: "d2-3723677766-font-bold";
|
||||
}
|
||||
@font-face {
|
||||
font-family: d2-3723677766-font-bold;
|
||||
src: url("data:application/font-woff;base64,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");
|
||||
}]]></style><style type="text/css"><![CDATA[.shape {
|
||||
shape-rendering: geometricPrecision;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
.connection {
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
.blend {
|
||||
mix-blend-mode: multiply;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.d2-3723677766 .fill-N1{fill:#0A0F25;}
|
||||
.d2-3723677766 .fill-N2{fill:#676C7E;}
|
||||
.d2-3723677766 .fill-N3{fill:#9499AB;}
|
||||
.d2-3723677766 .fill-N4{fill:#CFD2DD;}
|
||||
.d2-3723677766 .fill-N5{fill:#DEE1EB;}
|
||||
.d2-3723677766 .fill-N6{fill:#EEF1F8;}
|
||||
.d2-3723677766 .fill-N7{fill:#FFFFFF;}
|
||||
.d2-3723677766 .fill-B1{fill:#0D32B2;}
|
||||
.d2-3723677766 .fill-B2{fill:#0D32B2;}
|
||||
.d2-3723677766 .fill-B3{fill:#E3E9FD;}
|
||||
.d2-3723677766 .fill-B4{fill:#E3E9FD;}
|
||||
.d2-3723677766 .fill-B5{fill:#EDF0FD;}
|
||||
.d2-3723677766 .fill-B6{fill:#F7F8FE;}
|
||||
.d2-3723677766 .fill-AA2{fill:#4A6FF3;}
|
||||
.d2-3723677766 .fill-AA4{fill:#EDF0FD;}
|
||||
.d2-3723677766 .fill-AA5{fill:#F7F8FE;}
|
||||
.d2-3723677766 .fill-AB4{fill:#EDF0FD;}
|
||||
.d2-3723677766 .fill-AB5{fill:#F7F8FE;}
|
||||
.d2-3723677766 .stroke-N1{stroke:#0A0F25;}
|
||||
.d2-3723677766 .stroke-N2{stroke:#676C7E;}
|
||||
.d2-3723677766 .stroke-N3{stroke:#9499AB;}
|
||||
.d2-3723677766 .stroke-N4{stroke:#CFD2DD;}
|
||||
.d2-3723677766 .stroke-N5{stroke:#DEE1EB;}
|
||||
.d2-3723677766 .stroke-N6{stroke:#EEF1F8;}
|
||||
.d2-3723677766 .stroke-N7{stroke:#FFFFFF;}
|
||||
.d2-3723677766 .stroke-B1{stroke:#0D32B2;}
|
||||
.d2-3723677766 .stroke-B2{stroke:#0D32B2;}
|
||||
.d2-3723677766 .stroke-B3{stroke:#E3E9FD;}
|
||||
.d2-3723677766 .stroke-B4{stroke:#E3E9FD;}
|
||||
.d2-3723677766 .stroke-B5{stroke:#EDF0FD;}
|
||||
.d2-3723677766 .stroke-B6{stroke:#F7F8FE;}
|
||||
.d2-3723677766 .stroke-AA2{stroke:#4A6FF3;}
|
||||
.d2-3723677766 .stroke-AA4{stroke:#EDF0FD;}
|
||||
.d2-3723677766 .stroke-AA5{stroke:#F7F8FE;}
|
||||
.d2-3723677766 .stroke-AB4{stroke:#EDF0FD;}
|
||||
.d2-3723677766 .stroke-AB5{stroke:#F7F8FE;}
|
||||
.d2-3723677766 .background-color-N1{background-color:#0A0F25;}
|
||||
.d2-3723677766 .background-color-N2{background-color:#676C7E;}
|
||||
.d2-3723677766 .background-color-N3{background-color:#9499AB;}
|
||||
.d2-3723677766 .background-color-N4{background-color:#CFD2DD;}
|
||||
.d2-3723677766 .background-color-N5{background-color:#DEE1EB;}
|
||||
.d2-3723677766 .background-color-N6{background-color:#EEF1F8;}
|
||||
.d2-3723677766 .background-color-N7{background-color:#FFFFFF;}
|
||||
.d2-3723677766 .background-color-B1{background-color:#0D32B2;}
|
||||
.d2-3723677766 .background-color-B2{background-color:#0D32B2;}
|
||||
.d2-3723677766 .background-color-B3{background-color:#E3E9FD;}
|
||||
.d2-3723677766 .background-color-B4{background-color:#E3E9FD;}
|
||||
.d2-3723677766 .background-color-B5{background-color:#EDF0FD;}
|
||||
.d2-3723677766 .background-color-B6{background-color:#F7F8FE;}
|
||||
.d2-3723677766 .background-color-AA2{background-color:#4A6FF3;}
|
||||
.d2-3723677766 .background-color-AA4{background-color:#EDF0FD;}
|
||||
.d2-3723677766 .background-color-AA5{background-color:#F7F8FE;}
|
||||
.d2-3723677766 .background-color-AB4{background-color:#EDF0FD;}
|
||||
.d2-3723677766 .background-color-AB5{background-color:#F7F8FE;}
|
||||
.d2-3723677766 .color-N1{color:#0A0F25;}
|
||||
.d2-3723677766 .color-N2{color:#676C7E;}
|
||||
.d2-3723677766 .color-N3{color:#9499AB;}
|
||||
.d2-3723677766 .color-N4{color:#CFD2DD;}
|
||||
.d2-3723677766 .color-N5{color:#DEE1EB;}
|
||||
.d2-3723677766 .color-N6{color:#EEF1F8;}
|
||||
.d2-3723677766 .color-N7{color:#FFFFFF;}
|
||||
.d2-3723677766 .color-B1{color:#0D32B2;}
|
||||
.d2-3723677766 .color-B2{color:#0D32B2;}
|
||||
.d2-3723677766 .color-B3{color:#E3E9FD;}
|
||||
.d2-3723677766 .color-B4{color:#E3E9FD;}
|
||||
.d2-3723677766 .color-B5{color:#EDF0FD;}
|
||||
.d2-3723677766 .color-B6{color:#F7F8FE;}
|
||||
.d2-3723677766 .color-AA2{color:#4A6FF3;}
|
||||
.d2-3723677766 .color-AA4{color:#EDF0FD;}
|
||||
.d2-3723677766 .color-AA5{color:#F7F8FE;}
|
||||
.d2-3723677766 .color-AB4{color:#EDF0FD;}
|
||||
.d2-3723677766 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]></style><style type="text/css">.md em,
|
||||
.md dfn {
|
||||
font-family: "d2-3723677766-font-italic";
|
||||
}
|
||||
|
||||
.md b,
|
||||
.md strong {
|
||||
font-family: "d2-3723677766-font-bold";
|
||||
}
|
||||
|
||||
.md code,
|
||||
.md kbd,
|
||||
.md pre,
|
||||
.md samp {
|
||||
font-family: "d2-3723677766-font-mono";
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.md {
|
||||
tab-size: 4;
|
||||
}
|
||||
|
||||
/* variables are provided in d2renderers/d2svg/d2svg.go */
|
||||
|
||||
.md {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
margin: 0;
|
||||
color: var(--color-fg-default);
|
||||
background-color: transparent; /* we don't want to define the background color */
|
||||
font-family: "d2-3723677766-font-regular";
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.md details,
|
||||
.md figcaption,
|
||||
.md figure {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.md summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
.md [hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.md a {
|
||||
background-color: transparent;
|
||||
color: var(--color-accent-fg);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.md a:active,
|
||||
.md a:hover {
|
||||
outline-width: 0;
|
||||
}
|
||||
|
||||
.md abbr[title] {
|
||||
border-bottom: none;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
.md dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.md h1 {
|
||||
margin: 0.67em 0;
|
||||
font-weight: 600;
|
||||
padding-bottom: 0.3em;
|
||||
font-size: 2em;
|
||||
border-bottom: 1px solid var(--color-border-muted);
|
||||
}
|
||||
|
||||
.md mark {
|
||||
background-color: var(--color-attention-subtle);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.md small {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.md sub,
|
||||
.md sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.md sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
.md sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
.md img {
|
||||
border-style: none;
|
||||
max-width: 100%;
|
||||
box-sizing: content-box;
|
||||
background-color: var(--color-canvas-default);
|
||||
}
|
||||
|
||||
.md figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
|
||||
.md hr {
|
||||
box-sizing: content-box;
|
||||
overflow: hidden;
|
||||
background: transparent;
|
||||
border-bottom: 1px solid var(--color-border-muted);
|
||||
height: 0.25em;
|
||||
padding: 0;
|
||||
margin: 24px 0;
|
||||
background-color: var(--color-border-default);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.md input {
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.md [type="button"],
|
||||
.md [type="reset"],
|
||||
.md [type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
.md [type="button"]::-moz-focus-inner,
|
||||
.md [type="reset"]::-moz-focus-inner,
|
||||
.md [type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.md [type="button"]:-moz-focusring,
|
||||
.md [type="reset"]:-moz-focusring,
|
||||
.md [type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
|
||||
.md [type="checkbox"],
|
||||
.md [type="radio"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.md [type="number"]::-webkit-inner-spin-button,
|
||||
.md [type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.md [type="search"] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.md [type="search"]::-webkit-search-cancel-button,
|
||||
.md [type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.md ::-webkit-input-placeholder {
|
||||
color: inherit;
|
||||
opacity: 0.54;
|
||||
}
|
||||
|
||||
.md ::-webkit-file-upload-button {
|
||||
-webkit-appearance: button;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
.md a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.md hr::before {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.md hr::after {
|
||||
display: table;
|
||||
clear: both;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.md table {
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
display: block;
|
||||
width: max-content;
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.md td,
|
||||
.md th {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.md details summary {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.md details:not([open]) > *:not(summary) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.md kbd {
|
||||
display: inline-block;
|
||||
padding: 3px 5px;
|
||||
color: var(--color-fg-default);
|
||||
vertical-align: middle;
|
||||
background-color: var(--color-canvas-subtle);
|
||||
border: solid 1px var(--color-neutral-muted);
|
||||
border-bottom-color: var(--color-neutral-muted);
|
||||
border-radius: 6px;
|
||||
box-shadow: inset 0 -1px 0 var(--color-neutral-muted);
|
||||
}
|
||||
|
||||
.md h1,
|
||||
.md h2,
|
||||
.md h3,
|
||||
.md h4,
|
||||
.md h5,
|
||||
.md h6 {
|
||||
margin-top: 24px;
|
||||
margin-bottom: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 1.25;
|
||||
font-family: "d2-3723677766-font-regular";
|
||||
}
|
||||
|
||||
.md h2 {
|
||||
font-weight: 600;
|
||||
padding-bottom: 0.3em;
|
||||
font-size: 1.5em;
|
||||
border-bottom: 1px solid var(--color-border-muted);
|
||||
}
|
||||
|
||||
.md h3 {
|
||||
font-weight: 600;
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
.md h4 {
|
||||
font-weight: 600;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.md h5 {
|
||||
font-weight: 600;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
.md h6 {
|
||||
font-weight: 600;
|
||||
font-size: 0.85em;
|
||||
color: var(--color-fg-muted);
|
||||
}
|
||||
|
||||
.md p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.md blockquote {
|
||||
margin: 0;
|
||||
padding: 0 1em;
|
||||
color: var(--color-fg-muted);
|
||||
border-left: 0.25em solid var(--color-border-default);
|
||||
}
|
||||
|
||||
.md ul,
|
||||
.md ol {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
.md ol ol,
|
||||
.md ul ol {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
|
||||
.md ul ul ol,
|
||||
.md ul ol ol,
|
||||
.md ol ul ol,
|
||||
.md ol ol ol {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
|
||||
.md dd {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.md pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.md ::placeholder {
|
||||
color: var(--color-fg-subtle);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.md input::-webkit-outer-spin-button,
|
||||
.md input::-webkit-inner-spin-button {
|
||||
margin: 0;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.md::before {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.md::after {
|
||||
display: table;
|
||||
clear: both;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.md > *:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
.md > *:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.md a:not([href]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.md .absent {
|
||||
color: var(--color-danger-fg);
|
||||
}
|
||||
|
||||
.md .anchor {
|
||||
float: left;
|
||||
padding-right: 4px;
|
||||
margin-left: -20px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.md .anchor:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.md p,
|
||||
.md blockquote,
|
||||
.md ul,
|
||||
.md ol,
|
||||
.md dl,
|
||||
.md table,
|
||||
.md pre,
|
||||
.md details {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.md blockquote > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.md blockquote > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.md sup > a::before {
|
||||
content: "[";
|
||||
}
|
||||
|
||||
.md sup > a::after {
|
||||
content: "]";
|
||||
}
|
||||
|
||||
.md h1:hover .anchor,
|
||||
.md h2:hover .anchor,
|
||||
.md h3:hover .anchor,
|
||||
.md h4:hover .anchor,
|
||||
.md h5:hover .anchor,
|
||||
.md h6:hover .anchor {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.md h1 tt,
|
||||
.md h1 code,
|
||||
.md h2 tt,
|
||||
.md h2 code,
|
||||
.md h3 tt,
|
||||
.md h3 code,
|
||||
.md h4 tt,
|
||||
.md h4 code,
|
||||
.md h5 tt,
|
||||
.md h5 code,
|
||||
.md h6 tt,
|
||||
.md h6 code {
|
||||
padding: 0 0.2em;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.md ul.no-list,
|
||||
.md ol.no-list {
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.md ol[type="1"] {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.md ol[type="a"] {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
|
||||
.md ol[type="i"] {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
|
||||
.md div > ol:not([type]) {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.md ul ul,
|
||||
.md ul ol,
|
||||
.md ol ol,
|
||||
.md ol ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.md li > p {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.md li + li {
|
||||
margin-top: 0.25em;
|
||||
}
|
||||
|
||||
.md dl {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.md dl dt {
|
||||
padding: 0;
|
||||
margin-top: 16px;
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.md dl dd {
|
||||
padding: 0 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.md table th {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.md table th,
|
||||
.md table td {
|
||||
padding: 6px 13px;
|
||||
border: 1px solid var(--color-border-default);
|
||||
}
|
||||
|
||||
.md table tr {
|
||||
background-color: var(--color-canvas-default);
|
||||
border-top: 1px solid var(--color-border-muted);
|
||||
}
|
||||
|
||||
.md table tr:nth-child(2n) {
|
||||
background-color: var(--color-canvas-subtle);
|
||||
}
|
||||
|
||||
.md table img {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.md img[align="right"] {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.md img[align="left"] {
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.md span.frame {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.md span.frame > span {
|
||||
display: block;
|
||||
float: left;
|
||||
width: auto;
|
||||
padding: 7px;
|
||||
margin: 13px 0 0;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--color-border-default);
|
||||
}
|
||||
|
||||
.md span.frame span img {
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.md span.frame span span {
|
||||
display: block;
|
||||
padding: 5px 0 0;
|
||||
clear: both;
|
||||
color: var(--color-fg-default);
|
||||
}
|
||||
|
||||
.md span.align-center {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.md span.align-center > span {
|
||||
display: block;
|
||||
margin: 13px auto 0;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.md span.align-center span img {
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.md span.align-right {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.md span.align-right > span {
|
||||
display: block;
|
||||
margin: 13px 0 0;
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.md span.align-right span img {
|
||||
margin: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.md span.float-left {
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 13px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.md span.float-left span {
|
||||
margin: 13px 0 0;
|
||||
}
|
||||
|
||||
.md span.float-right {
|
||||
display: block;
|
||||
float: right;
|
||||
margin-left: 13px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.md span.float-right > span {
|
||||
display: block;
|
||||
margin: 13px auto 0;
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.md code,
|
||||
.md tt {
|
||||
padding: 0.2em 0.4em;
|
||||
margin: 0;
|
||||
font-size: 85%;
|
||||
background-color: var(--color-neutral-muted);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.md code br,
|
||||
.md tt br {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.md del code {
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
.md pre code {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
.md pre > code {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
word-break: normal;
|
||||
white-space: pre;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.md .highlight {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.md .highlight pre {
|
||||
margin-bottom: 0;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.md .highlight pre,
|
||||
.md pre {
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
background-color: var(--color-canvas-subtle);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.md pre code,
|
||||
.md pre tt {
|
||||
display: inline;
|
||||
max-width: auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
line-height: inherit;
|
||||
word-wrap: normal;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.md .csv-data td,
|
||||
.md .csv-data th {
|
||||
padding: 5px;
|
||||
overflow: hidden;
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.md .csv-data .blob-num {
|
||||
padding: 10px 8px 9px;
|
||||
text-align: right;
|
||||
background: var(--color-canvas-default);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.md .csv-data tr {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.md .csv-data th {
|
||||
font-weight: 600;
|
||||
background: var(--color-canvas-subtle);
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.md .footnotes {
|
||||
font-size: 12px;
|
||||
color: var(--color-fg-muted);
|
||||
border-top: 1px solid var(--color-border-default);
|
||||
}
|
||||
|
||||
.md .footnotes ol {
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.md .footnotes li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.md .footnotes li:target::before {
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
bottom: -8px;
|
||||
left: -24px;
|
||||
pointer-events: none;
|
||||
content: "";
|
||||
border: 2px solid var(--color-accent-emphasis);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.md .footnotes li:target {
|
||||
color: var(--color-fg-default);
|
||||
}
|
||||
|
||||
.md .task-list-item {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.md .task-list-item label {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.md .task-list-item.enabled label {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.md .task-list-item + .task-list-item {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.md .task-list-item .handle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.md .task-list-item-checkbox {
|
||||
margin: 0 0.2em 0.25em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.md .contains-task-list:dir(rtl) .task-list-item-checkbox {
|
||||
margin: 0 -1.6em 0.25em 0.2em;
|
||||
}
|
||||
</style><g id="description"><g class="shape" ></g><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="0.000000" y="8.000000" width="309" height="51"><div xmlns="http://www.w3.org/1999/xhtml" class="md"><h1>relay.from == relay.to</h1>
|
||||
</div></foreignObject></g></g><g id="Local/TCP/UDP"><g class="shape" ><path d="M 344 195 C 344 196 343 197 342 197 C 326 198 314 209 314 223 C 314 238 328 250 345 250 H 464 C 483 250 498 237 498 222 C 498 207 484 195 466 194 C 465 194 464 193 463 192 C 459 177 441 166 419 166 C 405 166 392 171 384 178 C 383 179 382 179 381 179 C 378 178 375 178 371 178 C 357 178 345 185 344 195 Z" class=" stroke-B1 fill-N7" style="stroke-width:2;" /></g><text x="404.757500" y="229.516000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">Local/TCP/UDP</text></g><g id="Remote/TCP/UDP"><g class="shape" ><path d="M 337 545 C 337 546 336 547 334 547 C 317 548 303 559 303 573 C 303 588 318 600 338 600 H 471 C 492 600 509 587 509 572 C 509 557 493 545 473 544 C 472 544 470 543 470 542 C 466 527 445 516 421 516 C 405 516 391 521 382 528 C 381 529 379 529 378 529 C 375 528 371 528 367 528 C 351 528 338 535 337 545 Z" class=" stroke-B1 fill-N7" style="stroke-width:2;" /></g><text x="405.357000" y="579.516000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">Remote/TCP/UDP</text></g><g id="SRC"><g class="shape" ><rect x="369.000000" y="0.000000" width="73.000000" height="66.000000" class=" stroke-B1 fill-B6" style="stroke-width:2;" /></g><text x="405.500000" y="38.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">SRC</text></g><g id=""relay.from""><g class="shape" ><rect x="346.000000" y="350.000000" width="119.000000" height="66.000000" class=" stroke-B1 fill-B6" style="stroke-width:2;" /></g><text x="405.500000" y="388.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">relay.from</text></g><g id=""relay.to""><g class="shape" ><rect x="356.000000" y="700.000000" width="100.000000" height="66.000000" class=" stroke-B1 fill-B6" style="stroke-width:2;" /></g><text x="406.000000" y="738.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">relay.to</text></g><g id="(SRC -> Local/TCP/UDP)[0]"><marker id="mk-3488378134" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" class="connection fill-B1" stroke-width="2" /> </marker><path d="M 405.500000 68.000000 C 405.500000 106.000000 405.600000 126.400000 405.961540 164.000185" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-3723677766)" /></g><g id="(Local/TCP/UDP -> "relay.from")[0]"><path d="M 405.980001 251.999900 C 405.600000 290.000000 405.500000 310.000000 405.500000 346.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-3723677766)" /></g><g id="("relay.from" -> Remote/TCP/UDP)[0]"><path d="M 405.500000 418.000000 C 405.500000 456.000000 405.600000 476.400000 405.961540 514.000185" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-3723677766)" /></g><g id="(Remote/TCP/UDP -> "relay.to")[0]"><path d="M 405.980001 601.999900 C 405.600000 640.000000 405.500000 660.000000 405.500000 696.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-3723677766)" /></g><mask id="d2-3723677766" maskUnits="userSpaceOnUse" x="-101" y="-101" width="711" height="968">
|
||||
<rect x="-101" y="-101" width="711" height="968" fill="white"></rect>
|
||||
|
||||
</mask></svg></svg>
|
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 37 KiB |
@@ -8,7 +8,7 @@ require (
|
||||
github.com/krolaw/dhcp4 v0.0.0-20190909130307-a50d88189771
|
||||
github.com/miekg/dns v1.1.57
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/phuslu/iploc v1.0.20231031
|
||||
github.com/phuslu/iploc v1.0.20240501
|
||||
github.com/prometheus/client_golang v1.17.0
|
||||
github.com/quic-go/quic-go v0.42.0
|
||||
github.com/refraction-networking/utls v1.5.4
|
||||
|
@@ -51,6 +51,8 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/phuslu/iploc v1.0.20231031 h1:AsKT2PqStXV+gqJjNJ5mcUJ7YT9i09W+NVthhz5987s=
|
||||
github.com/phuslu/iploc v1.0.20231031/go.mod h1:gsgExGWldwv1AEzZm+Ki9/vGfyjkL33pbSr9HGpt2Xg=
|
||||
github.com/phuslu/iploc v1.0.20240501 h1:lX2dEFOQzxVpTH3dgJ+pcNEpLxwaJUhoCGMoajuAI5w=
|
||||
github.com/phuslu/iploc v1.0.20240501/go.mod h1:VZqAWoi2A80YPvfk1AizLGHavNIG9nhBC8d87D/SeVs=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q=
|
||||
|
@@ -71,9 +71,8 @@ func ListHasIP(c4, c6 []*net.IPNet, i net.IP, c *cache.Cache, geo []string) bool
|
||||
}
|
||||
}
|
||||
if len(geo) != 0 {
|
||||
b := iploc.Country(i)
|
||||
if b != nil {
|
||||
bs := string(b)
|
||||
bs := iploc.Country(i)
|
||||
if bs != "" {
|
||||
for _, v := range geo {
|
||||
if v == bs {
|
||||
if c != nil {
|
||||
|
@@ -1,7 +1,5 @@
|
||||
# User System
|
||||
|
||||
⚠️ Currently, this feature is experimental. At present, only this [brook_linux_amd64.20240606](https://github.com/txthinking/bash/releases/download/v20221005/brook_linux_amd64.20240606) and [tun2brook](https://github.com/txthinking/tun2brook) support it.
|
||||
|
||||
This content introduces how to develop a user system with Brook. Your system only needs to focus on two concepts: **Token** and **User API**. To support user system, you **must use brook server/wsserver/wssserver/quicserver with the brook protocol**.
|
||||
|
||||
<img src="https://brook.app/images/user-system.png" width="500">
|
||||
@@ -14,14 +12,14 @@ For example, encrypt user id or make session, and encode in hexadecimal:
|
||||
|
||||
```
|
||||
hex_encode(your_encrypt_or_session_function(user id))
|
||||
// 3ae6afc9fad94abd8985d8ecc77afb273ae6afc9fad94abd8985d8ecc77afb273ae6afc9fad94abd8985d8ecc77afb27 // 48 bytes token
|
||||
// 3ae6afc9fad94abd8985d8ecc77afb273ae6afc9fad94abd8985d8ecc77afb273ae6afc9fad94abd8985d8ecc77afb27
|
||||
```
|
||||
|
||||
For example, UUID:
|
||||
|
||||
```javascript
|
||||
crypto.randomUUID().replaceAll('-', '')
|
||||
// 3ae6afc9fad94abd8985d8ecc77afb27 // 16 bytes token
|
||||
// 3ae6afc9fad94abd8985d8ecc77afb27
|
||||
```
|
||||
|
||||
## User API
|
||||
@@ -79,3 +77,6 @@ You can count the traffic of each user from serverLog
|
||||
brook link --server 1.2.3.4:9999 --password hello --token xxx
|
||||
```
|
||||
|
||||
## Basic reference implementation
|
||||
|
||||
https://github.com/TxThinkingInc/brook-dashboard
|
||||
|
@@ -148,8 +148,15 @@ func (s *QUICServer) ListenAndServe() error {
|
||||
return
|
||||
}
|
||||
defer ss.Clean()
|
||||
if err := s.TCPHandle(ss); err != nil {
|
||||
Log(Error{"from": ss.Src(), "dst": ss.Dst(), "error": err.Error()})
|
||||
if ss.Network() == "tcp" {
|
||||
if err := s.TCPHandle(ss); err != nil {
|
||||
Log(Error{"from": ss.Src(), "dst": ss.Dst(), "error": err.Error()})
|
||||
}
|
||||
}
|
||||
if ss.Network() == "udp" {
|
||||
if err := s.UDPOverTCPHandle(ss); err != nil {
|
||||
Log(Error{"from": c.RemoteAddr().String(), "dst": ss.Dst(), "error": err.Error()})
|
||||
}
|
||||
}
|
||||
}(&QUICConn{
|
||||
Conn: c,
|
||||
@@ -240,6 +247,18 @@ func (s *QUICServer) TCPHandle(ss Exchanger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *QUICServer) UDPOverTCPHandle(ss Exchanger) error {
|
||||
rc, err := NATDial("udp", ss.Src(), ss.Dst(), ss.Dst())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rc.Close()
|
||||
if err := ss.Exchange(rc); err != nil {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *QUICServer) UDPHandle(ss Exchanger) error {
|
||||
rc, err := NATDial("udp", ss.Src(), ss.Dst(), ss.Dst())
|
||||
if err != nil {
|
||||
|
@@ -16,10 +16,12 @@ package brook
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/phuslu/iploc"
|
||||
)
|
||||
|
||||
func TestTest(t *testing.T) {
|
||||
l, err := CAC("/tmp/a")
|
||||
log.Printf("%#v %v\n", l, err)
|
||||
log.Printf("%#v\n", iploc.Country(net.ParseIP("8.8.8.8")))
|
||||
}
|
||||
|
@@ -98,4 +98,3 @@ API.
|
||||
|
||||
This software is released under the GPL-3.0 license.
|
||||
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2FMetaCubeX%2Fmihomo?ref=badge_large)
|
||||
|
@@ -35,7 +35,7 @@
|
||||
"react-dom": "18.3.1",
|
||||
"react-error-boundary": "4.0.13",
|
||||
"react-fast-marquee": "1.6.4",
|
||||
"react-hook-form": "7.51.3",
|
||||
"react-hook-form": "7.51.4",
|
||||
"react-i18next": "14.1.1",
|
||||
"react-markdown": "9.0.1",
|
||||
"react-router-dom": "6.23.0",
|
||||
|
@@ -97,7 +97,7 @@
|
||||
"stylelint-config-standard": "36.0.0",
|
||||
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
|
||||
"stylelint-order": "6.0.4",
|
||||
"stylelint-scss": "6.2.1",
|
||||
"stylelint-scss": "6.3.0",
|
||||
"tailwindcss": "3.4.3",
|
||||
"tsx": "4.9.0",
|
||||
"typescript": "5.4.5"
|
||||
|
43
clash-nyanpasu/pnpm-lock.yaml
generated
@@ -121,8 +121,8 @@ importers:
|
||||
specifier: 6.0.4
|
||||
version: 6.0.4(stylelint@16.5.0(typescript@5.4.5))
|
||||
stylelint-scss:
|
||||
specifier: 6.2.1
|
||||
version: 6.2.1(stylelint@16.5.0(typescript@5.4.5))
|
||||
specifier: 6.3.0
|
||||
version: 6.3.0(stylelint@16.5.0(typescript@5.4.5))
|
||||
tailwindcss:
|
||||
specifier: 3.4.3
|
||||
version: 3.4.3
|
||||
@@ -226,8 +226,8 @@ importers:
|
||||
specifier: 1.6.4
|
||||
version: 1.6.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
react-hook-form:
|
||||
specifier: 7.51.3
|
||||
version: 7.51.3(react@18.3.1)
|
||||
specifier: 7.51.4
|
||||
version: 7.51.4(react@18.3.1)
|
||||
react-i18next:
|
||||
specifier: 14.1.1
|
||||
version: 14.1.1(i18next@23.11.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -2127,8 +2127,8 @@ packages:
|
||||
eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
|
||||
electron-to-chromium@1.4.754:
|
||||
resolution: {integrity: sha512-7Kr5jUdns5rL/M9wFFmMZAgFDuL2YOnanFH4OI4iFzUqyh3XOL7nAGbSlSMZdzKMIyyTpNSbqZsWG9odwLeKvA==}
|
||||
electron-to-chromium@1.4.756:
|
||||
resolution: {integrity: sha512-RJKZ9+vEBMeiPAvKNWyZjuYyUqMndcP1f335oHqn3BEQbs2NFtVrnK5+6Xg5wSM9TknNNpWghGDUCKGYF+xWXw==}
|
||||
|
||||
emoji-regex@10.3.0:
|
||||
resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==}
|
||||
@@ -2952,9 +2952,6 @@ packages:
|
||||
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
known-css-properties@0.29.0:
|
||||
resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==}
|
||||
|
||||
known-css-properties@0.30.0:
|
||||
resolution: {integrity: sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ==}
|
||||
|
||||
@@ -3622,8 +3619,8 @@ packages:
|
||||
react: '>= 16.8.0 || 18.0.0'
|
||||
react-dom: '>= 16.8.0 || 18.0.0'
|
||||
|
||||
react-hook-form@7.51.3:
|
||||
resolution: {integrity: sha512-cvJ/wbHdhYx8aviSWh28w9ImjmVsb5Y05n1+FW786vEZQJV5STNM0pW6ujS+oiBecb0ARBxJFyAnXj9+GHXACQ==}
|
||||
react-hook-form@7.51.4:
|
||||
resolution: {integrity: sha512-V14i8SEkh+V1gs6YtD0hdHYnoL4tp/HX/A45wWQN15CYr9bFRmmRdYStSO5L65lCCZRF+kYiSKhm9alqbcdiVA==}
|
||||
engines: {node: '>=12.22.0'}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17 || ^18
|
||||
@@ -3999,8 +3996,8 @@ packages:
|
||||
peerDependencies:
|
||||
stylelint: ^14.0.0 || ^15.0.0 || ^16.0.1
|
||||
|
||||
stylelint-scss@6.2.1:
|
||||
resolution: {integrity: sha512-ZoGLbVb1keZYRVGQlhB8G6sZOoNqw61whzzzGFWp05N12ErqLFfBv3JPrXiMLZaW98sBS7K/vUQhRnvUj4vwdw==}
|
||||
stylelint-scss@6.3.0:
|
||||
resolution: {integrity: sha512-8OSpiuf1xC7f8kllJsBOFAOYp/mR/C1FXMVeOFjtJPw+AFvEmC93FaklHt7MlOqU4poxuQ1TkYMyfI0V+1SxjA==}
|
||||
engines: {node: '>=18.12.0'}
|
||||
peerDependencies:
|
||||
stylelint: ^16.0.2
|
||||
@@ -4218,8 +4215,8 @@ packages:
|
||||
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
|
||||
update-browserslist-db@1.0.14:
|
||||
resolution: {integrity: sha512-JixKH8GR2pWYshIPUg/NujK3JO7JiqEEUiNArE86NQyrgUuZeTlZQN3xuS/yiV5Kb48ev9K6RqNkaJjXsdg7Jw==}
|
||||
update-browserslist-db@1.0.15:
|
||||
resolution: {integrity: sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
browserslist: '>= 4.21.0'
|
||||
@@ -5829,9 +5826,9 @@ snapshots:
|
||||
browserslist@4.23.0:
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001615
|
||||
electron-to-chromium: 1.4.754
|
||||
electron-to-chromium: 1.4.756
|
||||
node-releases: 2.0.14
|
||||
update-browserslist-db: 1.0.14(browserslist@4.23.0)
|
||||
update-browserslist-db: 1.0.15(browserslist@4.23.0)
|
||||
|
||||
buffer-alloc-unsafe@1.1.0: {}
|
||||
|
||||
@@ -6150,7 +6147,7 @@ snapshots:
|
||||
|
||||
eastasianwidth@0.2.0: {}
|
||||
|
||||
electron-to-chromium@1.4.754: {}
|
||||
electron-to-chromium@1.4.756: {}
|
||||
|
||||
emoji-regex@10.3.0: {}
|
||||
|
||||
@@ -7100,8 +7097,6 @@ snapshots:
|
||||
|
||||
kind-of@6.0.3: {}
|
||||
|
||||
known-css-properties@0.29.0: {}
|
||||
|
||||
known-css-properties@0.30.0: {}
|
||||
|
||||
less@4.2.0:
|
||||
@@ -7854,7 +7849,7 @@ snapshots:
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
react-hook-form@7.51.3(react@18.3.1):
|
||||
react-hook-form@7.51.4(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
@@ -8269,9 +8264,9 @@ snapshots:
|
||||
postcss-sorting: 8.0.2(postcss@8.4.38)
|
||||
stylelint: 16.5.0(typescript@5.4.5)
|
||||
|
||||
stylelint-scss@6.2.1(stylelint@16.5.0(typescript@5.4.5)):
|
||||
stylelint-scss@6.3.0(stylelint@16.5.0(typescript@5.4.5)):
|
||||
dependencies:
|
||||
known-css-properties: 0.29.0
|
||||
known-css-properties: 0.30.0
|
||||
postcss-media-query-parser: 0.2.3
|
||||
postcss-resolve-nested-selector: 0.1.1
|
||||
postcss-selector-parser: 6.0.16
|
||||
@@ -8606,7 +8601,7 @@ snapshots:
|
||||
|
||||
universalify@2.0.1: {}
|
||||
|
||||
update-browserslist-db@1.0.14(browserslist@4.23.0):
|
||||
update-browserslist-db@1.0.15(browserslist@4.23.0):
|
||||
dependencies:
|
||||
browserslist: 4.23.0
|
||||
escalade: 3.1.2
|
||||
|
@@ -1,6 +1,6 @@
|
||||
function main(params) {
|
||||
if (params.mode === "script") {
|
||||
params.mode = "rule";
|
||||
function main(config) {
|
||||
if (config.mode === "script") {
|
||||
config.mode = "rule";
|
||||
}
|
||||
return params;
|
||||
return config;
|
||||
}
|
||||
|
@@ -1,10 +1,10 @@
|
||||
function main(params) {
|
||||
if (Array.isArray(params.proxies)) {
|
||||
params.proxies.forEach((p, i) => {
|
||||
function main(config) {
|
||||
if (Array.isArray(config.proxies)) {
|
||||
config.proxies.forEach((p, i) => {
|
||||
if (p.type === "hysteria" && typeof p.alpn === "string") {
|
||||
params.proxies[i].alpn = [p.alpn];
|
||||
config.proxies[i].alpn = [p.alpn];
|
||||
}
|
||||
});
|
||||
}
|
||||
return params;
|
||||
return config;
|
||||
}
|
||||
|
@@ -1,18 +1,17 @@
|
||||
//! Some config file template
|
||||
|
||||
/// template for new a profile item
|
||||
pub const ITEM_LOCAL: &str = "# Profile Template for clash verge
|
||||
pub const ITEM_LOCAL: &str = "# Profile Template for Clash Verge
|
||||
|
||||
proxies:
|
||||
proxies: []
|
||||
|
||||
proxy-groups:
|
||||
proxy-groups: []
|
||||
|
||||
rules:
|
||||
rules: []
|
||||
";
|
||||
|
||||
/// enhanced profile
|
||||
pub const ITEM_MERGE: &str = "# Merge Template for clash verge
|
||||
# The `Merge` format used to enhance profile
|
||||
pub const ITEM_MERGE: &str = "# Profile Enhancement Merge Template for Clash Verge
|
||||
|
||||
prepend-rules: []
|
||||
|
||||
@@ -36,9 +35,9 @@ append-proxy-groups: []
|
||||
";
|
||||
|
||||
/// enhanced profile
|
||||
pub const ITEM_SCRIPT: &str = "// Define the `main` function
|
||||
pub const ITEM_SCRIPT: &str = "// Define main function (script entry)
|
||||
|
||||
function main(params) {
|
||||
return params;
|
||||
function main(config) {
|
||||
return config;
|
||||
}
|
||||
";
|
||||
|
@@ -13,6 +13,7 @@ import {
|
||||
import { useClash } from "@/hooks/use-clash";
|
||||
import { BaseDialog, DialogRef, Notice, Switch } from "@/components/base";
|
||||
import { StackModeSwitch } from "./stack-mode-switch";
|
||||
import { enhanceProfiles } from "@/services/cmds";
|
||||
|
||||
export const TunViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -65,6 +66,12 @@ export const TunViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
}),
|
||||
false
|
||||
);
|
||||
try {
|
||||
await enhanceProfiles();
|
||||
Notice.success("Refresh clash config", 1000);
|
||||
} catch (err: any) {
|
||||
Notice.error(err.message || err.toString(), 3000);
|
||||
}
|
||||
setOpen(false);
|
||||
} catch (err: any) {
|
||||
Notice.error(err.message || err.toString());
|
||||
|
@@ -1,2 +1,2 @@
|
||||
LINUX_VERSION-5.10 = .215
|
||||
LINUX_KERNEL_HASH-5.10.215 = 879ca159c34ea9d3a6775f292cc59c2d3931d57dca00f0bebe2675ea0c82c6a9
|
||||
LINUX_VERSION-5.10 = .216
|
||||
LINUX_KERNEL_HASH-5.10.216 = e310588c4b23f0959614e60f007afc20e9b1a8f296d682b041fa129f96fbe151
|
||||
|
@@ -1,2 +1,2 @@
|
||||
LINUX_VERSION-5.15 = .157
|
||||
LINUX_KERNEL_HASH-5.15.157 = aff22351d34d69a16762dcf1fd51fe228da55d4b96b67247bdd598a86cc7a414
|
||||
LINUX_VERSION-5.15 = .158
|
||||
LINUX_KERNEL_HASH-5.15.158 = f9071c83a4fd8b80af026b48cfc1869bfa25883f9148b92b5dc1e1e1e26dd5c6
|
||||
|
@@ -1,2 +1,2 @@
|
||||
LINUX_VERSION-5.4 = .274
|
||||
LINUX_KERNEL_HASH-5.4.274 = eac7b421a43cd46a3dbebf7c85d075faa7e164d80d215d31fcd35544b6f79ed4
|
||||
LINUX_VERSION-5.4 = .275
|
||||
LINUX_KERNEL_HASH-5.4.275 = dad2b068946f0ca0026130d7ab17601d5074d90b381379c4479314d4edf4304c
|
||||
|
@@ -19,7 +19,7 @@ Subject: [PATCH 210/210] b44: register adm switch
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
@@ -2249,6 +2251,69 @@ static void b44_adjust_link(struct net_d
|
||||
@@ -2251,6 +2253,69 @@ static void b44_adjust_link(struct net_d
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ Subject: [PATCH 210/210] b44: register adm switch
|
||||
static int b44_register_phy_one(struct b44 *bp)
|
||||
{
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
|
||||
@@ -2285,6 +2350,9 @@ static int b44_register_phy_one(struct b
|
||||
@@ -2287,6 +2352,9 @@ static int b44_register_phy_one(struct b
|
||||
if (!mdiobus_is_registered_device(bp->mii_bus, bp->phy_addr) &&
|
||||
(sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) {
|
||||
|
||||
@@ -99,7 +99,7 @@ Subject: [PATCH 210/210] b44: register adm switch
|
||||
dev_info(sdev->dev,
|
||||
"could not find PHY at %i, use fixed one\n",
|
||||
bp->phy_addr);
|
||||
@@ -2481,6 +2549,7 @@ static void b44_remove_one(struct ssb_de
|
||||
@@ -2483,6 +2551,7 @@ static void b44_remove_one(struct ssb_de
|
||||
unregister_netdev(dev);
|
||||
if (bp->flags & B44_FLAG_EXTERNAL_PHY)
|
||||
b44_unregister_phy_one(bp);
|
||||
|
@@ -43,7 +43,7 @@
|
||||
|
||||
if (bp->flags & B44_FLAG_EXTERNAL_PHY)
|
||||
return 0;
|
||||
@@ -2179,6 +2204,8 @@ static int b44_get_invariants(struct b44
|
||||
@@ -2181,6 +2206,8 @@ static int b44_get_invariants(struct b44
|
||||
* valid PHY address. */
|
||||
bp->phy_addr &= 0x1F;
|
||||
|
||||
|
@@ -1913,7 +1913,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
eth_hw_addr_inherit(slave_dev, master);
|
||||
--- a/net/ethernet/eth.c
|
||||
+++ b/net/ethernet/eth.c
|
||||
@@ -506,13 +506,14 @@ unsigned char * __weak arch_get_platform
|
||||
@@ -496,13 +496,14 @@ unsigned char * __weak arch_get_platform
|
||||
|
||||
int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
|
||||
{
|
||||
|
@@ -35,7 +35,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
/* Enable checksum offload */
|
||||
*tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
|
||||
@@ -1587,17 +1588,19 @@ ax88179_tx_fixup(struct usbnet *dev, str
|
||||
@@ -1582,17 +1583,19 @@ ax88179_tx_fixup(struct usbnet *dev, str
|
||||
{
|
||||
u32 tx_hdr1, tx_hdr2;
|
||||
int frame_size = dev->maxpacket;
|
||||
@@ -57,7 +57,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
if ((skb_header_cloned(skb) || headroom < 0) &&
|
||||
pskb_expand_head(skb, headroom < 0 ? 8 : 0, 0, GFP_ATOMIC)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
@@ -1608,6 +1611,8 @@ ax88179_tx_fixup(struct usbnet *dev, str
|
||||
@@ -1603,6 +1606,8 @@ ax88179_tx_fixup(struct usbnet *dev, str
|
||||
put_unaligned_le32(tx_hdr1, ptr);
|
||||
put_unaligned_le32(tx_hdr2, ptr + 4);
|
||||
|
||||
|
@@ -73,7 +73,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
|
||||
--- a/arch/Kconfig
|
||||
+++ b/arch/Kconfig
|
||||
@@ -1299,6 +1299,14 @@ config ARCH_HAS_ELFCORE_COMPAT
|
||||
@@ -1307,6 +1307,14 @@ config ARCH_HAS_ELFCORE_COMPAT
|
||||
config ARCH_HAS_PARANOID_L1D_FLUSH
|
||||
bool
|
||||
|
||||
@@ -90,7 +90,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
source "scripts/gcc-plugins/Kconfig"
|
||||
--- a/arch/x86/Kconfig
|
||||
+++ b/arch/x86/Kconfig
|
||||
@@ -85,6 +85,7 @@ config X86
|
||||
@@ -86,6 +86,7 @@ config X86
|
||||
select ARCH_HAS_PMEM_API if X86_64
|
||||
select ARCH_HAS_PTE_DEVMAP if X86_64
|
||||
select ARCH_HAS_PTE_SPECIAL
|
||||
|
@@ -552,7 +552,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
--- a/kernel/bounds.c
|
||||
+++ b/kernel/bounds.c
|
||||
@@ -22,6 +22,11 @@ int main(void)
|
||||
DEFINE(NR_CPUS_BITS, bits_per(CONFIG_NR_CPUS));
|
||||
DEFINE(NR_CPUS_BITS, order_base_2(CONFIG_NR_CPUS));
|
||||
#endif
|
||||
DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t));
|
||||
+#ifdef CONFIG_LRU_GEN
|
||||
|
@@ -1,30 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Mon, 7 Feb 2022 10:27:22 +0100
|
||||
Subject: [PATCH] arm64: dts: mediatek: mt7622: add support for coherent
|
||||
DMA
|
||||
|
||||
It improves performance by eliminating the need for a cache flush on rx and tx
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
@@ -357,7 +357,7 @@
|
||||
};
|
||||
|
||||
cci_control2: slave-if@5000 {
|
||||
- compatible = "arm,cci-400-ctrl-if";
|
||||
+ compatible = "arm,cci-400-ctrl-if", "syscon";
|
||||
interface-type = "ace";
|
||||
reg = <0x5000 0x1000>;
|
||||
};
|
||||
@@ -938,6 +938,8 @@
|
||||
power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
|
||||
mediatek,ethsys = <ðsys>;
|
||||
mediatek,sgmiisys = <&sgmiisys>;
|
||||
+ mediatek,cci-control = <&cci_control2>;
|
||||
+ dma-coherent;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
@@ -1,62 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 5 Feb 2022 18:36:36 +0100
|
||||
Subject: [PATCH] arm64: dts: mediatek: mt7622: introduce nodes for
|
||||
Wireless Ethernet Dispatch
|
||||
|
||||
Introduce wed0 and wed1 nodes in order to enable offloading forwarding
|
||||
between ethernet and wireless devices on the mt7622 chipset.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
@@ -894,6 +894,11 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ hifsys: syscon@1af00000 {
|
||||
+ compatible = "mediatek,mt7622-hifsys", "syscon";
|
||||
+ reg = <0 0x1af00000 0 0x70>;
|
||||
+ };
|
||||
+
|
||||
ethsys: syscon@1b000000 {
|
||||
compatible = "mediatek,mt7622-ethsys",
|
||||
"syscon";
|
||||
@@ -912,6 +917,26 @@
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
+ pcie_mirror: pcie-mirror@10000400 {
|
||||
+ compatible = "mediatek,mt7622-pcie-mirror",
|
||||
+ "syscon";
|
||||
+ reg = <0 0x10000400 0 0x10>;
|
||||
+ };
|
||||
+
|
||||
+ wed0: wed@1020a000 {
|
||||
+ compatible = "mediatek,mt7622-wed",
|
||||
+ "syscon";
|
||||
+ reg = <0 0x1020a000 0 0x1000>;
|
||||
+ interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ wed1: wed@1020b000 {
|
||||
+ compatible = "mediatek,mt7622-wed",
|
||||
+ "syscon";
|
||||
+ reg = <0 0x1020b000 0 0x1000>;
|
||||
+ interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ };
|
||||
+
|
||||
eth: ethernet@1b100000 {
|
||||
compatible = "mediatek,mt7622-eth",
|
||||
"mediatek,mt2701-eth",
|
||||
@@ -939,6 +964,9 @@
|
||||
mediatek,ethsys = <ðsys>;
|
||||
mediatek,sgmiisys = <&sgmiisys>;
|
||||
mediatek,cci-control = <&cci_control2>;
|
||||
+ mediatek,wed = <&wed0>, <&wed1>;
|
||||
+ mediatek,pcie-mirror = <&pcie_mirror>;
|
||||
+ mediatek,hifsys = <&hifsys>;
|
||||
dma-coherent;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
@@ -13,7 +13,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
@@ -963,7 +963,7 @@
|
||||
@@ -957,7 +957,7 @@
|
||||
power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
|
||||
mediatek,ethsys = <ðsys>;
|
||||
mediatek,sgmiisys = <&sgmiisys>;
|
||||
|
@@ -35,7 +35,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
ax88179_reset(dev);
|
||||
|
||||
@@ -1507,17 +1508,19 @@ ax88179_tx_fixup(struct usbnet *dev, str
|
||||
@@ -1502,17 +1503,19 @@ ax88179_tx_fixup(struct usbnet *dev, str
|
||||
{
|
||||
u32 tx_hdr1, tx_hdr2;
|
||||
int frame_size = dev->maxpacket;
|
||||
@@ -57,7 +57,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
if ((skb_header_cloned(skb) || headroom < 0) &&
|
||||
pskb_expand_head(skb, headroom < 0 ? 8 : 0, 0, GFP_ATOMIC)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
@@ -1528,6 +1531,8 @@ ax88179_tx_fixup(struct usbnet *dev, str
|
||||
@@ -1523,6 +1526,8 @@ ax88179_tx_fixup(struct usbnet *dev, str
|
||||
put_unaligned_le32(tx_hdr1, ptr);
|
||||
put_unaligned_le32(tx_hdr2, ptr + 4);
|
||||
|
||||
|
@@ -17,7 +17,7 @@ Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
|
||||
|
||||
--- a/drivers/bluetooth/btusb.c
|
||||
+++ b/drivers/bluetooth/btusb.c
|
||||
@@ -2287,6 +2287,23 @@ struct btmtk_section_map {
|
||||
@@ -2289,6 +2289,23 @@ struct btmtk_section_map {
|
||||
};
|
||||
} __packed;
|
||||
|
||||
@@ -41,7 +41,7 @@ Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
|
||||
static void btusb_mtk_wmt_recv(struct urb *urb)
|
||||
{
|
||||
struct hci_dev *hdev = urb->context;
|
||||
@@ -3941,6 +3958,7 @@ static int btusb_probe(struct usb_interf
|
||||
@@ -3943,6 +3960,7 @@ static int btusb_probe(struct usb_interf
|
||||
hdev->shutdown = btusb_mtk_shutdown;
|
||||
hdev->manufacturer = 70;
|
||||
hdev->cmd_timeout = btusb_mtk_cmd_timeout;
|
||||
|
@@ -18,7 +18,7 @@ Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
|
||||
|
||||
--- a/drivers/bluetooth/btusb.c
|
||||
+++ b/drivers/bluetooth/btusb.c
|
||||
@@ -2292,7 +2292,7 @@ static int btusb_set_bdaddr_mtk(struct h
|
||||
@@ -2294,7 +2294,7 @@ static int btusb_set_bdaddr_mtk(struct h
|
||||
struct sk_buff *skb;
|
||||
long ret;
|
||||
|
||||
|
@@ -58,7 +58,7 @@ Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
|
||||
|
||||
--- a/drivers/bluetooth/btusb.c
|
||||
+++ b/drivers/bluetooth/btusb.c
|
||||
@@ -476,6 +476,9 @@ static const struct usb_device_id blackl
|
||||
@@ -478,6 +478,9 @@ static const struct usb_device_id blackl
|
||||
{ USB_DEVICE(0x13d3, 0x3564), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
|
@@ -56,7 +56,7 @@ Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
|
||||
|
||||
--- a/drivers/bluetooth/btusb.c
|
||||
+++ b/drivers/bluetooth/btusb.c
|
||||
@@ -467,6 +467,9 @@ static const struct usb_device_id blackl
|
||||
@@ -469,6 +469,9 @@ static const struct usb_device_id blackl
|
||||
BTUSB_VALID_LE_STATES },
|
||||
|
||||
/* Additional MediaTek MT7921 Bluetooth devices */
|
||||
|
@@ -54,7 +54,7 @@ Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
|
||||
|
||||
--- a/drivers/bluetooth/btusb.c
|
||||
+++ b/drivers/bluetooth/btusb.c
|
||||
@@ -485,6 +485,9 @@ static const struct usb_device_id blackl
|
||||
@@ -487,6 +487,9 @@ static const struct usb_device_id blackl
|
||||
{ USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
|
@@ -1775,7 +1775,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
eth_hw_addr_inherit(slave_dev, master);
|
||||
--- a/net/ethernet/eth.c
|
||||
+++ b/net/ethernet/eth.c
|
||||
@@ -550,13 +550,14 @@ unsigned char * __weak arch_get_platform
|
||||
@@ -540,13 +540,14 @@ unsigned char * __weak arch_get_platform
|
||||
|
||||
int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
|
||||
{
|
||||
|
@@ -11,7 +11,7 @@ Submitted-by: Yousong Zhou <yszhou4tech@gmail.com>
|
||||
|
||||
--- a/net/ethernet/eth.c
|
||||
+++ b/net/ethernet/eth.c
|
||||
@@ -538,6 +538,63 @@ int eth_platform_get_mac_address(struct
|
||||
@@ -528,6 +528,63 @@ int eth_platform_get_mac_address(struct
|
||||
}
|
||||
EXPORT_SYMBOL(eth_platform_get_mac_address);
|
||||
|
||||
@@ -75,7 +75,7 @@ Submitted-by: Yousong Zhou <yszhou4tech@gmail.com>
|
||||
/**
|
||||
* nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named
|
||||
* 'mac-address' associated with given device.
|
||||
@@ -551,19 +608,23 @@ int nvmem_get_mac_address(struct device
|
||||
@@ -541,19 +598,23 @@ int nvmem_get_mac_address(struct device
|
||||
{
|
||||
struct nvmem_cell *cell;
|
||||
const void *mac;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
--- a/drivers/usb/serial/option.c
|
||||
+++ b/drivers/usb/serial/option.c
|
||||
@@ -278,6 +278,7 @@ static void option_instat_callback(struc
|
||||
@@ -282,6 +282,7 @@ static void option_instat_callback(struc
|
||||
#define QUECTEL_PRODUCT_EM061K_LWW 0x6008
|
||||
#define QUECTEL_PRODUCT_EM061K_LCN 0x6009
|
||||
#define QUECTEL_PRODUCT_EC200T 0x6026
|
||||
@@ -8,7 +8,7 @@
|
||||
#define QUECTEL_PRODUCT_RM500K 0x7001
|
||||
|
||||
#define CMOTECH_VENDOR_ID 0x16d8
|
||||
@@ -1251,6 +1252,7 @@ static const struct usb_device_id option
|
||||
@@ -1267,6 +1268,7 @@ static const struct usb_device_id option
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) },
|
||||
|
@@ -91,7 +91,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
for (i = sizeof(struct ipt_entry);
|
||||
i < e->target_offset;
|
||||
i += m->u.match_size) {
|
||||
@@ -1224,12 +1261,15 @@ compat_copy_entry_to_user(struct ipt_ent
|
||||
@@ -1226,12 +1263,15 @@ compat_copy_entry_to_user(struct ipt_ent
|
||||
compat_uint_t origsize;
|
||||
const struct xt_entry_match *ematch;
|
||||
int ret = 0;
|
||||
|
@@ -136,9 +136,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
/**
|
||||
* eth_type_trans - determine the packet's protocol ID.
|
||||
* @skb: received socket data
|
||||
@@ -174,6 +186,10 @@ __be16 eth_type_trans(struct sk_buff *sk
|
||||
} else {
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
@@ -426,6 +438,10 @@ struct sk_buff *eth_gro_receive(struct l
|
||||
NAPI_GRO_CB(p)->same_flow = 0;
|
||||
continue;
|
||||
}
|
||||
+
|
||||
+ if (eth_check_local_mask(eth->h_dest, dev->dev_addr,
|
||||
@@ -146,4 +146,4 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ skb->gro_skip = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
type = eh->h_proto;
|
||||
|
@@ -1,30 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Mon, 7 Feb 2022 10:27:22 +0100
|
||||
Subject: [PATCH] arm64: dts: mediatek: mt7622: add support for coherent
|
||||
DMA
|
||||
|
||||
It improves performance by eliminating the need for a cache flush on rx and tx
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
@@ -357,7 +357,7 @@
|
||||
};
|
||||
|
||||
cci_control2: slave-if@5000 {
|
||||
- compatible = "arm,cci-400-ctrl-if";
|
||||
+ compatible = "arm,cci-400-ctrl-if", "syscon";
|
||||
interface-type = "ace";
|
||||
reg = <0x5000 0x1000>;
|
||||
};
|
||||
@@ -937,6 +937,8 @@
|
||||
power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
|
||||
mediatek,ethsys = <ðsys>;
|
||||
mediatek,sgmiisys = <&sgmiisys>;
|
||||
+ mediatek,cci-control = <&cci_control2>;
|
||||
+ dma-coherent;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
@@ -1,62 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 5 Feb 2022 18:36:36 +0100
|
||||
Subject: [PATCH] arm64: dts: mediatek: mt7622: introduce nodes for
|
||||
Wireless Ethernet Dispatch
|
||||
|
||||
Introduce wed0 and wed1 nodes in order to enable offloading forwarding
|
||||
between ethernet and wireless devices on the mt7622 chipset.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
@@ -893,6 +893,11 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ hifsys: syscon@1af00000 {
|
||||
+ compatible = "mediatek,mt7622-hifsys", "syscon";
|
||||
+ reg = <0 0x1af00000 0 0x70>;
|
||||
+ };
|
||||
+
|
||||
ethsys: syscon@1b000000 {
|
||||
compatible = "mediatek,mt7622-ethsys",
|
||||
"syscon";
|
||||
@@ -911,6 +916,26 @@
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
+ pcie_mirror: pcie-mirror@10000400 {
|
||||
+ compatible = "mediatek,mt7622-pcie-mirror",
|
||||
+ "syscon";
|
||||
+ reg = <0 0x10000400 0 0x10>;
|
||||
+ };
|
||||
+
|
||||
+ wed0: wed@1020a000 {
|
||||
+ compatible = "mediatek,mt7622-wed",
|
||||
+ "syscon";
|
||||
+ reg = <0 0x1020a000 0 0x1000>;
|
||||
+ interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ wed1: wed@1020b000 {
|
||||
+ compatible = "mediatek,mt7622-wed",
|
||||
+ "syscon";
|
||||
+ reg = <0 0x1020b000 0 0x1000>;
|
||||
+ interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ };
|
||||
+
|
||||
eth: ethernet@1b100000 {
|
||||
compatible = "mediatek,mt7622-eth",
|
||||
"mediatek,mt2701-eth",
|
||||
@@ -938,6 +963,9 @@
|
||||
mediatek,ethsys = <ðsys>;
|
||||
mediatek,sgmiisys = <&sgmiisys>;
|
||||
mediatek,cci-control = <&cci_control2>;
|
||||
+ mediatek,wed = <&wed0>, <&wed1>;
|
||||
+ mediatek,pcie-mirror = <&pcie_mirror>;
|
||||
+ mediatek,hifsys = <&hifsys>;
|
||||
dma-coherent;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
@@ -61,7 +61,7 @@ Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
|
||||
/*
|
||||
* We need to store the untouched command line for future reference.
|
||||
* We also need to store the touched command line since the parameter
|
||||
@@ -866,6 +889,7 @@ asmlinkage __visible void __init __no_sa
|
||||
@@ -868,6 +891,7 @@ asmlinkage __visible void __init __no_sa
|
||||
pr_notice("%s", linux_banner);
|
||||
early_security_init();
|
||||
setup_arch(&command_line);
|
||||
|
@@ -136,9 +136,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
/**
|
||||
* eth_type_trans - determine the packet's protocol ID.
|
||||
* @skb: received socket data
|
||||
@@ -173,6 +185,10 @@ __be16 eth_type_trans(struct sk_buff *sk
|
||||
} else {
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
@@ -421,6 +433,10 @@ struct sk_buff *eth_gro_receive(struct l
|
||||
NAPI_GRO_CB(p)->same_flow = 0;
|
||||
continue;
|
||||
}
|
||||
+
|
||||
+ if (eth_check_local_mask(eth->h_dest, dev->dev_addr,
|
||||
@@ -146,4 +146,4 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ skb->gro_skip = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
type = eh->h_proto;
|
||||
|
@@ -1,8 +1,8 @@
|
||||
--- a/drivers/net/usb/qmi_wwan.c
|
||||
+++ b/drivers/net/usb/qmi_wwan.c
|
||||
@@ -1431,6 +1431,9 @@ static const struct usb_device_id produc
|
||||
@@ -1420,6 +1420,9 @@ static const struct usb_device_id produc
|
||||
{QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/
|
||||
{QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */
|
||||
{QMI_QUIRK_SET_DTR(0x1546, 0x1312, 4)}, /* u-blox LARA-R6 01B */
|
||||
{QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */
|
||||
+ {QMI_FIXED_INTF(0x2077, 0x2002, 4)}, /* T&W TW04C */
|
||||
+ {QMI_FIXED_INTF(0x2077, 0x2003, 4)}, /* T&W TW12G */
|
||||
|
@@ -506,7 +506,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
+MODULE_ALIAS("nf-flow-table-hw");
|
||||
--- a/net/netfilter/nf_tables_api.c
|
||||
+++ b/net/netfilter/nf_tables_api.c
|
||||
@@ -6041,6 +6041,13 @@ static int nf_tables_flowtable_parse_hoo
|
||||
@@ -6045,6 +6045,13 @@ static int nf_tables_flowtable_parse_hoo
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@@ -520,7 +520,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
ops = kcalloc(n, sizeof(struct nf_hook_ops), GFP_KERNEL);
|
||||
if (!ops)
|
||||
return -ENOMEM;
|
||||
@@ -6190,10 +6197,19 @@ static int nf_tables_newflowtable(struct
|
||||
@@ -6194,10 +6201,19 @@ static int nf_tables_newflowtable(struct
|
||||
}
|
||||
|
||||
flowtable->data.type = type;
|
||||
@@ -540,7 +540,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
err = nf_tables_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK],
|
||||
flowtable);
|
||||
if (err < 0)
|
||||
@@ -6319,7 +6335,8 @@ static int nf_tables_fill_flowtable_info
|
||||
@@ -6323,7 +6339,8 @@ static int nf_tables_fill_flowtable_info
|
||||
nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) ||
|
||||
nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) ||
|
||||
nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle),
|
||||
|
@@ -136,9 +136,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
/**
|
||||
* eth_type_trans - determine the packet's protocol ID.
|
||||
* @skb: received socket data
|
||||
@@ -174,6 +186,10 @@ __be16 eth_type_trans(struct sk_buff *sk
|
||||
} else {
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
@@ -470,6 +482,10 @@ struct sk_buff *eth_gro_receive(struct l
|
||||
NAPI_GRO_CB(p)->same_flow = 0;
|
||||
continue;
|
||||
}
|
||||
+
|
||||
+ if (eth_check_local_mask(eth->h_dest, dev->dev_addr,
|
||||
@@ -146,4 +146,4 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ skb->gro_skip = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
type = eh->h_proto;
|
||||
|
@@ -189,7 +189,7 @@ Signed-off-by: Adrian Panella <ianchi74@outlook.com>
|
||||
static int kernel_init(void *);
|
||||
|
||||
extern void init_IRQ(void);
|
||||
@@ -903,6 +907,18 @@ asmlinkage __visible void __init __no_sa
|
||||
@@ -905,6 +909,18 @@ asmlinkage __visible void __init __no_sa
|
||||
pr_notice("Kernel command line: %s\n", saved_command_line);
|
||||
/* parameters may set static keys */
|
||||
jump_label_init();
|
||||
|
@@ -1,6 +1,6 @@
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
@@ -559,6 +559,7 @@
|
||||
@@ -556,6 +556,7 @@
|
||||
compatible = "mediatek,mt7622-nor",
|
||||
"mediatek,mt8173-nor";
|
||||
reg = <0 0x11014000 0 0xe0>;
|
||||
|
@@ -14,7 +14,7 @@ Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
|
||||
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
@@ -553,6 +553,18 @@
|
||||
@@ -550,6 +550,18 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@@ -95,7 +95,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
@@ -339,7 +339,7 @@
|
||||
@@ -337,7 +337,7 @@
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-parent = <&gic>;
|
||||
reg = <0 0x10310000 0 0x1000>,
|
||||
|
@@ -112,7 +112,7 @@ Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
|
||||
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
@@ -942,6 +942,7 @@
|
||||
@@ -938,6 +938,7 @@
|
||||
clock-names = "hsdma";
|
||||
power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
|
||||
#dma-cells = <1>;
|
||||
|
@@ -21,7 +21,7 @@ Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
|
||||
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
|
||||
@@ -915,64 +915,67 @@
|
||||
@@ -916,64 +916,67 @@
|
||||
};
|
||||
};
|
||||
|
||||
@@ -194,7 +194,7 @@ Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
|
||||
&pio {
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
@@ -809,75 +809,83 @@
|
||||
@@ -804,75 +804,83 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
@@ -849,6 +849,12 @@
|
||||
@@ -844,6 +844,12 @@
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
@@ -13,7 +13,7 @@
|
||||
};
|
||||
|
||||
pcie1: pcie@1a145000 {
|
||||
@@ -887,6 +893,12 @@
|
||||
@@ -882,6 +888,12 @@
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
|
@@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||
@@ -837,6 +837,9 @@
|
||||
@@ -832,6 +832,9 @@
|
||||
bus-range = <0x00 0xff>;
|
||||
ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>;
|
||||
status = "disabled";
|
||||
@@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 7>;
|
||||
@@ -881,6 +884,9 @@
|
||||
@@ -876,6 +879,9 @@
|
||||
bus-range = <0x00 0xff>;
|
||||
ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>;
|
||||
status = "disabled";
|
||||
|
@@ -187,7 +187,7 @@ Signed-off-by: Michael Gray <michael.gray@lantisproject.com>
|
||||
static int kernel_init(void *);
|
||||
|
||||
extern void init_IRQ(void);
|
||||
@@ -901,6 +905,18 @@ asmlinkage __visible void __init __no_sa
|
||||
@@ -903,6 +907,18 @@ asmlinkage __visible void __init __no_sa
|
||||
page_alloc_init();
|
||||
|
||||
pr_notice("Kernel command line: %s\n", saved_command_line);
|
||||
|
@@ -168,7 +168,7 @@ Signed-off-by: Adrian Panella <ianchi74@outlook.com>
|
||||
static int kernel_init(void *);
|
||||
|
||||
extern void init_IRQ(void);
|
||||
@@ -901,6 +905,18 @@ asmlinkage __visible void __init __no_sa
|
||||
@@ -903,6 +907,18 @@ asmlinkage __visible void __init __no_sa
|
||||
page_alloc_init();
|
||||
|
||||
pr_notice("Kernel command line: %s\n", saved_command_line);
|
||||
|
@@ -1849,7 +1849,7 @@
|
||||
+obj-$(CONFIG_PHYTIUM_IXIC) += irq-phytium-ixic.o
|
||||
--- a/drivers/irqchip/irq-gic-v3-its.c
|
||||
+++ b/drivers/irqchip/irq-gic-v3-its.c
|
||||
@@ -4792,6 +4792,7 @@ static void its_restore_enable(void)
|
||||
@@ -4787,6 +4787,7 @@ static void its_restore_enable(void)
|
||||
{
|
||||
struct its_node *its;
|
||||
int ret;
|
||||
@@ -1857,7 +1857,7 @@
|
||||
|
||||
raw_spin_lock(&its_lock);
|
||||
list_for_each_entry(its, &its_nodes, entry) {
|
||||
@@ -4845,6 +4846,23 @@ static void its_restore_enable(void)
|
||||
@@ -4840,6 +4841,23 @@ static void its_restore_enable(void)
|
||||
GITS_TYPER_HCC(gic_read_typer(base + GITS_TYPER)))
|
||||
its_cpu_init_collection(its);
|
||||
}
|
||||
|
@@ -138,7 +138,7 @@ Subject: [PATCH] irqchip: gic-v3: add hackaround for rk3568 its
|
||||
if (alloc_lpis) {
|
||||
lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis);
|
||||
if (lpi_map)
|
||||
@@ -4726,6 +4763,13 @@ static bool __maybe_unused its_enable_qu
|
||||
@@ -4721,6 +4758,13 @@ static bool __maybe_unused its_enable_qu
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ Subject: [PATCH] irqchip: gic-v3: add hackaround for rk3568 its
|
||||
static const struct gic_quirk its_quirks[] = {
|
||||
#ifdef CONFIG_CAVIUM_ERRATUM_22375
|
||||
{
|
||||
@@ -4772,6 +4816,14 @@ static const struct gic_quirk its_quirks
|
||||
@@ -4767,6 +4811,14 @@ static const struct gic_quirk its_quirks
|
||||
.init = its_enable_quirk_hip07_161600802,
|
||||
},
|
||||
#endif
|
||||
@@ -167,7 +167,7 @@ Subject: [PATCH] irqchip: gic-v3: add hackaround for rk3568 its
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -4995,6 +5047,7 @@ static int __init its_probe_one(struct r
|
||||
@@ -4990,6 +5042,7 @@ static int __init its_probe_one(struct r
|
||||
u64 baser, tmp, typer;
|
||||
struct page *page;
|
||||
int err;
|
||||
@@ -175,7 +175,7 @@ Subject: [PATCH] irqchip: gic-v3: add hackaround for rk3568 its
|
||||
|
||||
its_base = ioremap(res->start, SZ_64K);
|
||||
if (!its_base) {
|
||||
@@ -5063,7 +5116,9 @@ static int __init its_probe_one(struct r
|
||||
@@ -5058,7 +5111,9 @@ static int __init its_probe_one(struct r
|
||||
|
||||
its->numa_node = numa_node;
|
||||
|
||||
@@ -186,7 +186,7 @@ Subject: [PATCH] irqchip: gic-v3: add hackaround for rk3568 its
|
||||
get_order(ITS_CMD_QUEUE_SZ));
|
||||
if (!page) {
|
||||
err = -ENOMEM;
|
||||
@@ -5094,6 +5149,9 @@ static int __init its_probe_one(struct r
|
||||
@@ -5089,6 +5144,9 @@ static int __init its_probe_one(struct r
|
||||
gits_write_cbaser(baser, its->base + GITS_CBASER);
|
||||
tmp = gits_read_cbaser(its->base + GITS_CBASER);
|
||||
|
||||
|
@@ -98,4 +98,3 @@ API.
|
||||
|
||||
This software is released under the GPL-3.0 license.
|
||||
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2FMetaCubeX%2Fmihomo?ref=badge_large)
|
||||
|
@@ -97,3 +97,7 @@ Options:
|
||||
--ssl-key-log-file=<path>
|
||||
|
||||
Saves SSL keys for Wireshark inspection.
|
||||
|
||||
--no-post-quantum
|
||||
|
||||
Overrides the default and disables post-quantum key agreement.
|
||||
|
@@ -115,6 +115,6 @@ mkdir -p out
|
||||
|
||||
export DEPOT_TOOLS_WIN_TOOLCHAIN=0
|
||||
|
||||
./gn/out/gn gen "$out" --args="$flags $EXTRA_FLAGS" --script-executable=$PYTHON
|
||||
./gn/out/gn gen "$out" --args="$flags $EXTRA_FLAGS"
|
||||
|
||||
ninja -C "$out" naive
|
||||
|
@@ -24,7 +24,11 @@ if [ ! "$target_cpu" ]; then
|
||||
target_cpu="$host_cpu"
|
||||
fi
|
||||
|
||||
PYTHON=$(which python3 2>/dev/null || which python 2>/dev/null)
|
||||
if which python3 >/dev/null 2>/dev/null; then
|
||||
PYTHON=python3
|
||||
else
|
||||
PYTHON=python
|
||||
fi
|
||||
|
||||
# sysroot
|
||||
case "$target_os" in
|
||||
|
@@ -1744,6 +1744,12 @@ static_library("preload_decoder") {
|
||||
|
||||
executable("naive") {
|
||||
sources = [
|
||||
"tools/naive/http_proxy_server_socket.cc",
|
||||
"tools/naive/http_proxy_server_socket.h",
|
||||
"tools/naive/naive_command_line.cc",
|
||||
"tools/naive/naive_command_line.h",
|
||||
"tools/naive/naive_config.cc",
|
||||
"tools/naive/naive_config.h",
|
||||
"tools/naive/naive_connection.cc",
|
||||
"tools/naive/naive_connection.h",
|
||||
"tools/naive/naive_padding_framer.cc",
|
||||
@@ -1752,15 +1758,13 @@ executable("naive") {
|
||||
"tools/naive/naive_padding_socket.h",
|
||||
"tools/naive/naive_protocol.cc",
|
||||
"tools/naive/naive_protocol.h",
|
||||
"tools/naive/naive_proxy_bin.cc",
|
||||
"tools/naive/naive_proxy_delegate.cc",
|
||||
"tools/naive/naive_proxy_delegate.h",
|
||||
"tools/naive/naive_proxy.cc",
|
||||
"tools/naive/naive_proxy.h",
|
||||
"tools/naive/naive_proxy_bin.cc",
|
||||
"tools/naive/naive_proxy_delegate.h",
|
||||
"tools/naive/naive_proxy_delegate.cc",
|
||||
"tools/naive/http_proxy_server_socket.cc",
|
||||
"tools/naive/http_proxy_server_socket.h",
|
||||
"tools/naive/redirect_resolver.h",
|
||||
"tools/naive/redirect_resolver.cc",
|
||||
"tools/naive/redirect_resolver.h",
|
||||
"tools/naive/socks5_server_socket.cc",
|
||||
"tools/naive/socks5_server_socket.h",
|
||||
]
|
||||
|
74
naiveproxy/src/net/tools/naive/naive_command_line.cc
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright 2024 klzgrad <kizdiv@gmail.com>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
#include "net/tools/naive/naive_command_line.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include "base/strings/string_util_win.h"
|
||||
#endif
|
||||
|
||||
DuplicateSwitchCollector::DuplicateSwitchCollector() = default;
|
||||
DuplicateSwitchCollector::~DuplicateSwitchCollector() = default;
|
||||
|
||||
void DuplicateSwitchCollector::ResolveDuplicate(
|
||||
std::string_view key,
|
||||
base::CommandLine::StringPieceType new_value,
|
||||
base::CommandLine::StringType& out_value) {
|
||||
out_value = new_value;
|
||||
values_by_key_[std::string(key)].push_back(
|
||||
base::CommandLine::StringType(new_value));
|
||||
}
|
||||
|
||||
const std::vector<base::CommandLine::StringType>&
|
||||
DuplicateSwitchCollector::GetValuesByKey(std::string_view key) {
|
||||
return values_by_key_[std::string(key)];
|
||||
}
|
||||
|
||||
namespace {
|
||||
DuplicateSwitchCollector* g_duplicate_switch_collector;
|
||||
}
|
||||
|
||||
void DuplicateSwitchCollector::InitInstance() {
|
||||
auto new_duplicate_switch_collector =
|
||||
std::make_unique<DuplicateSwitchCollector>();
|
||||
g_duplicate_switch_collector = new_duplicate_switch_collector.get();
|
||||
base::CommandLine::SetDuplicateSwitchHandler(
|
||||
std::move(new_duplicate_switch_collector));
|
||||
}
|
||||
|
||||
DuplicateSwitchCollector& DuplicateSwitchCollector::GetInstance() {
|
||||
CHECK(g_duplicate_switch_collector != nullptr);
|
||||
return *g_duplicate_switch_collector;
|
||||
}
|
||||
|
||||
base::Value::Dict GetSwitchesAsValue(const base::CommandLine& cmdline) {
|
||||
base::Value::Dict dict;
|
||||
for (const auto& [key, value] : cmdline.GetSwitches()) {
|
||||
const std::vector<base::CommandLine::StringType>& values =
|
||||
DuplicateSwitchCollector::GetInstance().GetValuesByKey(key);
|
||||
if (values.size() > 1) {
|
||||
base::Value::List list;
|
||||
for (const base::CommandLine::StringType& v : values) {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
list.Append(base::AsStringPiece16(v));
|
||||
#else
|
||||
list.Append(v);
|
||||
#endif
|
||||
}
|
||||
dict.Set(key, std::move(list));
|
||||
} else {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
dict.Set(key, base::AsStringPiece16(value));
|
||||
#else
|
||||
dict.Set(key, value);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return dict;
|
||||
}
|
36
naiveproxy/src/net/tools/naive/naive_command_line.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2024 klzgrad <kizdiv@gmail.com>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
#ifndef NET_TOOLS_NAIVE_NAIVE_COMMAND_LINE_H_
|
||||
#define NET_TOOLS_NAIVE_NAIVE_COMMAND_LINE_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/values.h"
|
||||
|
||||
class DuplicateSwitchCollector : public base::DuplicateSwitchHandler {
|
||||
public:
|
||||
DuplicateSwitchCollector();
|
||||
~DuplicateSwitchCollector() override;
|
||||
|
||||
void ResolveDuplicate(std::string_view key,
|
||||
base::CommandLine::StringPieceType new_value,
|
||||
base::CommandLine::StringType& out_value) override;
|
||||
|
||||
const std::vector<base::CommandLine::StringType>& GetValuesByKey(
|
||||
std::string_view key);
|
||||
|
||||
static void InitInstance();
|
||||
static DuplicateSwitchCollector& GetInstance();
|
||||
|
||||
private:
|
||||
std::map<std::string, std::vector<base::CommandLine::StringType>>
|
||||
values_by_key_;
|
||||
};
|
||||
|
||||
base::Value::Dict GetSwitchesAsValue(const base::CommandLine& cmdline);
|
||||
#endif // NET_TOOLS_NAIVE_NAIVE_COMMAND_LINE_H_
|
202
naiveproxy/src/net/tools/naive/naive_config.cc
Normal file
@@ -0,0 +1,202 @@
|
||||
// Copyright 2024 klzgrad <kizdiv@gmail.com>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
#include "net/tools/naive/naive_config.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "base/strings/escape.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "net/base/url_util.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace net {
|
||||
|
||||
NaiveListenConfig::NaiveListenConfig() = default;
|
||||
NaiveListenConfig::NaiveListenConfig(const NaiveListenConfig&) = default;
|
||||
NaiveListenConfig::~NaiveListenConfig() = default;
|
||||
|
||||
bool NaiveListenConfig::Parse(const std::string& str) {
|
||||
GURL url(str);
|
||||
if (url.scheme() == "socks") {
|
||||
protocol = ClientProtocol::kSocks5;
|
||||
} else if (url.scheme() == "http") {
|
||||
protocol = ClientProtocol::kHttp;
|
||||
} else if (url.scheme() == "redir") {
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
protocol = ClientProtocol::kRedir;
|
||||
#else
|
||||
std::cerr << "Redir protocol only supports Linux." << std::endl;
|
||||
return false;
|
||||
#endif
|
||||
} else {
|
||||
std::cerr << "Invalid scheme in " << str << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!url.username().empty()) {
|
||||
user = base::UnescapeBinaryURLComponent(url.username());
|
||||
}
|
||||
if (!url.password().empty()) {
|
||||
pass = base::UnescapeBinaryURLComponent(url.password());
|
||||
}
|
||||
|
||||
if (!url.host().empty()) {
|
||||
addr = url.HostNoBrackets();
|
||||
}
|
||||
|
||||
int effective_port = url.EffectiveIntPort();
|
||||
if (effective_port == url::PORT_INVALID) {
|
||||
std::cerr << "Invalid port in " << str << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (effective_port != url::PORT_UNSPECIFIED) {
|
||||
port = effective_port;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NaiveConfig::NaiveConfig() = default;
|
||||
NaiveConfig::NaiveConfig(const NaiveConfig&) = default;
|
||||
NaiveConfig::~NaiveConfig() = default;
|
||||
|
||||
bool NaiveConfig::Parse(const base::Value::Dict& value) {
|
||||
if (const base::Value* v = value.Find("listen")) {
|
||||
listen.clear();
|
||||
if (const std::string* str = v->GetIfString()) {
|
||||
if (!listen.emplace_back().Parse(*str)) {
|
||||
return false;
|
||||
}
|
||||
} else if (const base::Value::List* strs = v->GetIfList()) {
|
||||
for (const auto& str_e : *strs) {
|
||||
if (const std::string* s = str_e.GetIfString()) {
|
||||
if (!listen.emplace_back().Parse(*s)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Invalid listen element" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Invalid listen" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (const base::Value* v = value.Find("insecure-concurrency")) {
|
||||
if (std::optional<int> i = v->GetIfInt()) {
|
||||
insecure_concurrency = *i;
|
||||
} else if (const std::string* str = v->GetIfString()) {
|
||||
if (!base::StringToInt(*str, &insecure_concurrency)) {
|
||||
std::cerr << "Invalid concurrency" << std::endl;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Invalid concurrency" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (insecure_concurrency < 1) {
|
||||
std::cerr << "Invalid concurrency" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (const base::Value* v = value.Find("extra-headers")) {
|
||||
if (const std::string* str = v->GetIfString()) {
|
||||
extra_headers.AddHeadersFromString(*str);
|
||||
} else {
|
||||
std::cerr << "Invalid extra-headers" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (const base::Value* v = value.Find("proxy")) {
|
||||
if (const std::string* str = v->GetIfString(); str && !str->empty()) {
|
||||
GURL url(*str);
|
||||
net::GetIdentityFromURL(url, &proxy_user, &proxy_pass);
|
||||
|
||||
GURL::Replacements remove_auth;
|
||||
remove_auth.ClearUsername();
|
||||
remove_auth.ClearPassword();
|
||||
GURL url_no_auth = url.ReplaceComponents(remove_auth);
|
||||
proxy_url = url_no_auth.GetWithEmptyPath().spec();
|
||||
if (proxy_url.empty()) {
|
||||
std::cerr << "Invalid proxy" << std::endl;
|
||||
return false;
|
||||
} else if (proxy_url.back() == '/') {
|
||||
proxy_url.pop_back();
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Invalid proxy" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (const base::Value* v = value.Find("host-resolver-rules")) {
|
||||
if (const std::string* str = v->GetIfString()) {
|
||||
host_resolver_rules = *str;
|
||||
} else {
|
||||
std::cerr << "Invalid host-resolver-rules" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (const base::Value* v = value.Find("resolver-range")) {
|
||||
if (const std::string* str = v->GetIfString(); str && !str->empty()) {
|
||||
if (!net::ParseCIDRBlock(*str, &resolver_range, &resolver_prefix)) {
|
||||
std::cerr << "Invalid resolver-range" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (resolver_range.IsIPv6()) {
|
||||
std::cerr << "IPv6 resolver range not supported" << std::endl;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Invalid resolver-range" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (const base::Value* v = value.Find("log")) {
|
||||
if (const std::string* str = v->GetIfString()) {
|
||||
if (!str->empty()) {
|
||||
log.logging_dest = logging::LOG_TO_FILE;
|
||||
log_file = base::FilePath::FromUTF8Unsafe(*str);
|
||||
log.log_file_path = log_file.value().c_str();
|
||||
} else {
|
||||
log.logging_dest = logging::LOG_TO_STDERR;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Invalid log" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (const base::Value* v = value.Find("log-net-log")) {
|
||||
if (const std::string* str = v->GetIfString(); str && !str->empty()) {
|
||||
log_net_log = base::FilePath::FromUTF8Unsafe(*str);
|
||||
} else {
|
||||
std::cerr << "Invalid log-net-log" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (const base::Value* v = value.Find("ssl-key-log-file")) {
|
||||
if (const std::string* str = v->GetIfString(); str && !str->empty()) {
|
||||
ssl_key_log_file = base::FilePath::FromUTF8Unsafe(*str);
|
||||
} else {
|
||||
std::cerr << "Invalid ssl-key-log-file" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (const base::Value* v = value.Find("no-post-quantum")) {
|
||||
no_post_quantum = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace net
|
66
naiveproxy/src/net/tools/naive/naive_config.h
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright 2024 klzgrad <kizdiv@gmail.com>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
#ifndef NET_TOOLS_NAIVE_NAIVE_CONFIG_H_
|
||||
#define NET_TOOLS_NAIVE_NAIVE_CONFIG_H_
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/values.h"
|
||||
#include "net/base/ip_address.h"
|
||||
#include "net/http/http_request_headers.h"
|
||||
#include "net/tools/naive/naive_protocol.h"
|
||||
|
||||
namespace net {
|
||||
|
||||
struct NaiveListenConfig {
|
||||
ClientProtocol protocol = ClientProtocol::kSocks5;
|
||||
std::string user;
|
||||
std::string pass;
|
||||
std::string addr = "0.0.0.0";
|
||||
int port = 1080;
|
||||
|
||||
NaiveListenConfig();
|
||||
NaiveListenConfig(const NaiveListenConfig&);
|
||||
~NaiveListenConfig();
|
||||
bool Parse(const std::string& str);
|
||||
};
|
||||
|
||||
struct NaiveConfig {
|
||||
std::vector<NaiveListenConfig> listen = {NaiveListenConfig()};
|
||||
|
||||
int insecure_concurrency = 1;
|
||||
|
||||
HttpRequestHeaders extra_headers;
|
||||
|
||||
std::string proxy_url = "direct://";
|
||||
|
||||
std::u16string proxy_user;
|
||||
std::u16string proxy_pass;
|
||||
|
||||
std::string host_resolver_rules;
|
||||
|
||||
IPAddress resolver_range = {100, 64, 0, 0};
|
||||
size_t resolver_prefix = 10;
|
||||
|
||||
logging::LoggingSettings log = {.logging_dest = logging::LOG_NONE};
|
||||
base::FilePath log_file;
|
||||
|
||||
base::FilePath log_net_log;
|
||||
|
||||
base::FilePath ssl_key_log_file;
|
||||
|
||||
std::optional<bool> no_post_quantum;
|
||||
|
||||
NaiveConfig();
|
||||
NaiveConfig(const NaiveConfig&);
|
||||
~NaiveConfig();
|
||||
bool Parse(const base::Value::Dict& value);
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
#endif // NET_TOOLS_NAIVE_NAIVE_CONFIG_H_
|
@@ -7,6 +7,7 @@
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "base/allocator/allocator_check.h"
|
||||
@@ -60,8 +61,11 @@
|
||||
#include "net/socket/ssl_client_socket.h"
|
||||
#include "net/socket/tcp_server_socket.h"
|
||||
#include "net/socket/udp_server_socket.h"
|
||||
#include "net/ssl/ssl_config_service.h"
|
||||
#include "net/ssl/ssl_key_logger_impl.h"
|
||||
#include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
|
||||
#include "net/tools/naive/naive_command_line.h"
|
||||
#include "net/tools/naive/naive_config.h"
|
||||
#include "net/tools/naive/naive_protocol.h"
|
||||
#include "net/tools/naive/naive_proxy.h"
|
||||
#include "net/tools/naive/naive_proxy_delegate.h"
|
||||
@@ -87,42 +91,6 @@ constexpr int kExpectedMaxUsers = 8;
|
||||
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
|
||||
net::DefineNetworkTrafficAnnotation("naive", "");
|
||||
|
||||
struct CommandLine {
|
||||
std::vector<std::string> listens;
|
||||
std::string proxy;
|
||||
std::string concurrency;
|
||||
std::string extra_headers;
|
||||
std::string host_resolver_rules;
|
||||
std::string resolver_range;
|
||||
bool no_log;
|
||||
base::FilePath log;
|
||||
base::FilePath log_net_log;
|
||||
base::FilePath ssl_key_log_file;
|
||||
};
|
||||
|
||||
struct ListenParams {
|
||||
net::ClientProtocol protocol;
|
||||
std::string listen_user;
|
||||
std::string listen_pass;
|
||||
std::string listen_addr;
|
||||
int listen_port;
|
||||
};
|
||||
|
||||
struct Params {
|
||||
std::vector<ListenParams> listens;
|
||||
int concurrency;
|
||||
net::HttpRequestHeaders extra_headers;
|
||||
std::string proxy_url;
|
||||
std::u16string proxy_user;
|
||||
std::u16string proxy_pass;
|
||||
std::string host_resolver_rules;
|
||||
net::IPAddress resolver_range;
|
||||
size_t resolver_prefix;
|
||||
logging::LoggingSettings log_settings;
|
||||
base::FilePath net_log_path;
|
||||
base::FilePath ssl_key_path;
|
||||
};
|
||||
|
||||
std::unique_ptr<base::Value::Dict> GetConstants() {
|
||||
base::Value::Dict constants_dict = net::GetNetConstants();
|
||||
base::Value::Dict dict;
|
||||
@@ -134,278 +102,6 @@ std::unique_ptr<base::Value::Dict> GetConstants() {
|
||||
constants_dict.Set("clientInfo", std::move(dict));
|
||||
return std::make_unique<base::Value::Dict>(std::move(constants_dict));
|
||||
}
|
||||
|
||||
class MultipleListenCollector : public base::DuplicateSwitchHandler {
|
||||
public:
|
||||
void ResolveDuplicate(std::string_view key,
|
||||
base::CommandLine::StringPieceType new_value,
|
||||
base::CommandLine::StringType& out_value) override {
|
||||
out_value = new_value;
|
||||
if (key == "listen") {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
all_values_.push_back(base::WideToUTF8(new_value));
|
||||
#else
|
||||
all_values_.push_back(std::string(new_value));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<std::string>& GetAllValues() const {
|
||||
return all_values_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::string> all_values_;
|
||||
};
|
||||
|
||||
void GetCommandLine(const base::CommandLine& proc,
|
||||
CommandLine* cmdline,
|
||||
MultipleListenCollector& multiple_listens) {
|
||||
if (proc.HasSwitch("h") || proc.HasSwitch("help")) {
|
||||
std::cout << "Usage: naive { OPTIONS | config.json }\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
"-h, --help Show this message\n"
|
||||
"--version Print version\n"
|
||||
"--listen=<proto>://[addr][:port] [--listen=...]\n"
|
||||
" proto: socks, http\n"
|
||||
" redir (Linux only)\n"
|
||||
"--proxy=<proto>://[<user>:<pass>@]<hostname>[:<port>]\n"
|
||||
" proto: https, quic\n"
|
||||
"--insecure-concurrency=<N> Use N connections, insecure\n"
|
||||
"--extra-headers=... Extra headers split by CRLF\n"
|
||||
"--host-resolver-rules=... Resolver rules\n"
|
||||
"--resolver-range=... Redirect resolver range\n"
|
||||
"--log[=<path>] Log to stderr, or file\n"
|
||||
"--log-net-log=<path> Save NetLog\n"
|
||||
"--ssl-key-log-file=<path> Save SSL keys for Wireshark\n"
|
||||
<< std::endl;
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (proc.HasSwitch("version")) {
|
||||
std::cout << "naive " << version_info::GetVersionNumber() << std::endl;
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
cmdline->listens = multiple_listens.GetAllValues();
|
||||
cmdline->proxy = proc.GetSwitchValueASCII("proxy");
|
||||
cmdline->concurrency = proc.GetSwitchValueASCII("insecure-concurrency");
|
||||
cmdline->extra_headers = proc.GetSwitchValueASCII("extra-headers");
|
||||
cmdline->host_resolver_rules =
|
||||
proc.GetSwitchValueASCII("host-resolver-rules");
|
||||
cmdline->resolver_range = proc.GetSwitchValueASCII("resolver-range");
|
||||
cmdline->no_log = !proc.HasSwitch("log");
|
||||
cmdline->log = proc.GetSwitchValuePath("log");
|
||||
cmdline->log_net_log = proc.GetSwitchValuePath("log-net-log");
|
||||
cmdline->ssl_key_log_file = proc.GetSwitchValuePath("ssl-key-log-file");
|
||||
}
|
||||
|
||||
void GetCommandLineFromConfig(const base::FilePath& config_path,
|
||||
CommandLine* cmdline) {
|
||||
JSONFileValueDeserializer reader(config_path);
|
||||
int error_code;
|
||||
std::string error_message;
|
||||
std::unique_ptr<base::Value> value =
|
||||
reader.Deserialize(&error_code, &error_message);
|
||||
if (value == nullptr) {
|
||||
std::cerr << "Error reading " << config_path << ": (" << error_code << ") "
|
||||
<< error_message << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
base::Value::Dict* value_dict = value->GetIfDict();
|
||||
if (value_dict == nullptr) {
|
||||
std::cerr << "Invalid config format" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
const std::string* listen = value_dict->FindString("listen");
|
||||
if (listen != nullptr) {
|
||||
cmdline->listens = {*listen};
|
||||
} else {
|
||||
const base::Value::List* listen_list = value_dict->FindList("listen");
|
||||
if (listen_list != nullptr) {
|
||||
for (const auto& listen_element : *listen_list) {
|
||||
const std::string* listen_elemet_str = listen_element.GetIfString();
|
||||
if (listen_elemet_str == nullptr) {
|
||||
std::cerr << "Invalid listen element" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
cmdline->listens.push_back(*listen_elemet_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
const std::string* proxy = value_dict->FindString("proxy");
|
||||
if (proxy) {
|
||||
cmdline->proxy = *proxy;
|
||||
}
|
||||
const std::string* concurrency =
|
||||
value_dict->FindString("insecure-concurrency");
|
||||
if (concurrency) {
|
||||
cmdline->concurrency = *concurrency;
|
||||
}
|
||||
const std::string* extra_headers = value_dict->FindString("extra-headers");
|
||||
if (extra_headers) {
|
||||
cmdline->extra_headers = *extra_headers;
|
||||
}
|
||||
const std::string* host_resolver_rules =
|
||||
value_dict->FindString("host-resolver-rules");
|
||||
if (host_resolver_rules) {
|
||||
cmdline->host_resolver_rules = *host_resolver_rules;
|
||||
}
|
||||
const std::string* resolver_range = value_dict->FindString("resolver-range");
|
||||
if (resolver_range) {
|
||||
cmdline->resolver_range = *resolver_range;
|
||||
}
|
||||
cmdline->no_log = true;
|
||||
const std::string* log = value_dict->FindString("log");
|
||||
if (log) {
|
||||
cmdline->no_log = false;
|
||||
cmdline->log = base::FilePath::FromUTF8Unsafe(*log);
|
||||
}
|
||||
const std::string* log_net_log = value_dict->FindString("log-net-log");
|
||||
if (log_net_log) {
|
||||
cmdline->log_net_log = base::FilePath::FromUTF8Unsafe(*log_net_log);
|
||||
}
|
||||
const std::string* ssl_key_log_file =
|
||||
value_dict->FindString("ssl-key-log-file");
|
||||
if (ssl_key_log_file) {
|
||||
cmdline->ssl_key_log_file =
|
||||
base::FilePath::FromUTF8Unsafe(*ssl_key_log_file);
|
||||
}
|
||||
}
|
||||
|
||||
bool ParseListenParams(const std::string& listen_str,
|
||||
ListenParams& listen_params) {
|
||||
GURL url(listen_str);
|
||||
if (url.scheme() == "socks") {
|
||||
listen_params.protocol = net::ClientProtocol::kSocks5;
|
||||
} else if (url.scheme() == "http") {
|
||||
listen_params.protocol = net::ClientProtocol::kHttp;
|
||||
} else if (url.scheme() == "redir") {
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
listen_params.protocol = net::ClientProtocol::kRedir;
|
||||
#else
|
||||
std::cerr << "Redir protocol only supports Linux." << std::endl;
|
||||
return false;
|
||||
#endif
|
||||
} else {
|
||||
std::cerr << "Invalid scheme in --listen" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (!url.username().empty()) {
|
||||
listen_params.listen_user =
|
||||
base::UnescapeBinaryURLComponent(url.username());
|
||||
}
|
||||
if (!url.password().empty()) {
|
||||
listen_params.listen_pass =
|
||||
base::UnescapeBinaryURLComponent(url.password());
|
||||
}
|
||||
if (!url.host().empty()) {
|
||||
listen_params.listen_addr = url.HostNoBrackets();
|
||||
} else {
|
||||
listen_params.listen_addr = "0.0.0.0";
|
||||
}
|
||||
int port = url.EffectiveIntPort();
|
||||
if (port == url::PORT_INVALID) {
|
||||
std::cerr << "Invalid port in --listen" << std::endl;
|
||||
return false;
|
||||
} else if (port == url::PORT_UNSPECIFIED) {
|
||||
port = 1080;
|
||||
}
|
||||
listen_params.listen_port = port;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseCommandLine(const CommandLine& cmdline, Params* params) {
|
||||
url::AddStandardScheme("socks",
|
||||
url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION);
|
||||
url::AddStandardScheme("redir", url::SCHEME_WITH_HOST_AND_PORT);
|
||||
|
||||
bool any_redir_protocol = false;
|
||||
if (!cmdline.listens.empty()) {
|
||||
for (const std::string& listen : cmdline.listens) {
|
||||
ListenParams listen_params;
|
||||
if (!ParseListenParams(listen, listen_params)) {
|
||||
std::cerr << "Invalid listen: " << listen << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (listen_params.protocol == net::ClientProtocol::kRedir) {
|
||||
any_redir_protocol = true;
|
||||
}
|
||||
params->listens.push_back(listen_params);
|
||||
}
|
||||
} else {
|
||||
ListenParams default_listen = {
|
||||
.protocol = net::ClientProtocol::kSocks5,
|
||||
.listen_addr = "0.0.0.0",
|
||||
.listen_port = 1080,
|
||||
};
|
||||
params->listens = {default_listen};
|
||||
}
|
||||
|
||||
params->proxy_url = "direct://";
|
||||
GURL url(cmdline.proxy);
|
||||
GURL::Replacements remove_auth;
|
||||
remove_auth.ClearUsername();
|
||||
remove_auth.ClearPassword();
|
||||
GURL url_no_auth = url.ReplaceComponents(remove_auth);
|
||||
if (!cmdline.proxy.empty()) {
|
||||
params->proxy_url = url_no_auth.GetWithEmptyPath().spec();
|
||||
if (params->proxy_url.empty()) {
|
||||
std::cerr << "Invalid proxy URL" << std::endl;
|
||||
return false;
|
||||
} else if (params->proxy_url.back() == '/') {
|
||||
params->proxy_url.pop_back();
|
||||
}
|
||||
net::GetIdentityFromURL(url, ¶ms->proxy_user, ¶ms->proxy_pass);
|
||||
}
|
||||
|
||||
if (!cmdline.concurrency.empty()) {
|
||||
if (!base::StringToInt(cmdline.concurrency, ¶ms->concurrency) ||
|
||||
params->concurrency < 1) {
|
||||
std::cerr << "Invalid concurrency" << std::endl;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
params->concurrency = 1;
|
||||
}
|
||||
|
||||
params->extra_headers.AddHeadersFromString(cmdline.extra_headers);
|
||||
|
||||
params->host_resolver_rules = cmdline.host_resolver_rules;
|
||||
|
||||
if (any_redir_protocol) {
|
||||
std::string range = "100.64.0.0/10";
|
||||
if (!cmdline.resolver_range.empty())
|
||||
range = cmdline.resolver_range;
|
||||
|
||||
if (!net::ParseCIDRBlock(range, ¶ms->resolver_range,
|
||||
¶ms->resolver_prefix)) {
|
||||
std::cerr << "Invalid resolver range" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (params->resolver_range.IsIPv6()) {
|
||||
std::cerr << "IPv6 resolver range not supported" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cmdline.no_log) {
|
||||
if (!cmdline.log.empty()) {
|
||||
params->log_settings.logging_dest = logging::LOG_TO_FILE;
|
||||
params->log_settings.log_file_path = cmdline.log.value().c_str();
|
||||
} else {
|
||||
params->log_settings.logging_dest = logging::LOG_TO_STDERR;
|
||||
}
|
||||
} else {
|
||||
params->log_settings.logging_dest = logging::LOG_NONE;
|
||||
}
|
||||
|
||||
params->net_log_path = cmdline.log_net_log;
|
||||
params->ssl_key_path = cmdline.ssl_key_log_file;
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace net {
|
||||
@@ -471,7 +167,7 @@ std::unique_ptr<URLRequestContext> BuildCertURLRequestContext(NetLog* net_log) {
|
||||
|
||||
// Builds a URLRequestContext assuming there's only a single loop.
|
||||
std::unique_ptr<URLRequestContext> BuildURLRequestContext(
|
||||
const Params& params,
|
||||
const NaiveConfig& config,
|
||||
scoped_refptr<CertNetFetcherURLRequest> cert_net_fetcher,
|
||||
NetLog* net_log) {
|
||||
URLRequestContextBuilder builder;
|
||||
@@ -479,7 +175,7 @@ std::unique_ptr<URLRequestContext> BuildURLRequestContext(
|
||||
builder.DisableHttpCache();
|
||||
builder.set_net_log(net_log);
|
||||
|
||||
std::string proxy_url = params.proxy_url;
|
||||
std::string proxy_url = config.proxy_url;
|
||||
bool force_quic = false;
|
||||
if (proxy_url.compare(0, 7, "quic://") == 0) {
|
||||
proxy_url.replace(0, 4, "https");
|
||||
@@ -505,21 +201,36 @@ std::unique_ptr<URLRequestContext> BuildURLRequestContext(
|
||||
proxy_service->ForceReloadProxyConfig();
|
||||
builder.set_proxy_resolution_service(std::move(proxy_service));
|
||||
|
||||
if (!params.host_resolver_rules.empty()) {
|
||||
builder.set_host_mapping_rules(params.host_resolver_rules);
|
||||
if (!config.host_resolver_rules.empty()) {
|
||||
builder.set_host_mapping_rules(config.host_resolver_rules);
|
||||
}
|
||||
|
||||
builder.SetCertVerifier(
|
||||
CertVerifier::CreateDefault(std::move(cert_net_fetcher)));
|
||||
|
||||
builder.set_proxy_delegate(std::make_unique<NaiveProxyDelegate>(
|
||||
params.extra_headers,
|
||||
config.extra_headers,
|
||||
std::vector<PaddingType>{PaddingType::kVariant1, PaddingType::kNone}));
|
||||
|
||||
if (config.no_post_quantum == true) {
|
||||
struct NoPostQuantum : public SSLConfigService {
|
||||
SSLContextConfig GetSSLContextConfig() override {
|
||||
SSLContextConfig config;
|
||||
config.post_quantum_override = false;
|
||||
return config;
|
||||
}
|
||||
|
||||
bool CanShareConnectionWithClientCerts(std::string_view) const override {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
builder.set_ssl_config_service(std::make_unique<NoPostQuantum>());
|
||||
}
|
||||
|
||||
auto context = builder.Build();
|
||||
|
||||
if (!params.proxy_url.empty() && !params.proxy_user.empty() &&
|
||||
!params.proxy_pass.empty()) {
|
||||
if (!config.proxy_url.empty() && !config.proxy_user.empty() &&
|
||||
!config.proxy_pass.empty()) {
|
||||
auto* session = context->http_transaction_factory()->GetSession();
|
||||
auto* auth_cache = session->http_auth_cache();
|
||||
GURL proxy_gurl(proxy_url);
|
||||
@@ -530,7 +241,7 @@ std::unique_ptr<URLRequestContext> BuildURLRequestContext(
|
||||
net::HostPortPair::FromURL(proxy_gurl));
|
||||
}
|
||||
url::SchemeHostPort auth_origin(proxy_gurl);
|
||||
AuthCredentials credentials(params.proxy_user, params.proxy_pass);
|
||||
AuthCredentials credentials(config.proxy_user, config.proxy_pass);
|
||||
auth_cache->Add(auth_origin, HttpAuth::AUTH_PROXY,
|
||||
/*realm=*/{}, HttpAuth::AUTH_SCHEME_BASIC, {},
|
||||
/*challenge=*/"Basic", credentials, /*path=*/"/");
|
||||
@@ -565,9 +276,7 @@ int main(int argc, char* argv[]) {
|
||||
// content/app/content_main.cc: RunContentProcess()
|
||||
base::EnableTerminationOnOutOfMemory();
|
||||
|
||||
auto multiple_listens = std::make_unique<MultipleListenCollector>();
|
||||
MultipleListenCollector& multiple_listens_ref = *multiple_listens;
|
||||
base::CommandLine::SetDuplicateSwitchHandler(std::move(multiple_listens));
|
||||
DuplicateSwitchCollector::InitInstance();
|
||||
|
||||
// content/app/content_main.cc: RunContentProcess()
|
||||
base::CommandLine::Init(argc, argv);
|
||||
@@ -606,6 +315,9 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
url::AddStandardScheme("quic",
|
||||
url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION);
|
||||
url::AddStandardScheme("socks",
|
||||
url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION);
|
||||
url::AddStandardScheme("redir", url::SCHEME_WITH_HOST_AND_PORT);
|
||||
net::ClientSocketPoolManager::set_max_sockets_per_pool(
|
||||
net::HttpNetworkSession::NORMAL_SOCKET_POOL,
|
||||
kDefaultMaxSocketsPerPool * kExpectedMaxUsers);
|
||||
@@ -616,30 +328,70 @@ int main(int argc, char* argv[]) {
|
||||
net::HttpNetworkSession::NORMAL_SOCKET_POOL,
|
||||
kDefaultMaxSocketsPerGroup * kExpectedMaxUsers);
|
||||
|
||||
CommandLine cmdline;
|
||||
|
||||
Params params;
|
||||
const auto& proc = *base::CommandLine::ForCurrentProcess();
|
||||
const auto& args = proc.GetArgs();
|
||||
if (args.empty()) {
|
||||
if (proc.argv().size() >= 2) {
|
||||
GetCommandLine(proc, &cmdline, multiple_listens_ref);
|
||||
} else {
|
||||
auto path = base::FilePath::FromUTF8Unsafe("config.json");
|
||||
GetCommandLineFromConfig(path, &cmdline);
|
||||
}
|
||||
base::Value::Dict config_dict;
|
||||
if (args.empty() && proc.argv().size() >= 2) {
|
||||
config_dict = GetSwitchesAsValue(proc);
|
||||
} else {
|
||||
base::FilePath path(args[0]);
|
||||
GetCommandLineFromConfig(path, &cmdline);
|
||||
base::FilePath config_file;
|
||||
if (!args.empty()) {
|
||||
config_file = base::FilePath(args[0]);
|
||||
} else {
|
||||
config_file = base::FilePath::FromUTF8Unsafe("config.json");
|
||||
}
|
||||
JSONFileValueDeserializer reader(config_file);
|
||||
int error_code;
|
||||
std::string error_message;
|
||||
std::unique_ptr<base::Value> value =
|
||||
reader.Deserialize(&error_code, &error_message);
|
||||
if (value == nullptr) {
|
||||
std::cerr << "Error reading " << config_file << ": (" << error_code
|
||||
<< ") " << error_message << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (const base::Value::Dict* dict = value->GetIfDict()) {
|
||||
config_dict = dict->Clone();
|
||||
}
|
||||
}
|
||||
if (!ParseCommandLine(cmdline, ¶ms)) {
|
||||
|
||||
if (config_dict.contains("h") || config_dict.contains("help")) {
|
||||
std::cout << "Usage: naive { OPTIONS | config.json }\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
"-h, --help Show this message\n"
|
||||
"--version Print version\n"
|
||||
"--listen=<proto>://[addr][:port] [--listen=...]\n"
|
||||
" proto: socks, http\n"
|
||||
" redir (Linux only)\n"
|
||||
"--proxy=<proto>://[<user>:<pass>@]<hostname>[:<port>]\n"
|
||||
" proto: https, quic\n"
|
||||
"--insecure-concurrency=<N> Use N connections, insecure\n"
|
||||
"--extra-headers=... Extra headers split by CRLF\n"
|
||||
"--host-resolver-rules=... Resolver rules\n"
|
||||
"--resolver-range=... Redirect resolver range\n"
|
||||
"--log[=<path>] Log to stderr, or file\n"
|
||||
"--log-net-log=<path> Save NetLog\n"
|
||||
"--ssl-key-log-file=<path> Save SSL keys for Wireshark\n"
|
||||
"--no-post-quantum No post-quantum key agreement\n"
|
||||
<< std::endl;
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (config_dict.contains("version")) {
|
||||
std::cout << "naive " << version_info::GetVersionNumber() << std::endl;
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
net::NaiveConfig config;
|
||||
if (!config.Parse(config_dict)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
CHECK(logging::InitLogging(params.log_settings));
|
||||
CHECK(logging::InitLogging(config.log));
|
||||
|
||||
if (!params.ssl_key_path.empty()) {
|
||||
if (!config.ssl_key_log_file.empty()) {
|
||||
net::SSLClientSocket::SetSSLKeyLogger(
|
||||
std::make_unique<net::SSLKeyLoggerImpl>(params.ssl_key_path));
|
||||
std::make_unique<net::SSLKeyLoggerImpl>(config.ssl_key_log_file));
|
||||
}
|
||||
|
||||
// The declaration order for net_log and printing_log_observer is
|
||||
@@ -648,15 +400,15 @@ int main(int argc, char* argv[]) {
|
||||
// printing_log_observer.
|
||||
net::NetLog* net_log = net::NetLog::Get();
|
||||
std::unique_ptr<net::FileNetLogObserver> observer;
|
||||
if (!params.net_log_path.empty()) {
|
||||
if (!config.log_net_log.empty()) {
|
||||
observer = net::FileNetLogObserver::CreateUnbounded(
|
||||
params.net_log_path, net::NetLogCaptureMode::kDefault, GetConstants());
|
||||
config.log_net_log, net::NetLogCaptureMode::kDefault, GetConstants());
|
||||
observer->StartObserving(net_log);
|
||||
}
|
||||
|
||||
// Avoids net log overhead if verbose logging is disabled.
|
||||
std::unique_ptr<net::PrintingLogObserver> printing_log_observer;
|
||||
if (params.log_settings.logging_dest != logging::LOG_NONE && VLOG_IS_ON(1)) {
|
||||
if (config.log.logging_dest != logging::LOG_NONE && VLOG_IS_ON(1)) {
|
||||
printing_log_observer = std::make_unique<net::PrintingLogObserver>();
|
||||
net_log->AddObserver(printing_log_observer.get(),
|
||||
net::NetLogCaptureMode::kDefault);
|
||||
@@ -675,43 +427,41 @@ int main(int argc, char* argv[]) {
|
||||
cert_net_fetcher->SetURLRequestContext(cert_context.get());
|
||||
#endif
|
||||
auto context =
|
||||
net::BuildURLRequestContext(params, std::move(cert_net_fetcher), net_log);
|
||||
net::BuildURLRequestContext(config, std::move(cert_net_fetcher), net_log);
|
||||
auto* session = context->http_transaction_factory()->GetSession();
|
||||
|
||||
std::vector<std::unique_ptr<net::NaiveProxy>> naive_proxies;
|
||||
std::unique_ptr<net::RedirectResolver> resolver;
|
||||
|
||||
for (const ListenParams& listen_params : params.listens) {
|
||||
for (const net::NaiveListenConfig& listen_config : config.listen) {
|
||||
auto listen_socket =
|
||||
std::make_unique<net::TCPServerSocket>(net_log, net::NetLogSource());
|
||||
|
||||
int result = listen_socket->ListenWithAddressAndPort(
|
||||
listen_params.listen_addr, listen_params.listen_port, kListenBackLog);
|
||||
listen_config.addr, listen_config.port, kListenBackLog);
|
||||
if (result != net::OK) {
|
||||
LOG(ERROR) << "Failed to listen on "
|
||||
<< net::ToString(listen_params.protocol) << "://"
|
||||
<< listen_params.listen_addr << " "
|
||||
<< listen_params.listen_port << ": "
|
||||
<< net::ToString(listen_config.protocol) << "://"
|
||||
<< listen_config.addr << " " << listen_config.port << ": "
|
||||
<< net::ErrorToShortString(result);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
LOG(INFO) << "Listening on " << net::ToString(listen_params.protocol)
|
||||
<< "://" << listen_params.listen_addr << ":"
|
||||
<< listen_params.listen_port;
|
||||
LOG(INFO) << "Listening on " << net::ToString(listen_config.protocol)
|
||||
<< "://" << listen_config.addr << ":" << listen_config.port;
|
||||
|
||||
if (resolver == nullptr &&
|
||||
listen_params.protocol == net::ClientProtocol::kRedir) {
|
||||
listen_config.protocol == net::ClientProtocol::kRedir) {
|
||||
auto resolver_socket =
|
||||
std::make_unique<net::UDPServerSocket>(net_log, net::NetLogSource());
|
||||
resolver_socket->AllowAddressReuse();
|
||||
net::IPAddress listen_addr;
|
||||
if (!listen_addr.AssignFromIPLiteral(listen_params.listen_addr)) {
|
||||
LOG(ERROR) << "Failed to open resolver: " << listen_params.listen_addr;
|
||||
if (!listen_addr.AssignFromIPLiteral(listen_config.addr)) {
|
||||
LOG(ERROR) << "Failed to open resolver: " << listen_config.addr;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
result = resolver_socket->Listen(
|
||||
net::IPEndPoint(listen_addr, listen_params.listen_port));
|
||||
net::IPEndPoint(listen_addr, listen_config.port));
|
||||
if (result != net::OK) {
|
||||
LOG(ERROR) << "Failed to open resolver: "
|
||||
<< net::ErrorToShortString(result);
|
||||
@@ -719,14 +469,14 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
resolver = std::make_unique<net::RedirectResolver>(
|
||||
std::move(resolver_socket), params.resolver_range,
|
||||
params.resolver_prefix);
|
||||
std::move(resolver_socket), config.resolver_range,
|
||||
config.resolver_prefix);
|
||||
}
|
||||
|
||||
auto naive_proxy = std::make_unique<net::NaiveProxy>(
|
||||
std::move(listen_socket), listen_params.protocol,
|
||||
listen_params.listen_user, listen_params.listen_pass,
|
||||
params.concurrency, resolver.get(), session, kTrafficAnnotation,
|
||||
std::move(listen_socket), listen_config.protocol, listen_config.user,
|
||||
listen_config.pass, config.insecure_concurrency, resolver.get(),
|
||||
session, kTrafficAnnotation,
|
||||
std::vector<net::PaddingType>{net::PaddingType::kVariant1,
|
||||
net::PaddingType::kNone});
|
||||
naive_proxies.push_back(std::move(naive_proxy));
|
||||
|
@@ -95,8 +95,8 @@ case "$1" in
|
||||
check_list_update "$1" "Loyalsoldier/v2ray-rules-dat" "release" "gfw.txt"
|
||||
;;
|
||||
"china_list")
|
||||
check_list_update "$1" "Loyalsoldier/v2ray-rules-dat" "release" "direct-list.txt"
|
||||
sed -i -e "s/full://g" -e "/:/d" "$RESOURCES_DIR/china_list.txt"
|
||||
check_list_update "$1" "Loyalsoldier/v2ray-rules-dat" "release" "direct-list.txt" && \
|
||||
sed -i -e "s/full://g" -e "/:/d" "$RESOURCES_DIR/china_list.txt"
|
||||
;;
|
||||
*)
|
||||
echo -e "Usage: $0 <china_ip4 / china_ip6 / gfw_list / china_list>"
|
||||
|
@@ -21,13 +21,13 @@ define Download/geoip
|
||||
HASH:=2f7516c0f853625e0a7ca932f534eb6d963f4287d4a2c585b1d193b4bb0a0f4f
|
||||
endef
|
||||
|
||||
GEOSITE_VER:=20240426060244
|
||||
GEOSITE_VER:=20240504082351
|
||||
GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
|
||||
define Download/geosite
|
||||
URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
|
||||
URL_FILE:=dlc.dat
|
||||
FILE:=$(GEOSITE_FILE)
|
||||
HASH:=7aa19bb7fa5f99d62d3db87b632334caa356fb9b901f85f7168c064370973646
|
||||
HASH:=a4d70989c3928289f07528894f29788d7844bdbfb450dd6597595d1d0210881d
|
||||
endef
|
||||
|
||||
GEOSITE_IRAN_VER:=202404290026
|
||||
|
@@ -57,11 +57,14 @@ namespace v2rayN
|
||||
/// 取得存储资源
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string? LoadResource(string res)
|
||||
public static string? LoadResource(string? res)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(res)) return null;
|
||||
if (!File.Exists(res))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return File.ReadAllText(res);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@@ -895,18 +895,45 @@ namespace v2rayN.Handler
|
||||
ruleSets.AddRange(dnsRule.rule_set);
|
||||
}
|
||||
|
||||
//load custom ruleset file
|
||||
List<Ruleset4Sbox> customRulesets = [];
|
||||
if (_config.routingBasicItem.enableRoutingAdvanced)
|
||||
{
|
||||
var routing = ConfigHandler.GetDefaultRouting(_config);
|
||||
if (!Utils.IsNullOrEmpty(routing.customRulesetPath4Singbox))
|
||||
{
|
||||
var result = Utils.LoadResource(routing.customRulesetPath4Singbox);
|
||||
if (!Utils.IsNullOrEmpty(result))
|
||||
{
|
||||
customRulesets = (JsonUtils.Deserialize<List<Ruleset4Sbox>>(result) ?? [])
|
||||
.Where(t => t.tag != null)
|
||||
.Where(t => t.type != null)
|
||||
.Where(t => t.format != null)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Add ruleset srs
|
||||
singboxConfig.route.rule_set = [];
|
||||
foreach (var item in new HashSet<string>(ruleSets))
|
||||
{
|
||||
singboxConfig.route.rule_set.Add(new()
|
||||
var customRuleset = customRulesets.FirstOrDefault(t => t.tag != null && t.tag.Equals(item));
|
||||
if (customRuleset != null)
|
||||
{
|
||||
type = "remote",
|
||||
format = "binary",
|
||||
tag = item,
|
||||
url = string.Format(Global.SingboxRulesetUrl, item.StartsWith(geosite) ? geosite : geoip, item),
|
||||
download_detour = Global.ProxyTag
|
||||
});
|
||||
singboxConfig.route.rule_set.Add(customRuleset);
|
||||
}
|
||||
else
|
||||
{
|
||||
singboxConfig.route.rule_set.Add(new()
|
||||
{
|
||||
type = "remote",
|
||||
format = "binary",
|
||||
tag = item,
|
||||
url = string.Format(Global.SingboxRulesetUrl, item.StartsWith(geosite) ? geosite : geoip, item),
|
||||
download_detour = Global.ProxyTag
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@@ -264,7 +264,21 @@ namespace v2rayN.Handler
|
||||
|
||||
private static string GetIpv6(string address)
|
||||
{
|
||||
return Utils.IsIpv6(address) ? $"[{address}]" : address;
|
||||
if (Utils.IsIpv6(address))
|
||||
{
|
||||
if (address.StartsWith('[') && address.EndsWith(']'))
|
||||
{
|
||||
return address;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"[{address}]";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetStdTransport(ProfileItem item, string? securityDef, ref Dictionary<string, string> dicQuery)
|
||||
|
@@ -182,16 +182,11 @@ namespace v2rayN.Models
|
||||
[Serializable]
|
||||
public class RoutingBasicItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 域名解析策略
|
||||
/// </summary>
|
||||
public string domainStrategy { get; set; }
|
||||
|
||||
public string domainStrategy4Singbox { get; set; }
|
||||
|
||||
public string domainMatcher { get; set; }
|
||||
public string routingIndexId { get; set; }
|
||||
public bool enableRoutingAdvanced { get; set; }
|
||||
public bool enableRoutingAdvanced { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
@@ -15,6 +15,7 @@ namespace v2rayN.Models
|
||||
public bool enabled { get; set; } = true;
|
||||
public bool locked { get; set; }
|
||||
public string customIcon { get; set; }
|
||||
public string customRulesetPath4Singbox { get; set; }
|
||||
public string domainStrategy { get; set; }
|
||||
public string domainStrategy4Singbox { get; set; }
|
||||
public int sort { get; set; }
|
||||
|
@@ -238,7 +238,9 @@
|
||||
public string? tag { get; set; }
|
||||
public string? type { get; set; }
|
||||
public string? format { get; set; }
|
||||
public string? path { get; set; }
|
||||
public string? url { get; set; }
|
||||
public string? download_detour { get; set; }
|
||||
public string? update_interval { get; set; }
|
||||
}
|
||||
}
|
763
v2rayn/v2rayN/v2rayN/Resx/ResUI.Designer.cs
generated
@@ -1210,4 +1210,7 @@
|
||||
<data name="TbSettingsEnableCacheFile4Sbox" xml:space="preserve">
|
||||
<value>Enable cache file for sing-box (ruleset files)</value>
|
||||
</data>
|
||||
<data name="LvCustomRulesetPath4Singbox" xml:space="preserve">
|
||||
<value>Custom the rule-set of sing-box</value>
|
||||
</data>
|
||||
</root>
|
@@ -1207,4 +1207,7 @@
|
||||
<data name="TbSettingsEnableCacheFile4Sbox" xml:space="preserve">
|
||||
<value>启用sing-box(规则集文件)的缓存文件</value>
|
||||
</data>
|
||||
<data name="LvCustomRulesetPath4Singbox" xml:space="preserve">
|
||||
<value>自定义sing-box rule-set</value>
|
||||
</data>
|
||||
</root>
|
@@ -1180,4 +1180,7 @@
|
||||
<data name="TbSettingsEnableCacheFile4Sbox" xml:space="preserve">
|
||||
<value>啟用sing-box(規則集文件)的緩存文件</value>
|
||||
</data>
|
||||
<data name="LvCustomRulesetPath4Singbox" xml:space="preserve">
|
||||
<value>自訂sing-box rule-set</value>
|
||||
</data>
|
||||
</root>
|
@@ -192,6 +192,7 @@ namespace v2rayN.ViewModels
|
||||
remarks = item.remarks,
|
||||
url = item.url,
|
||||
customIcon = item.customIcon,
|
||||
customRulesetPath4Singbox = item.customRulesetPath4Singbox,
|
||||
sort = item.sort,
|
||||
};
|
||||
_routingItems.Add(it);
|
||||
|
@@ -88,6 +88,7 @@
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkDnsObjectDoc_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbDnsObjectDoc}" />
|
||||
<materialDesign:PackIcon Kind="Link" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<Button
|
||||
@@ -120,6 +121,7 @@
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkDnsSingboxObjectDoc_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbDnsSingboxObjectDoc}" />
|
||||
<materialDesign:PackIcon Kind="Link" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<Button
|
||||
|
@@ -4,6 +4,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:reactiveui="http://reactiveui.net"
|
||||
xmlns:resx="clr-namespace:v2rayN.Resx"
|
||||
@@ -83,6 +84,7 @@
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkRuleobjectDoc_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbRuleobjectDoc}" />
|
||||
<materialDesign:PackIcon Kind="Link" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
|
||||
|
@@ -114,17 +114,36 @@
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.LvRemarks}" />
|
||||
<TextBox
|
||||
x:Name="txtRemarks"
|
||||
<StackPanel
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="4"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
Style="{StaticResource DefTextBox}"
|
||||
TextWrapping="Wrap" />
|
||||
Orientation="Horizontal">
|
||||
|
||||
<TextBox
|
||||
x:Name="txtRemarks"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Width="300"
|
||||
Margin="4"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
Style="{StaticResource DefTextBox}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<TextBlock
|
||||
Margin="4"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.LvSort}" />
|
||||
<TextBox
|
||||
x:Name="txtSort"
|
||||
Width="100"
|
||||
Margin="4"
|
||||
HorizontalAlignment="Left"
|
||||
AcceptsReturn="True"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
@@ -190,11 +209,11 @@
|
||||
Style="{StaticResource DefTextBox}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button
|
||||
x:Name="btnBrowse"
|
||||
x:Name="btnBrowseCustomIcon"
|
||||
Grid.Row="3"
|
||||
Grid.Column="2"
|
||||
Margin="2,0,8,0"
|
||||
Click="btnBrowse_Click"
|
||||
Click="btnBrowseCustomIcon_Click"
|
||||
Content="{x:Static resx:ResUI.TbBrowse}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
|
||||
@@ -203,17 +222,30 @@
|
||||
Grid.Column="0"
|
||||
Margin="4"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.LvSort}" />
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkCustomRulesetPath4Singbox">
|
||||
<TextBlock Text="{x:Static resx:ResUI.LvCustomRulesetPath4Singbox}" />
|
||||
<materialDesign:PackIcon Kind="Link" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<TextBox
|
||||
x:Name="txtSort"
|
||||
x:Name="txtCustomRulesetPath4Singbox"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Width="600"
|
||||
Margin="4"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
AcceptsReturn="True"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
Style="{StaticResource DefTextBox}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button
|
||||
x:Name="btnBrowseCustomRulesetPath4Singbox"
|
||||
Grid.Row="4"
|
||||
Grid.Column="2"
|
||||
Margin="2,0,8,0"
|
||||
Click="btnBrowseCustomRulesetPath4Singbox_Click"
|
||||
Content="{x:Static resx:ResUI.TbBrowse}"
|
||||
Style="{StaticResource DefButton}" />
|
||||
</Grid>
|
||||
|
||||
<TabControl x:Name="tabAdvanced">
|
||||
|
@@ -51,6 +51,7 @@ namespace v2rayN.Views
|
||||
|
||||
this.Bind(ViewModel, vm => vm.SelectedRouting.url, v => v.txtUrl.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedRouting.customIcon, v => v.txtCustomIcon.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedRouting.customRulesetPath4Singbox, v => v.txtCustomRulesetPath4Singbox.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedRouting.sort, v => v.txtSort.Text).DisposeWith(disposables);
|
||||
|
||||
this.BindCommand(ViewModel, vm => vm.RuleAddCmd, v => v.menuRuleAdd).DisposeWith(disposables);
|
||||
@@ -128,7 +129,7 @@ namespace v2rayN.Views
|
||||
lstRules.SelectAll();
|
||||
}
|
||||
|
||||
private void btnBrowse_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||
private void btnBrowseCustomIcon_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
if (UI.OpenFileDialog(out string fileName,
|
||||
"PNG,ICO|*.png;*.ico") != true)
|
||||
@@ -138,5 +139,21 @@ namespace v2rayN.Views
|
||||
|
||||
txtCustomIcon.Text = fileName;
|
||||
}
|
||||
|
||||
private void btnBrowseCustomRulesetPath4Singbox_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (UI.OpenFileDialog(out string fileName,
|
||||
"Config|*.json|All|*.*") != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
txtCustomRulesetPath4Singbox.Text = fileName;
|
||||
}
|
||||
|
||||
private void linkCustomRulesetPath4Singbox(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Utils.ProcessStart("https://github.com/2dust/v2rayCustomRoutingList/blob/master/singbox_custom_ruleset_example.json");
|
||||
}
|
||||
}
|
||||
}
|
@@ -90,6 +90,7 @@
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkdomainStrategy_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbdomainStrategy}" />
|
||||
<materialDesign:PackIcon Kind="Link" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<ComboBox
|
||||
@@ -115,6 +116,7 @@
|
||||
Style="{StaticResource ToolbarTextBlock}">
|
||||
<Hyperlink Click="linkdomainStrategy4Singbox_Click">
|
||||
<TextBlock Text="{x:Static resx:ResUI.TbdomainStrategy4Singbox}" />
|
||||
<materialDesign:PackIcon Kind="Link" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<ComboBox
|
||||
|
@@ -170,17 +170,11 @@ JNIEXPORT void JNICALL Java_it_gui_yass_MainActivity_onNativeDestroy(JNIEnv* env
|
||||
g_activity_obj = nullptr;
|
||||
}
|
||||
|
||||
static uint64_t g_last_sync_time;
|
||||
static uint64_t g_last_tx_bytes;
|
||||
static uint64_t g_last_rx_bytes;
|
||||
static uint64_t g_last_sync_time = 0;
|
||||
static uint64_t g_last_tx_bytes = 0;
|
||||
static uint64_t g_last_rx_bytes = 0;
|
||||
|
||||
JNIEXPORT void JNICALL Java_it_gui_yass_MainActivity_nativeStart(JNIEnv* env, jobject obj) {
|
||||
g_last_sync_time = GetMonotonicTime();
|
||||
g_last_tx_bytes = 0;
|
||||
g_last_rx_bytes = 0;
|
||||
cli::total_tx_bytes = 0;
|
||||
cli::total_rx_bytes = 0;
|
||||
|
||||
g_worker->Start([&](asio::error_code ec) {
|
||||
if (!ec) {
|
||||
config::SaveConfig();
|
||||
@@ -204,8 +198,8 @@ JNIEXPORT jlongArray JNICALL Java_it_gui_yass_MainActivity_getRealtimeTransferRa
|
||||
static uint64_t rx_rate = 0;
|
||||
static uint64_t tx_rate = 0;
|
||||
if (delta_time > NS_PER_SECOND) {
|
||||
uint64_t rx_bytes = cli::total_rx_bytes;
|
||||
uint64_t tx_bytes = cli::total_tx_bytes;
|
||||
uint64_t rx_bytes = net::cli::total_rx_bytes;
|
||||
uint64_t tx_bytes = net::cli::total_tx_bytes;
|
||||
rx_rate = static_cast<double>(rx_bytes - g_last_rx_bytes) / delta_time * NS_PER_SECOND;
|
||||
tx_rate = static_cast<double>(tx_bytes - g_last_tx_bytes) / delta_time * NS_PER_SECOND;
|
||||
g_last_sync_time = sync_time;
|
||||
|