socks5 udp init

This commit is contained in:
rui.zheng 2015-10-16 17:54:32 +08:00
parent d7dfb3edaa
commit 7919b469cf
3 changed files with 138 additions and 55 deletions

View File

@ -3,6 +3,7 @@ package main
import ( import (
"flag" "flag"
"fmt"
"github.com/golang/glog" "github.com/golang/glog"
"sync" "sync"
) )
@ -15,6 +16,10 @@ const (
LDEBUG LDEBUG
) )
const (
Version = "2.0"
)
var ( var (
listenAddr, forwardAddr strSlice listenAddr, forwardAddr strSlice
pv bool // print version pv bool // print version
@ -24,7 +29,7 @@ var (
) )
func init() { func init() {
flag.Var(&listenAddr, "L", "listen address") flag.Var(&listenAddr, "L", "listen address, can listen on multiple ports")
flag.Var(&forwardAddr, "F", "forward address, can make a forward chain") flag.Var(&forwardAddr, "F", "forward address, can make a forward chain")
flag.BoolVar(&pv, "V", false, "print version") flag.BoolVar(&pv, "V", false, "print version")
flag.Parse() flag.Parse()
@ -38,7 +43,7 @@ func main() {
return return
} }
if pv { if pv {
printVersion() fmt.Println("gost", Version)
return return
} }

171
socks.go
View File

@ -5,6 +5,8 @@ import (
"errors" "errors"
"github.com/ginuerzh/gosocks5" "github.com/ginuerzh/gosocks5"
"github.com/golang/glog" "github.com/golang/glog"
"io"
"io/ioutil"
"net" "net"
"strconv" "strconv"
) )
@ -218,12 +220,18 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn) {
Transport(conn, tconn) Transport(conn, tconn)
case gosocks5.CmdBind: case gosocks5.CmdBind:
if glog.V(LINFO) {
glog.Infoln("socks5 bind:", req.Addr)
}
if len(forwardArgs) > 0 { if len(forwardArgs) > 0 {
forwardBind(req, conn) forwardBind(req, conn)
} else { } else {
serveBind(conn) serveBind(conn)
} }
case gosocks5.CmdUdp: case gosocks5.CmdUdp:
if glog.V(LINFO) {
glog.Infoln("socks5 udp associate:", req.Addr)
}
uconn, err := net.ListenUDP("udp", nil) uconn, err := net.ListenUDP("udp", nil)
if err != nil { if err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
@ -246,7 +254,7 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn) {
addr := ToSocksAddr(uconn.LocalAddr()) addr := ToSocksAddr(uconn.LocalAddr())
addr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String()) addr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String())
if glog.V(LINFO) { if glog.V(LINFO) {
glog.Infoln("socks5 udp:", addr) glog.Infoln("socks5 udp listen:", addr)
} }
rep := gosocks5.NewReply(gosocks5.Succeeded, addr) rep := gosocks5.NewReply(gosocks5.Succeeded, addr)
if err := rep.Write(conn); err != nil { if err := rep.Write(conn); err != nil {
@ -259,10 +267,66 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn) {
glog.Infoln(rep) glog.Infoln(rep)
} }
} }
srvTunnelUDP(conn, uconn) srvTunnelUDP(conn, uconn)
} }
} }
func serveUDP(conn *net.UDPConn) {
if len(forwardArgs) > 0 {
fconn, _, err = forwardChain(forwardArgs...)
if err != nil {
if glog.V(LWARNING) {
glog.Warningln("socks5 udp forward:", err)
}
if fconn != nil {
fconn.Close()
}
return
}
}
}
func forwardUDP(req *gosocks5.Request) (conn net.Conn, err error) {
if err != nil {
if conn != nil {
conn.Close()
}
rep := gosocks5.NewReply(gosocks5.Failure, nil)
if err := rep.Write(conn); err != nil {
if glog.V(LWARNING) {
glog.Warningln("socks5 udp forward:", err)
}
} else {
if glog.V(LDEBUG) {
glog.Infoln(rep)
}
}
return
}
if err = req.Write(fconn); err != nil {
if glog.V(LWARNING) {
glog.Warningln("socks5 udp forward:", err)
}
return
}
if err = peekReply(conn, fconn); err != nil {
if glog.V(LWARNING) {
glog.Warningln("socks5 udp forward:", err)
}
return
}
}
func transportUDP() {
}
func serveBind(conn net.Conn) error { func serveBind(conn net.Conn) error {
l, err := net.ListenTCP("tcp", nil) l, err := net.ListenTCP("tcp", nil)
if err != nil { if err != nil {
@ -339,15 +403,15 @@ func serveBind(conn net.Conn) error {
} }
func forwardBind(req *gosocks5.Request, conn net.Conn) error { func forwardBind(req *gosocks5.Request, conn net.Conn) error {
fc, _, err := forwardChain(forwardArgs...) fconn, _, err := forwardChain(forwardArgs...)
if err != nil { if err != nil {
if fc != nil { if fconn != nil {
fc.Close() fconn.Close()
} }
rep := gosocks5.NewReply(gosocks5.Failure, nil) rep := gosocks5.NewReply(gosocks5.Failure, nil)
if err := rep.Write(conn); err != nil { if err := rep.Write(conn); err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
glog.Warningln("socks5 bind:", err) glog.Warningln("socks5 bind forward:", err)
} }
} else { } else {
if glog.V(LDEBUG) { if glog.V(LDEBUG) {
@ -356,11 +420,11 @@ func forwardBind(req *gosocks5.Request, conn net.Conn) error {
} }
return err return err
} }
defer fc.Close() defer fconn.Close()
if err := req.Write(fc); err != nil { if err := req.Write(fconn); err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
glog.Warningln("socks5 bind:", err) glog.Warningln("socks5 bind forward:", err)
} }
gosocks5.NewReply(gosocks5.Failure, nil).Write(conn) gosocks5.NewReply(gosocks5.Failure, nil).Write(conn)
return err return err
@ -370,64 +434,91 @@ func forwardBind(req *gosocks5.Request, conn net.Conn) error {
} }
// first reply // first reply
if err := peekBindReply(conn, fc); err != nil { if err := peekReply(conn, fconn); err != nil {
if glog.V(LWARNING) {
glog.Warningln("socks5 bind forward:", err)
}
return err return err
} }
// second reply // second reply
if err := peekBindReply(conn, fc); err != nil { if err := peekReply(conn, fconn); err != nil {
if glog.V(LWARNING) {
glog.Warningln("socks5 bind forward:", err)
}
return err return err
} }
return Transport(conn, fc) return Transport(conn, fconn)
} }
func peekBindReply(conn, fc net.Conn) error { func peekReply(dst io.Writer, src io.Reader) error {
rep, err := gosocks5.ReadReply(fc) rep, err := gosocks5.ReadReply(src)
if err != nil { if err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
glog.Warningln("socks5 bind:", err) glog.Warningln(err)
} }
rep = gosocks5.NewReply(gosocks5.Failure, nil) rep = gosocks5.NewReply(gosocks5.Failure, nil)
} }
if err := rep.Write(conn); err != nil { if err := rep.Write(dst); err != nil {
if glog.V(LWARNING) {
glog.Warningln("socks5 bind:", err)
}
return err return err
} }
if glog.V(LDEBUG) { if glog.V(LDEBUG) {
glog.Infoln(rep) glog.Infoln(rep)
} }
if rep.Rep != gosocks5.Succeeded { if rep.Rep != gosocks5.Succeeded {
return errors.New("Bind failure") return errors.New("Failure")
} }
return nil return nil
} }
/* func cliTunnelUDP(uconn *net.UDPConn, sconn net.Conn) {
func forwardUDP() error { var raddr *net.UDPAddr
fc, _, err := forwardChain(forwardArgs...)
if err != nil {
if fc != nil {
fc.Close()
}
rep := gosocks5.NewReply(gosocks5.Failure, nil)
if err := rep.Write(conn); err != nil {
if glog.V(LWARNING) {
glog.Warningln("socks5 bind:", err)
}
} else {
if glog.V(LDEBUG) {
glog.Infoln(rep)
}
}
return err
}
defer fc.Close()
go func() {
b := make([]byte, 16*1024)
for {
n, addr, err := uconn.ReadFromUDP(b)
if err != nil {
log.Println(err)
return
} }
*/ raddr = addr
r := bytes.NewBuffer(b[:n])
udp, err := gosocks5.ReadUDPDatagram(r)
if err != nil {
return
}
udp.Header.Rsv = uint16(len(udp.Data))
//log.Println("r", raddr.String(), udp.Header)
if err := udp.Write(sconn); err != nil {
log.Println(err)
return
}
}
}()
for {
b := lpool.Take()
defer lpool.put(b)
udp, err := gosocks5.ReadUDPDatagram(sconn)
if err != nil {
log.Println(err)
return
}
//log.Println("w", udp.Header)
udp.Header.Rsv = 0
buf := bytes.NewBuffer(b[0:0])
udp.Write(buf)
if _, err := uconn.WriteTo(buf.Bytes(), raddr); err != nil {
log.Println(err)
return
}
}
}
func srvTunnelUDP(conn net.Conn, uconn *net.UDPConn) { func srvTunnelUDP(conn net.Conn, uconn *net.UDPConn) {
go func() { go func() {
b := make([]byte, 16*1024) b := make([]byte, 16*1024)

View File

@ -1,13 +0,0 @@
package main
import (
"fmt"
)
const (
Version = "2.0"
)
func printVersion() {
fmt.Println("gost", Version)
}