forward now works

This commit is contained in:
ginuerzh 2015-10-11 22:19:27 +08:00
parent e19ff132f4
commit 4309ea67e2
3 changed files with 61 additions and 56 deletions

57
conn.go
View File

@ -92,7 +92,8 @@ func handleConn(conn net.Conn, arg Args) {
selector := &serverSelector{
methods: []uint8{
gosocks5.MethodNoAuth, gosocks5.MethodUserPass,
gosocks5.MethodNoAuth,
gosocks5.MethodUserPass,
},
arg: arg,
}
@ -215,32 +216,40 @@ func connect(connType, addr string) (conn net.Conn, err error) {
addr += ":80"
}
if len(proxyArgs) > 0 && len(forwardArgs) > 0 {
return connectProxyForward(connType, addr, proxyArgs[0], forwardArgs[0])
}
if len(forwardArgs) > 0 {
// TODO: multi-foward
forward := forwardArgs[0]
return connectForward(addr, forward)
return connectForward(connType, addr, forward)
}
if len(proxyArgs) > 0 {
proxy := proxyArgs[0]
return connectProxy(connType, addr, proxy)
return connectForward(connType, addr, proxy)
}
return net.Dial("tcp", addr)
}
func connectProxy(connType, addr string, proxy Args) (conn net.Conn, err error) {
func connectProxyForward(connType, addr string, proxy, forward Args) (conn net.Conn, err error) {
return nil, errors.New("Not implemented")
}
func connectForward(connType, addr string, forward Args) (conn net.Conn, err error) {
if glog.V(LINFO) {
glog.Infoln("connect proxy:", proxy.Addr)
glog.Infoln(forward.Protocol, "forward:", forward.Addr)
}
conn, err = net.Dial("tcp", proxy.Addr)
conn, err = net.Dial("tcp", forward.Addr)
if err != nil {
return
}
switch proxy.Transport {
switch forward.Transport {
case "ws": // websocket connection
c, err := wsClient(conn, proxy.Addr)
c, err := wsClient(conn, forward.Addr)
if err != nil {
conn.Close()
return nil, err
@ -253,16 +262,16 @@ func connectProxy(connType, addr string, proxy Args) (conn net.Conn, err error)
default:
}
switch proxy.Protocol {
switch forward.Protocol {
case "ss": // shadowsocks
conn.Close()
return nil, errors.New("Not implemented")
case "socks", "socks5":
selector := &clientSelector{
methods: []uint8{gosocks5.MethodNoAuth, gosocks5.MethodUserPass},
arg: proxy,
arg: forward,
}
if proxy.EncMeth == "tls" {
if forward.EncMeth == "tls" {
selector.methods = []uint8{MethodTLS, MethodTLSAuth}
}
c := gosocks5.ClientConn(conn, selector)
@ -272,7 +281,6 @@ func connectProxy(connType, addr string, proxy Args) (conn net.Conn, err error)
}
conn = c
if connType == ConnHttp || connType == ConnHttpConnect {
host, port, _ := net.SplitHostPort(addr)
p, _ := strconv.ParseUint(port, 10, 16)
r := gosocks5.NewRequest(gosocks5.CmdConnect, &gosocks5.Addr{
@ -280,32 +288,19 @@ func connectProxy(connType, addr string, proxy Args) (conn net.Conn, err error)
Host: host,
Port: uint16(p),
})
if glog.V(LDEBUG) {
glog.Infoln(r.String())
}
if err := r.Write(conn); err != nil {
conn.Close()
return nil, err
}
rep, err := gosocks5.ReadReply(conn)
rep, err := requestSocks5(conn, r)
if err != nil {
conn.Close()
return nil, err
}
if glog.V(LDEBUG) {
glog.Infoln(rep.String())
}
if rep.Rep != gosocks5.Succeeded {
conn.Close()
return nil, errors.New("Service unavailable")
}
}
case "http":
fallthrough
default:
if connType == ConnHttpConnect {
if connType == ConnHttpConnect || connType == ConnSocks5 {
req := &http.Request{
Method: "CONNECT",
URL: &url.URL{Host: addr},
@ -315,9 +310,9 @@ func connectProxy(connType, addr string, proxy Args) (conn net.Conn, err error)
Header: make(http.Header),
}
req.Header.Set("Proxy-Connection", "keep-alive")
if proxy.User != nil {
if forward.User != nil {
req.Header.Set("Proxy-Authorization",
"Basic "+base64.StdEncoding.EncodeToString([]byte(proxy.User.String())))
"Basic "+base64.StdEncoding.EncodeToString([]byte(forward.User.String())))
}
if err = req.Write(conn); err != nil {
conn.Close()
@ -347,7 +342,3 @@ func connectProxy(connType, addr string, proxy Args) (conn net.Conn, err error)
return
}
func connectForward(addr string, forward Args) (net.Conn, error) {
return nil, errors.New("Not implemented")
}

View File

@ -80,7 +80,7 @@ func handleHttpRequest(req *http.Request, conn net.Conn, arg Args) {
return
}
} else {
if len(proxyArgs) > 0 {
if len(proxyArgs) > 0 || len(forwardArgs) > 0 {
err = req.WriteProxy(c)
} else {
err = req.Write(c)
@ -92,7 +92,6 @@ func handleHttpRequest(req *http.Request, conn net.Conn, arg Args) {
return
}
}
Transport(conn, c)
}

View File

@ -85,7 +85,7 @@ func (selector *serverSelector) Methods() []uint8 {
func (selector *serverSelector) Select(methods ...uint8) (method uint8) {
if glog.V(LDEBUG) {
glog.Infof("%x %x % x", gosocks5.Ver5, len(methods), methods)
glog.Infof("%d %d % d", gosocks5.Ver5, len(methods), methods)
}
method = gosocks5.MethodNoAcceptable
@ -94,11 +94,12 @@ func (selector *serverSelector) Select(methods ...uint8) (method uint8) {
for _, mm := range selector.methods {
if m == mm {
method = m
break
goto out
}
}
}
out:
if method == gosocks5.MethodNoAcceptable {
return
}
@ -117,7 +118,7 @@ func (selector *serverSelector) Select(methods ...uint8) (method uint8) {
func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Conn, error) {
if glog.V(LDEBUG) {
glog.Infof("%x %x", gosocks5.Ver5, method)
glog.Infof("%d %d", gosocks5.Ver5, method)
}
switch method {
@ -178,6 +179,23 @@ func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Con
return conn, nil
}
func requestSocks5(conn net.Conn, req *gosocks5.Request) (*gosocks5.Reply, error) {
if err := req.Write(conn); err != nil {
return nil, err
}
if glog.V(LDEBUG) {
glog.Infoln(req.String())
}
rep, err := gosocks5.ReadReply(conn)
if err != nil {
return nil, err
}
if glog.V(LDEBUG) {
glog.Infoln(rep.String())
}
return rep, nil
}
func handleSocks5Request(req *gosocks5.Request, conn net.Conn, arg Args) {
if glog.V(LDEBUG) {
glog.Infoln(req)
@ -218,10 +236,7 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn, arg Args) {
glog.Infoln(rep)
}
}
if err := Transport(conn, tconn); err != nil {
//log.Println(err)
}
Transport(conn, tconn)
case gosocks5.CmdBind:
l, err := net.ListenTCP("tcp", nil)
if err != nil {