|
|
|
@ -3,6 +3,7 @@ package gost |
|
|
|
import ( |
|
|
|
"errors" |
|
|
|
"net" |
|
|
|
"strings" |
|
|
|
"sync" |
|
|
|
"time" |
|
|
|
|
|
|
|
@ -27,17 +28,39 @@ func (c *forwardConnector) Connect(conn net.Conn, addr string) (net.Conn, error) |
|
|
|
|
|
|
|
type tcpDirectForwardHandler struct { |
|
|
|
raddr string |
|
|
|
group *NodeGroup |
|
|
|
options *HandlerOptions |
|
|
|
} |
|
|
|
|
|
|
|
// TCPDirectForwardHandler creates a server Handler for TCP port forwarding server.
|
|
|
|
// The raddr is the remote address that the server will forward to.
|
|
|
|
// NOTE: as of 2.6, remote address can be a comma-separated address list.
|
|
|
|
func TCPDirectForwardHandler(raddr string, opts ...HandlerOption) Handler { |
|
|
|
if raddr == "" { |
|
|
|
raddr = "0.0.0.0:0" |
|
|
|
group := NewNodeGroup() |
|
|
|
group.SetSelector(&defaultSelector{}, |
|
|
|
WithStrategy(&RoundStrategy{}), |
|
|
|
WithFilter(&FailFilter{ |
|
|
|
MaxFails: 1, |
|
|
|
FailTimeout: 30 * time.Second, |
|
|
|
}), |
|
|
|
) |
|
|
|
|
|
|
|
for i, addr := range strings.Split(raddr, ",") { |
|
|
|
if addr == "" { |
|
|
|
continue |
|
|
|
} |
|
|
|
// We treat the remote target server as a node, so we can put them in a group,
|
|
|
|
// and perform the node selection for load balancing.
|
|
|
|
group.AddNode(Node{ |
|
|
|
ID: i + 1, |
|
|
|
Addr: addr, |
|
|
|
Host: addr, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
h := &tcpDirectForwardHandler{ |
|
|
|
raddr: raddr, |
|
|
|
group: group, |
|
|
|
options: &HandlerOptions{}, |
|
|
|
} |
|
|
|
for _, opt := range opts { |
|
|
|
@ -49,29 +72,63 @@ func TCPDirectForwardHandler(raddr string, opts ...HandlerOption) Handler { |
|
|
|
func (h *tcpDirectForwardHandler) Handle(conn net.Conn) { |
|
|
|
defer conn.Close() |
|
|
|
|
|
|
|
log.Logf("[tcp] %s - %s", conn.RemoteAddr(), h.raddr) |
|
|
|
cc, err := h.options.Chain.Dial(h.raddr) |
|
|
|
node, err := h.group.Next() |
|
|
|
if err != nil { |
|
|
|
log.Logf("[tcp] %s -> %s : %s", conn.RemoteAddr(), h.raddr, err) |
|
|
|
log.Logf("[tcp] %s - %s : %s", conn.RemoteAddr(), h.raddr, err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
log.Logf("[tcp] %s - %s", conn.RemoteAddr(), node.Addr) |
|
|
|
cc, err := h.options.Chain.Dial(node.Addr) |
|
|
|
if err != nil { |
|
|
|
log.Logf("[tcp] %s -> %s : %s", conn.RemoteAddr(), node.Addr, err) |
|
|
|
node.MarkDead() |
|
|
|
return |
|
|
|
} |
|
|
|
defer cc.Close() |
|
|
|
|
|
|
|
log.Logf("[tcp] %s <-> %s", conn.RemoteAddr(), h.raddr) |
|
|
|
node.ResetDead() |
|
|
|
|
|
|
|
log.Logf("[tcp] %s <-> %s", conn.RemoteAddr(), node.Addr) |
|
|
|
transport(conn, cc) |
|
|
|
log.Logf("[tcp] %s >-< %s", conn.RemoteAddr(), h.raddr) |
|
|
|
log.Logf("[tcp] %s >-< %s", conn.RemoteAddr(), node.Addr) |
|
|
|
} |
|
|
|
|
|
|
|
type udpDirectForwardHandler struct { |
|
|
|
raddr string |
|
|
|
group *NodeGroup |
|
|
|
options *HandlerOptions |
|
|
|
} |
|
|
|
|
|
|
|
// UDPDirectForwardHandler creates a server Handler for UDP port forwarding server.
|
|
|
|
// The raddr is the remote address that the server will forward to.
|
|
|
|
// NOTE: as of 2.6, remote address can be a comma-separated address list.
|
|
|
|
func UDPDirectForwardHandler(raddr string, opts ...HandlerOption) Handler { |
|
|
|
group := NewNodeGroup() |
|
|
|
group.SetSelector(&defaultSelector{}, |
|
|
|
WithStrategy(&RoundStrategy{}), |
|
|
|
WithFilter(&FailFilter{ |
|
|
|
MaxFails: 1, |
|
|
|
FailTimeout: 30 * time.Second, |
|
|
|
}), |
|
|
|
) |
|
|
|
|
|
|
|
for i, addr := range strings.Split(raddr, ",") { |
|
|
|
if addr == "" { |
|
|
|
continue |
|
|
|
} |
|
|
|
// We treat the remote target server as a node, so we can put them in a group,
|
|
|
|
// and perform the node selection for load balancing.
|
|
|
|
group.AddNode(Node{ |
|
|
|
ID: i + 1, |
|
|
|
Addr: addr, |
|
|
|
Host: addr, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
h := &udpDirectForwardHandler{ |
|
|
|
raddr: raddr, |
|
|
|
group: group, |
|
|
|
options: &HandlerOptions{}, |
|
|
|
} |
|
|
|
for _, opt := range opts { |
|
|
|
@ -83,45 +140,79 @@ func UDPDirectForwardHandler(raddr string, opts ...HandlerOption) Handler { |
|
|
|
func (h *udpDirectForwardHandler) Handle(conn net.Conn) { |
|
|
|
defer conn.Close() |
|
|
|
|
|
|
|
node, err := h.group.Next() |
|
|
|
if err != nil { |
|
|
|
log.Logf("[udp] %s - %s : %s", conn.RemoteAddr(), h.raddr, err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
var cc net.Conn |
|
|
|
if h.options.Chain.IsEmpty() { |
|
|
|
raddr, err := net.ResolveUDPAddr("udp", h.raddr) |
|
|
|
raddr, err := net.ResolveUDPAddr("udp", node.Addr) |
|
|
|
if err != nil { |
|
|
|
log.Logf("[udp] %s - %s : %s", conn.LocalAddr(), h.raddr, err) |
|
|
|
node.MarkDead() |
|
|
|
log.Logf("[udp] %s - %s : %s", conn.LocalAddr(), node.Addr, err) |
|
|
|
return |
|
|
|
} |
|
|
|
cc, err = net.DialUDP("udp", nil, raddr) |
|
|
|
if err != nil { |
|
|
|
log.Logf("[udp] %s - %s : %s", conn.LocalAddr(), h.raddr, err) |
|
|
|
node.MarkDead() |
|
|
|
log.Logf("[udp] %s - %s : %s", conn.LocalAddr(), node.Addr, err) |
|
|
|
return |
|
|
|
} |
|
|
|
} else { |
|
|
|
var err error |
|
|
|
cc, err = getSOCKS5UDPTunnel(h.options.Chain, nil) |
|
|
|
if err != nil { |
|
|
|
log.Logf("[udp] %s - %s : %s", conn.LocalAddr(), h.raddr, err) |
|
|
|
log.Logf("[udp] %s - %s : %s", conn.LocalAddr(), node.Addr, err) |
|
|
|
return |
|
|
|
} |
|
|
|
cc = &udpTunnelConn{Conn: cc, raddr: h.raddr} |
|
|
|
cc = &udpTunnelConn{Conn: cc, raddr: node.Addr} |
|
|
|
} |
|
|
|
|
|
|
|
defer cc.Close() |
|
|
|
node.ResetDead() |
|
|
|
|
|
|
|
log.Logf("[udp] %s <-> %s", conn.RemoteAddr(), h.raddr) |
|
|
|
log.Logf("[udp] %s <-> %s", conn.RemoteAddr(), node.Addr) |
|
|
|
transport(conn, cc) |
|
|
|
log.Logf("[udp] %s >-< %s", conn.RemoteAddr(), h.raddr) |
|
|
|
log.Logf("[udp] %s >-< %s", conn.RemoteAddr(), node.Addr) |
|
|
|
} |
|
|
|
|
|
|
|
type tcpRemoteForwardHandler struct { |
|
|
|
raddr string |
|
|
|
group *NodeGroup |
|
|
|
options *HandlerOptions |
|
|
|
} |
|
|
|
|
|
|
|
// TCPRemoteForwardHandler creates a server Handler for TCP remote port forwarding server.
|
|
|
|
// The raddr is the remote address that the server will forward to.
|
|
|
|
// NOTE: as of 2.6, remote address can be a comma-separated address list.
|
|
|
|
func TCPRemoteForwardHandler(raddr string, opts ...HandlerOption) Handler { |
|
|
|
group := NewNodeGroup() |
|
|
|
group.SetSelector(&defaultSelector{}, |
|
|
|
WithStrategy(&RoundStrategy{}), |
|
|
|
WithFilter(&FailFilter{ |
|
|
|
MaxFails: 1, |
|
|
|
FailTimeout: 30 * time.Second, |
|
|
|
}), |
|
|
|
) |
|
|
|
|
|
|
|
for i, addr := range strings.Split(raddr, ",") { |
|
|
|
if addr == "" { |
|
|
|
continue |
|
|
|
} |
|
|
|
// We treat the remote target server as a node, so we can put them in a group,
|
|
|
|
// and perform the node selection for load balancing.
|
|
|
|
group.AddNode(Node{ |
|
|
|
ID: i + 1, |
|
|
|
Addr: addr, |
|
|
|
Host: addr, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
h := &tcpRemoteForwardHandler{ |
|
|
|
raddr: raddr, |
|
|
|
group: group, |
|
|
|
options: &HandlerOptions{}, |
|
|
|
} |
|
|
|
for _, opt := range opts { |
|
|
|
@ -133,28 +224,60 @@ func TCPRemoteForwardHandler(raddr string, opts ...HandlerOption) Handler { |
|
|
|
func (h *tcpRemoteForwardHandler) Handle(conn net.Conn) { |
|
|
|
defer conn.Close() |
|
|
|
|
|
|
|
cc, err := net.DialTimeout("tcp", h.raddr, DialTimeout) |
|
|
|
node, err := h.group.Next() |
|
|
|
if err != nil { |
|
|
|
log.Logf("[rtcp] %s -> %s : %s", conn.LocalAddr(), h.raddr, err) |
|
|
|
log.Logf("[rtcp] %s - %s : %s", conn.LocalAddr(), h.raddr, err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
cc, err := net.DialTimeout("tcp", node.Addr, DialTimeout) |
|
|
|
if err != nil { |
|
|
|
node.MarkDead() |
|
|
|
log.Logf("[rtcp] %s -> %s : %s", conn.LocalAddr(), node.Addr, err) |
|
|
|
return |
|
|
|
} |
|
|
|
defer cc.Close() |
|
|
|
node.ResetDead() |
|
|
|
|
|
|
|
log.Logf("[rtcp] %s <-> %s", conn.LocalAddr(), h.raddr) |
|
|
|
log.Logf("[rtcp] %s <-> %s", conn.LocalAddr(), node.Addr) |
|
|
|
transport(cc, conn) |
|
|
|
log.Logf("[rtcp] %s >-< %s", conn.LocalAddr(), h.raddr) |
|
|
|
log.Logf("[rtcp] %s >-< %s", conn.LocalAddr(), node.Addr) |
|
|
|
} |
|
|
|
|
|
|
|
type udpRemoteForwardHandler struct { |
|
|
|
raddr string |
|
|
|
group *NodeGroup |
|
|
|
options *HandlerOptions |
|
|
|
} |
|
|
|
|
|
|
|
// UDPRemoteForwardHandler creates a server Handler for UDP remote port forwarding server.
|
|
|
|
// The raddr is the remote address that the server will forward to.
|
|
|
|
// NOTE: as of 2.6, remote address can be a comma-separated address list.
|
|
|
|
func UDPRemoteForwardHandler(raddr string, opts ...HandlerOption) Handler { |
|
|
|
group := NewNodeGroup() |
|
|
|
group.SetSelector(&defaultSelector{}, |
|
|
|
WithStrategy(&RoundStrategy{}), |
|
|
|
WithFilter(&FailFilter{ |
|
|
|
MaxFails: 1, |
|
|
|
FailTimeout: 30 * time.Second, |
|
|
|
}), |
|
|
|
) |
|
|
|
for i, addr := range strings.Split(raddr, ",") { |
|
|
|
if addr == "" { |
|
|
|
continue |
|
|
|
} |
|
|
|
// We treat the remote target server as a node, so we can put them in a group,
|
|
|
|
// and perform the node selection for load balancing.
|
|
|
|
group.AddNode(Node{ |
|
|
|
ID: i + 1, |
|
|
|
Addr: addr, |
|
|
|
Host: addr, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
h := &udpRemoteForwardHandler{ |
|
|
|
raddr: raddr, |
|
|
|
group: group, |
|
|
|
options: &HandlerOptions{}, |
|
|
|
} |
|
|
|
for _, opt := range opts { |
|
|
|
@ -166,20 +289,30 @@ func UDPRemoteForwardHandler(raddr string, opts ...HandlerOption) Handler { |
|
|
|
func (h *udpRemoteForwardHandler) Handle(conn net.Conn) { |
|
|
|
defer conn.Close() |
|
|
|
|
|
|
|
raddr, err := net.ResolveUDPAddr("udp", h.raddr) |
|
|
|
node, err := h.group.Next() |
|
|
|
if err != nil { |
|
|
|
log.Logf("[rudp] %s - %s : %s", conn.RemoteAddr(), h.raddr, err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
raddr, err := net.ResolveUDPAddr("udp", node.Addr) |
|
|
|
if err != nil { |
|
|
|
node.MarkDead() |
|
|
|
log.Logf("[rudp] %s - %s : %s", conn.RemoteAddr(), node.Addr, err) |
|
|
|
return |
|
|
|
} |
|
|
|
cc, err := net.DialUDP("udp", nil, raddr) |
|
|
|
if err != nil { |
|
|
|
log.Logf("[rudp] %s - %s : %s", conn.RemoteAddr(), h.raddr, err) |
|
|
|
node.MarkDead() |
|
|
|
log.Logf("[rudp] %s - %s : %s", conn.RemoteAddr(), node.Addr, err) |
|
|
|
return |
|
|
|
} |
|
|
|
defer cc.Close() |
|
|
|
node.ResetDead() |
|
|
|
|
|
|
|
log.Logf("[rudp] %s <-> %s", conn.RemoteAddr(), h.raddr) |
|
|
|
log.Logf("[rudp] %s <-> %s", conn.RemoteAddr(), node.Addr) |
|
|
|
transport(conn, cc) |
|
|
|
log.Logf("[rudp] %s >-< %s", conn.RemoteAddr(), h.raddr) |
|
|
|
log.Logf("[rudp] %s >-< %s", conn.RemoteAddr(), node.Addr) |
|
|
|
} |
|
|
|
|
|
|
|
type udpDirectForwardListener struct { |
|
|
|
|