Commit c4a1b96b authored by rui.zheng's avatar rui.zheng

socks udp tunnel

parent 467ea676
...@@ -67,7 +67,7 @@ gost -L=admin:123456@localhost:8080 ...@@ -67,7 +67,7 @@ gost -L=admin:123456@localhost:8080
* 多端口监听 * 多端口监听
```bash ```bash
gost -L=http://localhost:8080 -L=socks://localhost:8081 -L=ss://aes-256-cfb:123456@:8082 gost -L=:8080 -L=ss://aes-256-cfb:123456@:8081
``` ```
##### 设置转发代理 ##### 设置转发代理
...@@ -88,28 +88,29 @@ gost -L=:8080 -F=http://admin:123456@192.168.1.1:8081 ...@@ -88,28 +88,29 @@ gost -L=:8080 -F=http://admin:123456@192.168.1.1:8081
```bash ```bash
gost -L=:8080 -F=http://192.168.1.1:8081 -F=socks://192.168.1.2:8082 -F=a.b.c.d:NNNN gost -L=:8080 -F=http://192.168.1.1:8081 -F=socks://192.168.1.2:8082 -F=a.b.c.d:NNNN
``` ```
gost按照-F设置顺序通过转发链将请求最终转发给a.b.c.d:NNNN处理,每一个转发代理可以是任意一种类型的代理(http/socks5) gost按照-F设置顺序通过转发链将请求最终转发给a.b.c.d:NNNN处理,每一个转发代理可以是任意http/socks5类型代理
#### SOCKS5 UDP数据处理 #### SOCKS5 UDP数据处理
##### 不设置转发代理 ##### 不设置转发代理
<img src="https://ginuerzh.github.io/images/udp01.png" height=110 /> <img src="https://ginuerzh.github.io/images/udp01.png" height=100 />
gost作为标准socks5代理处理UDP数据 gost作为标准socks5代理处理UDP数据
##### 设置转发代理 ##### 设置转发代理
<img src="https://ginuerzh.github.io/images/udp02.png" height=110 /> <img src="https://ginuerzh.github.io/images/udp02.png" height=100 />
##### 设置多个转发代理(转发链) ##### 设置多个转发代理(转发链)
<img src="https://ginuerzh.github.io/images/udp03.png" height=200 /> <img src="https://ginuerzh.github.io/images/udp03.png" height=200 />
当设置转发代理时,gost会使用UDP over TCP方式转发UDP数据 当设置转发代理时,gost会使用UDP-Over-TCP方式转发UDP数据。proxy1 - proxyN可以为任意http/socks5类型代理
##### 限制条件 ##### 限制条件
如果要转发socks5的BIND和UDP请求,转发链的末端(最后一个-F参数)必须是gost socks5类型代理,且转发链中的http代理必须支持CONNECT方法。 如果要转发socks5的BIND和UDP请求,转发链的末端(最后一个-F参数)必须是gost socks5类型代理,且转发链中的http代理必须支持CONNECT方法。
......
...@@ -34,29 +34,21 @@ func handleHttpRequest(req *http.Request, conn net.Conn, arg Args) { ...@@ -34,29 +34,21 @@ func handleHttpRequest(req *http.Request, conn net.Conn, arg Args) {
"Proxy-Agent: gost/" + Version + "\r\n\r\n" "Proxy-Agent: gost/" + Version + "\r\n\r\n"
if _, err := conn.Write([]byte(resp)); err != nil { if _, err := conn.Write([]byte(resp)); err != nil {
if glog.V(LWARNING) { glog.V(LWARNING).Infoln(err)
glog.Warningln(err)
}
}
if glog.V(LDEBUG) {
glog.Infoln(resp)
}
if glog.V(LWARNING) {
glog.Warningln("http: proxy authentication required")
} }
glog.V(LDEBUG).Infoln(resp)
glog.V(LWARNING).Infoln("http: proxy authentication required")
return return
} }
c, err := Connect(req.Host) c, err := Connect(req.Host)
if err != nil { if err != nil {
if glog.V(LWARNING) { glog.V(LWARNING).Infoln(err)
glog.Warningln(err)
}
b := []byte("HTTP/1.1 503 Service unavailable\r\n" + b := []byte("HTTP/1.1 503 Service unavailable\r\n" +
"Proxy-Agent: gost/" + Version + "\r\n\r\n") "Proxy-Agent: gost/" + Version + "\r\n\r\n")
if glog.V(LDEBUG) { glog.V(LDEBUG).Infoln(string(b))
glog.Infoln(string(b))
}
conn.Write(b) conn.Write(b)
return return
} }
...@@ -65,13 +57,10 @@ func handleHttpRequest(req *http.Request, conn net.Conn, arg Args) { ...@@ -65,13 +57,10 @@ func handleHttpRequest(req *http.Request, conn net.Conn, arg Args) {
if req.Method == "CONNECT" { if req.Method == "CONNECT" {
b := []byte("HTTP/1.1 200 Connection established\r\n" + b := []byte("HTTP/1.1 200 Connection established\r\n" +
"Proxy-Agent: gost/" + Version + "\r\n\r\n") "Proxy-Agent: gost/" + Version + "\r\n\r\n")
if glog.V(LDEBUG) { glog.V(LDEBUG).Infoln(string(b))
glog.Infoln(string(b))
}
if _, err := conn.Write(b); err != nil { if _, err := conn.Write(b); err != nil {
if glog.V(LWARNING) { glog.V(LWARNING).Infoln(err)
glog.Warningln(err)
}
return return
} }
} else { } else {
...@@ -81,9 +70,7 @@ func handleHttpRequest(req *http.Request, conn net.Conn, arg Args) { ...@@ -81,9 +70,7 @@ func handleHttpRequest(req *http.Request, conn net.Conn, arg Args) {
err = req.Write(c) err = req.Write(c)
} }
if err != nil { if err != nil {
if glog.V(LWARNING) { glog.V(LWARNING).Infoln(err)
glog.Warningln(err)
}
return return
} }
} }
......
This diff is collapsed.
...@@ -16,9 +16,7 @@ func handleShadow(conn net.Conn, arg Args) { ...@@ -16,9 +16,7 @@ func handleShadow(conn net.Conn, arg Args) {
password, _ := arg.User.Password() password, _ := arg.User.Password()
cipher, err := shadowsocks.NewCipher(method, password) cipher, err := shadowsocks.NewCipher(method, password)
if err != nil { if err != nil {
if glog.V(LWARNING) { glog.V(LWARNING).Infoln("shadowsocks:", err)
glog.Warningln("shadowsocks:", err)
}
return return
} }
conn = shadowsocks.NewConn(conn, cipher) conn = shadowsocks.NewConn(conn, cipher)
...@@ -26,28 +24,21 @@ func handleShadow(conn net.Conn, arg Args) { ...@@ -26,28 +24,21 @@ func handleShadow(conn net.Conn, arg Args) {
addr, extra, err := getShadowRequest(conn) addr, extra, err := getShadowRequest(conn)
if err != nil { if err != nil {
if glog.V(LWARNING) { glog.V(LWARNING).Infoln("shadowsocks:", err)
glog.Warningln("shadowsocks:", err)
}
return return
} }
if glog.V(LINFO) { glog.V(LINFO).Infoln("shadowsocks connect:", addr.String())
glog.Infoln("shadowsocks connect:", addr.String())
}
sconn, err := Connect(addr.String()) sconn, err := Connect(addr.String())
if err != nil { if err != nil {
if glog.V(LWARNING) { glog.V(LWARNING).Infoln("shadowsocks:", err)
glog.Warningln("shadowsocks:", err)
}
return return
} }
defer sconn.Close() defer sconn.Close()
if extra != nil { if extra != nil {
if _, err := sconn.Write(extra); err != nil { if _, err := sconn.Write(extra); err != nil {
if glog.V(LWARNING) { glog.V(LWARNING).Infoln("shadowsocks:", err)
glog.Warningln("shadowsocks:", err)
}
return return
} }
} }
......
package main package main
import ( import (
//"github.com/ginuerzh/gosocks5" "bytes"
//"github.com/golang/glog" "github.com/ginuerzh/gosocks5"
"github.com/golang/glog"
"net" "net"
"time"
) )
type UDPConn struct { type UDPConn struct {
isClient bool isClient bool
udpConn *net.UDPConn udp *net.UDPConn
addr net.Addr addr net.Addr
tcpConn net.Conn tcp net.Conn
} }
func Client(conn net.Conn, addr net.Addr) *UDPConn { func Client(conn net.Conn, addr net.Addr) *UDPConn {
client := &UDPConn{isClient: true} c := &UDPConn{isClient: true}
switch conn := conn.(type) { switch conn := conn.(type) {
case *net.UDPConn: case *net.UDPConn:
client.udpConn = conn c.udp = conn
client.addr = addr c.addr = addr
default: default:
client.tcpConn = conn c.tcp = conn
} }
return client return c
} }
func Server(conn net.Conn) *UDPConn { func Server(conn net.Conn) *UDPConn {
server := &UDPConn{} c := &UDPConn{}
switch conn := conn.(type) { switch conn := conn.(type) {
case *net.UDPConn: case *net.UDPConn:
server.udpConn = conn c.udp = conn
default: default:
server.tcpConn = conn c.tcp = conn
}
return c
}
func (c *UDPConn) ReadUDP() (*gosocks5.UDPDatagram, error) {
if c.isClient {
return c.readUDPClient()
}
return c.readUDPServer()
}
func (c *UDPConn) readUDPClient() (*gosocks5.UDPDatagram, error) {
if c.udp != nil {
return gosocks5.ReadUDPDatagram(c.udp)
}
return gosocks5.ReadUDPDatagram(c.tcp)
}
func (c *UDPConn) readUDPServer() (*gosocks5.UDPDatagram, error) {
if c.udp != nil {
b := make([]byte, 65535)
n, addr, err := c.udp.ReadFromUDP(b)
if err != nil {
return nil, err
}
dgram := gosocks5.NewUDPDatagram(
gosocks5.NewUDPHeader(0, 0, ToSocksAddr(addr)), b[:n])
return dgram, nil
}
return gosocks5.ReadUDPDatagram(c.tcp)
}
func (c *UDPConn) WriteUDP(dgram *gosocks5.UDPDatagram) error {
if c.isClient {
return c.writeUDPClient(dgram)
}
return c.writeUDPServer(dgram)
}
func (c *UDPConn) writeUDPClient(dgram *gosocks5.UDPDatagram) error {
if c.udp != nil {
dgram.Header.Rsv = 0
buffer := bytes.Buffer{}
dgram.Write(&buffer)
_, err := c.udp.WriteTo(buffer.Bytes(), c.addr)
return err
}
dgram.Header.Rsv = uint16(len(dgram.Data))
return dgram.Write(c.tcp)
}
func (c *UDPConn) writeUDPServer(dgram *gosocks5.UDPDatagram) error {
if c.udp != nil {
addr, err := net.ResolveUDPAddr("udp", dgram.Header.Addr.String())
if err != nil {
glog.V(LWARNING).Infoln(err)
return nil // drop silently
}
_, err = c.udp.WriteTo(dgram.Data, addr)
return err
}
dgram.Header.Rsv = uint16(len(dgram.Data))
return dgram.Write(c.tcp)
}
func (c *UDPConn) Close() error {
if c.udp != nil {
return c.udp.Close()
}
return c.tcp.Close()
}
func (c *UDPConn) LocalAddr() net.Addr {
if c.udp != nil {
return c.udp.LocalAddr()
}
return c.tcp.LocalAddr()
}
func (c *UDPConn) RemoteAddr() net.Addr {
if c.udp != nil {
return c.udp.RemoteAddr()
}
return c.tcp.RemoteAddr()
}
func (c *UDPConn) SetDeadline(t time.Time) error {
if c.udp != nil {
return c.udp.SetDeadline(t)
}
return c.tcp.SetDeadline(t)
}
func (c *UDPConn) SetReadDeadline(t time.Time) error {
if c.udp != nil {
return c.udp.SetReadDeadline(t)
}
return c.tcp.SetReadDeadline(t)
}
func (c *UDPConn) SetWriteDeadline(t time.Time) error {
if c.udp != nil {
return c.udp.SetWriteDeadline(t)
} }
return server return c.tcp.SetWriteDeadline(t)
} }
...@@ -62,12 +62,11 @@ nh/BAoGBAMY5z2f1pmMhrvtPDSlEVjgjELbaInxFaxPLR4Pdyzn83gtIIU14+R8X ...@@ -62,12 +62,11 @@ nh/BAoGBAMY5z2f1pmMhrvtPDSlEVjgjELbaInxFaxPLR4Pdyzn83gtIIU14+R8X
func init() { func init() {
var err error var err error
if cert, err = tls.LoadX509KeyPair("cert.pem", "key.pem"); err != nil { if cert, err = tls.LoadX509KeyPair("cert.pem", "key.pem"); err != nil {
if glog.V(LFATAL) { glog.V(LWARNING).Infoln(err)
glog.Warningln(err)
}
cert, err = tls.X509KeyPair([]byte(rawCert), []byte(rawKey)) cert, err = tls.X509KeyPair([]byte(rawCert), []byte(rawKey))
if err != nil && glog.V(LFATAL) { if err != nil {
glog.Warningln(err) glog.V(LFATAL).Infoln(err)
} }
} }
} }
...@@ -112,9 +111,7 @@ func parseArgs(ss []string) (args []Args) { ...@@ -112,9 +111,7 @@ func parseArgs(ss []string) (args []Args) {
} }
u, err := url.Parse(s) u, err := url.Parse(s)
if err != nil { if err != nil {
if glog.V(LWARNING) { glog.V(LWARNING).Infoln(err)
glog.Warningln(err)
}
continue continue
} }
...@@ -186,9 +183,9 @@ func Copy(dst io.Writer, src io.Reader) (written int64, err error) { ...@@ -186,9 +183,9 @@ func Copy(dst io.Writer, src io.Reader) (written int64, err error) {
return return
} }
func Pipe(src io.Reader, dst io.Writer, c chan<- error) { func Pipe(src io.Reader, dst io.Writer, ch chan<- error) {
_, err := Copy(dst, src) _, err := Copy(dst, src)
c <- err ch <- err
} }
func Transport(conn, conn2 net.Conn) (err error) { func Transport(conn, conn2 net.Conn) (err error) {
......
...@@ -105,9 +105,7 @@ func (s *ws) handle(w http.ResponseWriter, r *http.Request) { ...@@ -105,9 +105,7 @@ func (s *ws) handle(w http.ResponseWriter, r *http.Request) {
} }
conn, err := s.upgrader.Upgrade(w, r, nil) conn, err := s.upgrader.Upgrade(w, r, nil)
if err != nil { if err != nil {
if glog.V(LERROR) { glog.V(LERROR).Infoln(err)
glog.Errorln(err)
}
return return
} }
handleConn(wsServer(conn), s.arg) handleConn(wsServer(conn), s.arg)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment