Update On Sat May 4 20:29:57 CEST 2024

This commit is contained in:
github-action[bot]
2024-05-04 20:29:58 +02:00
parent 3b93444c52
commit e48c8c4fe3
120 changed files with 1379 additions and 8934 deletions

View File

@@ -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

View File

@@ -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
},
},

View File

@@ -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

View File

@@ -1,40 +0,0 @@
# Diagram
> Maybe outdated
## overview
![overview](https://txthinking.github.io/brook/svg/overview.svg)
## withoutBrookProtocol
![wbp](https://txthinking.github.io/brook/svg/wbp.svg)
## relayoverbrook
![relayoverbrook](https://txthinking.github.io/brook/svg/relayoverbrook.svg)
## dnsserveroverbrook
![dnsserveroverbrook](https://txthinking.github.io/brook/svg/dnsserveroverbrook.svg)
## relay
![relay](https://txthinking.github.io/brook/svg/relay.svg)
## dnsserver
![dnsserver](https://txthinking.github.io/brook/svg/dnsserver.svg)
## tproxy
![tproxy](https://txthinking.github.io/brook/svg/tproxy.svg)
## gui
![gui](https://txthinking.github.io/brook/svg/gui.svg)
## script
![script](https://txthinking.github.io/brook/svg/script.svg)

View File

@@ -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 |

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 36 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 50 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -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="&#34;relay.from&#34;"><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="&#34;relay.to&#34;"><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 -&gt; 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 -&gt; &#34;relay.from&#34;)[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="(&#34;relay.from&#34; -&gt; 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 -&gt; &#34;relay.to&#34;)[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

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 33 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 64 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 53 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -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

View File

@@ -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=

View File

@@ -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 {

View File

@@ -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

View File

@@ -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 {

View File

@@ -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")))
}