add data forward support for tunnels

This commit is contained in:
rui.zheng 2017-08-14 22:13:11 +08:00
parent 229927494b
commit 93fa95f27a
4 changed files with 60 additions and 7 deletions

View File

@ -129,7 +129,7 @@ func initChain() (*gost.Chain, error) {
} }
tr = gost.KCPTransporter(config) tr = gost.KCPTransporter(config)
case "ssh": case "ssh":
if node.Protocol == "direct" || node.Protocol == "remote" || node.Protocol == "forward" { if node.Protocol == "direct" || node.Protocol == "remote" {
tr = gost.SSHForwardTransporter() tr = gost.SSHForwardTransporter()
} else { } else {
tr = gost.SSHTunnelTransporter() tr = gost.SSHTunnelTransporter()
@ -187,10 +187,12 @@ func initChain() (*gost.Chain, error) {
connector = gost.SOCKS4AConnector() connector = gost.SOCKS4AConnector()
case "ss": case "ss":
connector = gost.ShadowConnector(node.User) connector = gost.ShadowConnector(node.User)
case "direct", "forward": case "direct":
connector = gost.SSHDirectForwardConnector() connector = gost.SSHDirectForwardConnector()
case "remote": case "remote":
connector = gost.SSHRemoteForwardConnector() connector = gost.SSHRemoteForwardConnector()
case "forward":
connector = gost.ForwardConnector()
case "http": case "http":
fallthrough fallthrough
default: default:
@ -239,6 +241,7 @@ func serve(chain *gost.Chain) error {
if err != nil && certFile != "" && keyFile != "" { if err != nil && certFile != "" && keyFile != "" {
return err return err
} }
var ln gost.Listener var ln gost.Listener
switch node.Transport { switch node.Transport {
case "tls": case "tls":
@ -364,8 +367,14 @@ func serve(chain *gost.Chain) error {
case "sni": case "sni":
handler = gost.SNIHandler(handlerOptions...) handler = gost.SNIHandler(handlerOptions...)
default: default:
handler = gost.AutoHandler(handlerOptions...) // start from 2.5, if remote is not empty, then we assume that it is a forward tunnel
if node.Remote != "" {
handler = gost.ForwardHandler(node.Remote, handlerOptions...)
} else {
handler = gost.AutoHandler(handlerOptions...)
}
} }
srv := &gost.Server{Listener: ln} srv := &gost.Server{Listener: ln}
go srv.Serve(handler) go srv.Serve(handler)
} }

View File

@ -12,6 +12,51 @@ import (
"github.com/go-log/log" "github.com/go-log/log"
) )
type forwardConnector struct {
}
// ForwardConnector creates a Connector for data forward client.
func ForwardConnector() Connector {
return &forwardConnector{}
}
func (c *forwardConnector) Connect(conn net.Conn, addr string) (net.Conn, error) {
return conn, nil
}
type forwardHandler struct {
raddr string
options *HandlerOptions
}
// ForwardHandler creates a server Handler for data forwarding server.
func ForwardHandler(raddr string, opts ...HandlerOption) Handler {
h := &forwardHandler{
raddr: raddr,
options: &HandlerOptions{},
}
for _, opt := range opts {
opt(h.options)
}
return h
}
func (h *forwardHandler) Handle(conn net.Conn) {
defer conn.Close()
log.Logf("[forward] %s - %s", conn.RemoteAddr(), h.raddr)
cc, err := h.options.Chain.Dial(h.raddr)
if err != nil {
log.Logf("[forward] %s -> %s : %s", conn.RemoteAddr(), h.raddr, err)
return
}
defer cc.Close()
log.Logf("[forward] %s <-> %s", conn.RemoteAddr(), h.raddr)
transport(conn, cc)
log.Logf("[forward] %s >-< %s", conn.RemoteAddr(), h.raddr)
}
type tcpDirectForwardHandler struct { type tcpDirectForwardHandler struct {
raddr string raddr string
options *HandlerOptions options *HandlerOptions

View File

@ -36,6 +36,7 @@ func ParseNode(s string) (node Node, err error) {
node = Node{ node = Node{
Addr: u.Host, Addr: u.Host,
Remote: strings.Trim(u.EscapedPath(), "/"),
Values: u.Query(), Values: u.Query(),
User: u.User, User: u.User,
} }
@ -56,9 +57,7 @@ func ParseNode(s string) (node Node, err error) {
node.Protocol = "http" node.Protocol = "http"
node.Transport = "tls" node.Transport = "tls"
case "tcp", "udp": // started from v2.1, tcp and udp are for local port forwarding case "tcp", "udp": // started from v2.1, tcp and udp are for local port forwarding
node.Remote = strings.Trim(u.EscapedPath(), "/")
case "rtcp", "rudp": // rtcp and rudp are for remote port forwarding case "rtcp", "rudp": // rtcp and rudp are for remote port forwarding
node.Remote = strings.Trim(u.EscapedPath(), "/")
default: default:
node.Transport = "tcp" node.Transport = "tcp"
} }
@ -68,7 +67,7 @@ func ParseNode(s string) (node Node, err error) {
case "socks", "socks5": case "socks", "socks5":
node.Protocol = "socks5" node.Protocol = "socks5"
case "tcp", "udp", "rtcp", "rudp": // port forwarding case "tcp", "udp", "rtcp", "rudp": // port forwarding
case "direct", "remote", "forward": // SSH port forwarding case "direct", "remote", "forward": // forwarding
case "redirect": // TCP transparent proxy case "redirect": // TCP transparent proxy
default: default:
node.Protocol = "" node.Protocol = ""

2
sni.go
View File

@ -56,7 +56,7 @@ func (h *sniHandler) Handle(conn net.Conn) {
return return
} }
cc, err := options.Chain.Dial(sni) cc, err := options.Chain.Dial(sni + ":443")
if err != nil { if err != nil {
log.Logf("[sni] %s -> %s : %s", conn.RemoteAddr(), sni, err) log.Logf("[sni] %s -> %s : %s", conn.RemoteAddr(), sni, err)
return return