add UDP remote port forwarding support

This commit is contained in:
rui.zheng 2017-08-01 14:13:02 +08:00
parent be68f616aa
commit 89681dd582
9 changed files with 303 additions and 183 deletions

View File

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

View File

@ -26,7 +26,7 @@ func tcpForward() {
if err != nil {
log.Fatal(err)
}
h := gost.TCPForwardHandler(
h := gost.TCPDirectForwardHandler(
"localhost:22",
gost.ChainHandlerOption(chain),
)

View File

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

View 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))
}

View File

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

View File

@ -12,15 +12,15 @@ import (
"github.com/go-log/log"
)
type tcpForwardHandler struct {
type tcpDirectForwardHandler struct {
raddr string
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.
func TCPForwardHandler(raddr string, opts ...HandlerOption) Handler {
h := &tcpForwardHandler{
func TCPDirectForwardHandler(raddr string, opts ...HandlerOption) Handler {
h := &tcpDirectForwardHandler{
raddr: raddr,
options: &HandlerOptions{},
}
@ -30,7 +30,7 @@ func TCPForwardHandler(raddr string, opts ...HandlerOption) Handler {
return h
}
func (h *tcpForwardHandler) Handle(conn net.Conn) {
func (h *tcpDirectForwardHandler) Handle(conn net.Conn) {
defer conn.Close()
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)
}
type udpForwardHandler struct {
type udpDirectForwardHandler struct {
raddr string
ttl time.Duration
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.
func UDPForwardHandler(raddr string, opts ...HandlerOption) Handler {
h := &udpForwardHandler{
func UDPDirectForwardHandler(raddr string, opts ...HandlerOption) Handler {
h := &udpDirectForwardHandler{
raddr: raddr,
options: &HandlerOptions{},
}
@ -65,7 +65,7 @@ func UDPForwardHandler(raddr string, opts ...HandlerOption) Handler {
return h
}
func (h *udpForwardHandler) Handle(conn net.Conn) {
func (h *udpDirectForwardHandler) Handle(conn net.Conn) {
defer conn.Close()
var cc net.Conn
@ -82,7 +82,7 @@ func (h *udpForwardHandler) Handle(conn net.Conn) {
}
} else {
var err error
cc, err = getSOCKS5UDPTunnel(h.options.Chain)
cc, err = getSOCKS5UDPTunnel(h.options.Chain, nil)
if err != nil {
log.Logf("[udp] %s - %s : %s", conn.LocalAddr(), h.raddr, err)
return
@ -97,15 +97,15 @@ func (h *udpForwardHandler) Handle(conn net.Conn) {
log.Logf("[udp] %s >-< %s", conn.RemoteAddr(), h.raddr)
}
type rtcpForwardHandler struct {
type tcpRemoteForwardHandler struct {
raddr string
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.
func RTCPForwardHandler(raddr string, opts ...HandlerOption) Handler {
h := &rtcpForwardHandler{
func TCPRemoteForwardHandler(raddr string, opts ...HandlerOption) Handler {
h := &tcpRemoteForwardHandler{
raddr: raddr,
options: &HandlerOptions{},
}
@ -115,7 +115,7 @@ func RTCPForwardHandler(raddr string, opts ...HandlerOption) Handler {
return h
}
func (h *rtcpForwardHandler) Handle(conn net.Conn) {
func (h *tcpRemoteForwardHandler) Handle(conn net.Conn) {
defer conn.Close()
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)
}
type rudpForwardHandler struct {
laddr string
type udpRemoteForwardHandler struct {
raddr string
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.
func RUDPForwardHandler(laddr, raddr string, opts ...HandlerOption) Handler {
h := &rudpForwardHandler{
laddr: laddr,
func UDPRemoteForwardHandler(raddr string, opts ...HandlerOption) Handler {
h := &udpRemoteForwardHandler{
raddr: raddr,
options: &HandlerOptions{},
}
@ -150,74 +148,35 @@ func RUDPForwardHandler(laddr, raddr string, opts ...HandlerOption) Handler {
return h
}
func (h *rudpForwardHandler) Handle(conn net.Conn) {
func (h *udpRemoteForwardHandler) Handle(conn net.Conn) {
defer conn.Close()
// TODO: handle connection
/*
ra, err := net.ResolveUDPAddr("udp", h.raddr)
raddr, err := net.ResolveUDPAddr("udp", h.raddr)
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
}
for {
dgram, err := gosocks5.ReadUDPDatagram(conn)
cc, err := net.DialUDP("udp", nil, raddr)
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
}
go func() {
b := make([]byte, mediumBufferSize)
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{})
}()
}
*/
log.Logf("[rudp] %s <-> %s", conn.RemoteAddr(), h.raddr)
transport(conn, cc)
log.Logf("[rudp] %s >-< %s", conn.RemoteAddr(), h.raddr)
}
type udpForwardListener struct {
type udpDirectForwardListener struct {
ln *net.UDPConn
conns map[string]*udpServerConn
connMutex sync.Mutex
connChan chan net.Conn
errChan chan error
ttl time.Duration
}
// UDPForwardListener creates a Listener for UDP port forwarding server.
func UDPForwardListener(addr string, ttl time.Duration) (Listener, error) {
// UDPDirectForwardListener creates a Listener for UDP port forwarding server.
func UDPDirectForwardListener(addr string, ttl time.Duration) (Listener, error) {
laddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
return nil, err
@ -226,7 +185,7 @@ func UDPForwardListener(addr string, ttl time.Duration) (Listener, error) {
if err != nil {
return nil, err
}
l := &udpForwardListener{
l := &udpDirectForwardListener{
ln: ln,
conns: make(map[string]*udpServerConn),
connChan: make(chan net.Conn, 1024),
@ -237,7 +196,7 @@ func UDPForwardListener(addr string, ttl time.Duration) (Listener, error) {
return l, nil
}
func (l *udpForwardListener) listenLoop() {
func (l *udpDirectForwardListener) listenLoop() {
for {
b := make([]byte, mediumBufferSize)
n, raddr, err := l.ln.ReadFromUDP(b)
@ -246,6 +205,7 @@ func (l *udpForwardListener) listenLoop() {
l.ln.Close()
l.errChan <- err
close(l.errChan)
return
}
if Debug {
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
select {
case conn = <-l.connChan:
@ -283,17 +243,17 @@ func (l *udpForwardListener) Accept() (conn net.Conn, err error) {
return
}
func (l *udpForwardListener) Addr() net.Addr {
func (l *udpDirectForwardListener) Addr() net.Addr {
return l.ln.LocalAddr()
}
func (l *udpForwardListener) Close() error {
func (l *udpDirectForwardListener) Close() error {
return l.ln.Close()
}
type udpServerConn struct {
conn *net.UDPConn
raddr *net.UDPAddr
conn net.PacketConn
raddr net.Addr
rChan, wChan chan []byte
closed chan struct{}
brokenChan chan struct{}
@ -302,7 +262,7 @@ type udpServerConn struct {
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{
conn: conn,
raddr: raddr,
@ -391,9 +351,9 @@ func (c *udpServerConn) writeLoop() {
if !ok {
return
}
n, err := c.conn.WriteToUDP(b, c.raddr)
n, err := c.conn.WriteTo(b, c.raddr)
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
}
if Debug {
@ -443,53 +403,27 @@ func (c *udpServerConn) SetWriteDeadline(t time.Time) error {
return 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) 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 {
type tcpRemoteForwardListener struct {
addr net.Addr
chain *Chain
closed chan struct{}
}
// RTCPForwardListener creates a Listener for TCP remote port forwarding server.
func RTCPForwardListener(addr string, chain *Chain) (Listener, error) {
// TCPRemoteForwardListener creates a Listener for TCP remote port forwarding server.
func TCPRemoteForwardListener(addr string, chain *Chain) (Listener, error) {
laddr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil {
return nil, err
}
return &rtcpForwardListener{
return &tcpRemoteForwardListener{
addr: laddr,
chain: chain,
closed: make(chan struct{}),
}, nil
}
func (l *rtcpForwardListener) Accept() (net.Conn, error) {
func (l *tcpRemoteForwardListener) Accept() (net.Conn, error) {
select {
case <-l.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()
if lastNode.Protocol == "forward" && lastNode.Transport == "ssh" {
conn, err = l.chain.Dial(l.addr.String())
@ -535,7 +469,7 @@ func (l *rtcpForwardListener) accept() (conn net.Conn, err error) {
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)
if err != nil {
return nil, err
@ -575,45 +509,111 @@ func (l *rtcpForwardListener) waitConnectSOCKS5(conn net.Conn) (net.Conn, error)
return conn, nil
}
func (l *rtcpForwardListener) Addr() net.Addr {
func (l *tcpRemoteForwardListener) Addr() net.Addr {
return l.addr
}
func (l *rtcpForwardListener) Close() error {
func (l *tcpRemoteForwardListener) Close() error {
close(l.closed)
return nil
}
type rudpForwardListener struct {
type udpRemoteForwardListener struct {
addr *net.UDPAddr
chain *Chain
conns map[string]*udpServerConn
connChan chan net.Conn
errChan chan error
ttl time.Duration
closed chan struct{}
}
// RUDPForwardListener creates a Listener for UDP remote port forwarding server.
func RUDPForwardListener(addr string, chain *Chain) (Listener, error) {
// UDPRemoteForwardListener creates a Listener for UDP remote port forwarding server.
func UDPRemoteForwardListener(addr string, chain *Chain, ttl time.Duration) (Listener, error) {
laddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
return nil, err
}
return &rudpForwardListener{
ln := &udpRemoteForwardListener{
addr: laddr,
chain: chain,
conns: make(map[string]*udpServerConn),
connChan: make(chan net.Conn, 1024),
errChan: make(chan error, 1),
ttl: ttl,
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 {
case <-l.closed:
return nil, errors.New("closed")
default:
}
var tempDelay time.Duration
for {
conn, err := l.accept()
lastNode := l.chain.LastNode()
if lastNode.Protocol == "socks5" {
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 tempDelay == 0 {
tempDelay = 1000 * time.Millisecond
@ -627,25 +627,27 @@ func (l *rudpForwardListener) Accept() (net.Conn, error) {
time.Sleep(tempDelay)
continue
}
return conn, nil
return
}
}
func (l *rudpForwardListener) accept() (conn net.Conn, err error) {
lastNode := l.chain.LastNode()
if lastNode.Protocol == "socks5" {
conn, err = getSOCKS5UDPTunnel(l.chain)
} else {
conn, err = net.ListenUDP("udp", l.addr)
func (l *udpRemoteForwardListener) Accept() (conn net.Conn, err error) {
var ok bool
select {
case conn = <-l.connChan:
case err, ok = <-l.errChan:
if !ok {
err = errors.New("accpet on closed listener")
}
}
return
}
func (l *rudpForwardListener) Addr() net.Addr {
func (l *udpRemoteForwardListener) Addr() net.Addr {
return l.addr
}
func (l *rudpForwardListener) Close() error {
func (l *udpRemoteForwardListener) Close() error {
close(l.closed)
return nil
}

View File

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

View File

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

6
vendor/vendor.json vendored
View File

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