Skip to content

Commit

Permalink
brook link:
Browse files Browse the repository at this point in the history
    --dialSocks5
    --dialSocks5Username
    --dialSocks5Password
brook testsocks5
brook testbrook
  • Loading branch information
txthinking committed Sep 29, 2022
1 parent cdab4ad commit 25b6889
Show file tree
Hide file tree
Showing 8 changed files with 311 additions and 11 deletions.
117 changes: 116 additions & 1 deletion cli/brook/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ var debugAddress string
func main() {
app := cli.NewApp()
app.Name = "Brook"
app.Version = "20220707"
app.Version = "20221010"
app.Usage = "A cross-platform network tool designed for developers"
app.Authors = []*cli.Author{
{
Expand Down Expand Up @@ -1444,6 +1444,18 @@ func main() {
Value: 60,
Usage: "connection deadline time (s)",
},
&cli.StringFlag{
Name: "dialSocks5",
Usage: "If you already have a socks5, such as 127.0.0.1:1081, and want [src <-> listen socks5 <-> $ brook connect <-> dialSocks5 <-> $ brook server/wsserver/wssserver <-> dst]",
},
&cli.StringFlag{
Name: "dialSocks5Username",
Usage: "Optional",
},
&cli.StringFlag{
Name: "dialSocks5Password",
Usage: "Optional",
},
},
Action: func(c *cli.Context) error {
if debug {
Expand Down Expand Up @@ -1474,6 +1486,13 @@ func main() {
if kind == "socks5" {
return errors.New("connect doesn't support socks5 link, you may want $ brook socks5tohttp")
}
if c.String("dialSocks5") != "" {
d, err := brook.NewSocks5Dial1(c.String("dialSocks5"), c.String("dialSocks5Username"), c.String("dialSocks5Password"), c.Int("tcpTimeout"), c.Int("udpTimeout"))
if err != nil {
return err
}
brook.Dial1 = d
}
g := runnergroup.New()
if kind == "server" {
s, err := brook.NewClient(c.String("socks5"), ip, server, password, c.Int("tcpTimeout"), c.Int("udpTimeout"))
Expand Down Expand Up @@ -1860,6 +1879,102 @@ func main() {
return g.Wait()
},
},
&cli.Command{
Name: "testsocks5",
Usage: "Test UDP and TCP of socks5 server",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "socks5",
Aliases: []string{"s"},
Usage: "like: 127.0.0.1:1080",
},
&cli.StringFlag{
Name: "username",
Aliases: []string{"u"},
Usage: "Socks5 username",
},
&cli.StringFlag{
Name: "password",
Aliases: []string{"p"},
Usage: "Socks5 password",
},
&cli.StringFlag{
Name: "dns",
Value: "8.8.8.8:53",
Usage: "DNS server for connecting",
},
&cli.StringFlag{
Name: "domain",
Value: "http3.ooo",
Usage: "Domain for query",
},
&cli.StringFlag{
Name: "a",
Value: "137.184.237.95",
Usage: "A record of domain",
},
},
Action: func(c *cli.Context) error {
if c.String("socks5") == "" {
cli.ShowCommandHelp(c, "testsocks5")
return nil
}
return brook.Socks5Test(c.String("socks5"), c.String("username"), c.String("password"), c.String("domain"), c.String("a"), c.String("dns"))
},
},
&cli.Command{
Name: "testbrook",
Usage: "Test UDP and TCP of brook server/wsserver/wssserver",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "link",
Aliases: []string{"l"},
Usage: "brook://... brook server/wsserver/wssserver",
},
&cli.StringFlag{
Name: "socks5",
Value: "127.0.0.1:11080",
Usage: "Temporarily listening socks5",
},
&cli.StringFlag{
Name: "dns",
Value: "8.8.8.8:53",
Usage: "DNS server for connecting",
},
&cli.StringFlag{
Name: "domain",
Value: "http3.ooo",
Usage: "Domain for query",
},
&cli.StringFlag{
Name: "a",
Value: "137.184.237.95",
Usage: "A record of domain",
},
},
Action: func(c *cli.Context) error {
if c.String("link") == "" {
cli.ShowCommandHelp(c, "testbrook")
return nil
}
socks5.Debug = true
fmt.Println("Run brook connect to listen", c.String("socks5"))
var cmd *exec.Cmd
var err error
go func() {
cmd = exec.Command("brook", "connect", "--link", c.String("link"), "--socks5", c.String("socks5"))
b, _ := cmd.CombinedOutput()
err = errors.New(string(b))
}()
time.Sleep(3 * time.Second)
if err != nil {
return err
}
err1 := brook.Socks5Test(c.String("socks5"), "", "", c.String("domain"), c.String("a"), c.String("dns"))
_ = cmd.Process.Signal(syscall.SIGTERM)
return err1
},
},
}
if err := app.Run(os.Args); err != nil {
log.Println(err)
Expand Down
39 changes: 34 additions & 5 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,14 @@ func (x *Client) TCPHandle(s *socks5.Server, c *net.TCPConn, r *socks5.Request)
if Debug {
log.Println("TCP", r.Address())
}
rc, err := Dial.Dial("tcp", x.ServerAddress)
var rc net.Conn
var err error
if Dial1 != nil {
rc, err = Dial1.Dial("tcp", x.ServerAddress)
}
if Dial1 == nil {
rc, err = Dial.Dial("tcp", x.ServerAddress)
}
if err != nil {
return ErrorReply(r, c, err)
}
Expand Down Expand Up @@ -136,12 +143,23 @@ func (x *Client) UDPHandle(s *socks5.Server, addr *net.UDPAddr, d *socks5.Datagr
if err != nil {
return err
}
rc, err := Dial.DialUDP("udp", laddr, raddr)
var rc net.Conn
if Dial1 != nil {
rc, err = Dial1.DialUDP("udp", laddr, raddr)
}
if Dial1 == nil {
rc, err = Dial.DialUDP("udp", laddr, raddr)
}
if err != nil {
if !strings.Contains(err.Error(), "address already in use") {
return err
}
rc, err = Dial.DialUDP("udp", nil, raddr)
if Dial1 != nil {
rc, err = Dial1.DialUDP("udp", nil, raddr)
}
if Dial1 == nil {
rc, err = Dial.DialUDP("udp", nil, raddr)
}
if err != nil {
return err
}
Expand Down Expand Up @@ -210,12 +228,23 @@ func (x *Client) UDPOverTCPHandle(s *socks5.Server, addr *net.UDPAddr, d *socks5
if err != nil {
return err
}
rc, err := Dial.DialTCP("tcp", laddr1, raddr1)
var rc net.Conn
if Dial1 != nil {
rc, err = Dial1.DialTCP("tcp", laddr1, raddr1)
}
if Dial1 == nil {
rc, err = Dial.DialTCP("tcp", laddr1, raddr1)
}
if err != nil {
if !strings.Contains(err.Error(), "address already in use") {
return err
}
rc, err = Dial.DialTCP("tcp", nil, raddr1)
if Dial1 != nil {
rc, err = Dial1.DialTCP("tcp", nil, raddr1)
}
if Dial1 == nil {
rc, err = Dial.DialTCP("tcp", nil, raddr1)
}
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/txthinking/crypto v0.0.0-20210716135230-de9624a415a4
github.com/txthinking/runnergroup v0.0.0-20210608031112-152c7c4432bf
github.com/txthinking/socks5 v0.0.0-20220615051428-39268faee3e6
github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe
github.com/txthinking/x v0.0.0-20220929041811-1b4d914e9133
github.com/urfave/cli/v2 v2.3.0
github.com/urfave/negroni v1.0.0
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ github.com/txthinking/socks5 v0.0.0-20220615051428-39268faee3e6 h1:8DkPbOq/EPxbD
github.com/txthinking/socks5 v0.0.0-20220615051428-39268faee3e6/go.mod h1:7NloQcrxaZYKURWph5HLxVDlIwMHJXCPkeWPtpftsIg=
github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe h1:gMWxZxBFRAXqoGkwkYlPX2zvyyKNWJpxOxCrjqJkm5A=
github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe/go.mod h1:WgqbSEmUYSjEV3B1qmee/PpP2NYEz4bL9/+mF1ma+s4=
github.com/txthinking/x v0.0.0-20220929041811-1b4d914e9133 h1:fUw8+3ruX0uv2gAko4D0v6IpLmSI2soOkGl6YYmiBrM=
github.com/txthinking/x v0.0.0-20220929041811-1b4d914e9133/go.mod h1:WgqbSEmUYSjEV3B1qmee/PpP2NYEz4bL9/+mF1ma+s4=
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
Expand Down
1 change: 1 addition & 0 deletions init.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
)

var Dial x.Dialer = x.DefaultDial
var Dial1 x.Dialer1

var Debug bool = false

Expand Down
55 changes: 55 additions & 0 deletions socks5dial1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) 2016-present Cloud <[email protected]>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 3 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

package brook

import (
"net"

"github.com/txthinking/socks5"
)

type Socks5Dial1 struct {
Client *socks5.Client
}

func NewSocks5Dial1(server, username, password string, tcpTimeout, udpTimeout int) (*Socks5Dial1, error) {
s5c, err := socks5.NewClient(server, username, password, tcpTimeout, udpTimeout)
if err != nil {
return nil, err
}
return &Socks5Dial1{
Client: s5c,
}, nil
}

func (d *Socks5Dial1) Dial(network, addr string) (net.Conn, error) {
return d.Client.Dial(network, addr)
}

func (d *Socks5Dial1) DialTCP(network string, laddr, raddr *net.TCPAddr) (net.Conn, error) {
src := ""
if laddr != nil {
src = laddr.String()
}
return d.Client.DialWithLocalAddr(network, src, raddr.String(), nil)
}

func (d *Socks5Dial1) DialUDP(network string, laddr, raddr *net.UDPAddr) (net.Conn, error) {
src := ""
if laddr != nil {
src = laddr.String()
}
return d.Client.DialWithLocalAddr(network, src, raddr.String(), nil)
}
99 changes: 99 additions & 0 deletions socks5test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright (c) 2016-present Cloud <[email protected]>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 3 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

package brook

import (
"errors"
"fmt"
"log"

"github.com/miekg/dns"
"github.com/txthinking/socks5"
)

func Socks5Test(s, u, p, domain, a, ds string) error {
s5c, err := socks5.NewClient(s, u, p, 0, 60)
if err != nil {
return err
}

fmt.Println("Testing UDP: query " + domain + " A on " + ds)
uc, err := s5c.Dial("udp", ds)
if err != nil {
return err
}
defer uc.Close()
m := &dns.Msg{}
m.RecursionDesired = true
m.SetQuestion(domain+".", dns.TypeA)
b, err := m.Pack()
if err != nil {
return err
}
if _, err := uc.Write(b); err != nil {
return err
}
log.Printf("Sent Datagram. %#v\n", b)
b = make([]byte, 512)
i, err := uc.Read(b)
if err != nil {
return err
}
if err := m.Unpack(b[:i]); err != nil {
return err
}
if len(m.Answer) == 0 {
return err
}
v, ok := m.Answer[0].(*dns.A)
if !ok {
return err
}
if v.A.String() != a {
fmt.Println("Expect", a, "but got", v.A.String())
}
if v.A.String() == a {
fmt.Println("UDP: OK")
}

fmt.Println("Testing TCP: query " + domain + " A on " + ds)
c := &dns.Client{Net: "tcp"}
tc, err := s5c.Dial("tcp", ds)
if err != nil {
return err
}
defer tc.Close()
m = &dns.Msg{}
m.RecursionDesired = true
m.SetQuestion(domain+".", dns.TypeA)
m, _, err = c.ExchangeWithConn(m, &dns.Conn{Conn: tc})
if err != nil {
return err
}
if len(m.Answer) == 0 {
return errors.New("no answer")
}
v, ok = m.Answer[0].(*dns.A)
if !ok {
return errors.New("invalid answer")
}
if v.A.String() != a {
fmt.Println("Expect", a, "but got", v.A.String())
}
if v.A.String() == a {
fmt.Println("TCP: OK")
}
return nil
}
Loading

0 comments on commit 25b6889

Please sign in to comment.