Commit 89681dd5 authored by rui.zheng's avatar rui.zheng

add UDP remote port forwarding support

parent be68f616
...@@ -5,6 +5,7 @@ import ( ...@@ -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() { ...@@ -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() { ...@@ -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() { ...@@ -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() { ...@@ -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() { ...@@ -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() { ...@@ -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))
......
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() { ...@@ -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() { ...@@ -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))
} }
This diff is collapsed.
...@@ -747,7 +747,7 @@ func (h *socks5Handler) tunnelClientUDP(uc *net.UDPConn, cc net.Conn) (err error ...@@ -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 ...@@ -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 ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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
}
...@@ -4,6 +4,7 @@ ...@@ -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 { ...@@ -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
} }
...@@ -15,10 +15,10 @@ ...@@ -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=",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment