add udp tunnel

This commit is contained in:
ginuerzh 2015-10-18 20:30:40 +08:00
parent 7919b469cf
commit 6d369f37ac
2 changed files with 115 additions and 9 deletions

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"bytes"
"crypto/tls" "crypto/tls"
"errors" "errors"
"github.com/ginuerzh/gosocks5" "github.com/ginuerzh/gosocks5"
@ -268,24 +269,90 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn) {
} }
} }
srvTunnelUDP(conn, uconn) clientConn, dgram, err := createClientConn(conn, uconn)
} if err != nil {
} if glog.V(LWARNING) {
glog.Warningln("socks5 udp:", err)
}
return
}
if glog.V(LDEBUG) {
glog.Infof("[udp] length %d, to %s", len(dgram.Data), dgram.Header.Addr)
}
func serveUDP(conn *net.UDPConn) { serverConn, err := createServerConn(uconn)
if len(forwardArgs) > 0 {
fconn, _, err = forwardChain(forwardArgs...)
if err != nil { if err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
glog.Warningln("socks5 udp forward:", err) glog.Warningln("socks5 udp forward:", err)
} }
if fconn != nil { }
fconn.Close() default:
} if glog.V(LWARNING) {
glog.Warningln("Unrecognized request: ", req)
}
}
}
func createClientConn(conn net.Conn, uconn *net.UDPConn) (c *UDPConn, dgram *gosocks5.UDPDatagram, err error) {
var raddr *net.UDPAddr
dgramChan := make(chan *gosocks5.UDPDatagram, 1)
errChan := make(chan error, 1)
go func() {
b := make([]byte, 64*1024+262)
n, addr, err := uconn.ReadFromUDP(b)
if err != nil {
errChan <- err
return return
} }
raddr = addr
dgram, err := gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n]))
if err != nil {
errChan <- err
return
}
dgramChan <- dgram
}()
go func() {
dgram, err := gosocks5.ReadUDPDatagram(conn)
if err != nil {
errChan <- err
return
}
dgramChan <- dgram
}()
select {
case dgram = <-dgramChan:
if raddr != nil {
c = Client(uconn, raddr)
} else {
c = Client(conn, nil)
}
case err = <-errChan:
} }
return
}
func createServerConn(uconn *net.UDPConn) (c *UDPConn, err error) {
if len(forwardArgs) == 0 {
c = Server(uconn)
return
}
fconn, _, err := forwardChain(forwardArgs...)
if err != nil {
if fconn != nil {
fconn.Close()
}
return
}
c = Server(fconn)
return
} }
func forwardUDP(req *gosocks5.Request) (conn net.Conn, err error) { func forwardUDP(req *gosocks5.Request) (conn net.Conn, err error) {

39
udp.go Normal file
View File

@ -0,0 +1,39 @@
package main
import (
"github.com/ginuerzh/gosocks5"
"github.com/golang/glog"
"net"
)
type UDPConn struct {
isClient bool
udpConn *net.UDPConn
udpAddr *net.UDPAddr
tcpConn net.Conn
}
func Client(conn net.Conn, addr net.Addr) *UDPConn {
client := &UDPConn{isClient: true}
switch conn := conn.(type) {
case net.UDPConn:
client.udpConn = conn
client.udpAddr = addr
default:
client.tcpConn = conn
}
return client
}
func Server(conn net.Conn) *UDPConn {
server := &UDPConn{}
switch conn := conn.(type) {
case net.UDPConn:
server.udpConn = conn
default:
server.tcpConn = conn
}
return server
}