mirror of
https://github.com/bolucat/Archive.git
synced 2025-12-24 13:28:37 +08:00
Update On Sat Apr 6 20:26:16 CEST 2024
This commit is contained in:
@@ -9,7 +9,6 @@ require (
|
||||
github.com/getsentry/sentry-go v0.27.0
|
||||
github.com/go-ping/ping v1.1.0
|
||||
github.com/gobwas/ws v1.3.2
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/labstack/echo/v4 v4.11.4
|
||||
github.com/prometheus/client_golang v1.19.0
|
||||
github.com/prometheus/common v0.48.0
|
||||
|
||||
@@ -110,8 +110,6 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
|
||||
@@ -57,6 +57,10 @@ func (r *Config) Validate() error {
|
||||
if len(r.TCPRemotes) == 0 && len(r.UDPRemotes) == 0 {
|
||||
return errors.New("both tcp and udp remotes are empty")
|
||||
}
|
||||
|
||||
if len(r.UDPRemotes) > 0 {
|
||||
zap.S().Warn("UDP RELAY WAS DISABLED FOR NOW, THIS FEATURE WILL BE AVAILABLE IN THE FUTURE")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -111,7 +115,7 @@ func (r *Config) defaultLabel() string {
|
||||
func (r *Config) Adjust() error {
|
||||
if r.Label == "" {
|
||||
r.Label = r.defaultLabel()
|
||||
zap.S().Warnf("label is empty, set default label:%s", r.Label)
|
||||
zap.S().Debugf("label is empty, set default label:%s", r.Label)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,22 +7,19 @@ import (
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/cmgr"
|
||||
"github.com/Ehco1996/ehco/internal/constant"
|
||||
"github.com/Ehco1996/ehco/internal/metrics"
|
||||
"github.com/Ehco1996/ehco/internal/relay/conf"
|
||||
"github.com/Ehco1996/ehco/internal/transporter"
|
||||
)
|
||||
|
||||
type Relay struct {
|
||||
Name string // unique name for all relay\
|
||||
Name string // unique name for all relay
|
||||
TransportType string
|
||||
ListenType string
|
||||
TP transporter.RelayTransporter
|
||||
|
||||
TP transporter.RelayTransporter
|
||||
|
||||
LocalTCPAddr *net.TCPAddr
|
||||
LocalUDPAddr *net.UDPAddr
|
||||
|
||||
closeTcpF func() error
|
||||
closeUdpF func() error
|
||||
closeTcpF func() error
|
||||
|
||||
cfg *conf.Config
|
||||
l *zap.SugaredLogger
|
||||
@@ -33,10 +30,6 @@ func NewRelay(cfg *conf.Config, connMgr cmgr.Cmgr) (*Relay, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
localUDPAddr, err := net.ResolveUDPAddr("udp", cfg.Listen)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r := &Relay{
|
||||
cfg: cfg,
|
||||
@@ -44,7 +37,6 @@ func NewRelay(cfg *conf.Config, connMgr cmgr.Cmgr) (*Relay, error) {
|
||||
|
||||
Name: cfg.Label,
|
||||
LocalTCPAddr: localTCPAddr,
|
||||
LocalUDPAddr: localUDPAddr,
|
||||
ListenType: cfg.ListenType,
|
||||
TransportType: cfg.TransportType,
|
||||
TP: transporter.NewRelayTransporter(cfg, connMgr),
|
||||
@@ -80,23 +72,11 @@ func (r *Relay) ListenAndServe() error {
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
if len(r.cfg.UDPRemotes) > 0 {
|
||||
go func() {
|
||||
errCh <- r.RunLocalUDPServer()
|
||||
}()
|
||||
}
|
||||
return <-errCh
|
||||
}
|
||||
|
||||
func (r *Relay) Close() {
|
||||
r.l.Infof("Close relay label: %s", r.Name)
|
||||
if r.closeUdpF != nil {
|
||||
err := r.closeUdpF()
|
||||
if err != nil {
|
||||
r.l.Errorf(err.Error())
|
||||
}
|
||||
}
|
||||
if r.closeTcpF != nil {
|
||||
err := r.closeTcpF()
|
||||
if err != nil {
|
||||
@@ -106,63 +86,19 @@ func (r *Relay) Close() {
|
||||
}
|
||||
|
||||
func (r *Relay) RunLocalTCPServer() error {
|
||||
lis, err := net.ListenTCP("tcp", r.LocalTCPAddr)
|
||||
rawServer, err := transporter.NewRawServer(r.LocalTCPAddr.String(), r.TP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer lis.Close() //nolint: errcheck
|
||||
r.closeTcpF = func() error {
|
||||
return lis.Close()
|
||||
return rawServer.Close()
|
||||
}
|
||||
r.l.Infof("Start TCP relay Server: %s", r.Name)
|
||||
for {
|
||||
c, err := lis.AcceptTCP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go func(c net.Conn) {
|
||||
remote := r.TP.GetRemote()
|
||||
metrics.CurConnectionCount.WithLabelValues(remote.Label, metrics.METRIC_CONN_TYPE_TCP).Inc()
|
||||
defer metrics.CurConnectionCount.WithLabelValues(remote.Label, metrics.METRIC_CONN_TYPE_TCP).Dec()
|
||||
if err := r.TP.HandleTCPConn(c, remote); err != nil {
|
||||
r.l.Errorf("HandleTCPConn meet error tp:%s from:%s to:%s err:%s",
|
||||
r.TransportType,
|
||||
c.RemoteAddr(), remote.Address, err)
|
||||
}
|
||||
}(c)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Relay) RunLocalUDPServer() error {
|
||||
lis, err := net.ListenUDP("udp", r.LocalUDPAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer lis.Close() //nolint: errcheck
|
||||
r.closeUdpF = func() error {
|
||||
return lis.Close()
|
||||
}
|
||||
r.l.Infof("Start UDP relay Server: %s", r.Name)
|
||||
|
||||
buf := transporter.BufferPool.Get()
|
||||
defer transporter.BufferPool.Put(buf)
|
||||
for {
|
||||
n, addr, err := lis.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bc := r.TP.GetOrCreateBufferCh(addr)
|
||||
bc.Ch <- buf[0:n]
|
||||
if !bc.Handled.Load() {
|
||||
bc.Handled.Store(true)
|
||||
go r.TP.HandleUDPConn(bc.UDPAddr, lis)
|
||||
}
|
||||
}
|
||||
return rawServer.ListenAndServe()
|
||||
}
|
||||
|
||||
func (r *Relay) RunLocalMTCPServer() error {
|
||||
tp := r.TP.(*transporter.Raw)
|
||||
tp := r.TP.(*transporter.RawClient)
|
||||
mTCPServer := transporter.NewMTCPServer(r.LocalTCPAddr.String(), tp, r.l.Named("MTCPServer"))
|
||||
r.closeTcpF = func() error {
|
||||
return mTCPServer.Close()
|
||||
@@ -172,7 +108,7 @@ func (r *Relay) RunLocalMTCPServer() error {
|
||||
}
|
||||
|
||||
func (r *Relay) RunLocalWSServer() error {
|
||||
tp := r.TP.(*transporter.Raw)
|
||||
tp := r.TP.(*transporter.RawClient)
|
||||
wsServer := transporter.NewWSServer(r.LocalTCPAddr.String(), tp, r.l.Named("WSServer"))
|
||||
r.closeTcpF = func() error {
|
||||
return wsServer.Close()
|
||||
@@ -182,8 +118,8 @@ func (r *Relay) RunLocalWSServer() error {
|
||||
}
|
||||
|
||||
func (r *Relay) RunLocalWSSServer() error {
|
||||
tp := r.TP.(*transporter.Raw)
|
||||
wssServer := transporter.NewWSSServer(r.LocalTCPAddr.String(), tp, r.l.Named("NewWSSServer"))
|
||||
tp := r.TP.(*transporter.RawClient)
|
||||
wssServer := transporter.NewWSSServer(r.LocalTCPAddr.String(), tp, r.l.Named("WSSServer"))
|
||||
r.closeTcpF = func() error {
|
||||
return wssServer.Close()
|
||||
}
|
||||
@@ -192,7 +128,7 @@ func (r *Relay) RunLocalWSSServer() error {
|
||||
}
|
||||
|
||||
func (r *Relay) RunLocalMWSSServer() error {
|
||||
tp := r.TP.(*transporter.Raw)
|
||||
tp := r.TP.(*transporter.RawClient)
|
||||
mwssServer := transporter.NewMWSSServer(r.LocalTCPAddr.String(), tp, r.l.Named("MWSSServer"))
|
||||
r.closeTcpF = func() error {
|
||||
return mwssServer.Close()
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package transporter
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/constant"
|
||||
)
|
||||
|
||||
@@ -51,17 +47,3 @@ func (bp *BytePool) Put(b []byte) {
|
||||
// buffer didn't go back into pool, just discard
|
||||
}
|
||||
}
|
||||
|
||||
type BufferCh struct {
|
||||
Ch chan []byte
|
||||
Handled atomic.Bool
|
||||
UDPAddr *net.UDPAddr
|
||||
}
|
||||
|
||||
func newudpBufferCh(clientUDPAddr *net.UDPAddr) *BufferCh {
|
||||
return &BufferCh{
|
||||
Ch: make(chan []byte, 100),
|
||||
Handled: atomic.Bool{},
|
||||
UDPAddr: clientUDPAddr,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,6 @@ import (
|
||||
|
||||
// RelayTransporter
|
||||
type RelayTransporter interface {
|
||||
// UDP相关
|
||||
GetOrCreateBufferCh(uaddr *net.UDPAddr) *BufferCh
|
||||
HandleUDPConn(uaddr *net.UDPAddr, local *net.UDPConn)
|
||||
|
||||
// TCP相关
|
||||
dialRemote(remote *lb.Node) (net.Conn, error)
|
||||
HandleTCPConn(c net.Conn, remote *lb.Node) error
|
||||
GetRemote() *lb.Node
|
||||
@@ -30,34 +25,18 @@ func NewRelayTransporter(cfg *conf.Config, connMgr cmgr.Cmgr) RelayTransporter {
|
||||
Label: fmt.Sprintf("%s-%s", cfg.Label, addr),
|
||||
}
|
||||
}
|
||||
udpNodeList := make([]*lb.Node, len(cfg.UDPRemotes))
|
||||
for idx, addr := range cfg.UDPRemotes {
|
||||
udpNodeList[idx] = &lb.Node{
|
||||
Address: addr,
|
||||
Label: fmt.Sprintf("%s-%s", cfg.Label, addr),
|
||||
}
|
||||
}
|
||||
raw := newRaw(cfg.Label, lb.NewRoundRobin(tcpNodeList), lb.NewRoundRobin(udpNodeList), connMgr)
|
||||
|
||||
raw := newRawClient(cfg.Label, lb.NewRoundRobin(tcpNodeList), connMgr)
|
||||
switch cfg.TransportType {
|
||||
case constant.Transport_RAW:
|
||||
return raw
|
||||
case constant.Transport_WS:
|
||||
return &Ws{Raw: raw}
|
||||
return newWsClient(raw)
|
||||
case constant.Transport_WSS:
|
||||
return &Wss{Raw: raw}
|
||||
return newWSSClient(raw)
|
||||
case constant.Transport_MWSS:
|
||||
logger := raw.l.Named("MWSSClient")
|
||||
mWSSClient := NewMWSSClient(logger)
|
||||
mwss := &Mwss{mtp: NewSmuxTransporter(logger, mWSSClient.InitNewSession)}
|
||||
mwss.Raw = raw
|
||||
return mwss
|
||||
return newMWSSClient(raw)
|
||||
case constant.Transport_MTCP:
|
||||
logger := raw.l.Named("MTCPClient")
|
||||
mTCPClient := NewMTCPClient(logger)
|
||||
mtcp := &MTCP{mtp: NewSmuxTransporter(logger, mTCPClient.InitNewSession)}
|
||||
mtcp.Raw = raw
|
||||
return mtcp
|
||||
return newMTCPClient(raw)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -56,7 +56,8 @@ func (sm *SessionWithMetrics) canCloseSession(remoteAddr string, l *zap.SugaredL
|
||||
return true
|
||||
}
|
||||
|
||||
func NewSmuxTransporter(l *zap.SugaredLogger,
|
||||
func NewSmuxTransporter(
|
||||
l *zap.SugaredLogger,
|
||||
initSessionF func(ctx context.Context, addr string) (*smux.Session, error),
|
||||
) *smuxTransporter {
|
||||
tr := &smuxTransporter{
|
||||
@@ -2,9 +2,7 @@
|
||||
package transporter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
@@ -16,134 +14,28 @@ import (
|
||||
"github.com/Ehco1996/ehco/pkg/lb"
|
||||
)
|
||||
|
||||
type Raw struct {
|
||||
type RawClient struct {
|
||||
relayLabel string
|
||||
|
||||
// TCP
|
||||
cmgr cmgr.Cmgr
|
||||
tCPRemotes lb.RoundRobin
|
||||
|
||||
// UDP todo refactor udp relay
|
||||
udpmu sync.Mutex
|
||||
uDPRemotes lb.RoundRobin
|
||||
uDPBufferChMap map[string]*BufferCh
|
||||
|
||||
l *zap.SugaredLogger
|
||||
l *zap.SugaredLogger
|
||||
}
|
||||
|
||||
func newRaw(
|
||||
relayLabel string,
|
||||
tcpRemotes, udpRemotes lb.RoundRobin,
|
||||
cmgr cmgr.Cmgr,
|
||||
) *Raw {
|
||||
r := &Raw{
|
||||
cmgr: cmgr,
|
||||
|
||||
relayLabel: relayLabel,
|
||||
tCPRemotes: tcpRemotes,
|
||||
uDPRemotes: udpRemotes,
|
||||
uDPBufferChMap: make(map[string]*BufferCh),
|
||||
|
||||
l: zap.S().Named(relayLabel),
|
||||
func newRawClient(relayLabel string, tcpRemotes lb.RoundRobin, cmgr cmgr.Cmgr) *RawClient {
|
||||
r := &RawClient{
|
||||
cmgr: cmgr,
|
||||
relayLabel: relayLabel,
|
||||
tCPRemotes: tcpRemotes,
|
||||
l: zap.S().Named(relayLabel),
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (raw *Raw) GetOrCreateBufferCh(uaddr *net.UDPAddr) *BufferCh {
|
||||
raw.udpmu.Lock()
|
||||
defer raw.udpmu.Unlock()
|
||||
|
||||
bc, found := raw.uDPBufferChMap[uaddr.String()]
|
||||
if !found {
|
||||
bc := newudpBufferCh(uaddr)
|
||||
raw.uDPBufferChMap[uaddr.String()] = bc
|
||||
return bc
|
||||
}
|
||||
return bc
|
||||
}
|
||||
|
||||
func (raw *Raw) HandleUDPConn(uaddr *net.UDPAddr, local *net.UDPConn) {
|
||||
remote := raw.uDPRemotes.Next()
|
||||
metrics.CurConnectionCount.WithLabelValues(remote.Label, metrics.METRIC_CONN_TYPE_UDP).Inc()
|
||||
defer metrics.CurConnectionCount.WithLabelValues(remote.Label, metrics.METRIC_CONN_TYPE_UDP).Dec()
|
||||
|
||||
bc := raw.GetOrCreateBufferCh(uaddr)
|
||||
remoteUdp, _ := net.ResolveUDPAddr("udp", remote.Address)
|
||||
rc, err := net.DialUDP("udp", nil, remoteUdp)
|
||||
if err != nil {
|
||||
raw.l.Error(err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
rc.Close()
|
||||
raw.udpmu.Lock()
|
||||
delete(raw.uDPBufferChMap, uaddr.String())
|
||||
raw.udpmu.Unlock()
|
||||
}()
|
||||
|
||||
raw.l.Infof("HandleUDPConn from %s to %s", local.LocalAddr().String(), remote.Label)
|
||||
|
||||
buf := BufferPool.Get()
|
||||
defer BufferPool.Put(buf)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
defer cancel()
|
||||
for {
|
||||
_ = rc.SetDeadline(time.Now().Add(constant.IdleTimeOut))
|
||||
i, err := rc.Read(buf)
|
||||
if err != nil {
|
||||
raw.l.Error(err)
|
||||
break
|
||||
}
|
||||
metrics.NetWorkTransmitBytes.WithLabelValues(
|
||||
remote.Label, metrics.METRIC_CONN_TYPE_UDP, metrics.METRIC_CONN_FLOW_READ,
|
||||
).Add(float64(i))
|
||||
|
||||
if _, err := local.WriteToUDP(buf[0:i], uaddr); err != nil {
|
||||
raw.l.Error(err)
|
||||
break
|
||||
}
|
||||
metrics.NetWorkTransmitBytes.WithLabelValues(
|
||||
remote.Label, metrics.METRIC_CONN_TYPE_UDP, metrics.METRIC_CONN_FLOW_WRITE,
|
||||
).Add(float64(i))
|
||||
}
|
||||
}()
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case b := <-bc.Ch:
|
||||
// read from local udp listener ch
|
||||
metrics.NetWorkTransmitBytes.WithLabelValues(
|
||||
remote.Label, metrics.METRIC_CONN_TYPE_UDP, metrics.METRIC_CONN_FLOW_READ,
|
||||
).Add(float64(len(b)))
|
||||
|
||||
_ = rc.SetDeadline(time.Now().Add(constant.IdleTimeOut))
|
||||
if _, err := rc.Write(b); err != nil {
|
||||
raw.l.Error(err)
|
||||
return
|
||||
}
|
||||
metrics.NetWorkTransmitBytes.WithLabelValues(
|
||||
remote.Label, metrics.METRIC_CONN_TYPE_UDP, metrics.METRIC_CONN_FLOW_WRITE,
|
||||
).Add(float64(len(b)))
|
||||
}
|
||||
}()
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func (raw *Raw) GetRemote() *lb.Node {
|
||||
func (raw *RawClient) GetRemote() *lb.Node {
|
||||
return raw.tCPRemotes.Next()
|
||||
}
|
||||
|
||||
func (raw *Raw) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
func (raw *RawClient) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
t1 := time.Now()
|
||||
d := net.Dialer{Timeout: constant.DialTimeOut}
|
||||
rc, err := d.Dial("tcp", remote.Address)
|
||||
@@ -156,8 +48,7 @@ func (raw *Raw) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
func (raw *Raw) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
// todo refactor metrics to server
|
||||
func (raw *RawClient) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
metrics.CurConnectionCount.WithLabelValues(remote.Label, metrics.METRIC_CONN_TYPE_TCP).Inc()
|
||||
defer metrics.CurConnectionCount.WithLabelValues(remote.Label, metrics.METRIC_CONN_TYPE_TCP).Dec()
|
||||
|
||||
@@ -172,3 +63,44 @@ func (raw *Raw) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
defer raw.cmgr.RemoveConnection(relayConn)
|
||||
return relayConn.Transport(remote.Label)
|
||||
}
|
||||
|
||||
type RawServer struct {
|
||||
rtp RelayTransporter
|
||||
lis *net.TCPListener
|
||||
l *zap.SugaredLogger
|
||||
}
|
||||
|
||||
func NewRawServer(addr string, rtp RelayTransporter) (*RawServer, error) {
|
||||
tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lis, err := net.ListenTCP("tcp", tcpAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &RawServer{lis: lis, rtp: rtp}, nil
|
||||
}
|
||||
|
||||
func (s *RawServer) Close() error {
|
||||
return s.lis.Close()
|
||||
}
|
||||
|
||||
func (s *RawServer) ListenAndServe() error {
|
||||
for {
|
||||
c, err := s.lis.AcceptTCP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func(c net.Conn) {
|
||||
remote := s.rtp.GetRemote()
|
||||
metrics.CurConnectionCount.WithLabelValues(remote.Label, metrics.METRIC_CONN_TYPE_TCP).Inc()
|
||||
defer metrics.CurConnectionCount.WithLabelValues(remote.Label, metrics.METRIC_CONN_TYPE_TCP).Dec()
|
||||
if err := s.rtp.HandleTCPConn(c, remote); err != nil {
|
||||
s.l.Errorf("HandleTCPConn meet error tp:%s from:%s to:%s err:%s",
|
||||
s.rtp,
|
||||
c.RemoteAddr(), remote.Address, err)
|
||||
}
|
||||
}(c)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,12 +15,37 @@ import (
|
||||
"github.com/Ehco1996/ehco/pkg/lb"
|
||||
)
|
||||
|
||||
type MTCP struct {
|
||||
*Raw
|
||||
mtp *smuxTransporter
|
||||
type MTCPClient struct {
|
||||
*RawClient
|
||||
dialer *net.Dialer
|
||||
mtp *smuxTransporter
|
||||
}
|
||||
|
||||
func (s *MTCP) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
func newMTCPClient(raw *RawClient) *MTCPClient {
|
||||
dialer := &net.Dialer{Timeout: constant.DialTimeOut}
|
||||
c := &MTCPClient{dialer: dialer, RawClient: raw}
|
||||
mtp := NewSmuxTransporter(raw.l.Named("mtcp"), c.initNewSession)
|
||||
c.mtp = mtp
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *MTCPClient) initNewSession(ctx context.Context, addr string) (*smux.Session, error) {
|
||||
rc, err := c.dialer.Dial("tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// stream multiplex
|
||||
cfg := smux.DefaultConfig()
|
||||
cfg.KeepAliveDisabled = true
|
||||
session, err := smux.Client(rc, cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.l.Infof("init new session to: %s", rc.RemoteAddr())
|
||||
return session, nil
|
||||
}
|
||||
|
||||
func (s *MTCPClient) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
t1 := time.Now()
|
||||
mtcpc, err := s.mtp.Dial(context.TODO(), remote.Address)
|
||||
if err != nil {
|
||||
@@ -32,7 +57,7 @@ func (s *MTCP) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
return mtcpc, nil
|
||||
}
|
||||
|
||||
func (s *MTCP) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
func (s *MTCPClient) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
clonedRemote := remote.Clone()
|
||||
mtcpc, err := s.dialRemote(clonedRemote)
|
||||
if err != nil {
|
||||
@@ -46,7 +71,7 @@ func (s *MTCP) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
}
|
||||
|
||||
type MTCPServer struct {
|
||||
raw *Raw
|
||||
raw *RawClient
|
||||
listenAddr string
|
||||
listener net.Listener
|
||||
l *zap.SugaredLogger
|
||||
@@ -55,7 +80,7 @@ type MTCPServer struct {
|
||||
connChan chan net.Conn
|
||||
}
|
||||
|
||||
func NewMTCPServer(listenAddr string, raw *Raw, l *zap.SugaredLogger) *MTCPServer {
|
||||
func NewMTCPServer(listenAddr string, raw *RawClient, l *zap.SugaredLogger) *MTCPServer {
|
||||
return &MTCPServer{
|
||||
l: l,
|
||||
raw: raw,
|
||||
@@ -138,28 +163,3 @@ func (s *MTCPServer) ListenAndServe() error {
|
||||
func (s *MTCPServer) Close() error {
|
||||
return s.listener.Close()
|
||||
}
|
||||
|
||||
type MTCPClient struct {
|
||||
l *zap.SugaredLogger
|
||||
dialer *net.Dialer
|
||||
}
|
||||
|
||||
func NewMTCPClient(l *zap.SugaredLogger) *MTCPClient {
|
||||
return &MTCPClient{l: l, dialer: &net.Dialer{Timeout: constant.DialTimeOut}}
|
||||
}
|
||||
|
||||
func (c *MTCPClient) InitNewSession(ctx context.Context, addr string) (*smux.Session, error) {
|
||||
rc, err := c.dialer.Dial("tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// stream multiplex
|
||||
cfg := smux.DefaultConfig()
|
||||
cfg.KeepAliveDisabled = true
|
||||
session, err := smux.Client(rc, cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.l.Infof("init new session to: %s", rc.RemoteAddr())
|
||||
return session, nil
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gobwas/ws"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/conn"
|
||||
@@ -17,14 +17,18 @@ import (
|
||||
"github.com/Ehco1996/ehco/pkg/lb"
|
||||
)
|
||||
|
||||
type Ws struct {
|
||||
*Raw
|
||||
type WsClient struct {
|
||||
*RawClient
|
||||
}
|
||||
|
||||
func (s *Ws) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
func newWsClient(raw *RawClient) *WsClient {
|
||||
return &WsClient{RawClient: raw}
|
||||
}
|
||||
|
||||
func (s *WsClient) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
t1 := time.Now()
|
||||
d := ws.Dialer{Timeout: constant.DialTimeOut}
|
||||
wsc, _, _, err := d.Dial(context.TODO(), remote.Address+"/ws/")
|
||||
wsc, _, _, err := d.Dial(context.TODO(), remote.Address+"/handshake/")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -34,7 +38,7 @@ func (s *Ws) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
return wsc, nil
|
||||
}
|
||||
|
||||
func (s *Ws) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
func (s *WsClient) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
clonedRemote := remote.Clone()
|
||||
wsc, err := s.dialRemote(clonedRemote)
|
||||
if err != nil {
|
||||
@@ -50,30 +54,32 @@ func (s *Ws) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
}
|
||||
|
||||
type WSServer struct {
|
||||
raw *Raw
|
||||
l *zap.SugaredLogger
|
||||
raw *RawClient
|
||||
e *echo.Echo
|
||||
httpServer *http.Server
|
||||
l *zap.SugaredLogger
|
||||
}
|
||||
|
||||
func NewWSServer(listenAddr string, raw *Raw, l *zap.SugaredLogger) *WSServer {
|
||||
s := &WSServer{raw: raw, l: l}
|
||||
mux := mux.NewRouter()
|
||||
mux.HandleFunc("/", web.MakeIndexF())
|
||||
mux.HandleFunc("/ws/", s.HandleRequest)
|
||||
s.httpServer = &http.Server{
|
||||
Addr: listenAddr,
|
||||
ReadHeaderTimeout: 30 * time.Second,
|
||||
Handler: mux,
|
||||
func NewWSServer(listenAddr string, raw *RawClient, l *zap.SugaredLogger) *WSServer {
|
||||
s := &WSServer{
|
||||
l: l,
|
||||
raw: raw,
|
||||
httpServer: &http.Server{Addr: listenAddr, ReadHeaderTimeout: 30 * time.Second},
|
||||
}
|
||||
e := web.NewEchoServer()
|
||||
e.GET("/", echo.WrapHandler(web.MakeIndexF()))
|
||||
e.GET("/handshake/", echo.WrapHandler(http.HandlerFunc(s.HandleRequest)))
|
||||
s.e = e
|
||||
s.httpServer.Handler = e
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *WSServer) ListenAndServe() error {
|
||||
return s.httpServer.ListenAndServe()
|
||||
return s.e.StartServer(s.httpServer)
|
||||
}
|
||||
|
||||
func (s *WSServer) Close() error {
|
||||
return s.httpServer.Close()
|
||||
return s.e.Close()
|
||||
}
|
||||
|
||||
func (s *WSServer) HandleRequest(w http.ResponseWriter, req *http.Request) {
|
||||
@@ -81,7 +87,6 @@ func (s *WSServer) HandleRequest(w http.ResponseWriter, req *http.Request) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
remote := s.raw.GetRemote()
|
||||
if err := s.raw.HandleTCPConn(wsc, remote); err != nil {
|
||||
s.l.Errorf("HandleTCPConn meet error from:%s to:%s err:%s", wsc.RemoteAddr(), remote.Address, err)
|
||||
|
||||
@@ -3,31 +3,32 @@ package transporter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gobwas/ws"
|
||||
"github.com/gorilla/mux"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/conn"
|
||||
"github.com/Ehco1996/ehco/internal/metrics"
|
||||
mytls "github.com/Ehco1996/ehco/internal/tls"
|
||||
"github.com/Ehco1996/ehco/internal/web"
|
||||
"github.com/Ehco1996/ehco/pkg/lb"
|
||||
)
|
||||
|
||||
type Wss struct {
|
||||
*Raw
|
||||
type WSSClient struct {
|
||||
WsClient
|
||||
}
|
||||
|
||||
func (s *Wss) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
func newWSSClient(raw *RawClient) *WSSClient {
|
||||
return &WSSClient{*newWsClient(raw)}
|
||||
}
|
||||
|
||||
func (s *WSSClient) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
t1 := time.Now()
|
||||
d := ws.Dialer{TLSConfig: mytls.DefaultTLSConfig}
|
||||
wssc, _, _, err := d.Dial(context.TODO(), remote.Address+"/wss/")
|
||||
wssc, _, _, err := d.Dial(context.TODO(), remote.Address+"/handshake/")
|
||||
if err != nil {
|
||||
println("wss called", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
latency := time.Since(t1)
|
||||
@@ -36,7 +37,7 @@ func (s *Wss) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
return wssc, nil
|
||||
}
|
||||
|
||||
func (s *Wss) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
func (s *WSSClient) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
clonedRemote := remote.Clone()
|
||||
wssc, err := s.dialRemote(clonedRemote)
|
||||
if err != nil {
|
||||
@@ -50,48 +51,14 @@ func (s *Wss) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
return relayConn.Transport(remote.Label)
|
||||
}
|
||||
|
||||
type WSSServer struct {
|
||||
raw *Raw
|
||||
l *zap.SugaredLogger
|
||||
httpServer *http.Server
|
||||
}
|
||||
type WSSServer struct{ WSServer }
|
||||
|
||||
func NewWSSServer(listenAddr string, raw *Raw, l *zap.SugaredLogger) *WSSServer {
|
||||
s := &WSSServer{raw: raw, l: l}
|
||||
mux := mux.NewRouter()
|
||||
mux.HandleFunc("/", web.MakeIndexF())
|
||||
mux.HandleFunc("/wss/", s.HandleRequest)
|
||||
|
||||
s.httpServer = &http.Server{
|
||||
Handler: mux,
|
||||
Addr: listenAddr,
|
||||
ReadHeaderTimeout: 30 * time.Second,
|
||||
TLSConfig: mytls.DefaultTLSConfig,
|
||||
}
|
||||
return s
|
||||
func NewWSSServer(listenAddr string, raw *RawClient, l *zap.SugaredLogger) *WSSServer {
|
||||
wsServer := NewWSServer(listenAddr, raw, l)
|
||||
return &WSSServer{WSServer: *wsServer}
|
||||
}
|
||||
|
||||
func (s *WSSServer) ListenAndServe() error {
|
||||
lis, err := net.Listen("tcp", s.httpServer.Addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer lis.Close()
|
||||
return s.httpServer.Serve(tls.NewListener(lis, s.httpServer.TLSConfig))
|
||||
}
|
||||
|
||||
func (s *WSSServer) Close() error {
|
||||
return s.httpServer.Close()
|
||||
}
|
||||
|
||||
func (s *WSSServer) HandleRequest(w http.ResponseWriter, req *http.Request) {
|
||||
wsc, _, _, err := ws.UpgradeHTTP(req, w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
remote := s.raw.GetRemote()
|
||||
if err := s.raw.HandleTCPConn(wsc, remote); err != nil {
|
||||
s.l.Errorf("HandleTCPConn meet error from:%s to:%s err:%s", wsc.RemoteAddr(), remote.Address, err)
|
||||
}
|
||||
s.httpServer.TLSConfig = mytls.DefaultTLSConfig
|
||||
return s.WSServer.ListenAndServe()
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gobwas/ws"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/xtaci/smux"
|
||||
"go.uber.org/zap"
|
||||
|
||||
@@ -21,14 +21,39 @@ import (
|
||||
"github.com/Ehco1996/ehco/pkg/lb"
|
||||
)
|
||||
|
||||
type Mwss struct {
|
||||
*Raw
|
||||
mtp *smuxTransporter
|
||||
type MWSSClient struct {
|
||||
*RawClient
|
||||
dialer *ws.Dialer
|
||||
mtp *smuxTransporter
|
||||
}
|
||||
|
||||
func (s *Mwss) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
func newMWSSClient(raw *RawClient) *MWSSClient {
|
||||
dialer := &ws.Dialer{TLSConfig: mytls.DefaultTLSConfig, Timeout: constant.DialTimeOut}
|
||||
c := &MWSSClient{dialer: dialer, RawClient: raw}
|
||||
mtp := NewSmuxTransporter(raw.l.Named("mwss"), c.initNewSession)
|
||||
c.mtp = mtp
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *MWSSClient) initNewSession(ctx context.Context, addr string) (*smux.Session, error) {
|
||||
rc, _, _, err := c.dialer.Dial(ctx, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// stream multiplex
|
||||
cfg := smux.DefaultConfig()
|
||||
cfg.KeepAliveDisabled = true
|
||||
session, err := smux.Client(rc, cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.l.Infof("init new session to: %s", rc.RemoteAddr())
|
||||
return session, nil
|
||||
}
|
||||
|
||||
func (s *MWSSClient) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
t1 := time.Now()
|
||||
mwssc, err := s.mtp.Dial(context.TODO(), remote.Address+"/mwss/")
|
||||
mwssc, err := s.mtp.Dial(context.TODO(), remote.Address+"/handshake/")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -39,7 +64,7 @@ func (s *Mwss) dialRemote(remote *lb.Node) (net.Conn, error) {
|
||||
return mwssc, nil
|
||||
}
|
||||
|
||||
func (s *Mwss) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
func (s *MWSSClient) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
clonedRemote := remote.Clone()
|
||||
mwsc, err := s.dialRemote(clonedRemote)
|
||||
if err != nil {
|
||||
@@ -53,7 +78,7 @@ func (s *Mwss) HandleTCPConn(c net.Conn, remote *lb.Node) error {
|
||||
}
|
||||
|
||||
type MWSSServer struct {
|
||||
raw *Raw
|
||||
raw *RawClient
|
||||
httpServer *http.Server
|
||||
l *zap.SugaredLogger
|
||||
|
||||
@@ -61,7 +86,7 @@ type MWSSServer struct {
|
||||
errChan chan error
|
||||
}
|
||||
|
||||
func NewMWSSServer(listenAddr string, raw *Raw, l *zap.SugaredLogger) *MWSSServer {
|
||||
func NewMWSSServer(listenAddr string, raw *RawClient, l *zap.SugaredLogger) *MWSSServer {
|
||||
s := &MWSSServer{
|
||||
raw: raw,
|
||||
l: l,
|
||||
@@ -69,12 +94,12 @@ func NewMWSSServer(listenAddr string, raw *Raw, l *zap.SugaredLogger) *MWSSServe
|
||||
connChan: make(chan net.Conn, 1024),
|
||||
}
|
||||
|
||||
mux := mux.NewRouter()
|
||||
mux.Handle("/", web.MakeIndexF())
|
||||
mux.Handle("/mwss/", http.HandlerFunc(s.HandleRequest))
|
||||
e := web.NewEchoServer()
|
||||
e.GET("/", echo.WrapHandler(web.MakeIndexF()))
|
||||
e.GET("/handshake/", echo.WrapHandler(http.HandlerFunc(s.HandleRequest)))
|
||||
s.httpServer = &http.Server{
|
||||
Addr: listenAddr,
|
||||
Handler: mux,
|
||||
Handler: e,
|
||||
TLSConfig: mytls.DefaultTLSConfig,
|
||||
ReadHeaderTimeout: 30 * time.Second,
|
||||
}
|
||||
@@ -154,32 +179,3 @@ func (s *MWSSServer) Accept() (conn net.Conn, err error) {
|
||||
func (s *MWSSServer) Close() error {
|
||||
return s.httpServer.Close()
|
||||
}
|
||||
|
||||
type MWSSClient struct {
|
||||
dialer *ws.Dialer
|
||||
l *zap.SugaredLogger
|
||||
}
|
||||
|
||||
func NewMWSSClient(l *zap.SugaredLogger) *MWSSClient {
|
||||
dialer := &ws.Dialer{TLSConfig: mytls.DefaultTLSConfig, Timeout: constant.DialTimeOut}
|
||||
return &MWSSClient{
|
||||
dialer: dialer,
|
||||
l: l,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *MWSSClient) InitNewSession(ctx context.Context, addr string) (*smux.Session, error) {
|
||||
rc, _, _, err := c.dialer.Dial(ctx, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// stream multiplex
|
||||
cfg := smux.DefaultConfig()
|
||||
cfg.KeepAliveDisabled = true
|
||||
session, err := smux.Client(rc, cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.l.Infof("init new session to: %s", rc.RemoteAddr())
|
||||
return session, nil
|
||||
}
|
||||
@@ -49,10 +49,7 @@ func NewServer(cfg *config.Config, relayReloader reloader.Reloader, connMgr cmgr
|
||||
for _, temp := range templates.Templates() {
|
||||
l.Debug("template name: ", temp.Name())
|
||||
}
|
||||
e := echo.New()
|
||||
e.Debug = true
|
||||
e.HidePort = true
|
||||
e.HideBanner = true
|
||||
e := NewEchoServer()
|
||||
e.Use(NginxLogMiddleware(l))
|
||||
e.Renderer = &echoTemplate{templates: templates}
|
||||
if cfg.WebToken != "" {
|
||||
|
||||
11
echo/internal/web/utils.go
Normal file
11
echo/internal/web/utils.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package web
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
func NewEchoServer() *echo.Echo {
|
||||
e := echo.New()
|
||||
e.Debug = true
|
||||
e.HidePort = true
|
||||
e.HideBanner = true
|
||||
return e
|
||||
}
|
||||
@@ -148,11 +148,11 @@ func TestRelayOverRaw(t *testing.T) {
|
||||
t.Log("test tcp done!")
|
||||
|
||||
// test udp
|
||||
res = echo.SendUdpMsg(msg, RAW_LISTEN)
|
||||
if string(res) != string(msg) {
|
||||
t.Fatal(res)
|
||||
}
|
||||
t.Log("test udp done!")
|
||||
// res = echo.SendUdpMsg(msg, RAW_LISTEN)
|
||||
// if string(res) != string(msg) {
|
||||
// t.Fatal(res)
|
||||
// }
|
||||
// t.Log("test udp done!")
|
||||
}
|
||||
|
||||
func TestRelayWithDeadline(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user