add UDP remote port forwarding support
This commit is contained in:
parent
be68f616aa
commit
89681dd582
@ -5,6 +5,7 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"log"
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ginuerzh/gost/gost"
|
"github.com/ginuerzh/gost/gost"
|
||||||
)
|
)
|
||||||
@ -132,13 +133,13 @@ func tcpForwardServer() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
h := gost.TCPForwardHandler("localhost:22")
|
h := gost.TCPDirectForwardHandler("localhost:22")
|
||||||
log.Fatal(s.Serve(ln, h))
|
log.Fatal(s.Serve(ln, h))
|
||||||
}
|
}
|
||||||
|
|
||||||
func rtcpForwardServer() {
|
func rtcpForwardServer() {
|
||||||
s := &gost.Server{}
|
s := &gost.Server{}
|
||||||
ln, err := gost.RTCPForwardListener(
|
ln, err := gost.TCPRemoteForwardListener(
|
||||||
":1222",
|
":1222",
|
||||||
gost.NewChain(
|
gost.NewChain(
|
||||||
gost.Node{
|
gost.Node{
|
||||||
@ -156,7 +157,7 @@ func rtcpForwardServer() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal()
|
log.Fatal()
|
||||||
}
|
}
|
||||||
h := gost.RTCPForwardHandler(
|
h := gost.TCPRemoteForwardHandler(
|
||||||
":1222",
|
":1222",
|
||||||
gost.AddrHandlerOption("127.0.0.1:22"),
|
gost.AddrHandlerOption("127.0.0.1:22"),
|
||||||
)
|
)
|
||||||
@ -165,7 +166,7 @@ func rtcpForwardServer() {
|
|||||||
|
|
||||||
func rudpForwardServer() {
|
func rudpForwardServer() {
|
||||||
s := &gost.Server{}
|
s := &gost.Server{}
|
||||||
ln, err := gost.RUDPForwardListener(
|
ln, err := gost.UDPRemoteForwardListener(
|
||||||
":10053",
|
":10053",
|
||||||
gost.NewChain(
|
gost.NewChain(
|
||||||
gost.Node{
|
gost.Node{
|
||||||
@ -179,11 +180,12 @@ func rudpForwardServer() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
30*time.Second,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal()
|
log.Fatal()
|
||||||
}
|
}
|
||||||
h := gost.RUDPForwardHandler(":10053", "localhost:53")
|
h := gost.UDPRemoteForwardHandler("localhost:53")
|
||||||
log.Fatal(s.Serve(ln, h))
|
log.Fatal(s.Serve(ln, h))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ func tcpForward() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
h := gost.TCPForwardHandler(
|
h := gost.TCPDirectForwardHandler(
|
||||||
"localhost:22",
|
"localhost:22",
|
||||||
gost.ChainHandlerOption(chain),
|
gost.ChainHandlerOption(chain),
|
||||||
)
|
)
|
||||||
|
@ -24,11 +24,11 @@ func sshRemoteForward() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
s := &gost.Server{}
|
s := &gost.Server{}
|
||||||
ln, err := gost.RTCPForwardListener(":11800", chain)
|
ln, err := gost.TCPRemoteForwardListener(":11800", chain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
h := gost.RTCPForwardHandler(
|
h := gost.TCPRemoteForwardHandler(
|
||||||
"localhost:10000",
|
"localhost:10000",
|
||||||
)
|
)
|
||||||
log.Fatal(s.Serve(ln, h))
|
log.Fatal(s.Serve(ln, h))
|
||||||
|
57
gost/examples/forward/udp/direct.go
Normal file
57
gost/examples/forward/udp/direct.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ginuerzh/gost/gost"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
laddr, faddr string
|
||||||
|
quiet bool
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||||
|
|
||||||
|
flag.StringVar(&laddr, "L", ":18080", "listen address")
|
||||||
|
flag.StringVar(&faddr, "F", ":8080", "forward address")
|
||||||
|
flag.BoolVar(&quiet, "q", false, "quiet mode")
|
||||||
|
flag.BoolVar(&gost.Debug, "d", false, "debug mode")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if quiet {
|
||||||
|
gost.SetLogger(&gost.NopLogger{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
udpDirectForwardServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
func udpDirectForwardServer() {
|
||||||
|
s := &gost.Server{}
|
||||||
|
ln, err := gost.UDPDirectForwardListener(laddr, time.Second*30)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
h := gost.UDPDirectForwardHandler(
|
||||||
|
faddr,
|
||||||
|
/*
|
||||||
|
gost.ChainHandlerOption(gost.NewChain(gost.Node{
|
||||||
|
Protocol: "socks5",
|
||||||
|
Transport: "tcp",
|
||||||
|
Addr: ":11080",
|
||||||
|
User: url.UserPassword("admin", "123456"),
|
||||||
|
Client: &gost.Client{
|
||||||
|
Connector: gost.SOCKS5Connector(
|
||||||
|
url.UserPassword("admin", "123456"),
|
||||||
|
),
|
||||||
|
Transporter: gost.TCPTransporter(),
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
*/
|
||||||
|
)
|
||||||
|
log.Fatal(s.Serve(ln, h))
|
||||||
|
}
|
@ -27,19 +27,15 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
func main() {
|
func main() {
|
||||||
udpForwardServer()
|
udpRemoteForwardServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
func udpForwardServer() {
|
func udpRemoteForwardServer() {
|
||||||
s := &gost.Server{}
|
s := &gost.Server{}
|
||||||
ln, err := gost.UDPForwardListener(laddr, time.Second*30)
|
ln, err := gost.UDPRemoteForwardListener(
|
||||||
if err != nil {
|
laddr,
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
h := gost.UDPForwardHandler(
|
|
||||||
faddr,
|
|
||||||
/*
|
/*
|
||||||
gost.ChainHandlerOption(gost.NewChain(gost.Node{
|
gost.NewChain(gost.Node{
|
||||||
Protocol: "socks5",
|
Protocol: "socks5",
|
||||||
Transport: "tcp",
|
Transport: "tcp",
|
||||||
Addr: ":11080",
|
Addr: ":11080",
|
||||||
@ -50,8 +46,15 @@ func udpForwardServer() {
|
|||||||
),
|
),
|
||||||
Transporter: gost.TCPTransporter(),
|
Transporter: gost.TCPTransporter(),
|
||||||
},
|
},
|
||||||
})),
|
}),
|
||||||
*/
|
*/
|
||||||
|
nil,
|
||||||
|
time.Second*30)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
h := gost.UDPRemoteForwardHandler(
|
||||||
|
faddr,
|
||||||
)
|
)
|
||||||
log.Fatal(s.Serve(ln, h))
|
log.Fatal(s.Serve(ln, h))
|
||||||
}
|
}
|
272
gost/forward.go
272
gost/forward.go
@ -12,15 +12,15 @@ import (
|
|||||||
"github.com/go-log/log"
|
"github.com/go-log/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type tcpForwardHandler struct {
|
type tcpDirectForwardHandler struct {
|
||||||
raddr string
|
raddr string
|
||||||
options *HandlerOptions
|
options *HandlerOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
// TCPForwardHandler creates a server Handler for TCP port forwarding server.
|
// TCPDirectForwardHandler creates a server Handler for TCP port forwarding server.
|
||||||
// The raddr is the remote address that the server will forward to.
|
// The raddr is the remote address that the server will forward to.
|
||||||
func TCPForwardHandler(raddr string, opts ...HandlerOption) Handler {
|
func TCPDirectForwardHandler(raddr string, opts ...HandlerOption) Handler {
|
||||||
h := &tcpForwardHandler{
|
h := &tcpDirectForwardHandler{
|
||||||
raddr: raddr,
|
raddr: raddr,
|
||||||
options: &HandlerOptions{},
|
options: &HandlerOptions{},
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ func TCPForwardHandler(raddr string, opts ...HandlerOption) Handler {
|
|||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *tcpForwardHandler) Handle(conn net.Conn) {
|
func (h *tcpDirectForwardHandler) Handle(conn net.Conn) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
log.Logf("[tcp] %s - %s", conn.RemoteAddr(), h.raddr)
|
log.Logf("[tcp] %s - %s", conn.RemoteAddr(), h.raddr)
|
||||||
@ -46,16 +46,16 @@ func (h *tcpForwardHandler) Handle(conn net.Conn) {
|
|||||||
log.Logf("[tcp] %s >-< %s", conn.RemoteAddr(), h.raddr)
|
log.Logf("[tcp] %s >-< %s", conn.RemoteAddr(), h.raddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
type udpForwardHandler struct {
|
type udpDirectForwardHandler struct {
|
||||||
raddr string
|
raddr string
|
||||||
ttl time.Duration
|
ttl time.Duration
|
||||||
options *HandlerOptions
|
options *HandlerOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDPForwardHandler creates a server Handler for UDP port forwarding server.
|
// UDPDirectForwardHandler creates a server Handler for UDP port forwarding server.
|
||||||
// The raddr is the remote address that the server will forward to.
|
// The raddr is the remote address that the server will forward to.
|
||||||
func UDPForwardHandler(raddr string, opts ...HandlerOption) Handler {
|
func UDPDirectForwardHandler(raddr string, opts ...HandlerOption) Handler {
|
||||||
h := &udpForwardHandler{
|
h := &udpDirectForwardHandler{
|
||||||
raddr: raddr,
|
raddr: raddr,
|
||||||
options: &HandlerOptions{},
|
options: &HandlerOptions{},
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ func UDPForwardHandler(raddr string, opts ...HandlerOption) Handler {
|
|||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *udpForwardHandler) Handle(conn net.Conn) {
|
func (h *udpDirectForwardHandler) Handle(conn net.Conn) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
var cc net.Conn
|
var cc net.Conn
|
||||||
@ -82,7 +82,7 @@ func (h *udpForwardHandler) Handle(conn net.Conn) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
cc, err = getSOCKS5UDPTunnel(h.options.Chain)
|
cc, err = getSOCKS5UDPTunnel(h.options.Chain, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Logf("[udp] %s - %s : %s", conn.LocalAddr(), h.raddr, err)
|
log.Logf("[udp] %s - %s : %s", conn.LocalAddr(), h.raddr, err)
|
||||||
return
|
return
|
||||||
@ -97,15 +97,15 @@ func (h *udpForwardHandler) Handle(conn net.Conn) {
|
|||||||
log.Logf("[udp] %s >-< %s", conn.RemoteAddr(), h.raddr)
|
log.Logf("[udp] %s >-< %s", conn.RemoteAddr(), h.raddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
type rtcpForwardHandler struct {
|
type tcpRemoteForwardHandler struct {
|
||||||
raddr string
|
raddr string
|
||||||
options *HandlerOptions
|
options *HandlerOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTCPForwardHandler creates a server Handler for TCP remote port forwarding server.
|
// TCPRemoteForwardHandler creates a server Handler for TCP remote port forwarding server.
|
||||||
// The raddr is the remote address that the server will forward to.
|
// The raddr is the remote address that the server will forward to.
|
||||||
func RTCPForwardHandler(raddr string, opts ...HandlerOption) Handler {
|
func TCPRemoteForwardHandler(raddr string, opts ...HandlerOption) Handler {
|
||||||
h := &rtcpForwardHandler{
|
h := &tcpRemoteForwardHandler{
|
||||||
raddr: raddr,
|
raddr: raddr,
|
||||||
options: &HandlerOptions{},
|
options: &HandlerOptions{},
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ func RTCPForwardHandler(raddr string, opts ...HandlerOption) Handler {
|
|||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *rtcpForwardHandler) Handle(conn net.Conn) {
|
func (h *tcpRemoteForwardHandler) Handle(conn net.Conn) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
cc, err := net.DialTimeout("tcp", h.raddr, DialTimeout)
|
cc, err := net.DialTimeout("tcp", h.raddr, DialTimeout)
|
||||||
@ -130,17 +130,15 @@ func (h *rtcpForwardHandler) Handle(conn net.Conn) {
|
|||||||
log.Logf("[rtcp] %s >-< %s", conn.LocalAddr(), h.raddr)
|
log.Logf("[rtcp] %s >-< %s", conn.LocalAddr(), h.raddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
type rudpForwardHandler struct {
|
type udpRemoteForwardHandler struct {
|
||||||
laddr string
|
|
||||||
raddr string
|
raddr string
|
||||||
options *HandlerOptions
|
options *HandlerOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
// RUDPForwardHandler creates a server Handler for UDP remote port forwarding server.
|
// UDPRemoteForwardHandler creates a server Handler for UDP remote port forwarding server.
|
||||||
// The raddr is the remote address that the server will forward to.
|
// The raddr is the remote address that the server will forward to.
|
||||||
func RUDPForwardHandler(laddr, raddr string, opts ...HandlerOption) Handler {
|
func UDPRemoteForwardHandler(raddr string, opts ...HandlerOption) Handler {
|
||||||
h := &rudpForwardHandler{
|
h := &udpRemoteForwardHandler{
|
||||||
laddr: laddr,
|
|
||||||
raddr: raddr,
|
raddr: raddr,
|
||||||
options: &HandlerOptions{},
|
options: &HandlerOptions{},
|
||||||
}
|
}
|
||||||
@ -150,74 +148,35 @@ func RUDPForwardHandler(laddr, raddr string, opts ...HandlerOption) Handler {
|
|||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *rudpForwardHandler) Handle(conn net.Conn) {
|
func (h *udpRemoteForwardHandler) Handle(conn net.Conn) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
// TODO: handle connection
|
raddr, err := net.ResolveUDPAddr("udp", h.raddr)
|
||||||
|
|
||||||
/*
|
|
||||||
ra, err := net.ResolveUDPAddr("udp", h.raddr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Logf("[rudp] %s - %s : %s", h.laddr, h.raddr, err)
|
log.Logf("[rudp] %s - %s : %s", conn.RemoteAddr(), h.raddr, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
cc, err := net.DialUDP("udp", nil, raddr)
|
||||||
for {
|
|
||||||
dgram, err := gosocks5.ReadUDPDatagram(conn)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Logf("[rudp] %s -> %s : %s", h.laddr, h.raddr, err)
|
log.Logf("[rudp] %s - %s : %s", conn.RemoteAddr(), h.raddr, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
log.Logf("[rudp] %s <-> %s", conn.RemoteAddr(), h.raddr)
|
||||||
b := make([]byte, mediumBufferSize)
|
transport(conn, cc)
|
||||||
|
log.Logf("[rudp] %s >-< %s", conn.RemoteAddr(), h.raddr)
|
||||||
relay, err := net.DialUDP("udp", nil, ra)
|
|
||||||
if err != nil {
|
|
||||||
log.Logf("[rudp] %s -> %s : %s", h.laddr, h.raddr, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer relay.Close()
|
|
||||||
|
|
||||||
if _, err := relay.Write(dgram.Data); err != nil {
|
|
||||||
log.Logf("[rudp] %s -> %s : %s", h.laddr, h.raddr, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if Debug {
|
|
||||||
log.Logf("[rudp] %s >>> %s length: %d", h.laddr, h.raddr, len(dgram.Data))
|
|
||||||
}
|
|
||||||
relay.SetReadDeadline(time.Now().Add(ReadTimeout))
|
|
||||||
n, err := relay.Read(b)
|
|
||||||
if err != nil {
|
|
||||||
log.Logf("[rudp] %s <- %s : %s", h.laddr, h.raddr, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
relay.SetReadDeadline(time.Time{})
|
|
||||||
if Debug {
|
|
||||||
log.Logf("[rudp] %s <<< %s length: %d", h.laddr, h.raddr, n)
|
|
||||||
}
|
|
||||||
conn.SetWriteDeadline(time.Now().Add(WriteTimeout))
|
|
||||||
if err := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(uint16(n), 0, dgram.Header.Addr), b[:n]).Write(conn); err != nil {
|
|
||||||
log.Logf("[rudp] %s <- %s : %s", h.laddr, h.raddr, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
conn.SetWriteDeadline(time.Time{})
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type udpForwardListener struct {
|
type udpDirectForwardListener struct {
|
||||||
ln *net.UDPConn
|
ln *net.UDPConn
|
||||||
conns map[string]*udpServerConn
|
conns map[string]*udpServerConn
|
||||||
connMutex sync.Mutex
|
|
||||||
connChan chan net.Conn
|
connChan chan net.Conn
|
||||||
errChan chan error
|
errChan chan error
|
||||||
ttl time.Duration
|
ttl time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDPForwardListener creates a Listener for UDP port forwarding server.
|
// UDPDirectForwardListener creates a Listener for UDP port forwarding server.
|
||||||
func UDPForwardListener(addr string, ttl time.Duration) (Listener, error) {
|
func UDPDirectForwardListener(addr string, ttl time.Duration) (Listener, error) {
|
||||||
laddr, err := net.ResolveUDPAddr("udp", addr)
|
laddr, err := net.ResolveUDPAddr("udp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -226,7 +185,7 @@ func UDPForwardListener(addr string, ttl time.Duration) (Listener, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
l := &udpForwardListener{
|
l := &udpDirectForwardListener{
|
||||||
ln: ln,
|
ln: ln,
|
||||||
conns: make(map[string]*udpServerConn),
|
conns: make(map[string]*udpServerConn),
|
||||||
connChan: make(chan net.Conn, 1024),
|
connChan: make(chan net.Conn, 1024),
|
||||||
@ -237,7 +196,7 @@ func UDPForwardListener(addr string, ttl time.Duration) (Listener, error) {
|
|||||||
return l, nil
|
return l, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *udpForwardListener) listenLoop() {
|
func (l *udpDirectForwardListener) listenLoop() {
|
||||||
for {
|
for {
|
||||||
b := make([]byte, mediumBufferSize)
|
b := make([]byte, mediumBufferSize)
|
||||||
n, raddr, err := l.ln.ReadFromUDP(b)
|
n, raddr, err := l.ln.ReadFromUDP(b)
|
||||||
@ -246,6 +205,7 @@ func (l *udpForwardListener) listenLoop() {
|
|||||||
l.ln.Close()
|
l.ln.Close()
|
||||||
l.errChan <- err
|
l.errChan <- err
|
||||||
close(l.errChan)
|
close(l.errChan)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if Debug {
|
if Debug {
|
||||||
log.Logf("[udp] %s >>> %s : length %d", raddr, l.Addr(), n)
|
log.Logf("[udp] %s >>> %s : length %d", raddr, l.Addr(), n)
|
||||||
@ -271,7 +231,7 @@ func (l *udpForwardListener) listenLoop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *udpForwardListener) Accept() (conn net.Conn, err error) {
|
func (l *udpDirectForwardListener) Accept() (conn net.Conn, err error) {
|
||||||
var ok bool
|
var ok bool
|
||||||
select {
|
select {
|
||||||
case conn = <-l.connChan:
|
case conn = <-l.connChan:
|
||||||
@ -283,17 +243,17 @@ func (l *udpForwardListener) Accept() (conn net.Conn, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *udpForwardListener) Addr() net.Addr {
|
func (l *udpDirectForwardListener) Addr() net.Addr {
|
||||||
return l.ln.LocalAddr()
|
return l.ln.LocalAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *udpForwardListener) Close() error {
|
func (l *udpDirectForwardListener) Close() error {
|
||||||
return l.ln.Close()
|
return l.ln.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
type udpServerConn struct {
|
type udpServerConn struct {
|
||||||
conn *net.UDPConn
|
conn net.PacketConn
|
||||||
raddr *net.UDPAddr
|
raddr net.Addr
|
||||||
rChan, wChan chan []byte
|
rChan, wChan chan []byte
|
||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
brokenChan chan struct{}
|
brokenChan chan struct{}
|
||||||
@ -302,7 +262,7 @@ type udpServerConn struct {
|
|||||||
nopChan chan int
|
nopChan chan int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newUDPServerConn(conn *net.UDPConn, raddr *net.UDPAddr, ttl time.Duration) *udpServerConn {
|
func newUDPServerConn(conn net.PacketConn, raddr net.Addr, ttl time.Duration) *udpServerConn {
|
||||||
c := &udpServerConn{
|
c := &udpServerConn{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
raddr: raddr,
|
raddr: raddr,
|
||||||
@ -391,9 +351,9 @@ func (c *udpServerConn) writeLoop() {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n, err := c.conn.WriteToUDP(b, c.raddr)
|
n, err := c.conn.WriteTo(b, c.raddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Logf("[udp] %s <<< %s : %s", c.RemoteAddr(), c.LocalAddr(), err)
|
log.Logf("[udp] %s - %s : %s", c.RemoteAddr(), c.LocalAddr(), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if Debug {
|
if Debug {
|
||||||
@ -443,53 +403,27 @@ func (c *udpServerConn) SetWriteDeadline(t time.Time) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type udpTunnelConn struct {
|
type tcpRemoteForwardListener struct {
|
||||||
raddr string
|
|
||||||
net.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *udpTunnelConn) Read(b []byte) (n int, err error) {
|
|
||||||
dgram, err := gosocks5.ReadUDPDatagram(c.Conn)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n = copy(b, dgram.Data)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *udpTunnelConn) Write(b []byte) (n int, err error) {
|
|
||||||
addr, err := net.ResolveUDPAddr("udp", c.raddr)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dgram := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(uint16(len(b)), 0, toSocksAddr(addr)), b)
|
|
||||||
if err = dgram.Write(c.Conn); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return len(b), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type rtcpForwardListener struct {
|
|
||||||
addr net.Addr
|
addr net.Addr
|
||||||
chain *Chain
|
chain *Chain
|
||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTCPForwardListener creates a Listener for TCP remote port forwarding server.
|
// TCPRemoteForwardListener creates a Listener for TCP remote port forwarding server.
|
||||||
func RTCPForwardListener(addr string, chain *Chain) (Listener, error) {
|
func TCPRemoteForwardListener(addr string, chain *Chain) (Listener, error) {
|
||||||
laddr, err := net.ResolveTCPAddr("tcp", addr)
|
laddr, err := net.ResolveTCPAddr("tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &rtcpForwardListener{
|
return &tcpRemoteForwardListener{
|
||||||
addr: laddr,
|
addr: laddr,
|
||||||
chain: chain,
|
chain: chain,
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *rtcpForwardListener) Accept() (net.Conn, error) {
|
func (l *tcpRemoteForwardListener) Accept() (net.Conn, error) {
|
||||||
select {
|
select {
|
||||||
case <-l.closed:
|
case <-l.closed:
|
||||||
return nil, errors.New("closed")
|
return nil, errors.New("closed")
|
||||||
@ -516,7 +450,7 @@ func (l *rtcpForwardListener) Accept() (net.Conn, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *rtcpForwardListener) accept() (conn net.Conn, err error) {
|
func (l *tcpRemoteForwardListener) accept() (conn net.Conn, err error) {
|
||||||
lastNode := l.chain.LastNode()
|
lastNode := l.chain.LastNode()
|
||||||
if lastNode.Protocol == "forward" && lastNode.Transport == "ssh" {
|
if lastNode.Protocol == "forward" && lastNode.Transport == "ssh" {
|
||||||
conn, err = l.chain.Dial(l.addr.String())
|
conn, err = l.chain.Dial(l.addr.String())
|
||||||
@ -535,7 +469,7 @@ func (l *rtcpForwardListener) accept() (conn net.Conn, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *rtcpForwardListener) waitConnectSOCKS5(conn net.Conn) (net.Conn, error) {
|
func (l *tcpRemoteForwardListener) waitConnectSOCKS5(conn net.Conn) (net.Conn, error) {
|
||||||
conn, err := socks5Handshake(conn, l.chain.LastNode().User)
|
conn, err := socks5Handshake(conn, l.chain.LastNode().User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -575,45 +509,111 @@ func (l *rtcpForwardListener) waitConnectSOCKS5(conn net.Conn) (net.Conn, error)
|
|||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *rtcpForwardListener) Addr() net.Addr {
|
func (l *tcpRemoteForwardListener) Addr() net.Addr {
|
||||||
return l.addr
|
return l.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *rtcpForwardListener) Close() error {
|
func (l *tcpRemoteForwardListener) Close() error {
|
||||||
close(l.closed)
|
close(l.closed)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type rudpForwardListener struct {
|
type udpRemoteForwardListener struct {
|
||||||
addr *net.UDPAddr
|
addr *net.UDPAddr
|
||||||
chain *Chain
|
chain *Chain
|
||||||
|
conns map[string]*udpServerConn
|
||||||
|
connChan chan net.Conn
|
||||||
|
errChan chan error
|
||||||
|
ttl time.Duration
|
||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RUDPForwardListener creates a Listener for UDP remote port forwarding server.
|
// UDPRemoteForwardListener creates a Listener for UDP remote port forwarding server.
|
||||||
func RUDPForwardListener(addr string, chain *Chain) (Listener, error) {
|
func UDPRemoteForwardListener(addr string, chain *Chain, ttl time.Duration) (Listener, error) {
|
||||||
laddr, err := net.ResolveUDPAddr("udp", addr)
|
laddr, err := net.ResolveUDPAddr("udp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &rudpForwardListener{
|
ln := &udpRemoteForwardListener{
|
||||||
addr: laddr,
|
addr: laddr,
|
||||||
chain: chain,
|
chain: chain,
|
||||||
|
conns: make(map[string]*udpServerConn),
|
||||||
|
connChan: make(chan net.Conn, 1024),
|
||||||
|
errChan: make(chan error, 1),
|
||||||
|
ttl: ttl,
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
}, nil
|
}
|
||||||
|
go ln.listenLoop()
|
||||||
|
return ln, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *rudpForwardListener) Accept() (net.Conn, error) {
|
func (l *udpRemoteForwardListener) listenLoop() {
|
||||||
|
for {
|
||||||
|
conn, err := l.connect()
|
||||||
|
if err != nil {
|
||||||
|
log.Logf("[rudp] %s : %s", l.Addr(), err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
for {
|
||||||
|
b := make([]byte, mediumBufferSize)
|
||||||
|
n, raddr, err := conn.ReadFrom(b)
|
||||||
|
if err != nil {
|
||||||
|
log.Logf("[rudp] %s : %s", l.Addr(), err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if Debug {
|
||||||
|
log.Logf("[udp] %s >>> %s : length %d", raddr, l.Addr(), n)
|
||||||
|
}
|
||||||
|
uc, ok := l.conns[raddr.String()]
|
||||||
|
if !ok || uc.Closed() {
|
||||||
|
uc = newUDPServerConn(conn, raddr, l.ttl)
|
||||||
|
l.conns[raddr.String()] = uc
|
||||||
|
|
||||||
|
select {
|
||||||
|
case l.connChan <- uc:
|
||||||
|
default:
|
||||||
|
uc.Close()
|
||||||
|
log.Logf("[rudp] %s - %s: connection queue is full", raddr, l.Addr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case uc.rChan <- b[:n]:
|
||||||
|
default:
|
||||||
|
log.Logf("[rudp] %s -> %s : write queue is full", raddr, l.Addr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *udpRemoteForwardListener) connect() (conn net.PacketConn, err error) {
|
||||||
|
var tempDelay time.Duration
|
||||||
|
|
||||||
|
for {
|
||||||
select {
|
select {
|
||||||
case <-l.closed:
|
case <-l.closed:
|
||||||
return nil, errors.New("closed")
|
return nil, errors.New("closed")
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
var tempDelay time.Duration
|
lastNode := l.chain.LastNode()
|
||||||
for {
|
if lastNode.Protocol == "socks5" {
|
||||||
conn, err := l.accept()
|
var cc net.Conn
|
||||||
|
cc, err = getSOCKS5UDPTunnel(l.chain, l.addr)
|
||||||
|
if err != nil {
|
||||||
|
log.Logf("[rudp] %s : %s", l.Addr(), err)
|
||||||
|
} else {
|
||||||
|
conn = &udpTunnelConn{Conn: cc}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
conn, err = net.ListenUDP("udp", l.addr)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if tempDelay == 0 {
|
if tempDelay == 0 {
|
||||||
tempDelay = 1000 * time.Millisecond
|
tempDelay = 1000 * time.Millisecond
|
||||||
@ -627,25 +627,27 @@ func (l *rudpForwardListener) Accept() (net.Conn, error) {
|
|||||||
time.Sleep(tempDelay)
|
time.Sleep(tempDelay)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return conn, nil
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *rudpForwardListener) accept() (conn net.Conn, err error) {
|
func (l *udpRemoteForwardListener) Accept() (conn net.Conn, err error) {
|
||||||
lastNode := l.chain.LastNode()
|
var ok bool
|
||||||
if lastNode.Protocol == "socks5" {
|
select {
|
||||||
conn, err = getSOCKS5UDPTunnel(l.chain)
|
case conn = <-l.connChan:
|
||||||
} else {
|
case err, ok = <-l.errChan:
|
||||||
conn, err = net.ListenUDP("udp", l.addr)
|
if !ok {
|
||||||
|
err = errors.New("accpet on closed listener")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *rudpForwardListener) Addr() net.Addr {
|
func (l *udpRemoteForwardListener) Addr() net.Addr {
|
||||||
return l.addr
|
return l.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *rudpForwardListener) Close() error {
|
func (l *udpRemoteForwardListener) Close() error {
|
||||||
close(l.closed)
|
close(l.closed)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -747,7 +747,7 @@ func (h *socks5Handler) tunnelClientUDP(uc *net.UDPConn, cc net.Conn) (err error
|
|||||||
var clientAddr *net.UDPAddr
|
var clientAddr *net.UDPAddr
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
b := make([]byte, largeBufferSize)
|
b := make([]byte, mediumBufferSize)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
n, addr, err := uc.ReadFromUDP(b)
|
n, addr, err := uc.ReadFromUDP(b)
|
||||||
@ -876,12 +876,12 @@ func (h *socks5Handler) tunnelServerUDP(cc net.Conn, uc *net.UDPConn) (err error
|
|||||||
errc := make(chan error, 2)
|
errc := make(chan error, 2)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
b := make([]byte, largeBufferSize)
|
b := make([]byte, mediumBufferSize)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
n, addr, err := uc.ReadFromUDP(b)
|
n, addr, err := uc.ReadFromUDP(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// log.Logf("[udp-tun] %s <- %s : %s", cc.RemoteAddr(), addr, err)
|
log.Logf("[udp-tun] %s <- %s : %s", cc.RemoteAddr(), addr, err)
|
||||||
errc <- err
|
errc <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -904,7 +904,7 @@ func (h *socks5Handler) tunnelServerUDP(cc net.Conn, uc *net.UDPConn) (err error
|
|||||||
for {
|
for {
|
||||||
dgram, err := gosocks5.ReadUDPDatagram(cc)
|
dgram, err := gosocks5.ReadUDPDatagram(cc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// log.Logf("[udp-tun] %s -> 0 : %s", cc.RemoteAddr(), err)
|
log.Logf("[udp-tun] %s -> 0 : %s", cc.RemoteAddr(), err)
|
||||||
errc <- err
|
errc <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1057,7 +1057,7 @@ func (h *socks4Handler) handleBind(conn net.Conn, req *gosocks4.Request) {
|
|||||||
log.Logf("[socks4-bind] %s >-< %s", conn.RemoteAddr(), cc.RemoteAddr())
|
log.Logf("[socks4-bind] %s >-< %s", conn.RemoteAddr(), cc.RemoteAddr())
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSOCKS5UDPTunnel(chain *Chain) (net.Conn, error) {
|
func getSOCKS5UDPTunnel(chain *Chain, addr net.Addr) (net.Conn, error) {
|
||||||
conn, err := chain.Conn()
|
conn, err := chain.Conn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1070,10 +1070,14 @@ func getSOCKS5UDPTunnel(chain *Chain) (net.Conn, error) {
|
|||||||
conn = cc
|
conn = cc
|
||||||
|
|
||||||
conn.SetWriteDeadline(time.Now().Add(WriteTimeout))
|
conn.SetWriteDeadline(time.Now().Add(WriteTimeout))
|
||||||
if err = gosocks5.NewRequest(CmdUDPTun, nil).Write(conn); err != nil {
|
req := gosocks5.NewRequest(CmdUDPTun, toSocksAddr(addr))
|
||||||
|
if err := req.Write(conn); err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if Debug {
|
||||||
|
log.Log("[socks5]", req)
|
||||||
|
}
|
||||||
conn.SetWriteDeadline(time.Time{})
|
conn.SetWriteDeadline(time.Time{})
|
||||||
|
|
||||||
conn.SetReadDeadline(time.Now().Add(ReadTimeout))
|
conn.SetReadDeadline(time.Now().Add(ReadTimeout))
|
||||||
@ -1083,6 +1087,9 @@ func getSOCKS5UDPTunnel(chain *Chain) (net.Conn, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
conn.SetReadDeadline(time.Time{})
|
conn.SetReadDeadline(time.Time{})
|
||||||
|
if Debug {
|
||||||
|
log.Log("[socks5]", reply)
|
||||||
|
}
|
||||||
|
|
||||||
if reply.Rep != gosocks5.Succeeded {
|
if reply.Rep != gosocks5.Succeeded {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -1107,3 +1114,47 @@ func socks5Handshake(conn net.Conn, user *url.Userinfo) (net.Conn, error) {
|
|||||||
}
|
}
|
||||||
return cc, nil
|
return cc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type udpTunnelConn struct {
|
||||||
|
raddr string
|
||||||
|
net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *udpTunnelConn) Read(b []byte) (n int, err error) {
|
||||||
|
dgram, err := gosocks5.ReadUDPDatagram(c.Conn)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n = copy(b, dgram.Data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *udpTunnelConn) ReadFrom(b []byte) (n int, addr net.Addr, err error) {
|
||||||
|
dgram, err := gosocks5.ReadUDPDatagram(c.Conn)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n = copy(b, dgram.Data)
|
||||||
|
addr, err = net.ResolveUDPAddr("udp", dgram.Header.Addr.String())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *udpTunnelConn) Write(b []byte) (n int, err error) {
|
||||||
|
addr, err := net.ResolveUDPAddr("udp", c.raddr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dgram := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(uint16(len(b)), 0, toSocksAddr(addr)), b)
|
||||||
|
if err = dgram.Write(c.Conn); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return len(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *udpTunnelConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
|
||||||
|
dgram := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(uint16(len(b)), 0, toSocksAddr(addr)), b)
|
||||||
|
if err = dgram.Write(c.Conn); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return len(b), nil
|
||||||
|
}
|
||||||
|
9
vendor/github.com/ginuerzh/gosocks5/socks5.go
generated
vendored
9
vendor/github.com/ginuerzh/gosocks5/socks5.go
generated
vendored
@ -4,6 +4,7 @@
|
|||||||
package gosocks5
|
package gosocks5
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -658,10 +659,14 @@ func (d *UDPDatagram) Write(w io.Writer) error {
|
|||||||
if h == nil {
|
if h == nil {
|
||||||
h = &UDPHeader{}
|
h = &UDPHeader{}
|
||||||
}
|
}
|
||||||
if err := h.Write(w); err != nil {
|
buf := bytes.Buffer{}
|
||||||
|
if err := h.Write(&buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := buf.Write(d.Data); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err := w.Write(d.Data)
|
|
||||||
|
|
||||||
|
_, err := buf.WriteTo(w)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
@ -15,10 +15,10 @@
|
|||||||
"revisionTime": "2017-02-09T14:09:51Z"
|
"revisionTime": "2017-02-09T14:09:51Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "5TwW96Afcvo+zm0tAn+DSNIQreQ=",
|
"checksumSHA1": "4JEexBJToQeQm7fAo2PHVdCU3zM=",
|
||||||
"path": "github.com/ginuerzh/gosocks5",
|
"path": "github.com/ginuerzh/gosocks5",
|
||||||
"revision": "0f737bddba2abd1496dc03c8b39b817cc5f33fa7",
|
"revision": "cb895c2f7a2cdceaf74ac6497f709b71a999168a",
|
||||||
"revisionTime": "2017-01-19T05:34:58Z"
|
"revisionTime": "2017-08-01T04:47:37Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "9e9tjPDTESeCEdUMElph250lurs=",
|
"checksumSHA1": "9e9tjPDTESeCEdUMElph250lurs=",
|
||||||
|
Loading…
Reference in New Issue
Block a user