Update On Sat Jun 15 20:30:11 CEST 2024

This commit is contained in:
github-action[bot]
2024-06-15 20:30:12 +02:00
parent b730d8852b
commit b9b5aadb6c
68 changed files with 1297 additions and 628 deletions

View File

@@ -9,7 +9,7 @@
"listen": "127.0.0.1:1234",
"listen_type": "raw",
"transport_type": "raw",
"label": "relay1",
"label": "iperf3",
"tcp_remotes": ["0.0.0.0:5201"]
}
]

View File

@@ -116,7 +116,7 @@ func MustStartComponents(mainCtx context.Context, cfg *config.Config) {
}()
if cfg.NeedStartWebServer() {
webS, err := web.NewServer(cfg, rs, rs.Cmgr)
webS, err := web.NewServer(cfg, rs, rs, rs.Cmgr)
if err != nil {
cliLogger.Fatalf("NewWebServer meet err=%s", err.Error())
}

View File

@@ -0,0 +1,14 @@
package glue
import (
"context"
)
type Reloader interface {
Reload(force bool) error
}
type HealthChecker interface {
// get relay by ID and check the connection health
HealthCheck(ctx context.Context, RelayID string) error
}

View File

@@ -0,0 +1,19 @@
package relay
import (
"context"
"fmt"
"github.com/Ehco1996/ehco/internal/glue"
)
var _ glue.HealthChecker = (*Server)(nil)
func (r *Server) HealthCheck(ctx context.Context, relayID string) error {
rs, ok := r.relayM.Load(relayID)
if !ok {
return fmt.Errorf("label for relay: %s not found,can not health check", relayID)
}
inner, _ := rs.(*Relay)
return inner.relayServer.HealthCheck(ctx)
}

View File

@@ -1,13 +1,13 @@
package relay
import (
"github.com/Ehco1996/ehco/internal/glue"
"github.com/Ehco1996/ehco/internal/relay/conf"
"github.com/Ehco1996/ehco/internal/reloader"
"go.uber.org/zap"
)
// make sure Server implements the reloader.Reloader interface
var _ reloader.Reloader = (*Server)(nil)
var _ glue.Reloader = (*Server)(nil)
func (s *Server) Reload(force bool) error {
// k:name v: *Config

View File

@@ -1,5 +0,0 @@
package reloader
type Reloader interface {
Reload(force bool) error
}

View File

@@ -24,15 +24,21 @@ type baseTransporter struct {
cmgr cmgr.Cmgr
tCPRemotes lb.RoundRobin
relayer RelayClient
}
func NewBaseTransporter(cfg *conf.Config, cmgr cmgr.Cmgr) *baseTransporter {
func NewBaseTransporter(cfg *conf.Config, cmgr cmgr.Cmgr) (*baseTransporter, error) {
relayer, err := newRelayClient(cfg)
if err != nil {
return nil, err
}
return &baseTransporter{
cfg: cfg,
cmgr: cmgr,
tCPRemotes: cfg.ToTCPRemotes(),
l: zap.S().Named(cfg.GetLoggerName()),
}
relayer: relayer,
}, nil
}
func (b *baseTransporter) GetTCPListenAddr() (*net.TCPAddr, error) {
@@ -94,3 +100,7 @@ func (b *baseTransporter) RelayTCPConn(c net.Conn, handshakeF TCPHandShakeF) err
defer b.cmgr.RemoveConnection(relayConn)
return relayConn.Transport(remote.Label)
}
func (b *baseTransporter) HealthCheck(ctx context.Context) error {
return b.relayer.HealthCheck(ctx, b.GetRemote().Clone())
}

View File

@@ -1,6 +1,8 @@
package transporter
import (
"context"
"fmt"
"net"
"github.com/Ehco1996/ehco/internal/cmgr"
@@ -12,39 +14,45 @@ import (
type TCPHandShakeF func(remote *lb.Node) (net.Conn, error)
type RelayClient interface {
HealthCheck(ctx context.Context, remote *lb.Node) error
TCPHandShake(remote *lb.Node) (net.Conn, error)
RelayTCPConn(c net.Conn, handshakeF TCPHandShakeF) error
}
func newRelayClient(base *baseTransporter) (RelayClient, error) {
switch base.cfg.TransportType {
func newRelayClient(cfg *conf.Config) (RelayClient, error) {
switch cfg.TransportType {
case constant.RelayTypeRaw:
return newRawClient(base)
case constant.RelayTypeWS:
return newWsClient(base)
case constant.RelayTypeMWS:
return newMwsClient(base)
case constant.RelayTypeWSS:
return newWssClient(base)
case constant.RelayTypeMWSS:
return newMwssClient(base)
return newRawClient(cfg)
case constant.RelayTypeMTCP:
return newMtcpClient(base)
return newMtcpClient(cfg)
case constant.RelayTypeWS:
return newWsClient(cfg)
case constant.RelayTypeMWS:
return newMwsClient(cfg)
case constant.RelayTypeWSS:
return newWssClient(cfg)
case constant.RelayTypeMWSS:
return newMwssClient(cfg)
default:
panic("unsupported transport type" + base.cfg.TransportType)
return nil, fmt.Errorf("unsupported transport type" + cfg.TransportType)
}
}
type RelayServer interface {
ListenAndServe() error
Close() error
HealthCheck(ctx context.Context) error
}
func NewRelayServer(cfg *conf.Config, cmgr cmgr.Cmgr) (RelayServer, error) {
base := NewBaseTransporter(cfg, cmgr)
base, err := NewBaseTransporter(cfg, cmgr)
if err != nil {
return nil, err
}
switch cfg.ListenType {
case constant.RelayTypeRaw:
return newRawServer(base)
case constant.RelayTypeMTCP:
return newMtcpServer(base)
case constant.RelayTypeWS:
return newWsServer(base)
case constant.RelayTypeMWS:
@@ -53,8 +61,6 @@ func NewRelayServer(cfg *conf.Config, cmgr cmgr.Cmgr) (RelayServer, error) {
return newWssServer(base)
case constant.RelayTypeMWSS:
return newMwssServer(base)
case constant.RelayTypeMTCP:
return newMtcpServer(base)
default:
panic("unsupported transport type" + cfg.ListenType)
}

View File

@@ -2,12 +2,15 @@
package transporter
import (
"context"
"net"
"time"
"github.com/Ehco1996/ehco/internal/constant"
"github.com/Ehco1996/ehco/internal/metrics"
"github.com/Ehco1996/ehco/internal/relay/conf"
"github.com/Ehco1996/ehco/pkg/lb"
"go.uber.org/zap"
)
var (
@@ -16,15 +19,16 @@ var (
)
type RawClient struct {
*baseTransporter
dialer *net.Dialer
cfg *conf.Config
l *zap.SugaredLogger
}
func newRawClient(base *baseTransporter) (*RawClient, error) {
func newRawClient(cfg *conf.Config) (*RawClient, error) {
r := &RawClient{
baseTransporter: base,
dialer: &net.Dialer{Timeout: constant.DialTimeOut},
l: zap.S().Named("raw"),
cfg: cfg,
dialer: &net.Dialer{Timeout: constant.DialTimeOut},
}
return r, nil
}
@@ -41,11 +45,22 @@ func (raw *RawClient) TCPHandShake(remote *lb.Node) (net.Conn, error) {
return rc, nil
}
func (raw *RawClient) HealthCheck(ctx context.Context, remote *lb.Node) error {
l := zap.S().Named("health-check")
l.Infof("start send req to %s", remote.Address)
c, err := raw.TCPHandShake(remote)
if err != nil {
l.Errorf("send req to %s meet error:%s", remote.Address, err)
return err
}
c.Close()
return nil
}
type RawServer struct {
*baseTransporter
localTCPAddr *net.TCPAddr
lis *net.TCPListener
relayer RelayClient
}
func newRawServer(base *baseTransporter) (*RawServer, error) {
@@ -57,15 +72,10 @@ func newRawServer(base *baseTransporter) (*RawServer, error) {
if err != nil {
return nil, err
}
relayer, err := newRelayClient(base)
if err != nil {
return nil, err
}
return &RawServer{
lis: lis,
baseTransporter: base,
localTCPAddr: addr,
relayer: relayer,
}, nil
}

View File

@@ -6,8 +6,10 @@ import (
"time"
"github.com/xtaci/smux"
"go.uber.org/zap"
"github.com/Ehco1996/ehco/internal/metrics"
"github.com/Ehco1996/ehco/internal/relay/conf"
"github.com/Ehco1996/ehco/pkg/lb"
)
@@ -21,13 +23,13 @@ type MtcpClient struct {
muxTP *smuxTransporter
}
func newMtcpClient(base *baseTransporter) (*MtcpClient, error) {
raw, err := newRawClient(base)
func newMtcpClient(cfg *conf.Config) (*MtcpClient, error) {
raw, err := newRawClient(cfg)
if err != nil {
return nil, err
}
c := &MtcpClient{RawClient: raw}
c.muxTP = NewSmuxTransporter(raw.l.Named("mtcp"), c.initNewSession)
c.muxTP = NewSmuxTransporter(zap.S().Named("mtcp"), c.initNewSession)
return c, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/Ehco1996/ehco/internal/conn"
"github.com/Ehco1996/ehco/internal/constant"
"github.com/Ehco1996/ehco/internal/metrics"
"github.com/Ehco1996/ehco/internal/relay/conf"
"github.com/Ehco1996/ehco/internal/web"
"github.com/Ehco1996/ehco/pkg/lb"
)
@@ -23,15 +24,16 @@ var (
)
type WsClient struct {
*baseTransporter
dialer *ws.Dialer
cfg *conf.Config
l *zap.SugaredLogger
}
func newWsClient(base *baseTransporter) (*WsClient, error) {
func newWsClient(cfg *conf.Config) (*WsClient, error) {
s := &WsClient{
baseTransporter: base,
dialer: &ws.Dialer{Timeout: constant.DialTimeOut},
cfg: cfg,
l: zap.S().Named(cfg.TransportType),
dialer: &ws.Dialer{Timeout: constant.DialTimeOut},
}
return s, nil
}
@@ -53,12 +55,23 @@ func (s *WsClient) TCPHandShake(remote *lb.Node) (net.Conn, error) {
return c, nil
}
func (s *WsClient) HealthCheck(ctx context.Context, remote *lb.Node) error {
l := zap.S().Named("health-check")
l.Infof("start send req to %s", remote.Address)
c, err := s.TCPHandShake(remote)
if err != nil {
l.Errorf("send req to %s meet error:%s", remote.Address, err)
return err
}
c.Close()
return nil
}
type WsServer struct {
*baseTransporter
e *echo.Echo
httpServer *http.Server
relayer RelayClient
}
func newWsServer(base *baseTransporter) (*WsServer, error) {
@@ -79,11 +92,6 @@ func newWsServer(base *baseTransporter) (*WsServer, error) {
e.GET(base.cfg.GetWSHandShakePath(), echo.WrapHandler(http.HandlerFunc(s.HandleRequest)))
s.e = e
relayer, err := newRelayClient(base)
if err != nil {
return nil, err
}
s.relayer = relayer
return s, nil
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/xtaci/smux"
"github.com/Ehco1996/ehco/internal/metrics"
"github.com/Ehco1996/ehco/internal/relay/conf"
"github.com/Ehco1996/ehco/pkg/lb"
)
@@ -29,8 +30,8 @@ type MwsClient struct {
muxTP *smuxTransporter
}
func newMwsClient(base *baseTransporter) (*MwsClient, error) {
wc, err := newWssClient(base)
func newMwsClient(cfg *conf.Config) (*MwsClient, error) {
wc, err := newWssClient(cfg)
if err != nil {
return nil, err
}

View File

@@ -1,6 +1,7 @@
package transporter
import (
"github.com/Ehco1996/ehco/internal/relay/conf"
mytls "github.com/Ehco1996/ehco/internal/tls"
)
@@ -13,8 +14,8 @@ type WssClient struct {
*WsClient
}
func newWssClient(base *baseTransporter) (*WssClient, error) {
wc, err := newWsClient(base)
func newWssClient(cfg *conf.Config) (*WssClient, error) {
wc, err := newWsClient(cfg)
if err != nil {
return nil, err
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/xtaci/smux"
"github.com/Ehco1996/ehco/internal/metrics"
"github.com/Ehco1996/ehco/internal/relay/conf"
"github.com/Ehco1996/ehco/pkg/lb"
)
@@ -29,8 +30,8 @@ type MwssClient struct {
muxTP *smuxTransporter
}
func newMwssClient(base *baseTransporter) (*MwssClient, error) {
wc, err := newWssClient(base)
func newMwssClient(cfg *conf.Config) (*MwssClient, error) {
wc, err := newWssClient(cfg)
if err != nil {
return nil, err
}

View File

@@ -12,7 +12,7 @@ import (
"go.uber.org/zap"
)
const defaultPageSize = 10
const defaultPageSize = 20
func MakeIndexF() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
@@ -51,13 +51,15 @@ func (s *Server) HandleClashProxyProvider(c echo.Context) error {
}
func (s *Server) handleClashProxyProvider(c echo.Context, subName string, grouped bool) error {
if s.relayServerReloader != nil {
if err := s.relayServerReloader.Reload(true); err != nil {
if s.Reloader != nil {
if err := s.Reloader.Reload(true); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
}
} else {
s.l.Debugf("relayServerReloader is nil this should not happen")
s.l.Debugf("Reloader is nil this should not happen")
return echo.NewHTTPError(http.StatusBadRequest, "should not happen error happen :)")
}
clashSubList, err := s.cfg.GetClashSubList()
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
@@ -81,11 +83,10 @@ func (s *Server) handleClashProxyProvider(c echo.Context, subName string, groupe
}
func (s *Server) HandleReload(c echo.Context) error {
if s.relayServerReloader == nil {
if s.Reloader == nil {
return echo.NewHTTPError(http.StatusBadRequest, "reload not support")
}
err := s.relayServerReloader.Reload(true)
err := s.Reloader.Reload(true)
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
}
@@ -97,6 +98,18 @@ func (s *Server) HandleReload(c echo.Context) error {
return nil
}
func (s *Server) HandleHealthCheck(c echo.Context) error {
relayLabel := c.QueryParam("relay_label")
if relayLabel == "" {
return echo.NewHTTPError(http.StatusBadRequest, "relay_label is required")
}
if err := s.HealthCheck(c.Request().Context(), relayLabel); err != nil {
res := CommonResp{Message: err.Error()}
return c.JSON(http.StatusBadRequest, res)
}
return c.JSON(http.StatusOK, CommonResp{Message: "connect success"})
}
func (s *Server) CurrentConfig(c echo.Context) error {
ret, err := json.Marshal(s.cfg)
if err != nil {

View File

@@ -17,21 +17,23 @@ import (
"github.com/Ehco1996/ehco/internal/cmgr"
"github.com/Ehco1996/ehco/internal/config"
"github.com/Ehco1996/ehco/internal/glue"
"github.com/Ehco1996/ehco/internal/metrics"
"github.com/Ehco1996/ehco/internal/reloader"
)
//go:embed templates/*.html
var templatesFS embed.FS
type Server struct {
glue.Reloader
glue.HealthChecker
e *echo.Echo
addr string
l *zap.SugaredLogger
cfg *config.Config
relayServerReloader reloader.Reloader
connMgr cmgr.Cmgr
connMgr cmgr.Cmgr
}
type echoTemplate struct {
@@ -42,7 +44,11 @@ func (t *echoTemplate) Render(w io.Writer, name string, data interface{}, c echo
return t.templates.ExecuteTemplate(w, name, data)
}
func NewServer(cfg *config.Config, relayReloader reloader.Reloader, connMgr cmgr.Cmgr) (*Server, error) {
func NewServer(
cfg *config.Config,
relayReloader glue.Reloader,
healthChecker glue.HealthChecker,
connMgr cmgr.Cmgr) (*Server, error) {
l := zap.S().Named("web")
templates := template.Must(template.ParseFS(templatesFS, "templates/*.html"))
@@ -79,12 +85,14 @@ func NewServer(cfg *config.Config, relayReloader reloader.Reloader, connMgr cmgr
return nil, err
}
s := &Server{
e: e,
l: l,
cfg: cfg,
connMgr: connMgr,
relayServerReloader: relayReloader,
addr: net.JoinHostPort(cfg.WebHost, fmt.Sprintf("%d", cfg.WebPort)),
Reloader: relayReloader,
HealthChecker: healthChecker,
e: e,
l: l,
cfg: cfg,
connMgr: connMgr,
addr: net.JoinHostPort(cfg.WebHost, fmt.Sprintf("%d", cfg.WebPort)),
}
// register handler
@@ -99,7 +107,7 @@ func NewServer(cfg *config.Config, relayReloader reloader.Reloader, connMgr cmgr
api := e.Group("/api/v1")
api.GET("/config/", s.CurrentConfig)
api.POST("/config/reload/", s.HandleReload)
api.GET("/health_check/", s.HandleHealthCheck)
return s, nil
}

View File

@@ -3,7 +3,9 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/1.0.0/css/bulma.min.css">
<meta name="description" content="ehco web">
<meta name="keywords" content="ehco-relay">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/1.0.1/css/bulma.min.css">
<title>Connections</title>
</head>
<body>
@@ -57,9 +59,9 @@
{{if gt .CurrentPage 1}}
<li><a class="pagination-link" href="?conn_type={{.ConnType}}&page=1&page_size={{.PageSize}}">1</a></li>
{{end}}
<li><span class="pagination-ellipsis">&hellip;</span></li>
<li><span class="pagination-ellipsis"></span></li>
<li><a class="pagination-link is-current" aria-label="Page {{.CurrentPage}}" aria-current="page">{{.CurrentPage}}</a></li>
<li><span class="pagination-ellipsis">&hellip;</span></li>
<li><span class="pagination-ellipsis"></span></li>
{{if lt .CurrentPage .TotalPage}}
<li><a class="pagination-link" href="?conn_type={{.ConnType}}&page={{.TotalPage}}&page_size={{.PageSize}}">{{.TotalPage}}</a></li>
{{end}}

View File

@@ -1,7 +1,9 @@
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="description" content="ehco web" />
<meta name="keywords" content="ehco-relay" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
rel="stylesheet"
@@ -18,7 +20,6 @@
<h1 class="title has-text-centered">
ehco is a network relay tool and a typo :)
</h1>
<!-- Build Info Card -->
<div class="card">
<header class="card-header">
@@ -38,7 +39,6 @@
</div>
</div>
</div>
<!-- Stylish Links Card -->
<div class="card">
<header class="card-header">
@@ -82,7 +82,7 @@
</div>
</div>
<!-- Clash Providers card -->
{{if .SubConfigs}}
{{ if .SubConfigs }}
<div class="card">
<header class="card-header">
<p class="card-header-title has-text-centered">
@@ -92,7 +92,7 @@
<div class="card-content">
<div class="content">
<ul>
{{range .SubConfigs}}
{{ range .SubConfigs }}
<li>
<a
class="button is-info is-light"
@@ -108,12 +108,11 @@
>
</li>
</ul>
{{end}}
{{ end }}
</div>
</div>
</div>
{{end}}
{{ end }}
<!-- Reload Config Button -->
<div class="has-text-centered">
<button
@@ -125,7 +124,6 @@
</div>
</div>
</div>
<!-- Footer -->
<div class="hero-foot">
<footer class="footer">
@@ -137,7 +135,6 @@
</footer>
</div>
</section>
<script>
$(document).ready(function () {
$("#reloadButton").click(function () {

View File

@@ -0,0 +1,5 @@
package web
type CommonResp struct {
Message string `json:"msg"`
}