add forward support

This commit is contained in:
rui.zheng 2017-07-23 21:20:09 +08:00
parent 9b2bd7a88c
commit 1c76ca4b26
12 changed files with 654 additions and 50 deletions

View File

@ -38,13 +38,16 @@ func (c *Chain) LastNode() Node {
// AddNode appends the node(s) to the chain. // AddNode appends the node(s) to the chain.
func (c *Chain) AddNode(nodes ...Node) { func (c *Chain) AddNode(nodes ...Node) {
if c == nil {
return
}
c.nodes = append(c.nodes, nodes...) c.nodes = append(c.nodes, nodes...)
} }
// IsEmpty checks if the chain is empty. // IsEmpty checks if the chain is empty.
// An empty chain means that there is no proxy node in the chain. // An empty chain means that there is no proxy node in the chain.
func (c *Chain) IsEmpty() bool { func (c *Chain) IsEmpty() bool {
return len(c.nodes) == 0 return c == nil || len(c.nodes) == 0
} }
// Dial connects to the target address addr through the chain. // Dial connects to the target address addr through the chain.

View File

@ -26,14 +26,12 @@ func (c *Client) Dial(addr string) (net.Conn, error) {
return c.Transporter.Dial(addr) return c.Transporter.Dial(addr)
} }
// Handshake performs a handshake with the proxy. // Handshake performs a handshake with the proxy over connection conn.
// The conn should be an connection to this proxy.
func (c *Client) Handshake(conn net.Conn) (net.Conn, error) { func (c *Client) Handshake(conn net.Conn) (net.Conn, error) {
return c.Transporter.Handshake(conn) return c.Transporter.Handshake(conn)
} }
// Connect connects to the address addr via the proxy. // Connect connects to the address addr via the proxy over connection conn.
// The conn should be an connection to this proxy.
func (c *Client) Connect(conn net.Conn, addr string) (net.Conn, error) { func (c *Client) Connect(conn net.Conn, addr string) (net.Conn, error) {
return c.Connector.Connect(conn, addr) return c.Connector.Connect(conn, addr)
} }

419
gost/forward.go Normal file
View File

@ -0,0 +1,419 @@
package gost
import (
"crypto/tls"
"errors"
"net"
"time"
"fmt"
"github.com/ginuerzh/gosocks5"
"github.com/go-log/log"
)
type tcpForwardHandler struct {
raddr string
options *HandlerOptions
}
// TCPForwardHandler creates a server Handler for TCP port forwarding server.
// The raddr is the remote address that the server will forward to.
func TCPForwardHandler(raddr string, opts ...HandlerOption) Handler {
h := &tcpForwardHandler{
raddr: raddr,
options: &HandlerOptions{
Chain: new(Chain),
},
}
for _, opt := range opts {
opt(h.options)
}
return h
}
func (h *tcpForwardHandler) Handle(conn net.Conn) {
defer conn.Close()
log.Logf("[tcp] %s - %s", conn.RemoteAddr(), h.raddr)
cc, err := h.options.Chain.Dial(h.raddr)
if err != nil {
log.Logf("[tcp] %s -> %s : %s", conn.RemoteAddr(), h.raddr, err)
return
}
defer cc.Close()
log.Logf("[tcp] %s <-> %s", conn.RemoteAddr(), h.raddr)
transport(conn, cc)
log.Logf("[tcp] %s >-< %s", conn.RemoteAddr(), h.raddr)
}
type udpForwardHandler struct {
raddr string
ttl time.Duration
options *HandlerOptions
}
// UDPForwardHandler creates a server Handler for UDP port forwarding server.
// The raddr is the remote address that the server will forward to.
func UDPForwardHandler(raddr string, ttl time.Duration, opts ...HandlerOption) Handler {
h := &udpForwardHandler{
raddr: raddr,
ttl: ttl,
options: &HandlerOptions{
Chain: new(Chain),
},
}
for _, opt := range opts {
opt(h.options)
}
return h
}
func (h *udpForwardHandler) Handle(conn net.Conn) {
defer conn.Close()
}
type rtcpForwardHandler struct {
laddr string
raddr string
options *HandlerOptions
}
// RTCPForwardHandler creates a server Handler for TCP remote port forwarding server.
// The raddr is the remote address that the server will forward to.
func RTCPForwardHandler(laddr, raddr string, opts ...HandlerOption) Handler {
h := &rtcpForwardHandler{
laddr: laddr,
raddr: raddr,
options: &HandlerOptions{},
}
for _, opt := range opts {
opt(h.options)
}
return h
}
func (h *rtcpForwardHandler) Handle(conn net.Conn) {
defer conn.Close()
cc, err := net.DialTimeout("tcp", h.raddr, DialTimeout)
if err != nil {
log.Logf("[rtcp] %s -> %s : %s", h.laddr, h.raddr, err)
return
}
defer cc.Close()
log.Logf("[rtcp] %s <-> %s", h.laddr, h.raddr)
transport(cc, conn)
log.Logf("[rtcp] %s >-< %s", h.laddr, h.raddr)
}
type rudpForwardHandler struct {
laddr string
raddr string
options *HandlerOptions
}
// RUDPForwardHandler creates a server Handler for UDP remote port forwarding server.
// The raddr is the remote address that the server will forward to.
func RUDPForwardHandler(laddr, raddr string, opts ...HandlerOption) Handler {
h := &rudpForwardHandler{
laddr: laddr,
raddr: raddr,
options: &HandlerOptions{},
}
for _, opt := range opts {
opt(h.options)
}
return h
}
func (h *rudpForwardHandler) Handle(conn net.Conn) {
defer conn.Close()
// TODO: handle connection
/*
ra, err := net.ResolveUDPAddr("udp", h.raddr)
if err != nil {
log.Logf("[rudp] %s - %s : %s", h.laddr, h.raddr, err)
return
}
for {
dgram, err := gosocks5.ReadUDPDatagram(conn)
if err != nil {
log.Logf("[rudp] %s -> %s : %s", h.laddr, h.raddr, err)
return
}
go func() {
b := make([]byte, mediumBufferSize)
relay, err := net.DialUDP("udp", nil, ra)
if err != nil {
log.Logf("[rudp] %s -> %s : %s", h.laddr, h.raddr, err)
return
}
defer relay.Close()
if _, err := relay.Write(dgram.Data); err != nil {
log.Logf("[rudp] %s -> %s : %s", h.laddr, h.raddr, err)
return
}
if Debug {
log.Logf("[rudp] %s >>> %s length: %d", h.laddr, h.raddr, len(dgram.Data))
}
relay.SetReadDeadline(time.Now().Add(ReadTimeout))
n, err := relay.Read(b)
if err != nil {
log.Logf("[rudp] %s <- %s : %s", h.laddr, h.raddr, err)
return
}
relay.SetReadDeadline(time.Time{})
if Debug {
log.Logf("[rudp] %s <<< %s length: %d", h.laddr, h.raddr, n)
}
conn.SetWriteDeadline(time.Now().Add(WriteTimeout))
if err := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(uint16(n), 0, dgram.Header.Addr), b[:n]).Write(conn); err != nil {
log.Logf("[rudp] %s <- %s : %s", h.laddr, h.raddr, err)
return
}
conn.SetWriteDeadline(time.Time{})
}()
}
*/
}
type udpForwardListener struct {
addr *net.UDPAddr
conn *net.UDPConn
}
// UDPForwardListener creates a Listener for UDP port forwarding server.
func UDPForwardListener(addr string) (Listener, error) {
laddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
return nil, err
}
conn, err := net.ListenUDP("udp", laddr)
if err != nil {
return nil, err
}
return &udpForwardListener{conn: conn}, nil
}
func (l *udpForwardListener) Accept() (net.Conn, error) {
// TODO: create udp forward connection
return nil, nil
}
func (l *udpForwardListener) Addr() net.Addr {
return l.addr
}
func (l *udpForwardListener) Close() error {
return l.conn.Close()
}
type rtcpForwardListener struct {
addr net.Addr
chain *Chain
selector *clientSelector
close chan struct{}
}
// RTCPForwardListener creates a Listener for TCP remote port forwarding server.
func RTCPForwardListener(addr string, chain *Chain) (Listener, error) {
laddr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil {
return nil, err
}
if chain.IsEmpty() || chain.LastNode().Protocol != "socks5" {
return nil, errors.New("invalid chain")
}
selector := &clientSelector{
TLSConfig: &tls.Config{InsecureSkipVerify: true},
User: chain.LastNode().User,
}
selector.AddMethod(
gosocks5.MethodNoAuth,
gosocks5.MethodUserPass,
MethodTLS,
)
return &rtcpForwardListener{
addr: laddr,
chain: chain,
selector: selector,
close: make(chan struct{}),
}, nil
}
func (l *rtcpForwardListener) Accept() (net.Conn, error) {
select {
case <-l.close:
return nil, errors.New("closed")
default:
}
if l.chain.IsEmpty() || l.chain.LastNode().Protocol != "socks5" {
return nil, errors.New("invalid chain")
}
conn, err := l.chain.Conn()
if err != nil {
return nil, err
}
cc, err := l.handshake(conn)
if err != nil {
conn.Close()
return nil, err
}
return cc, nil
}
func (l *rtcpForwardListener) handshake(conn net.Conn) (net.Conn, error) {
cc := gosocks5.ClientConn(conn, l.selector)
if err := cc.Handleshake(); err != nil {
return nil, err
}
conn = cc
req := gosocks5.NewRequest(gosocks5.CmdBind, toSocksAddr(l.addr))
if err := req.Write(conn); err != nil {
log.Log("[rtcp] SOCKS5 BIND request: ", err)
return nil, err
}
// first reply, bind status
conn.SetReadDeadline(time.Now().Add(ReadTimeout))
rep, err := gosocks5.ReadReply(conn)
if err != nil {
log.Log("[rtcp] SOCKS5 BIND reply: ", err)
return nil, err
}
conn.SetReadDeadline(time.Time{})
if rep.Rep != gosocks5.Succeeded {
log.Logf("[rtcp] bind on %s failure", l.addr)
return nil, fmt.Errorf("Bind on %s failure", l.addr.String())
}
log.Logf("[rtcp] BIND ON %s OK", rep.Addr)
// second reply, peer connected
rep, err = gosocks5.ReadReply(conn)
if err != nil {
log.Log("[rtcp]", err)
return nil, err
}
if rep.Rep != gosocks5.Succeeded {
log.Logf("[rtcp] peer connect failure: %d", rep.Rep)
return nil, errors.New("peer connect failure")
}
log.Logf("[rtcp] PEER %s CONNECTED", rep.Addr)
return conn, nil
}
func (l *rtcpForwardListener) Addr() net.Addr {
return l.addr
}
func (l *rtcpForwardListener) Close() error {
close(l.close)
return nil
}
type rudpForwardListener struct {
addr net.Addr
chain *Chain
selector *clientSelector
close chan struct{}
}
// RUDPForwardListener creates a Listener for UDP remote port forwarding server.
func RUDPForwardListener(addr string, chain *Chain) (Listener, error) {
laddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
return nil, err
}
if chain.IsEmpty() || chain.LastNode().Protocol != "socks5" {
return nil, errors.New("invalid chain")
}
selector := &clientSelector{
TLSConfig: &tls.Config{InsecureSkipVerify: true},
User: chain.LastNode().User,
}
selector.AddMethod(
gosocks5.MethodNoAuth,
gosocks5.MethodUserPass,
MethodTLS,
)
return &rudpForwardListener{
addr: laddr,
chain: chain,
selector: selector,
close: make(chan struct{}),
}, nil
}
func (l *rudpForwardListener) Accept() (net.Conn, error) {
select {
case <-l.close:
return nil, errors.New("closed")
default:
}
conn, err := l.chain.Conn()
if err != nil {
return nil, err
}
cc, err := l.handshake(conn)
if err != nil {
conn.Close()
return nil, err
}
conn = cc
return cc, nil
}
func (l *rudpForwardListener) handshake(conn net.Conn) (net.Conn, error) {
cc := gosocks5.ClientConn(conn, l.selector)
if err := cc.Handleshake(); err != nil {
return nil, err
}
conn = cc
req := gosocks5.NewRequest(CmdUDPTun, toSocksAddr(l.addr))
if err := req.Write(conn); err != nil {
log.Log("[rudp] SOCKS5 UDP relay request: ", err)
return nil, err
}
conn.SetReadDeadline(time.Now().Add(ReadTimeout))
rep, err := gosocks5.ReadReply(conn)
if err != nil {
log.Log("[rudp] SOCKS5 UDP relay reply: ", err)
return nil, err
}
conn.SetReadDeadline(time.Time{})
if rep.Rep != gosocks5.Succeeded {
log.Logf("[rudp] bind on %s failure: %d", l.addr, rep.Rep)
return nil, fmt.Errorf("Bind on %s failure", l.addr.String())
}
log.Logf("[rudp] BIND ON %s OK", rep.Addr)
return conn, nil
}
func (l *rudpForwardListener) Addr() net.Addr {
return l.addr
}
func (l *rudpForwardListener) Close() error {
close(l.close)
return nil
}

View File

@ -25,9 +25,9 @@ var (
// DialTimeout is the timeout of dial. // DialTimeout is the timeout of dial.
DialTimeout = 30 * time.Second DialTimeout = 30 * time.Second
// ReadTimeout is the timeout for reading. // ReadTimeout is the timeout for reading.
ReadTimeout = 90 * time.Second ReadTimeout = 30 * time.Second
// WriteTimeout is the timeout for writing. // WriteTimeout is the timeout for writing.
WriteTimeout = 90 * time.Second WriteTimeout = 60 * time.Second
// default udp node TTL in second for udp port forwarding. // default udp node TTL in second for udp port forwarding.
defaultTTL = 60 defaultTTL = 60
) )

View File

@ -87,6 +87,8 @@ func HTTPHandler(opts ...HandlerOption) Handler {
} }
func (h *httpHandler) Handle(conn net.Conn) { func (h *httpHandler) Handle(conn net.Conn) {
defer conn.Close()
req, err := http.ReadRequest(bufio.NewReader(conn)) req, err := http.ReadRequest(bufio.NewReader(conn))
if err != nil { if err != nil {
log.Log("[http]", err) log.Log("[http]", err)

View File

@ -19,8 +19,8 @@ import (
) )
var ( var (
// SALT is the default salt for KCP cipher. // KCPSalt is the default salt for KCP cipher.
SALT = "kcp-go" KCPSalt = "kcp-go"
) )
// KCPConfig describes the config for KCP. // KCPConfig describes the config for KCP.
@ -204,7 +204,7 @@ func (tr *kcpTransporter) Dial(addr string) (conn net.Conn, err error) {
func (tr *kcpTransporter) dial(addr string, config *KCPConfig) (*kcpSession, error) { func (tr *kcpTransporter) dial(addr string, config *KCPConfig) (*kcpSession, error) {
kcpconn, err := kcp.DialWithOptions(addr, kcpconn, err := kcp.DialWithOptions(addr,
blockCrypt(config.Key, config.Crypt, SALT), config.DataShard, config.ParityShard) blockCrypt(config.Key, config.Crypt, KCPSalt), config.DataShard, config.ParityShard)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -260,7 +260,7 @@ func KCPListener(addr string, config *KCPConfig) (Listener, error) {
config.Init() config.Init()
ln, err := kcp.ListenWithOptions(addr, ln, err := kcp.ListenWithOptions(addr,
blockCrypt(config.Key, config.Crypt, SALT), config.DataShard, config.ParityShard) blockCrypt(config.Key, config.Crypt, KCPSalt), config.DataShard, config.ParityShard)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,9 +1,14 @@
package gost package gost
import (
"net/url"
)
// Node is a proxy node, mainly used to construct a proxy chain. // Node is a proxy node, mainly used to construct a proxy chain.
type Node struct { type Node struct {
Addr string Addr string
Protocol string Protocol string
Transport string Transport string
User *url.Userinfo
Client *Client Client *Client
} }

91
gost/redirect.go Normal file
View File

@ -0,0 +1,91 @@
// +build !windows
package gost
import (
"errors"
"fmt"
"net"
"syscall"
"github.com/go-log/log"
)
type tcpRedirectHandler struct {
options *HandlerOptions
}
// TCPRedirectHandler creates a server Handler for TCP redirect server.
func TCPRedirectHandler(opts ...HandlerOption) Handler {
h := &tcpRedirectHandler{
options: &HandlerOptions{
Chain: new(Chain),
},
}
for _, opt := range opts {
opt(h.options)
}
return h
}
func (h *tcpRedirectHandler) Handle(c net.Conn) {
conn, ok := c.(*net.TCPConn)
if !ok {
log.Log("[red-tcp] not a TCP connection")
}
srcAddr := conn.RemoteAddr()
dstAddr, conn, err := h.getOriginalDstAddr(conn)
if err != nil {
log.Logf("[red-tcp] %s -> %s : %s", srcAddr, dstAddr, err)
return
}
defer conn.Close()
log.Logf("[red-tcp] %s -> %s", srcAddr, dstAddr)
cc, err := h.options.Chain.Dial(dstAddr.String())
if err != nil {
log.Logf("[red-tcp] %s -> %s : %s", srcAddr, dstAddr, err)
return
}
defer cc.Close()
log.Logf("[red-tcp] %s <-> %s", srcAddr, dstAddr)
transport(conn, cc)
log.Logf("[red-tcp] %s >-< %s", srcAddr, dstAddr)
}
func (h *tcpRedirectHandler) getOriginalDstAddr(conn *net.TCPConn) (addr net.Addr, c *net.TCPConn, err error) {
defer conn.Close()
fc, err := conn.File()
if err != nil {
return
}
defer fc.Close()
mreq, err := syscall.GetsockoptIPv6Mreq(int(fc.Fd()), syscall.IPPROTO_IP, 80)
if err != nil {
return
}
// only ipv4 support
ip := net.IPv4(mreq.Multiaddr[4], mreq.Multiaddr[5], mreq.Multiaddr[6], mreq.Multiaddr[7])
port := uint16(mreq.Multiaddr[2])<<8 + uint16(mreq.Multiaddr[3])
addr, err = net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", ip.String(), port))
if err != nil {
return
}
cc, err := net.FileConn(fc)
if err != nil {
return
}
c, ok := cc.(*net.TCPConn)
if !ok {
err = errors.New("not a TCP connection")
}
return
}

31
gost/redirect_win.go Normal file
View File

@ -0,0 +1,31 @@
// +build windows
package gost
import (
"net"
"github.com/go-log/log"
)
type tcpRedirectHandler struct {
options *HandlerOptions
}
// TCPRedirectHandler creates a server Handler for TCP redirect server.
func TCPRedirectHandler(opts ...HandlerOption) Handler {
h := &tcpRedirectHandler{
options: &HandlerOptions{
Chain: new(Chain),
},
}
for _, opt := range opts {
opt(h.options)
}
return h
}
func (h *tcpRedirectHandler) Handle(c net.Conn) {
log.Log("[red-tcp] TCP redirect is not available on the Windows platform")
c.Close()
}

View File

@ -365,6 +365,8 @@ func SOCKS5Handler(opts ...HandlerOption) Handler {
} }
func (h *socks5Handler) Handle(conn net.Conn) { func (h *socks5Handler) Handle(conn net.Conn) {
defer conn.Close()
conn = gosocks5.ServerConn(conn, h.selector) conn = gosocks5.ServerConn(conn, h.selector)
req, err := gosocks5.ReadRequest(conn) req, err := gosocks5.ReadRequest(conn)
if err != nil { if err != nil {
@ -960,6 +962,8 @@ func SOCKS4Handler(opts ...HandlerOption) Handler {
} }
func (h *socks4Handler) Handle(conn net.Conn) { func (h *socks4Handler) Handle(conn net.Conn) {
defer conn.Close()
req, err := gosocks4.ReadRequest(conn) req, err := gosocks4.ReadRequest(conn)
if err != nil { if err != nil {
log.Log("[socks4]", err) log.Log("[socks4]", err)

View File

@ -6,8 +6,6 @@ import (
"net/url" "net/url"
"sync"
"github.com/ginuerzh/gost/gost" "github.com/ginuerzh/gost/gost"
) )
@ -17,27 +15,22 @@ func init() {
} }
func main() { func main() {
wg := sync.WaitGroup{} go httpServer()
wg.Add(1) go socks5Server()
go httpServer(&wg) go tlsServer()
wg.Add(1) go shadowServer()
go socks5Server(&wg) go wsServer()
wg.Add(1) go wssServer()
go tlsServer(&wg) go kcpServer()
wg.Add(1) go tcpForwardServer()
go shadowServer(&wg) go rtcpForwardServer()
wg.Add(1) // go rudpForwardServer()
go wsServer(&wg) go tcpRedirectServer()
wg.Add(1)
go wssServer(&wg) select {}
wg.Add(1)
go kcpServer(&wg)
wg.Wait()
} }
func httpServer(wg *sync.WaitGroup) { func httpServer() {
defer wg.Done()
s := &gost.Server{} s := &gost.Server{}
s.Handle(gost.HTTPHandler( s.Handle(gost.HTTPHandler(
gost.UsersHandlerOption(url.UserPassword("admin", "123456")), gost.UsersHandlerOption(url.UserPassword("admin", "123456")),
@ -49,9 +42,7 @@ func httpServer(wg *sync.WaitGroup) {
log.Fatal(s.Serve(ln)) log.Fatal(s.Serve(ln))
} }
func socks5Server(wg *sync.WaitGroup) { func socks5Server() {
defer wg.Done()
cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem") cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -69,9 +60,7 @@ func socks5Server(wg *sync.WaitGroup) {
log.Fatal(s.Serve(ln)) log.Fatal(s.Serve(ln))
} }
func shadowServer(wg *sync.WaitGroup) { func shadowServer() {
defer wg.Done()
s := &gost.Server{} s := &gost.Server{}
s.Handle(gost.ShadowHandler( s.Handle(gost.ShadowHandler(
gost.UsersHandlerOption(url.UserPassword("chacha20", "123456")), gost.UsersHandlerOption(url.UserPassword("chacha20", "123456")),
@ -83,9 +72,7 @@ func shadowServer(wg *sync.WaitGroup) {
log.Fatal(s.Serve(ln)) log.Fatal(s.Serve(ln))
} }
func tlsServer(wg *sync.WaitGroup) { func tlsServer() {
defer wg.Done()
s := &gost.Server{} s := &gost.Server{}
s.Handle(gost.HTTPHandler( s.Handle(gost.HTTPHandler(
gost.UsersHandlerOption(url.UserPassword("admin", "123456")), gost.UsersHandlerOption(url.UserPassword("admin", "123456")),
@ -101,9 +88,7 @@ func tlsServer(wg *sync.WaitGroup) {
log.Fatal(s.Serve(ln)) log.Fatal(s.Serve(ln))
} }
func wsServer(wg *sync.WaitGroup) { func wsServer() {
defer wg.Done()
s := &gost.Server{} s := &gost.Server{}
s.Handle(gost.HTTPHandler( s.Handle(gost.HTTPHandler(
gost.UsersHandlerOption(url.UserPassword("admin", "123456")), gost.UsersHandlerOption(url.UserPassword("admin", "123456")),
@ -115,9 +100,7 @@ func wsServer(wg *sync.WaitGroup) {
log.Fatal(s.Serve(ln)) log.Fatal(s.Serve(ln))
} }
func wssServer(wg *sync.WaitGroup) { func wssServer() {
defer wg.Done()
s := &gost.Server{} s := &gost.Server{}
s.Handle(gost.HTTPHandler( s.Handle(gost.HTTPHandler(
gost.UsersHandlerOption(url.UserPassword("admin", "123456")), gost.UsersHandlerOption(url.UserPassword("admin", "123456")),
@ -134,9 +117,7 @@ func wssServer(wg *sync.WaitGroup) {
log.Fatal(s.Serve(ln)) log.Fatal(s.Serve(ln))
} }
func kcpServer(wg *sync.WaitGroup) { func kcpServer() {
defer wg.Done()
s := &gost.Server{} s := &gost.Server{}
s.Handle(gost.HTTPHandler()) s.Handle(gost.HTTPHandler())
ln, err := gost.KCPListener(":8388", nil) ln, err := gost.KCPListener(":8388", nil)
@ -145,3 +126,71 @@ func kcpServer(wg *sync.WaitGroup) {
} }
log.Fatal(s.Serve(ln)) log.Fatal(s.Serve(ln))
} }
func tcpForwardServer() {
s := &gost.Server{}
s.Handle(gost.TCPForwardHandler("ginuerzh.xyz:22"))
ln, err := gost.TCPListener(":2222")
if err != nil {
log.Fatal(err)
}
log.Fatal(s.Serve(ln))
}
func rtcpForwardServer() {
s := &gost.Server{}
s.Handle(gost.RTCPForwardHandler(":1222", "ginuerzh.xyz:22"))
ln, err := gost.RTCPForwardListener(
":1222",
gost.NewChain(
gost.Node{
Protocol: "socks5",
Transport: "tcp",
Addr: "localhost:12345",
User: url.UserPassword("admin", "123456"),
Client: gost.NewClient(
gost.SOCKS5Connector(url.UserPassword("admin", "123456")),
gost.TCPTransporter(),
),
},
),
)
if err != nil {
log.Fatal()
}
log.Fatal(s.Serve(ln))
}
func rudpForwardServer() {
s := &gost.Server{}
s.Handle(gost.RUDPForwardHandler(":10053", "localhost:53"))
ln, err := gost.RUDPForwardListener(
":10053",
gost.NewChain(
gost.Node{
Protocol: "socks5",
Transport: "tcp",
Addr: "localhost:12345",
User: url.UserPassword("admin", "123456"),
Client: gost.NewClient(
gost.SOCKS5Connector(url.UserPassword("admin", "123456")),
gost.TCPTransporter(),
),
},
),
)
if err != nil {
log.Fatal()
}
log.Fatal(s.Serve(ln))
}
func tcpRedirectServer() {
s := &gost.Server{}
s.Handle(gost.TCPRedirectHandler())
ln, err := gost.TCPListener(":8008")
if err != nil {
log.Fatal(err)
}
log.Fatal(s.Serve(ln))
}

View File

@ -106,6 +106,8 @@ func ShadowHandler(opts ...HandlerOption) Handler {
} }
func (h *shadowHandler) Handle(conn net.Conn) { func (h *shadowHandler) Handle(conn net.Conn) {
defer conn.Close()
var method, password string var method, password string
users := h.options.Users users := h.options.Users