add forward support
This commit is contained in:
parent
9b2bd7a88c
commit
1c76ca4b26
@ -38,13 +38,16 @@ func (c *Chain) LastNode() Node {
|
||||
|
||||
// AddNode appends the node(s) to the chain.
|
||||
func (c *Chain) AddNode(nodes ...Node) {
|
||||
if c == nil {
|
||||
return
|
||||
}
|
||||
c.nodes = append(c.nodes, nodes...)
|
||||
}
|
||||
|
||||
// IsEmpty checks if the chain is empty.
|
||||
// An empty chain means that there is no proxy node in the chain.
|
||||
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.
|
||||
|
@ -26,14 +26,12 @@ func (c *Client) Dial(addr string) (net.Conn, error) {
|
||||
return c.Transporter.Dial(addr)
|
||||
}
|
||||
|
||||
// Handshake performs a handshake with the proxy.
|
||||
// The conn should be an connection to this proxy.
|
||||
// Handshake performs a handshake with the proxy over connection conn.
|
||||
func (c *Client) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
return c.Transporter.Handshake(conn)
|
||||
}
|
||||
|
||||
// Connect connects to the address addr via the proxy.
|
||||
// The conn should be an connection to this proxy.
|
||||
// Connect connects to the address addr via the proxy over connection conn.
|
||||
func (c *Client) Connect(conn net.Conn, addr string) (net.Conn, error) {
|
||||
return c.Connector.Connect(conn, addr)
|
||||
}
|
||||
|
419
gost/forward.go
Normal file
419
gost/forward.go
Normal 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
|
||||
}
|
@ -25,9 +25,9 @@ var (
|
||||
// DialTimeout is the timeout of dial.
|
||||
DialTimeout = 30 * time.Second
|
||||
// ReadTimeout is the timeout for reading.
|
||||
ReadTimeout = 90 * time.Second
|
||||
ReadTimeout = 30 * time.Second
|
||||
// WriteTimeout is the timeout for writing.
|
||||
WriteTimeout = 90 * time.Second
|
||||
WriteTimeout = 60 * time.Second
|
||||
// default udp node TTL in second for udp port forwarding.
|
||||
defaultTTL = 60
|
||||
)
|
||||
|
@ -87,6 +87,8 @@ func HTTPHandler(opts ...HandlerOption) Handler {
|
||||
}
|
||||
|
||||
func (h *httpHandler) Handle(conn net.Conn) {
|
||||
defer conn.Close()
|
||||
|
||||
req, err := http.ReadRequest(bufio.NewReader(conn))
|
||||
if err != nil {
|
||||
log.Log("[http]", err)
|
||||
|
@ -19,8 +19,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// SALT is the default salt for KCP cipher.
|
||||
SALT = "kcp-go"
|
||||
// KCPSalt is the default salt for KCP cipher.
|
||||
KCPSalt = "kcp-go"
|
||||
)
|
||||
|
||||
// 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) {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -260,7 +260,7 @@ func KCPListener(addr string, config *KCPConfig) (Listener, error) {
|
||||
config.Init()
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1,9 +1,14 @@
|
||||
package gost
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// Node is a proxy node, mainly used to construct a proxy chain.
|
||||
type Node struct {
|
||||
Addr string
|
||||
Protocol string
|
||||
Transport string
|
||||
User *url.Userinfo
|
||||
Client *Client
|
||||
}
|
||||
|
91
gost/redirect.go
Normal file
91
gost/redirect.go
Normal 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
31
gost/redirect_win.go
Normal 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()
|
||||
}
|
@ -365,6 +365,8 @@ func SOCKS5Handler(opts ...HandlerOption) Handler {
|
||||
}
|
||||
|
||||
func (h *socks5Handler) Handle(conn net.Conn) {
|
||||
defer conn.Close()
|
||||
|
||||
conn = gosocks5.ServerConn(conn, h.selector)
|
||||
req, err := gosocks5.ReadRequest(conn)
|
||||
if err != nil {
|
||||
@ -960,6 +962,8 @@ func SOCKS4Handler(opts ...HandlerOption) Handler {
|
||||
}
|
||||
|
||||
func (h *socks4Handler) Handle(conn net.Conn) {
|
||||
defer conn.Close()
|
||||
|
||||
req, err := gosocks4.ReadRequest(conn)
|
||||
if err != nil {
|
||||
log.Log("[socks4]", err)
|
||||
|
127
gost/srv/srv.go
127
gost/srv/srv.go
@ -6,8 +6,6 @@ import (
|
||||
|
||||
"net/url"
|
||||
|
||||
"sync"
|
||||
|
||||
"github.com/ginuerzh/gost/gost"
|
||||
)
|
||||
|
||||
@ -17,27 +15,22 @@ func init() {
|
||||
}
|
||||
|
||||
func main() {
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
go httpServer(&wg)
|
||||
wg.Add(1)
|
||||
go socks5Server(&wg)
|
||||
wg.Add(1)
|
||||
go tlsServer(&wg)
|
||||
wg.Add(1)
|
||||
go shadowServer(&wg)
|
||||
wg.Add(1)
|
||||
go wsServer(&wg)
|
||||
wg.Add(1)
|
||||
go wssServer(&wg)
|
||||
wg.Add(1)
|
||||
go kcpServer(&wg)
|
||||
wg.Wait()
|
||||
go httpServer()
|
||||
go socks5Server()
|
||||
go tlsServer()
|
||||
go shadowServer()
|
||||
go wsServer()
|
||||
go wssServer()
|
||||
go kcpServer()
|
||||
go tcpForwardServer()
|
||||
go rtcpForwardServer()
|
||||
// go rudpForwardServer()
|
||||
go tcpRedirectServer()
|
||||
|
||||
select {}
|
||||
}
|
||||
|
||||
func httpServer(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
func httpServer() {
|
||||
s := &gost.Server{}
|
||||
s.Handle(gost.HTTPHandler(
|
||||
gost.UsersHandlerOption(url.UserPassword("admin", "123456")),
|
||||
@ -49,9 +42,7 @@ func httpServer(wg *sync.WaitGroup) {
|
||||
log.Fatal(s.Serve(ln))
|
||||
}
|
||||
|
||||
func socks5Server(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
func socks5Server() {
|
||||
cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -69,9 +60,7 @@ func socks5Server(wg *sync.WaitGroup) {
|
||||
log.Fatal(s.Serve(ln))
|
||||
}
|
||||
|
||||
func shadowServer(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
func shadowServer() {
|
||||
s := &gost.Server{}
|
||||
s.Handle(gost.ShadowHandler(
|
||||
gost.UsersHandlerOption(url.UserPassword("chacha20", "123456")),
|
||||
@ -83,9 +72,7 @@ func shadowServer(wg *sync.WaitGroup) {
|
||||
log.Fatal(s.Serve(ln))
|
||||
}
|
||||
|
||||
func tlsServer(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
func tlsServer() {
|
||||
s := &gost.Server{}
|
||||
s.Handle(gost.HTTPHandler(
|
||||
gost.UsersHandlerOption(url.UserPassword("admin", "123456")),
|
||||
@ -101,9 +88,7 @@ func tlsServer(wg *sync.WaitGroup) {
|
||||
log.Fatal(s.Serve(ln))
|
||||
}
|
||||
|
||||
func wsServer(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
func wsServer() {
|
||||
s := &gost.Server{}
|
||||
s.Handle(gost.HTTPHandler(
|
||||
gost.UsersHandlerOption(url.UserPassword("admin", "123456")),
|
||||
@ -115,9 +100,7 @@ func wsServer(wg *sync.WaitGroup) {
|
||||
log.Fatal(s.Serve(ln))
|
||||
}
|
||||
|
||||
func wssServer(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
func wssServer() {
|
||||
s := &gost.Server{}
|
||||
s.Handle(gost.HTTPHandler(
|
||||
gost.UsersHandlerOption(url.UserPassword("admin", "123456")),
|
||||
@ -134,9 +117,7 @@ func wssServer(wg *sync.WaitGroup) {
|
||||
log.Fatal(s.Serve(ln))
|
||||
}
|
||||
|
||||
func kcpServer(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
func kcpServer() {
|
||||
s := &gost.Server{}
|
||||
s.Handle(gost.HTTPHandler())
|
||||
ln, err := gost.KCPListener(":8388", nil)
|
||||
@ -145,3 +126,71 @@ func kcpServer(wg *sync.WaitGroup) {
|
||||
}
|
||||
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))
|
||||
}
|
||||
|
@ -106,6 +106,8 @@ func ShadowHandler(opts ...HandlerOption) Handler {
|
||||
}
|
||||
|
||||
func (h *shadowHandler) Handle(conn net.Conn) {
|
||||
defer conn.Close()
|
||||
|
||||
var method, password string
|
||||
|
||||
users := h.options.Users
|
||||
|
Loading…
Reference in New Issue
Block a user