socks5 udp init
This commit is contained in:
parent
d7dfb3edaa
commit
7919b469cf
9
main.go
9
main.go
@ -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
171
socks.go
@ -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)
|
||||||
|
13
version.go
13
version.go
@ -1,13 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
Version = "2.0"
|
|
||||||
)
|
|
||||||
|
|
||||||
func printVersion() {
|
|
||||||
fmt.Println("gost", Version)
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user