merge branch 2.0

This commit is contained in:
rui.zheng 2016-02-05 15:31:38 +08:00
commit 10ca37d721
6 changed files with 103 additions and 92 deletions

View File

@ -121,7 +121,7 @@ gost -L=:8080 -F=socks://server_ip:1080
如果transport已经使用了加密模式(wss, tls)则socks5不会再使用加密方法防止不必要的双重加密。 如果transport已经使用了加密模式(wss, tls)则socks5不会再使用加密方法防止不必要的双重加密。
#### shadowsocks #### shadowsocks
gost对shadowsocks的支持是基于[shadowsocks-go](https://github.com/shadowsocks/shadowsocks-go)库。 gost对shadowsocks加密方法的支持是基于[shadowsocks-go](https://github.com/shadowsocks/shadowsocks-go)库。
服务端: 服务端:
```bash ```bash
@ -133,7 +133,8 @@ gost -L=:8080 -F=ss://aes-128-cfb:123456@server_ip:8338
``` ```
#### TLS #### TLS
gost内置了tls证书如果需要使用其他tls证书在gost目录放置key.pem(公钥)和cert.pem(私钥)两个文件即可。 gost内置了tls证书如果需要使用其他tls证书在gost目录放置cert.pem(公钥)和key.pem(私钥)两个文件即可。
SOCKS5 UDP数据处理 SOCKS5 UDP数据处理
------ ------

22
conn.go
View File

@ -16,6 +16,7 @@ import (
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
"sync"
"sync/atomic" "sync/atomic"
"time" "time"
) )
@ -24,6 +25,21 @@ var (
connCounter int32 connCounter int32
) )
var (
// tcp buffer pool
tcpPool = sync.Pool{
New: func() interface{} {
return make([]byte, 16*1024)
},
}
// udp buffer pool
udpPool = sync.Pool{
New: func() interface{} {
return make([]byte, 64*1024+262)
},
}
)
func listenAndServe(arg Args) error { func listenAndServe(arg Args) error {
var ln net.Listener var ln net.Listener
var err error var err error
@ -120,7 +136,9 @@ func handleConn(conn net.Conn, arg Args) {
// http + socks5 // http + socks5
b := make([]byte, 16*1024) //b := make([]byte, 16*1024)
b := tcpPool.Get().([]byte)
defer tcpPool.Put(b)
n, err := io.ReadAtLeast(conn, b, 2) n, err := io.ReadAtLeast(conn, b, 2)
if err != nil { if err != nil {
@ -214,7 +232,7 @@ func Connect(addr string) (conn net.Conn, err error) {
func forwardChain(chain ...Args) (conn net.Conn, end Args, err error) { func forwardChain(chain ...Args) (conn net.Conn, end Args, err error) {
end = chain[0] end = chain[0]
if conn, err = net.DialTimeout("tcp", end.Addr, time.Second*30); err != nil { if conn, err = net.DialTimeout("tcp", end.Addr, time.Second*90); err != nil {
return return
} }
c, err := forward(conn, end) c, err := forward(conn, end)

View File

@ -18,7 +18,7 @@ const (
) )
const ( const (
Version = "2.0-rc2" Version = "2.0-rc3"
) )
var ( var (

152
socks.go
View File

@ -7,6 +7,7 @@ import (
"github.com/ginuerzh/gosocks5" "github.com/ginuerzh/gosocks5"
"github.com/golang/glog" "github.com/golang/glog"
"io" "io"
"io/ioutil"
"net" "net"
"net/url" "net/url"
"strconv" "strconv"
@ -18,6 +19,10 @@ const (
MethodTLSAuth uint8 = 0x82 // extended method for tls+auth MethodTLSAuth uint8 = 0x82 // extended method for tls+auth
) )
const (
CmdUdpTun uint8 = 0xf3 // extended method for udp over tcp
)
type clientSelector struct { type clientSelector struct {
methods []uint8 methods []uint8
user *url.Userinfo user *url.Userinfo
@ -193,7 +198,7 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn) {
} else { } else {
serveBind(conn) serveBind(conn)
} }
case gosocks5.CmdUdp: case gosocks5.CmdUdp, CmdUdpTun:
glog.V(LINFO).Infoln("[socks5] UDP ASSOCIATE", req.Addr) glog.V(LINFO).Infoln("[socks5] UDP ASSOCIATE", req.Addr)
uconn, err := net.ListenUDP("udp", nil) uconn, err := net.ListenUDP("udp", nil)
if err != nil { if err != nil {
@ -211,7 +216,6 @@ 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())
glog.V(LINFO).Infoln("[socks5] UDP listen on", 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 {
@ -219,43 +223,67 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn) {
return return
} else { } else {
glog.V(LDEBUG).Infoln(rep) glog.V(LDEBUG).Infoln(rep)
glog.V(LINFO).Infoln("[socks5] UDP listen on", addr)
} }
cc, dgram, err := createClientConn(conn, uconn) var cc *UDPConn
var dgram *gosocks5.UDPDatagram
if req.Cmd == CmdUdpTun {
dgram, err = gosocks5.ReadUDPDatagram(conn)
if err != nil {
glog.V(LWARNING).Infoln("socks5 udp:", err)
return
}
cc = Client(conn, nil)
glog.V(LINFO).Infof("[udp] -> %s, length %d", dgram.Header.Addr, len(dgram.Data))
} else {
b := udpPool.Get().([]byte)
defer udpPool.Put(b)
n, raddr, err := uconn.ReadFromUDP(b)
if err != nil {
glog.V(LWARNING).Infoln("socks5 udp:", err)
return
}
dgram, err = gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n]))
if err != nil {
glog.V(LWARNING).Infoln("socks5 udp:", err)
return
}
cc = Client(uconn, raddr)
glog.V(LINFO).Infof("[udp] %s -> %s, length %d", raddr, dgram.Header.Addr, len(dgram.Data))
}
sc, err := createServerConn(uconn)
if err != nil { if err != nil {
glog.V(LWARNING).Infoln("socks5 udp:", err) glog.V(LWARNING).Infoln("socks5 udp:", err)
return return
} }
glog.V(LINFO).Infof("[udp] to %s, length %d", dgram.Header.Addr, len(dgram.Data)) defer sc.Close()
raddr, err := net.ResolveUDPAddr("udp", dgram.Header.Addr.String()) if err = sc.WriteUDPTimeout(dgram, time.Second*90); err != nil {
glog.V(LWARNING).Infoln("socks5 udp:", err)
return
}
dgram, err = sc.ReadUDPTimeout(time.Second * 90)
if err != nil { if err != nil {
glog.V(LWARNING).Infoln("socks5 udp:", err) glog.V(LWARNING).Infoln("socks5 udp:", err)
return return
} }
sc, err := createServerConn(uconn, raddr) glog.V(LINFO).Infof("[udp] <- %s, length %d", dgram.Header.Addr, len(dgram.Data))
if err != nil {
if err = cc.WriteUDPTimeout(dgram, time.Second*90); err != nil {
glog.V(LWARNING).Infoln("socks5 udp:", err) glog.V(LWARNING).Infoln("socks5 udp:", err)
return return
} }
if err = sc.WriteUDPTimeout(dgram, time.Second*30); err != nil { if req.Cmd == gosocks5.CmdUdp {
glog.V(LWARNING).Infoln("socks5 udp:", err) go TransportUDP(cc, sc)
return ioutil.ReadAll(conn) // wait for client exit
glog.V(LINFO).Infoln("[udp] transfer done")
} else {
TransportUDP(cc, sc)
} }
dgram, err = sc.ReadUDPTimeout(time.Second * 30)
if err != nil {
glog.V(LWARNING).Infoln("socks5 udp:", err)
return
}
glog.V(LINFO).Infof("[udp] from %s, length %d", dgram.Header.Addr, len(dgram.Data))
if err = cc.WriteUDPTimeout(dgram, time.Second*30); err != nil {
glog.V(LWARNING).Infoln("socks5 udp:", err)
return
}
TransportUDP(cc, sc)
default: default:
glog.V(LWARNING).Infoln("Unrecognized request: ", req) glog.V(LWARNING).Infoln("Unrecognized request: ", req)
} }
@ -288,6 +316,7 @@ func serveBind(conn net.Conn) error {
glog.V(LDEBUG).Infoln(rep) glog.V(LDEBUG).Infoln(rep)
glog.V(LINFO).Infoln("[socks5] BIND on", addr, "OK") glog.V(LINFO).Infoln("[socks5] BIND on", addr, "OK")
l.SetDeadline(time.Now().Add(time.Minute * 30)) // wait 30 minutes at most
tconn, err := l.AcceptTCP() tconn, err := l.AcceptTCP()
l.Close() // only accept one peer l.Close() // only accept one peer
if err != nil { if err != nil {
@ -319,7 +348,7 @@ func serveBind(conn net.Conn) error {
func forwardBind(req *gosocks5.Request, conn net.Conn) error { func forwardBind(req *gosocks5.Request, conn net.Conn) error {
fconn, _, err := forwardChain(forwardArgs...) fconn, _, err := forwardChain(forwardArgs...)
if err != nil { if err != nil {
glog.V(LWARNING).Infoln("[socks5] BIND(forward)", req.Addr, err) glog.V(LWARNING).Infoln("[socks5] BIND forward", req.Addr, err)
if fconn != nil { if fconn != nil {
fconn.Close() fconn.Close()
} }
@ -334,7 +363,7 @@ func forwardBind(req *gosocks5.Request, conn net.Conn) error {
defer fconn.Close() defer fconn.Close()
if err := req.Write(fconn); err != nil { if err := req.Write(fconn); err != nil {
glog.V(LWARNING).Infoln("[socks5] BIND(forward)", err) glog.V(LWARNING).Infoln("[socks5] BIND forward", err)
gosocks5.NewReply(gosocks5.Failure, nil).Write(conn) gosocks5.NewReply(gosocks5.Failure, nil).Write(conn)
return err return err
} }
@ -343,18 +372,18 @@ func forwardBind(req *gosocks5.Request, conn net.Conn) error {
// first reply // first reply
rep, err := peekReply(conn, fconn) rep, err := peekReply(conn, fconn)
if err != nil { if err != nil {
glog.V(LWARNING).Infoln("[socks5] BIND(forward)", err) glog.V(LWARNING).Infoln("[socks5] BIND forward", err)
return err return err
} }
glog.V(LINFO).Infoln("[socks5] BIND(forward) on", rep.Addr, "OK") glog.V(LINFO).Infoln("[socks5] BIND forward on", rep.Addr, "OK")
// second reply // second reply
rep, err = peekReply(conn, fconn) rep, err = peekReply(conn, fconn)
if err != nil { if err != nil {
glog.V(LWARNING).Infoln("[socks5] BIND(forward) accept", err) glog.V(LWARNING).Infoln("[socks5] BIND forward accept", err)
return err return err
} }
glog.V(LINFO).Infoln("[socks5] BIND(forward) accept", rep.Addr) glog.V(LINFO).Infoln("[socks5] BIND forward accept", rep.Addr)
return Transport(conn, fconn) return Transport(conn, fconn)
} }
@ -377,53 +406,7 @@ func peekReply(dst io.Writer, src io.Reader) (rep *gosocks5.Reply, err error) {
return return
} }
func createClientConn(conn net.Conn, uconn *net.UDPConn) (c *UDPConn, dgram *gosocks5.UDPDatagram, err error) { func createServerConn(uconn *net.UDPConn) (c *UDPConn, 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
}
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 {
glog.V(LINFO).Infoln("[udp] client", raddr)
c = Client(uconn, raddr)
} else {
glog.V(LINFO).Infoln("[udp] tunnel")
c = Client(conn, nil)
}
case err = <-errChan:
}
return
}
func createServerConn(uconn *net.UDPConn, addr net.Addr) (c *UDPConn, err error) {
if len(forwardArgs) == 0 { if len(forwardArgs) == 0 {
c = Server(uconn) c = Server(uconn)
return return
@ -436,9 +419,9 @@ func createServerConn(uconn *net.UDPConn, addr net.Addr) (c *UDPConn, err error)
} }
return return
} }
glog.V(LINFO).Infoln("forward udp associate") glog.V(LINFO).Infoln("[udp] forward associate")
req := gosocks5.NewRequest(gosocks5.CmdUdp, nil) req := gosocks5.NewRequest(CmdUdpTun, nil)
if err = req.Write(fconn); err != nil { if err = req.Write(fconn); err != nil {
fconn.Close() fconn.Close()
return return
@ -455,7 +438,7 @@ func createServerConn(uconn *net.UDPConn, addr net.Addr) (c *UDPConn, err error)
fconn.Close() fconn.Close()
return nil, errors.New("Failure") return nil, errors.New("Failure")
} }
glog.V(LINFO).Infoln("forward udp associate, on", rep.Addr, "OK") glog.V(LINFO).Infoln("[udp] forward associate on", rep.Addr, "OK")
c = Server(fconn) c = Server(fconn)
return return
@ -481,8 +464,11 @@ func PipeUDP(src, dst *UDPConn, ch chan<- error) {
if err != nil { if err != nil {
break break
} }
// glog.V(LDEBUG).Infof("[udp] addr %s, length %d", dgram.Header.Addr, len(dgram.Data)) if src.isClient {
glog.V(LDEBUG).Infof("[udp] -> %s, length %d", dgram.Header.Addr, len(dgram.Data))
} else {
glog.V(LDEBUG).Infof("[udp] <- %s, length %d", dgram.Header.Addr, len(dgram.Data))
}
if err = dst.WriteUDP(dgram); err != nil { if err = dst.WriteUDP(dgram); err != nil {
break break
} }
@ -501,9 +487,9 @@ func TransportUDP(cc, sc *UDPConn) (err error) {
select { select {
case err = <-wChan: case err = <-wChan:
//log.Println("w exit", err) // glog.V(LDEBUG).Infoln("w exit", err)
case err = <-rChan: case err = <-rChan:
//log.Println("r exit", err) // glog.V(LDEBUG).Infoln("r exit", err)
} }
return return

5
udp.go
View File

@ -72,7 +72,10 @@ func (c *UDPConn) readUDPClient() (*gosocks5.UDPDatagram, error) {
func (c *UDPConn) readUDPServer() (*gosocks5.UDPDatagram, error) { func (c *UDPConn) readUDPServer() (*gosocks5.UDPDatagram, error) {
if c.udp != nil { if c.udp != nil {
b := make([]byte, 65535) // b := make([]byte, 65535)
b := udpPool.Get().([]byte)
defer udpPool.Put(b)
n, addr, err := c.udp.ReadFrom(b) n, addr, err := c.udp.ReadFrom(b)
if err != nil { if err != nil {
return nil, err return nil, err

9
ws.go
View File

@ -129,15 +129,18 @@ func (s *ws) handle(w http.ResponseWriter, r *http.Request) {
} }
func (s *ws) ListenAndServe() error { func (s *ws) ListenAndServe() error {
http.HandleFunc("/ws", s.handle) sm := http.NewServeMux()
return http.ListenAndServe(s.arg.Addr, nil) sm.HandleFunc("/ws", s.handle)
return http.ListenAndServe(s.arg.Addr, sm)
} }
func (s *ws) listenAndServeTLS() error { func (s *ws) listenAndServeTLS() error {
http.HandleFunc("/ws", s.handle) sm := http.NewServeMux()
sm.HandleFunc("/ws", s.handle)
server := &http.Server{ server := &http.Server{
Addr: s.arg.Addr, Addr: s.arg.Addr,
TLSConfig: &tls.Config{Certificates: []tls.Certificate{s.arg.Cert}}, TLSConfig: &tls.Config{Certificates: []tls.Certificate{s.arg.Cert}},
Handler: sm,
} }
return server.ListenAndServeTLS("", "") return server.ListenAndServeTLS("", "")
} }