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

add UDP remote port forwarding support

parent be68f616
......@@ -5,6 +5,7 @@ import (
"flag"
"log"
"net/url"
"time"
"github.com/ginuerzh/gost/gost"
)
......@@ -132,13 +133,13 @@ func tcpForwardServer() {
if err != nil {
log.Fatal(err)
}
h := gost.TCPForwardHandler("localhost:22")
h := gost.TCPDirectForwardHandler("localhost:22")
log.Fatal(s.Serve(ln, h))
}
func rtcpForwardServer() {
s := &gost.Server{}
ln, err := gost.RTCPForwardListener(
ln, err := gost.TCPRemoteForwardListener(
":1222",
gost.NewChain(
gost.Node{
......@@ -156,7 +157,7 @@ func rtcpForwardServer() {
if err != nil {
log.Fatal()
}
h := gost.RTCPForwardHandler(
h := gost.TCPRemoteForwardHandler(
":1222",
gost.AddrHandlerOption("127.0.0.1:22"),
)
......@@ -165,7 +166,7 @@ func rtcpForwardServer() {
func rudpForwardServer() {
s := &gost.Server{}
ln, err := gost.RUDPForwardListener(
ln, err := gost.UDPRemoteForwardListener(
":10053",
gost.NewChain(
gost.Node{
......@@ -179,11 +180,12 @@ func rudpForwardServer() {
},
},
),
30*time.Second,
)
if err != nil {
log.Fatal()
}
h := gost.RUDPForwardHandler(":10053", "localhost:53")
h := gost.UDPRemoteForwardHandler("localhost:53")
log.Fatal(s.Serve(ln, h))
}
......
......@@ -26,7 +26,7 @@ func tcpForward() {
if err != nil {
log.Fatal(err)
}
h := gost.TCPForwardHandler(
h := gost.TCPDirectForwardHandler(
"localhost:22",
gost.ChainHandlerOption(chain),
)
......
......@@ -24,11 +24,11 @@ func sshRemoteForward() {
)
s := &gost.Server{}
ln, err := gost.RTCPForwardListener(":11800", chain)
ln, err := gost.TCPRemoteForwardListener(":11800", chain)
if err != nil {
log.Fatal(err)
}
h := gost.RTCPForwardHandler(
h := gost.TCPRemoteForwardHandler(
"localhost:10000",
)
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() {
}
}
func main() {
udpForwardServer()
udpRemoteForwardServer()
}
func udpForwardServer() {
func udpRemoteForwardServer() {
s := &gost.Server{}
ln, err := gost.UDPForwardListener(laddr, time.Second*30)
if err != nil {
log.Fatal(err)
}
h := gost.UDPForwardHandler(
faddr,
ln, err := gost.UDPRemoteForwardListener(
laddr,
/*
gost.ChainHandlerOption(gost.NewChain(gost.Node{
gost.NewChain(gost.Node{
Protocol: "socks5",
Transport: "tcp",
Addr: ":11080",
......@@ -50,8 +46,15 @@ func udpForwardServer() {
),
Transporter: gost.TCPTransporter(),
},
})),
}),
*/
nil,
time.Second*30)
if err != nil {
log.Fatal(err)
}
h := gost.UDPRemoteForwardHandler(
faddr,
)
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
var clientAddr *net.UDPAddr
go func() {
b := make([]byte, largeBufferSize)
b := make([]byte, mediumBufferSize)
for {
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)
go func() {
b := make([]byte, largeBufferSize)
b := make([]byte, mediumBufferSize)
for {
n, addr, err := uc.ReadFromUDP(b)
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
return
}
......@@ -904,7 +904,7 @@ func (h *socks5Handler) tunnelServerUDP(cc net.Conn, uc *net.UDPConn) (err error
for {
dgram, err := gosocks5.ReadUDPDatagram(cc)
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
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())
}
func getSOCKS5UDPTunnel(chain *Chain) (net.Conn, error) {
func getSOCKS5UDPTunnel(chain *Chain, addr net.Addr) (net.Conn, error) {
conn, err := chain.Conn()
if err != nil {
return nil, err
......@@ -1070,10 +1070,14 @@ func getSOCKS5UDPTunnel(chain *Chain) (net.Conn, error) {
conn = cc
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()
return nil, err
}
if Debug {
log.Log("[socks5]", req)
}
conn.SetWriteDeadline(time.Time{})
conn.SetReadDeadline(time.Now().Add(ReadTimeout))
......@@ -1083,6 +1087,9 @@ func getSOCKS5UDPTunnel(chain *Chain) (net.Conn, error) {
return nil, err
}
conn.SetReadDeadline(time.Time{})
if Debug {
log.Log("[socks5]", reply)
}
if reply.Rep != gosocks5.Succeeded {
conn.Close()
......@@ -1107,3 +1114,47 @@ func socks5Handshake(conn net.Conn, user *url.Userinfo) (net.Conn, error) {
}
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 @@
package gosocks5
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
......@@ -658,10 +659,14 @@ func (d *UDPDatagram) Write(w io.Writer) error {
if h == nil {
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
}
_, err := w.Write(d.Data)
_, err := buf.WriteTo(w)
return err
}
......@@ -15,10 +15,10 @@
"revisionTime": "2017-02-09T14:09:51Z"
},
{
"checksumSHA1": "5TwW96Afcvo+zm0tAn+DSNIQreQ=",
"checksumSHA1": "4JEexBJToQeQm7fAo2PHVdCU3zM=",
"path": "github.com/ginuerzh/gosocks5",
"revision": "0f737bddba2abd1496dc03c8b39b817cc5f33fa7",
"revisionTime": "2017-01-19T05:34:58Z"
"revision": "cb895c2f7a2cdceaf74ac6497f709b71a999168a",
"revisionTime": "2017-08-01T04:47:37Z"
},
{
"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