Projects STRLCPY SeaMoon Commits 707c6922
🤬
  • ■ ■ ■ ■
    .github/conf/.goreleaser.yml
    skipped 14 lines
    15 15   - 6
    16 16   - 7
    17 17   ldflags:
    18  - - -s -w -X github.com/DVKunion/SeaMoon/pkg/consts.Version={{.Version}} -X github.com/DVKunion/SeaMoon/pkg/consts.Commit={{.Sha}}
     18 + - -s -w -X github.com/DVKunion/SeaMoon/system/xlog.Version={{.Version}} -X github.com/DVKunion/SeaMoon/system/xlog.Commit={{.Sha}}
    19 19  checksum:
    20 20   name_template: 'checksums.txt'
    21 21  snapshot:
    skipped 7 lines
  • ■ ■ ■ ■
    .github/workflows/build.yml
    skipped 35 lines
    36 36   run: |
    37 37   cp -r /tmp/dist cmd/client/static
    38 38   go mod tidy
    39  - go build -o seamoon -v --ldflags "-s -w -X github.com/DVKunion/SeaMoon/pkg/consts.Version=${{github.ref_name}} -X github.com/DVKunion/SeaMoon/pkg/consts.Commit=${{github.sha}}" cmd/main.go
     39 + go build -o seamoon -v --ldflags "-s -w -X github.com/DVKunion/SeaMoon/pkg/system/xlog.Version=${{github.ref_name}} -X github.com/DVKunion/SeaMoon/pkg/system/xlog.Commit=${{github.sha}}" cmd/main.go
    40 40   - uses: actions/upload-artifact@v4
    41 41   with:
    42 42   path: seamoon
  • ■ ■ ■ ■
    Dockerfile
    skipped 5 lines
    6 6  ENV CGO_ENABLED 0
    7 7  ENV VERSION=${VERSION}
    8 8  ENV SHA=${SHA}
    9  -RUN go build -ldflags "-X github.com/DVKunion/SeaMoon/server/consts.Version=${VERSION} -X github.com/DVKunion/SeaMoon/server/consts.Commit=${SHA}" -o /tmp/seamoon cmd/main.go
     9 +RUN go build -ldflags "-X github.com/DVKunion/SeaMoon/system/xlog.Version=${VERSION} -X github.com/DVKunion/SeaMoon/system/xlog.Commit=${SHA}" -o /tmp/seamoon cmd/main.go
    10 10  RUN chmod +x /tmp/seamoon
    11 11  # run stage
    12 12  FROM alpine:3.19
    skipped 10 lines
  • ■ ■ ■ ■ ■ ■
    cmd/client/client.go
    skipped 14 lines
    15 15   "github.com/DVKunion/SeaMoon/cmd/client/static"
    16 16   "github.com/DVKunion/SeaMoon/pkg/api/service"
    17 17   "github.com/DVKunion/SeaMoon/pkg/signal"
    18  - "github.com/DVKunion/SeaMoon/pkg/system/consts"
    19  - "github.com/DVKunion/SeaMoon/pkg/system/errors"
    20 18   "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    21 19  )
    22 20   
    skipped 10 lines
    33 31   // 如果配置了自动恢复设置,尝试发送恢复信号
    34 32   rec, err := service.SVC.GetConfigByName(ctx, "auto_start")
    35 33   if err != nil {
    36  - xlog.Error(errors.SignalGetObjError, "err", err)
     34 + xlog.Error(xlog.SignalGetObjError, "err", err)
    37 35   return
    38 36   }
    39 37   signal.Signal().Recover(ctx, rec.Value)
    skipped 6 lines
    46 44   
    47 45   xlog.Info(xlog.ApiServiceStart, "addr", addr.Value, "port", port.Value)
    48 46   
    49  - if consts.Version != "dev" || !debug {
     47 + if xlog.Version != "dev" || !debug {
    50 48   gin.SetMode(gin.ReleaseMode)
    51 49   }
    52 50   
    skipped 19 lines
    72 70   })
    73 71   
    74 72   if err := server.Run(strings.Join([]string{addr.Value, port.Value}, ":")); err != http.ErrServerClosed {
    75  - xlog.Error(errors.ApiServeError, "err", err)
     73 + xlog.Error(xlog.ApiServeError, "err", err)
    76 74   }
    77 75  }
    78 76   
  • ■ ■ ■ ■ ■ ■
    cmd/main.go
    skipped 8 lines
    9 9   "github.com/DVKunion/SeaMoon/cmd/client"
    10 10   "github.com/DVKunion/SeaMoon/cmd/server"
    11 11   "github.com/DVKunion/SeaMoon/pkg/api/database/drivers"
    12  - "github.com/DVKunion/SeaMoon/pkg/system/consts"
     12 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    13 13  )
    14 14   
    15 15  var (
    skipped 28 lines
    44 44   Use: "version",
    45 45   Short: "SeaMoon version info",
    46 46   Run: func(cmd *cobra.Command, args []string) {
    47  - fmt.Println(consts.Version)
     47 + fmt.Println(xlog.Version)
    48 48   },
    49 49   }
    50 50  )
    skipped 38 lines
  • ■ ■ ■ ■
    cmd/server/server.go
    skipped 66 lines
    67 67   srvOpt = append(srvOpt, service.WithCrypt(os.Getenv("SM_SS_CRYPT")))
    68 68   
    69 69   if err := s.srv.Serve(ln, srvOpt...); err != nil {
    70  - xlog.Error(errors.ServiceError, err)
     70 + xlog.Error(xlog.ServiceError, err)
    71 71   return err
    72 72   }
    73 73   return nil
    skipped 2 lines
  • ■ ■ ■ ■ ■ ■
    pkg/api/controller/middleware/jwt.go
    skipped 8 lines
    9 9   "github.com/DVKunion/SeaMoon/pkg/api/controller/servant"
    10 10   "github.com/DVKunion/SeaMoon/pkg/api/enum"
    11 11   "github.com/DVKunion/SeaMoon/pkg/system/errors"
     12 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    12 13   "github.com/DVKunion/SeaMoon/pkg/tools"
    13 14  )
    14 15   
    skipped 2 lines
    17 18   tokenString := c.GetHeader("Authorization")
    18 19   
    19 20   if tokenString == "" {
    20  - servant.ErrorMsg(c, http.StatusUnauthorized, errors.ApiError(errors.ApiParamsRequire, nil))
     21 + servant.ErrorMsg(c, http.StatusUnauthorized, errors.ApiError(xlog.ApiParamsRequire, nil))
    21 22   c.Abort()
    22 23   return
    23 24   }
    skipped 3 lines
    27 28   
    28 29   if err != nil {
    29 30   // 认证失败
    30  - servant.ErrorMsg(c, http.StatusForbidden, errors.ApiError(errors.ApiAuthError, err))
     31 + servant.ErrorMsg(c, http.StatusForbidden, errors.ApiError(xlog.ApiAuthError, err))
    31 32   c.Abort()
    32 33   return
    33 34   }
    skipped 7 lines
    41 42   }
    42 43   
    43 44   // 校验不通过
    44  - servant.ErrorMsg(c, http.StatusForbidden, errors.ApiError(errors.ApiAuthLimit, err))
     45 + servant.ErrorMsg(c, http.StatusForbidden, errors.ApiError(xlog.ApiAuthLimit, err))
    45 46   c.Abort()
    46 47   return
    47 48  }
    skipped 1 lines
  • ■ ■ ■ ■ ■
    pkg/api/controller/servant/response.go
    skipped 5 lines
    6 6   "github.com/gin-gonic/gin"
    7 7   
    8 8   "github.com/DVKunion/SeaMoon/pkg/system/errors"
     9 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    9 10  )
    10 11   
    11 12  // SuccessMsg 通用正常响应
    skipped 9 lines
    21 22  // ErrorMsg 通用错误响应
    22 23  func ErrorMsg(c *gin.Context, code int, err error) {
    23 24   if err == nil {
    24  - err = errors.ApiError(errors.ApiCommonError, nil)
     25 + err = errors.ApiError(xlog.ApiCommonError, nil)
    25 26   }
    26 27   c.JSON(code, gin.H{
    27 28   "success": false,
    skipped 5 lines
  • ■ ■ ■ ■ ■ ■
    pkg/api/controller/v1/auth.go
    skipped 8 lines
    9 9   "github.com/DVKunion/SeaMoon/pkg/api/models"
    10 10   "github.com/DVKunion/SeaMoon/pkg/api/service"
    11 11   "github.com/DVKunion/SeaMoon/pkg/system/errors"
     12 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    12 13  )
    13 14   
    14 15  func Login(c *gin.Context) {
    15 16   var obj *models.AuthApi
    16 17   if err := c.ShouldBindJSON(&obj); err != nil {
    17  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     18 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    18 19   return
    19 20   }
    20 21   
    21 22   if token, err := service.SVC.Login(c, obj); err != nil {
    22  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     23 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    23 24   } else {
    24 25   servant.SuccessMsg(c, 1, token)
    25 26   }
    skipped 2 lines
    28 29  func Passwd(c *gin.Context) {
    29 30   var obj *models.AuthApi
    30 31   if err := c.ShouldBindJSON(&obj); err != nil {
    31  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     32 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    32 33   return
    33 34   }
    34 35   
    35 36   if err := service.SVC.UpdatePassword(c, obj); err != nil {
    36  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     37 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    37 38   } else {
    38 39   servant.SuccessMsg(c, 1, "更新成功")
    39 40   }
    skipped 2 lines
  • ■ ■ ■ ■ ■ ■
    pkg/api/controller/v1/config.go
    skipped 8 lines
    9 9   "github.com/DVKunion/SeaMoon/pkg/api/models"
    10 10   "github.com/DVKunion/SeaMoon/pkg/api/service"
    11 11   "github.com/DVKunion/SeaMoon/pkg/system/errors"
     12 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    12 13  )
    13 14   
    14 15  func ListConfigs(c *gin.Context) {
    15 16   p, s := servant.GetPageSize(c)
    16 17   if config, err := service.SVC.ListConfigs(c, p, s); err != nil {
    17  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     18 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    18 19   } else {
    19 20   servant.SuccessMsg(c, 1, config.ToApi())
    20 21   }
    skipped 2 lines
    23 24  func UpdateConfig(c *gin.Context) {
    24 25   var obj models.ConfigApi
    25 26   if err := c.ShouldBindJSON(&obj); err != nil {
    26  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     27 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    27 28   return
    28 29   }
    29 30   if err := service.SVC.UpdateConfig(c, obj.ToModel()); err != nil {
    30  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     31 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    31 32   } else {
    32 33   servant.SuccessMsg(c, 1, nil)
    33 34   }
    skipped 2 lines
  • ■ ■ ■ ■ ■ ■
    pkg/api/controller/v1/provider.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "net/http"
     5 + "sync"
    5 6   
    6 7   "github.com/gin-gonic/gin"
    7 8   
    8 9   "github.com/DVKunion/SeaMoon/pkg/api/controller/servant"
     10 + "github.com/DVKunion/SeaMoon/pkg/api/enum"
    9 11   "github.com/DVKunion/SeaMoon/pkg/api/models"
    10 12   "github.com/DVKunion/SeaMoon/pkg/api/service"
     13 + "github.com/DVKunion/SeaMoon/pkg/signal"
    11 14   "github.com/DVKunion/SeaMoon/pkg/system/errors"
     15 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    12 16  )
    13 17   
    14 18  func ListProviders(c *gin.Context) {
    15 19   total, err := service.SVC.TotalProviders(c)
    16 20   if err != nil {
    17  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     21 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    18 22   return
    19 23   }
    20 24   
    21 25   p, s := servant.GetPageSize(c)
    22 26   if res, err := service.SVC.ListProviders(c, p, s); err != nil {
    23  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     27 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    24 28   } else {
    25 29   servant.SuccessMsg(c, total, res.ToApi())
    26 30   }
    skipped 2 lines
    29 33  func GetProviderById(c *gin.Context) {
    30 34   id, err := servant.GetPathId(c)
    31 35   if err != nil {
    32  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     36 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    33 37   return
    34 38   }
    35 39   if res, err := service.SVC.GetProviderById(c, uint(id)); err != nil {
    36  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     40 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    37 41   } else {
    38 42   servant.SuccessMsg(c, 1, res.ToApi())
    39 43   }
    skipped 2 lines
    42 46  func ListActiveProviders(c *gin.Context) {
    43 47   total, err := service.SVC.TotalProviders(c)
    44 48   if err != nil {
    45  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     49 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    46 50   return
    47 51   }
    48 52   
    49 53   if res, err := service.SVC.ListActiveProviders(c); err != nil {
    50  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     54 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    51 55   } else {
    52 56   servant.SuccessMsg(c, total, res.ToApi())
    53 57   }
    skipped 2 lines
    56 60  func CreateProvider(c *gin.Context) {
    57 61   var obj models.ProviderCreateApi
    58 62   if err := c.ShouldBindJSON(&obj); err != nil {
    59  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     63 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    60 64   return
    61 65   }
    62 66   
    63 67   if service.SVC.ExistProvider(c, obj.Name) {
    64  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsExist, nil))
     68 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsExist, nil))
    65 69   return
    66 70   }
    67 71   
    68 72   if res, err := service.SVC.CreateProvider(c, obj.ToModel(true)); err != nil {
    69  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     73 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    70 74   } else {
     75 + signal.Signal().SendProviderSignal(res.ID, enum.ProvStatusSync, nil)
    71 76   servant.SuccessMsg(c, 1, res.ToApi())
    72 77   }
    73 78  }
    skipped 1 lines
    75 80  func UpdateProvider(c *gin.Context) {
    76 81   var obj *models.ProviderCreateApi
    77 82   if err := c.ShouldBindJSON(&obj); err != nil {
    78  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     83 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    79 84   return
    80 85   }
    81 86   
    82 87   id, err := servant.GetPathId(c)
    83 88   if err != nil {
    84  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     89 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    85 90   return
    86 91   }
    87 92   
    88 93   obj.ID = uint(id)
    89 94   
    90 95   if res, err := service.SVC.UpdateProvider(c, obj.ToModel(false)); err != nil {
    91  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     96 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    92 97   } else {
     98 + signal.Signal().SendProviderSignal(res.ID, enum.ProvStatusSync, nil)
    93 99   servant.SuccessMsg(c, 1, res.ToApi())
    94 100   }
    95 101  }
    skipped 1 lines
    97 103  func DeleteProvider(c *gin.Context) {
    98 104   id, err := servant.GetPathId(c)
    99 105   if err != nil {
    100  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     106 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    101 107   return
    102 108   }
    103 109   
    104  - if err = service.SVC.DeleteProvider(c, uint(id)); err != nil {
    105  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
    106  - } else {
    107  - servant.SuccessMsg(c, 1, nil)
    108  - }
     110 + wg := &sync.WaitGroup{}
     111 + wg.Add(1)
     112 + signal.Signal().SendProviderSignal(uint(id), enum.ProvStatusDelete, wg)
     113 + wg.Wait()
     114 + servant.SuccessMsg(c, 1, nil)
    109 115  }
    110 116   
    111 117  func SyncProvider(c *gin.Context) {
    112 118   id, err := servant.GetPathId(c)
    113 119   if err != nil {
    114  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     120 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    115 121   return
    116 122   }
    117  - if err = service.SVC.SyncProvider(c, uint(id)); err != nil {
    118  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
    119  - } else {
    120  - servant.SuccessMsg(c, 1, nil)
    121  - }
     123 + wg := &sync.WaitGroup{}
     124 + wg.Add(1)
     125 + signal.Signal().SendProviderSignal(uint(id), enum.ProvStatusSync, wg)
     126 + wg.Wait()
     127 + servant.SuccessMsg(c, 1, nil)
    122 128  }
    123 129   
  • ■ ■ ■ ■ ■ ■
    pkg/api/controller/v1/proxy.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "net/http"
     5 + "sync"
    5 6   
    6 7   "github.com/gin-gonic/gin"
    7 8   
    skipped 3 lines
    11 12   "github.com/DVKunion/SeaMoon/pkg/api/service"
    12 13   "github.com/DVKunion/SeaMoon/pkg/signal"
    13 14   "github.com/DVKunion/SeaMoon/pkg/system/errors"
     15 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    14 16   "github.com/DVKunion/SeaMoon/pkg/tools"
    15 17  )
    16 18   
    17 19  func ListProxies(c *gin.Context) {
    18 20   total, err := service.SVC.TotalProxies(c)
    19 21   if err != nil {
    20  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     22 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    21 23   return
    22 24   }
    23 25   
    24 26   p, s := servant.GetPageSize(c)
    25 27   if res, err := service.SVC.ListProxies(c, p, s); err != nil {
    26  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     28 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    27 29   } else {
    28 30   servant.SuccessMsg(c, total, res.ToApi())
    29 31   }
    skipped 2 lines
    32 34  func GetProxyById(c *gin.Context) {
    33 35   id, err := servant.GetPathId(c)
    34 36   if err != nil {
    35  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     37 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    36 38   return
    37 39   }
    38 40   if res, err := service.SVC.GetProxyById(c, uint(id)); err != nil {
    39  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     41 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    40 42   } else {
    41 43   servant.SuccessMsg(c, 1, res.ToApi())
    42 44   }
    skipped 2 lines
    45 47  func CreateProxy(c *gin.Context) {
    46 48   var obj models.ProxyCreateApi
    47 49   if err := c.ShouldBindJSON(&obj); err != nil {
    48  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     50 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    49 51   return
    50 52   }
    51 53   
    52 54   if service.SVC.ExistProvider(c, obj.Name) {
    53  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsExist, nil))
     55 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsExist, nil))
    54 56   return
    55 57   }
    56 58   
    skipped 3 lines
    60 62   *obj.Status = enum.ProxyStatusError
    61 63   *obj.StatusMessage = err.Error()
    62 64   } else {
    63  - // todo: 发送部署请求
     65 + signal.Signal().SendTunnelSignal(tun.ID, enum.TunnelActive, nil)
    64 66   obj.TunnelID = tun.ID
    65 67   }
    66 68   }
    67 69   
    68 70   // 非账户来的,直接带着
    69  - 
    70 71   if res, err := service.SVC.CreateProxy(c, obj.ToModel(true)); err != nil {
    71  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     72 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    72 73   return
    73 74   } else {
    74 75   // 发送启动通知
    75  - signal.Signal().SendProxySignal(res.ID, enum.ProxyStatusActive)
     76 + signal.Signal().SendProxySignal(res.ID, enum.ProxyStatusActive, nil)
    76 77   servant.SuccessMsg(c, 1, res.ToApi())
    77 78   }
    78 79  }
    skipped 1 lines
    80 81  func UpdateProxy(c *gin.Context) {
    81 82   var obj *models.ProxyCreateApi
    82 83   if err := c.ShouldBindJSON(&obj); err != nil {
    83  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     84 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    84 85   return
    85 86   }
    86 87   id, err := servant.GetPathId(c)
    87 88   if err != nil {
    88  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     89 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    89 90   return
    90 91   }
    91 92   
    92  - // 朝着队列发送控制信号
    93  - signal.Signal().SendProxySignal(obj.ID, *obj.Status)
    94 93   m := obj.ToModel(false)
    95  - // 这里愚蠢de做一个特殊处理: 当代理关闭时,自动将连接数清零
    96  - if *obj.Status == enum.ProxyStatusInactive {
    97  - m.Conn = tools.IntPtr(0)
     94 + if m.Status != nil {
     95 + signal.Signal().SendProxySignal(obj.ID, *obj.Status, nil)
     96 + // 这里愚蠢de做一个特殊处理: 当代理关闭时,自动将连接数清零
     97 + if *m.Status == enum.ProxyStatusInactive {
     98 + m.Conn = tools.IntPtr(0)
     99 + }
    98 100   }
    99 101   if res, err := service.SVC.UpdateProxy(c, uint(id), m); err != nil {
    100  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     102 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    101 103   } else {
    102 104   servant.SuccessMsg(c, 1, res.ToApi())
    103 105   }
    skipped 2 lines
    106 108  func DeleteProxy(c *gin.Context) {
    107 109   id, err := servant.GetPathId(c)
    108 110   if err != nil {
    109  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     111 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    110 112   return
    111 113   }
    112 114   
    113  - if err = service.SVC.DeleteProxy(c, uint(id)); err != nil {
    114  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
    115  - } else {
    116  - servant.SuccessMsg(c, 1, nil)
    117  - }
     115 + wg := &sync.WaitGroup{}
     116 + wg.Add(1)
     117 + signal.Signal().SendProxySignal(uint(id), enum.ProxyStatusDelete, wg)
     118 + wg.Wait()
     119 + servant.SuccessMsg(c, 1, nil)
    118 120  }
    119 121   
    120 122  func SpeedRateProxy(c *gin.Context) {
    121 123   id, err := servant.GetPathId(c)
    122 124   if err != nil {
    123  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     125 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    124 126   return
    125 127   }
    126 128   
    127 129   // todo 全量测速
    128 130   if proxy, err := service.SVC.GetProxyById(c, uint(id)); err != nil || *proxy.Status != enum.ProxyStatusActive {
    129  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     131 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    130 132   } else {
    131  - signal.Signal().SendProxySignal(proxy.ID, enum.ProxyStatusSpeeding)
    132  - if err := service.SVC.UpdateProxyStatus(c, proxy.ID, enum.ProxyStatusSpeeding, ""); err != nil {
    133  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
    134  - }
    135  - // 发送测速信号
     133 + signal.Signal().SendProxySignal(proxy.ID, enum.ProxyStatusSpeeding, nil)
    136 134   servant.SuccessMsg(c, 1, proxy.ToApi())
    137 135   }
    138 136  }
    skipped 1 lines
  • ■ ■ ■ ■ ■ ■
    pkg/api/controller/v1/tunnel.go
    skipped 10 lines
    11 11   "github.com/DVKunion/SeaMoon/pkg/api/models"
    12 12   "github.com/DVKunion/SeaMoon/pkg/api/service"
    13 13   "github.com/DVKunion/SeaMoon/pkg/system/errors"
     14 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    14 15  )
    15 16   
    16 17  func ListTunnels(c *gin.Context) {
    17 18   total, err := service.SVC.TotalTunnels(c)
    18 19   if err != nil {
    19  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     20 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    20 21   return
    21 22   }
    22 23   
    23 24   p, s := servant.GetPageSize(c)
    24 25   if res, err := service.SVC.ListTunnels(c, p, s); err != nil {
    25  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     26 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    26 27   } else {
    27 28   servant.SuccessMsg(c, total, res.ToApi(extra()))
    28 29   }
    skipped 2 lines
    31 32  func GetTunnelById(c *gin.Context) {
    32 33   id, err := servant.GetPathId(c)
    33 34   if err != nil {
    34  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     35 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    35 36   return
    36 37   }
    37 38   if res, err := service.SVC.GetTunnelById(c, uint(id)); err != nil {
    38  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     39 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    39 40   } else {
    40 41   servant.SuccessMsg(c, 1, res.ToApi(extra()))
    41 42   }
    skipped 2 lines
    44 45  func CreateTunnel(c *gin.Context) {
    45 46   var obj models.TunnelCreateApi
    46 47   if err := c.ShouldBindJSON(&obj); err != nil {
    47  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     48 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    48 49   return
    49 50   }
    50 51   
    51 52   if service.SVC.ExistTunnel(c, obj.Name, nil) {
    52  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsExist, nil))
     53 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsExist, nil))
    53 54   return
    54 55   }
    55 56   
    56 57   if res, err := service.SVC.CreateTunnel(c, obj.ToModel(true)); err != nil {
    57  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     58 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    58 59   } else {
    59 60   servant.SuccessMsg(c, 1, res.ToApi(extra()))
    60 61   }
    skipped 2 lines
    63 64  func UpdateTunnel(c *gin.Context) {
    64 65   var obj *models.TunnelCreateApi
    65 66   if err := c.ShouldBindJSON(&obj); err != nil {
    66  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     67 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    67 68   return
    68 69   }
    69 70   
    70 71   id, err := servant.GetPathId(c)
    71 72   if err != nil {
    72  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     73 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    73 74   return
    74 75   }
    75 76   
    76 77   obj.ID = uint(id)
    77 78   
    78 79   if res, err := service.SVC.UpdateTunnel(c, obj.ToModel(false)); err != nil {
    79  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     80 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    80 81   } else {
    81 82   servant.SuccessMsg(c, 1, res.ToApi(extra()))
    82 83   }
    skipped 2 lines
    85 86  func DeleteTunnel(c *gin.Context) {
    86 87   id, err := servant.GetPathId(c)
    87 88   if err != nil {
    88  - servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(errors.ApiParamsError, err))
     89 + servant.ErrorMsg(c, http.StatusBadRequest, errors.ApiError(xlog.ApiParamsError, err))
    89 90   return
    90 91   }
    91 92   
    92 93   if err = service.SVC.DeleteTunnel(c, uint(id)); err != nil {
    93  - servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(errors.ApiServiceError, err))
     94 + servant.ErrorMsg(c, http.StatusInternalServerError, errors.ApiError(xlog.ApiServiceError, err))
    94 95   } else {
    95 96   servant.SuccessMsg(c, 1, nil)
    96 97   }
    skipped 18 lines
  • ■ ■ ■ ■ ■
    pkg/api/enum/provider.go
    skipped 15 lines
    16 16   ProvStatusCrete ProviderStatus = iota + 1
    17 17   ProvStatusSuccess
    18 18   ProvStatusFailed
     19 + ProvStatusSync
    19 20   ProvStatusForbidden
    20  - ProvStatusAuthError
    21 21   ProvStatusSyncError
    22 22   ProvStatusArrearsError
     23 + ProvStatusDelete
    23 24  )
    24 25   
  • ■ ■ ■ ■ ■ ■
    pkg/api/enum/proxy.go
    skipped 9 lines
    10 10   ProxyStatusInactive
    11 11   ProxyStatusError
    12 12   ProxyStatusSpeeding
     13 + ProxyStatusRecover
     14 + ProxyStatusDelete
    13 15  )
    14 16   
    15 17  type ProxyType string
    skipped 26 lines
  • ■ ■ ■ ■ ■
    pkg/api/enum/tunnel.go
    skipped 7 lines
    8 8   TunnelInactive // 停用
    9 9   TunnelError // 不可用
    10 10   TunnelWaiting // 异常
     11 + TunnelDelete // 删除
    11 12  )
    12 13   
    13 14  type TunnelType string
    skipped 36 lines
  • ■ ■ ■ ■ ■ ■
    pkg/api/models/config.go
    skipped 2 lines
    3 3  import (
    4 4   "gorm.io/gorm"
    5 5   
    6  - "github.com/DVKunion/SeaMoon/pkg/system/consts"
     6 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    7 7  )
    8 8   
    9 9  var DefaultConfig = []Config{
    skipped 15 lines
    25 25   },
    26 26   {
    27 27   Key: "version",
    28  - Value: consts.Version,
     28 + Value: xlog.Version,
    29 29   },
    30 30  }
    31 31   
    skipped 63 lines
  • ■ ■ ■ ■ ■ ■
    pkg/api/service/provider.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "context"
    5  - "errors"
    6 5   
    7 6   "github.com/DVKunion/SeaMoon/pkg/api/database/dao"
    8 7   "github.com/DVKunion/SeaMoon/pkg/api/enum"
    9 8   "github.com/DVKunion/SeaMoon/pkg/api/models"
    10 9   "github.com/DVKunion/SeaMoon/pkg/sdk"
    11  - "github.com/DVKunion/SeaMoon/pkg/tools"
     10 + "github.com/DVKunion/SeaMoon/pkg/system/errors"
     11 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    12 12  )
    13 13   
    14 14  type provider struct {
    skipped 22 lines
    37 37   
    38 38  func (p *provider) CreateProvider(ctx context.Context, obj *models.Provider) (*models.Provider, error) {
    39 39   if obj.Type == nil || obj.CloudAuth == nil || len(obj.Regions) <= 0 {
    40  - return nil, errors.New("empty auth info")
    41  - }
    42  - // do auth check
    43  - info, err := sdk.GetSDK(*obj.Type).Auth(obj.CloudAuth, obj.Regions[0])
    44  - if err != nil {
    45  - obj.Info = &models.ProviderInfo{
    46  - Amount: tools.Float64Ptr(0),
    47  - Cost: tools.Float64Ptr(0),
    48  - }
    49  - *obj.Status = enum.ProvStatusAuthError
    50  - *obj.StatusMessage = err.Error()
    51  - } else {
    52  - *obj.Status = enum.ProvStatusSuccess
    53  - obj.Info = info
     40 + return nil, errors.New(xlog.ServiceDBNeedParamsError)
    54 41   }
    55 42   
    56  - if err = dao.Q.Provider.WithContext(ctx).Create(obj); err != nil {
     43 + if err := dao.Q.Provider.WithContext(ctx).Create(obj); err != nil {
    57 44   return nil, err
    58 45   }
    59 46   return p.GetProviderByName(ctx, *obj.Name)
    60 47  }
    61 48   
     49 +// UpdateProvider 用于通用式更新
    62 50  func (p *provider) UpdateProvider(ctx context.Context, obj *models.Provider) (*models.Provider, error) {
    63 51   if obj.ID == 0 {
    64  - return nil, errors.New("empty object")
    65  - }
    66  - 
    67  - info, err := sdk.GetSDK(*obj.Type).Auth(obj.CloudAuth, obj.Regions[0])
    68  - if err != nil {
    69  - obj.Info = &models.ProviderInfo{
    70  - Amount: tools.Float64Ptr(0),
    71  - Cost: tools.Float64Ptr(0),
    72  - }
    73  - *obj.Status = enum.ProvStatusAuthError
    74  - *obj.StatusMessage = err.Error()
    75  - } else {
    76  - *obj.Status = enum.ProvStatusSuccess
    77  - obj.Info = info
     52 + return nil, errors.New(xlog.ServiceDBNeedParamsError)
    78 53   }
    79 54   
    80 55   query := dao.Q.Provider
    81 56   
    82  - if _, err = query.WithContext(ctx).Where(query.ID.Eq(obj.ID)).Updates(obj); err != nil {
     57 + if _, err := query.WithContext(ctx).Where(query.ID.Eq(obj.ID)).Updates(obj); err != nil {
    83 58   return nil, err
    84 59   }
    85 60   
    86 61   return p.GetProviderById(ctx, obj.ID)
    87 62  }
    88 63   
    89  -func (p *provider) DeleteProvider(ctx context.Context, id uint) error {
    90  - prov, err := p.GetProviderById(ctx, id)
    91  - if err != nil {
    92  - return err
     64 +// UpdateProviderStatus 用于更新状态,通常吞掉了状态更新时的错误
     65 +func (p *provider) UpdateProviderStatus(ctx context.Context, id uint, status enum.ProviderStatus, msg string) {
     66 + query := dao.Q.Provider
     67 + 
     68 + if _, err := query.WithContext(ctx).Where(query.ID.Eq(id)).Updates(&models.Provider{
     69 + Status: &status,
     70 + StatusMessage: &msg,
     71 + }); err != nil {
     72 + xlog.Error(xlog.ServiceDBUpdateStatusError, "type", "provider_status", "err", err)
    93 73   }
    94  - for _, tun := range prov.Tunnels {
    95  - // 具体清理逻辑下落到了 tunnel 身上
    96  - if err = SVC.DeleteTunnel(ctx, tun.ID); err != nil {
    97  - return err
    98  - }
    99  - }
    100  - // 然后删除数据
     74 +}
     75 + 
     76 +func (p *provider) DeleteProvider(ctx context.Context, id uint) error {
    101 77   query := dao.Q.Provider
    102 78   res, err := query.WithContext(ctx).Where(query.ID.Eq(id)).Delete()
    103 79   if err != nil || res.Error != nil {
    skipped 2 lines
    106 82   return nil
    107 83  }
    108 84   
    109  -func (p *provider) SyncProvider(ctx context.Context, id uint) error {
    110  - prov, err := p.GetProviderById(ctx, id)
    111  - if err != nil {
    112  - return err
    113  - }
    114  - 
     85 +func (p *provider) SyncProvider(ctx context.Context, prov *models.Provider) error {
    115 86   // 先同步账户
    116 87   // do auth check
    117 88   info, err := sdk.GetSDK(*prov.Type).Auth(prov.CloudAuth, prov.Regions[0])
    118 89   if err != nil {
    119  - *prov.Status = enum.ProvStatusAuthError
    120  - *prov.StatusMessage = err.Error()
    121  - _, err = p.UpdateProvider(ctx, prov)
    122 90   return err
    123  - } else {
    124  - *prov.Status = enum.ProvStatusSuccess
    125  - prov.Info = info
    126 91   }
     92 + 
     93 + prov.Info = info
    127 94   
    128 95   // 自动同步函数
    129 96   tuns, err := sdk.GetSDK(*prov.Type).SyncFC(prov.CloudAuth, prov.Regions)
    130 97   if err != nil {
    131  - *prov.Status = enum.ProvStatusSyncError
    132  - *prov.StatusMessage = err.Error()
    133  - _, err = p.UpdateProvider(ctx, prov)
    134 98   return err
    135 99   }
    136 100   
    skipped 2 lines
    139 103   if SVC.ExistTunnel(ctx, nil, tun.UniqID) {
    140 104   continue
    141 105   }
    142  - tun.ProviderId = id
     106 + tun.ProviderId = prov.ID
    143 107   if _, err = SVC.CreateTunnel(ctx, tun.ToModel(true)); err != nil {
    144 108   return err
    145 109   }
    skipped 13 lines
  • ■ ■ ■ ■ ■ ■
    pkg/api/service/proxy.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "context"
    5  - "errors"
    6 5   
    7 6   "github.com/showwin/speedtest-go/speedtest"
    8 7   
    9 8   "github.com/DVKunion/SeaMoon/pkg/api/database/dao"
    10 9   "github.com/DVKunion/SeaMoon/pkg/api/enum"
    11 10   "github.com/DVKunion/SeaMoon/pkg/api/models"
     11 + "github.com/DVKunion/SeaMoon/pkg/system/errors"
     12 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    12 13  )
    13 14   
    14 15  type proxy struct {
    skipped 37 lines
    52 53   return p.GetProxyById(ctx, id)
    53 54  }
    54 55   
    55  -func (p *proxy) UpdateProxyConn(ctx context.Context, id uint, op int) error {
     56 +func (p *proxy) UpdateProxyConn(ctx context.Context, id uint, op int) {
    56 57   query := dao.Q.Proxy
    57 58   
    58  - if op == 1 {
     59 + switch op {
     60 + case 1:
    59 61   if _, err := query.WithContext(ctx).Where(query.ID.Eq(id)).UpdateSimple(query.Conn.Add(1)); err != nil {
    60  - return err
     62 + xlog.Error(xlog.ServiceDBUpdateFiledError, "type", "proxy_conn", "err", err)
    61 63   }
    62  - }
    63  - 
    64  - if op == -1 {
     64 + case 2:
    65 65   if _, err := query.WithContext(ctx).Where(query.ID.Eq(id)).UpdateSimple(query.Conn.Sub(1)); err != nil {
    66  - return err
     66 + xlog.Error(xlog.ServiceDBUpdateFiledError, "type", "proxy_conn", "err", err)
    67 67   }
    68 68   }
    69  - 
    70  - return nil
    71 69  }
    72 70   
    73  -func (p *proxy) UpdateProxyNetFlow(ctx context.Context, id uint, in int64, out int64) error {
     71 +func (p *proxy) UpdateProxyNetworkInfo(ctx context.Context, id uint, in int64, out int64) {
    74 72   query := dao.Q.Proxy
    75 73   
    76 74   if _, err := query.WithContext(ctx).Where(query.ID.Eq(id)).UpdateSimple(
    77 75   query.InBound.Add(in),
    78 76   query.OutBound.Add(out),
    79 77   ); err != nil {
    80  - return err
     78 + xlog.Error(xlog.ServiceDBUpdateFiledError, "type", "proxy_network", "err", err)
    81 79   }
    82  - 
    83  - return nil
    84 80  }
    85 81   
    86  -func (p *proxy) UpdateProxyStatus(ctx context.Context, id uint, status enum.ProxyStatus, msg string) error {
     82 +func (p *proxy) UpdateProxyStatus(ctx context.Context, id uint, status enum.ProxyStatus, msg string) {
    87 83   query := dao.Q.Proxy
    88 84   
    89 85   if _, err := query.WithContext(ctx).Where(query.ID.Eq(id)).Updates(&models.Proxy{
    90 86   Status: &status,
    91 87   StatusMessage: &msg,
    92 88   }); err != nil {
    93  - return err
     89 + xlog.Error(xlog.ServiceDBUpdateStatusError, "type", "proxy_status", "err", err)
    94 90   }
    95  - return nil
    96 91  }
    97 92   
    98 93  func (p *proxy) DeleteProxy(ctx context.Context, id uint) error {
    skipped 2 lines
    101 96   return err
    102 97   }
    103 98   if *target.Status == enum.ProxyStatusActive {
    104  - return errors.New("禁止删除运行中的服务,请先停止服务")
     99 + return errors.New(xlog.ServiceDBDeleteError)
    105 100   }
    106 101   query := dao.Q.Proxy
    107 102   res, err := query.WithContext(ctx).Where(query.ID.Eq(id)).Delete()
    skipped 48 lines
  • ■ ■ ■ ■ ■ ■
    pkg/api/service/tunnel.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "context"
    5  - "errors"
    6 5   
    7 6   "github.com/DVKunion/SeaMoon/pkg/api/database/dao"
    8 7   "github.com/DVKunion/SeaMoon/pkg/api/enum"
    9 8   "github.com/DVKunion/SeaMoon/pkg/api/models"
    10 9   "github.com/DVKunion/SeaMoon/pkg/sdk"
     10 + "github.com/DVKunion/SeaMoon/pkg/system/errors"
     11 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    11 12  )
    12 13   
    13 14  type tunnel struct {
    skipped 42 lines
    56 57   return nil, err
    57 58   }
    58 59   
    59  - if *obj.Status == enum.TunnelInitializing {
    60  - err = t.DeployTunnel(ctx, obj.ID)
    61  - if err != nil {
    62  - return nil, err
    63  - }
    64  - }
    65  - 
    66 60   return t.GetTunnelByName(ctx, *obj.Name)
    67 61  }
    68 62   
    69 63  func (t *tunnel) UpdateTunnel(ctx context.Context, obj *models.Tunnel) (*models.Tunnel, error) {
    70  - tun, err := t.GetTunnelById(ctx, obj.ID)
    71  - 
    72  - if err != nil {
    73  - return nil, err
    74  - }
    75  - 
    76  - // 更新状态为激活时,要去尝试 deploy
    77  - if tun.Status != obj.Status {
    78  - switch *obj.Status {
    79  - case enum.TunnelInitializing:
    80  - // todo: deal with error
    81  - _ = t.DeployTunnel(ctx, tun.ID)
    82  - case enum.TunnelInactive:
    83  - // 再停掉远端的服务
    84  - if err := t.StopTunnel(ctx, obj); err != nil {
    85  - *obj.Status = enum.TunnelError
    86  - *obj.StatusMessage = err.Error()
    87  - }
    88  - }
    89  - }
    90  - 
    91 64   query := dao.Q.Tunnel
    92 65   
    93 66   if _, err := query.WithContext(ctx).Where(query.ID.Eq(obj.ID)).Updates(obj); err != nil {
    skipped 3 lines
    97 70   return t.GetTunnelById(ctx, obj.ID)
    98 71  }
    99 72   
    100  -func (t *tunnel) DeleteTunnel(ctx context.Context, id uint) error {
    101  - tun, err := t.GetTunnelById(ctx, id)
    102  - if err != nil {
    103  - return err
    104  - }
     73 +func (t *tunnel) UpdateTunnelStatus(ctx context.Context, id uint, status enum.TunnelStatus, msg string) {
     74 + query := dao.Q.Tunnel
    105 75   
    106  - // 先停掉本地的服务
    107  - for _, py := range tun.Proxies {
    108  - // 需要先停掉所有的服务
    109  - if err = SVC.UpdateProxyStatus(ctx, py.ID, enum.ProxyStatusInactive, ""); err != nil {
    110  - return err
    111  - }
    112  - // 然后删除数据
    113  - if err = SVC.DeleteProxy(ctx, py.ID); err != nil {
    114  - return err
    115  - }
     76 + if _, err := query.WithContext(ctx).Where(query.ID.Eq(id)).Updates(&models.Tunnel{
     77 + Status: &status,
     78 + StatusMessage: &msg,
     79 + }); err != nil {
     80 + xlog.Error(xlog.ServiceDBUpdateStatusError, "type", "tunnel_status", "err", err)
    116 81   }
    117  - // 再停掉远端的服务
    118  - if err = t.StopTunnel(ctx, tun); err != nil {
    119  - return err
     82 +}
     83 + 
     84 +func (t *tunnel) UpdateTunnelAddr(ctx context.Context, id uint, addr string) {
     85 + query := dao.Q.Tunnel
     86 + 
     87 + if _, err := query.WithContext(ctx).Where(query.ID.Eq(id)).Updates(&models.Tunnel{
     88 + Addr: &addr,
     89 + }); err != nil {
     90 + xlog.Error(xlog.ServiceDBUpdateFiledError, "type", "tunnel_addr", "err", err)
    120 91   }
     92 +}
    121 93   
    122  - // 最后清理掉数据
     94 +func (t *tunnel) DeleteTunnel(ctx context.Context, id uint) error {
    123 95   query := dao.Q.Tunnel
    124 96   res, err := query.WithContext(ctx).Where(query.ID.Eq(id)).Delete()
    125 97   if err != nil || res.Error != nil {
    skipped 14 lines
    140 112   return false
    141 113  }
    142 114   
    143  -func (t *tunnel) DeployTunnel(ctx context.Context, id uint) error {
    144  - tun, err := t.GetTunnelById(ctx, id)
     115 +func (t *tunnel) DeployTunnel(ctx context.Context, tun *models.Tunnel) (string, error) {
    145 116   
    146 117   prv, err := SVC.GetProviderById(ctx, tun.ProviderId)
    147 118   if err != nil {
    148  - *tun.Status = enum.TunnelError
    149  - *tun.StatusMessage = err.Error()
    150  - _, _ = t.UpdateTunnel(ctx, tun)
    151  - return err
     119 + return "", err
    152 120   }
    153 121   
    154 122   addr, err := sdk.GetSDK(*prv.Type).Deploy(prv.CloudAuth, tun)
    155 123   if err != nil {
    156  - *tun.Status = enum.TunnelError
    157  - *tun.StatusMessage = err.Error()
    158  - _, _ = t.UpdateTunnel(ctx, tun)
    159  - return err
     124 + return "", err
    160 125   }
    161  - *tun.Status = enum.TunnelActive
    162  - *tun.Addr = addr
    163  - _, err = t.UpdateTunnel(ctx, tun)
    164  - return err
     126 + return addr, nil
    165 127  }
    166 128   
    167 129  func (t *tunnel) StopTunnel(ctx context.Context, tun *models.Tunnel) error {
    skipped 11 lines
  • ■ ■ ■ ■ ■ ■
    pkg/listener/tcp.go
    skipped 13 lines
    14 14   "github.com/DVKunion/SeaMoon/pkg/tools"
    15 15  )
    16 16   
    17  -func TCPListen(ctx context.Context, py *models.Proxy, tun *models.Tunnel) (net.Listener, error) {
     17 +func TCPListen(ctx context.Context, py *models.Proxy) (net.Listener, error) {
    18 18   server, err := net.Listen("tcp", py.Addr())
     19 + if err != nil {
     20 + return nil, err
     21 + }
     22 + tun, err := db_service.SVC.GetTunnelById(ctx, py.TunnelID)
    19 23   if err != nil {
    20 24   return nil, err
    21 25   }
    skipped 11 lines
    33 37   return
    34 38   } else {
    35 39   // 除此之外,都为异常。为了保证服务正常不出现 panic 和空指针,跳过该 conn
    36  - xlog.Error(errors.ListenerAcceptError, "err", err)
     40 + xlog.Error(xlog.ListenerAcceptError, "err", err)
    37 41   continue
    38 42   }
    39 43   }
    40  - if err = db_service.SVC.UpdateProxyConn(ctx, id, 1); err != nil {
    41  - // todo: do log
    42  - }
     44 + db_service.SVC.UpdateProxyConn(ctx, id, 1)
     45 + 
    43 46   if srv, ok := service.Factory.Load(*tun.Type); ok {
    44 47   destConn, err := srv.(service.Service).Conn(ctx, *t,
    45 48   service.WithAddr(tun.GetAddr()), service.WithTorFlag(tun.Config.Tor))
    46 49   if err != nil {
    47  - xlog.Error(errors.ListenerDailError, "err", err)
    48  - if err = db_service.SVC.UpdateProxyConn(ctx, id, -1); err != nil {
    49  - // todo: do log
    50  - }
     50 + xlog.Error(xlog.ListenerDailError, "err", err)
     51 + db_service.SVC.UpdateProxyConn(ctx, id, -1)
    51 52   continue
    52 53   }
    53 54   go func() {
    54 55   if _, err = db_service.SVC.UpdateProxy(ctx, id, &models.Proxy{
    55 56   Lag: tools.Int64Ptr(destConn.Delay()),
    56 57   }); err != nil {
    57  - xlog.Error(errors.ListenerLagError, "id", id, "err", err)
     58 + xlog.Error(xlog.ListenerLagError, "id", id, "err", err)
    58 59   }
    59 60   }()
    60 61   go func() {
    61 62   in, out, err := network.Transport(conn, destConn)
    62 63   if err != nil {
    63  - xlog.Error(errors.NetworkTransportError, "err", err)
     64 + xlog.Error(xlog.NetworkTransportError, "err", err)
    64 65   }
    65  - if err = db_service.SVC.UpdateProxyConn(ctx, id, -1); err != nil {
    66  - // todo: do log
    67  - }
    68  - if err = db_service.SVC.UpdateProxyNetFlow(ctx, id, in, out); err != nil {
    69  - // todo: do log
    70  - }
     66 + db_service.SVC.UpdateProxyConn(ctx, id, -1)
     67 + db_service.SVC.UpdateProxyNetworkInfo(ctx, id, in, out)
    71 68   }()
    72 69   }
    73 70   }
    skipped 2 lines
  • ■ ■ ■ ■ ■
    pkg/network/addr.go
    skipped 5 lines
    6 6   "strconv"
    7 7   
    8 8   "github.com/DVKunion/SeaMoon/pkg/system/errors"
     9 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    9 10  )
    10 11   
    11 12  /*
    skipped 89 lines
    101 102   addr.Host = string(b[pos : pos+addrlen])
    102 103   pos += addrlen
    103 104   default:
    104  - return errors.New(errors.NetworkAddrTypeError)
     105 + return errors.New(xlog.NetworkAddrTypeError)
    105 106   }
    106 107   
    107 108   addr.Port = binary.BigEndian.Uint16(b[pos:])
    skipped 55 lines
  • ■ ■ ■ ■ ■ ■
    pkg/network/socks5.go
    skipped 9 lines
    10 10   "io/ioutil"
    11 11   
    12 12   "github.com/DVKunion/SeaMoon/pkg/system/errors"
     13 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    13 14  )
    14 15   
    15 16  // Address types
    skipped 63 lines
    79 80   }
    80 81   
    81 82   if b[0] != SOCKS5Version {
    82  - return nil, errors.New(errors.NetworkVersionError)
     83 + return nil, errors.New(xlog.NetworkVersionError)
    83 84   }
    84 85   
    85 86   if b[1] == 0 {
    86  - return nil, errors.New(errors.NetworkMethodError)
     87 + return nil, errors.New(xlog.NetworkMethodError)
    87 88   }
    88 89   
    89 90   length := 2 + int(b[1])
    skipped 59 lines
    149 150   }
    150 151   
    151 152   if b[0] != SOCKS5UserPassVer {
    152  - return nil, errors.New(errors.NetworkVersionError)
     153 + return nil, errors.New(xlog.NetworkVersionError)
    153 154   }
    154 155   
    155 156   req := &UserPassRequest{
    skipped 79 lines
    235 236   }
    236 237   
    237 238   if b[0] != SOCKS5UserPassVer {
    238  - return nil, errors.New(errors.NetworkVersionError)
     239 + return nil, errors.New(xlog.NetworkVersionError)
    239 240   }
    240 241   
    241 242   res := &UserPassResponse{
    skipped 49 lines
    291 292   }
    292 293   
    293 294   if b[0] != SOCKS5Version {
    294  - return nil, errors.New(errors.NetworkVersionError)
     295 + return nil, errors.New(xlog.NetworkVersionError)
    295 296   }
    296 297   
    297 298   request := &SOCKS5Request{
    skipped 10 lines
    308 309   case AddrDomain:
    309 310   length = 7 + int(b[4])
    310 311   default:
    311  - return nil, errors.New(errors.NetworkAddrTypeError)
     312 + return nil, errors.New(xlog.NetworkAddrTypeError)
    312 313   }
    313 314   
    314 315   if n < length {
    skipped 74 lines
    389 390   }
    390 391   
    391 392   if b[0] != SOCKS5Version {
    392  - return nil, errors.New(errors.NetworkVersionError)
     393 + return nil, errors.New(xlog.NetworkVersionError)
    393 394   }
    394 395   
    395 396   reply := &Reply{
    skipped 10 lines
    406 407   case AddrDomain:
    407 408   length = 7 + int(b[4])
    408 409   default:
    409  - return nil, errors.New(errors.NetworkAddrTypeError)
     410 + return nil, errors.New(xlog.NetworkAddrTypeError)
    410 411   }
    411 412   
    412 413   if n < length {
    skipped 129 lines
    542 543   case AddrDomain:
    543 544   hlen = 7 + int(b[4])
    544 545   default:
    545  - return nil, errors.New(errors.NetworkAddrTypeError)
     546 + return nil, errors.New(xlog.NetworkAddrTypeError)
    546 547   }
    547 548   
    548 549   dlen := int(header.Rsv)
    skipped 48 lines
  • ■ ■ ■ ■ ■
    pkg/sdk/aliyun/aliyun_sdk.go
    skipped 15 lines
    16 16   
    17 17   "github.com/DVKunion/SeaMoon/pkg/api/enum"
    18 18   "github.com/DVKunion/SeaMoon/pkg/api/models"
    19  - "github.com/DVKunion/SeaMoon/pkg/system/consts"
    20 19   "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    21 20  )
    22 21   
    skipped 93 lines
    116 115   WithInstanceType("e1"). // 性能实例
    117 116   WithTimeout(300).
    118 117   WithCustomContainerConfig(fc.NewCustomContainerConfig().
    119  - WithImage(fmt.Sprintf("%s:%s", registryEndPoint[tun.Config.Region], consts.Version)).
     118 + WithImage(fmt.Sprintf("%s:%s", registryEndPoint[tun.Config.Region], xlog.Version)).
    120 119   WithCommand("[\"./seamoon\"]").
    121 120   WithArgs("[\"server\"]"))); err != nil {
    122 121   return "", err
    skipped 108 lines
  • ■ ■ ■ ■ ■ ■
    pkg/sdk/sealos/sealos.go
    skipped 4 lines
    5 5   "strings"
    6 6   
    7 7   "github.com/DVKunion/SeaMoon/pkg/api/enum"
    8  - "github.com/DVKunion/SeaMoon/pkg/system/consts"
     8 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    9 9   "github.com/DVKunion/SeaMoon/pkg/tools"
    10 10   
    11 11   "github.com/DVKunion/SeaMoon/pkg/api/models"
    skipped 18 lines
    30 30   // 拼接规则 seamoon-NAME-TYPE
    31 31   svc := "seamoon-" + *tun.Name + "-" + string(*tun.Type)
    32 32   // sealos 默认用 dockerhub 镜像
    33  - img := "dvkunion/seamoon:" + consts.Version
     33 + img := "dvkunion/seamoon:" + xlog.Version
    34 34   // 域名自己生成了一个随机 12 位字符串
    35 35   host := tools.GenerateRandomLetterString(12)
    36 36   
    skipped 73 lines
  • ■ ■ ■ ■ ■ ■
    pkg/sdk/tencent/tencent_sdk.go
    skipped 14 lines
    15 15   
    16 16   "github.com/DVKunion/SeaMoon/pkg/api/enum"
    17 17   "github.com/DVKunion/SeaMoon/pkg/api/models"
    18  - "github.com/DVKunion/SeaMoon/pkg/system/consts"
    19 18   "github.com/DVKunion/SeaMoon/pkg/system/errors"
    20 19   "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    21 20  )
    skipped 190 lines
    212 211   request.Code = &scf.Code{
    213 212   ImageConfig: &scf.ImageConfig{
    214 213   ImageType: common.StringPtr("personal"),
    215  - ImageUri: common.StringPtr(strings.Join([]string{RegistryEndPoint[tun.Config.Region], consts.Version}, ":")),
     214 + ImageUri: common.StringPtr(strings.Join([]string{registryEndPoint[tun.Config.Region], xlog.Version}, ":")),
    216 215   Command: common.StringPtr("/app/seamoon"),
    217 216   Args: common.StringPtr("server -p " + strconv.Itoa(int(*tun.Port)) + " -t " + string(*tun.Type)),
    218 217   ImagePort: common.Int64Ptr(int64(*tun.Port)),
    skipped 43 lines
    262 261   return "", err
    263 262   }
    264 263   if *fc.Response.TotalCount != 1 {
    265  - return "", errors.New(errors.SDKFCInfoError)
     264 + return "", errors.New(xlog.SDKFCInfoError)
    266 265   }
    267 266   xlog.Info(xlog.SDKWaitingFCStatus, "status", *fc.Response.Functions[0].Status, "cnt", cnt)
    268 267   switch *fc.Response.Functions[0].Status {
    skipped 146 lines
    415 414   req.Namespace = fc.Namespace
    416 415   fcd, err := client.GetFunction(req)
    417 416   if err != nil {
    418  - xlog.Error(errors.SDKFCDetailError, "name", *fc.FunctionName, "err", err)
     417 + xlog.Error(xlog.SDKFCDetailError, "name", *fc.FunctionName, "err", err)
    419 418   continue
    420 419   } else {
    421 420   target.detail = fcd.Response
    422 421   // 解析触发器
    423 422   trigger := fcd.Response.Triggers
    424 423   if len(trigger) < 1 {
    425  - xlog.Error(errors.SDKTriggerError, "name", *fc.FunctionName, "err", err)
     424 + xlog.Error(xlog.SDKTriggerError, "name", *fc.FunctionName, "err", err)
    426 425   } else {
    427 426   var tri triggerDesc
    428 427   err := json.Unmarshal([]byte(*trigger[0].TriggerDesc), &tri)
    429 428   if err != nil {
    430  - xlog.Error(errors.SDKTriggerUnmarshalError, "name", *fc.FunctionName, "err", err)
     429 + xlog.Error(xlog.SDKTriggerUnmarshalError, "name", *fc.FunctionName, "err", err)
    431 430   }
    432 431   target.addr = strings.Replace(tri.Service.SubDomain, "https://", "", -1)
    433 432   target.auth = tri.Api.AuthType
    skipped 9 lines
  • ■ ■ ■ ■ ■ ■
    pkg/service/grpc.go
    skipped 13 lines
    14 14   "github.com/DVKunion/SeaMoon/pkg/api/enum"
    15 15   pb "github.com/DVKunion/SeaMoon/pkg/service/proto"
    16 16   "github.com/DVKunion/SeaMoon/pkg/service/proto/gost"
    17  - "github.com/DVKunion/SeaMoon/pkg/system/consts"
    18  - "github.com/DVKunion/SeaMoon/pkg/system/errors"
    19 17   "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    20 18   "github.com/DVKunion/SeaMoon/pkg/transfer"
    21 19   "github.com/DVKunion/SeaMoon/pkg/tunnel"
    skipped 121 lines
    143 141   gt := tunnel.GRPCWrapConn(g.addr, server)
    144 142   
    145 143   if err := transfer.AutoTransport(gt); err != nil {
    146  - xlog.Error(errors.ServiceTransportError, "type", "socks5", "err", err)
     144 + xlog.Error(xlog.ServiceTransportError, "type", "socks5", "err", err)
    147 145   return err
    148 146   }
    149 147   return nil
    skipped 3 lines
    153 151   gt := tunnel.GRPCWrapConn(g.addr, server)
    154 152   
    155 153   if err := transfer.HttpTransport(gt); err != nil {
    156  - xlog.Error(errors.ServiceTransportError, "type", "http", "err", err)
     154 + xlog.Error(xlog.ServiceTransportError, "type", "http", "err", err)
    157 155   return err
    158 156   }
    159 157   
    skipped 4 lines
    164 162   gt := tunnel.GRPCWrapConn(g.addr, server)
    165 163   
    166 164   if err := transfer.Socks5Transport(gt, false); err != nil {
    167  - xlog.Error(errors.ServiceTransportError, "type", "socks5", "err", err)
     165 + xlog.Error(xlog.ServiceTransportError, "type", "socks5", "err", err)
    168 166   return err
    169 167   }
    170 168   return nil
    skipped 3 lines
    174 172   gt := tunnel.GRPCWrapConn(g.addr, server)
    175 173   
    176 174   if err := transfer.V2rayTransport(gt, "shadowsocks"); err != nil {
    177  - xlog.Error(errors.ServiceTransportError, "type", "v2ray-ssr", "err", err)
     175 + xlog.Error(xlog.ServiceTransportError, "type", "v2ray-ssr", "err", err)
    178 176   return err
    179 177   }
    180 178   return nil
    skipped 3 lines
    184 182   gt := tunnel.GRPCWrapConn(g.addr, server)
    185 183   
    186 184   if err := transfer.V2rayTransport(gt, "vmess"); err != nil {
    187  - xlog.Error(errors.ServiceTransportError, "type", "vmess", "err", err)
     185 + xlog.Error(xlog.ServiceTransportError, "type", "vmess", "err", err)
    188 186   return err
    189 187   }
    190 188   return nil
    skipped 3 lines
    194 192   gt := tunnel.GRPCWrapConn(g.addr, server)
    195 193   
    196 194   if err := transfer.V2rayTransport(gt, "vless"); err != nil {
    197  - xlog.Error(errors.ServiceTransportError, "type", "vless", "err", err)
     195 + xlog.Error(xlog.ServiceTransportError, "type", "vless", "err", err)
    198 196   return err
    199 197   }
    200 198   return nil
    skipped 4 lines
    205 203   gt := tunnel.GRPCWrapConn(g.addr, server)
    206 204   
    207 205   if err := transfer.AutoTransport(gt); err != nil {
    208  - xlog.Error(errors.ServiceTransportError, "type", "socks5", "err", err)
     206 + xlog.Error(xlog.ServiceTransportError, "type", "socks5", "err", err)
    209 207   return err
    210 208   }
    211 209   return nil
    skipped 3 lines
    215 213   return &pb.Pong{
    216 214   Status: "OK",
    217 215   Time: g.startAt.Format("2006-01-02 15:04:05"),
    218  - Version: consts.Version,
    219  - Commit: consts.Commit,
     216 + Version: xlog.Version,
     217 + Commit: xlog.Commit,
    220 218   }, nil
    221 219  }
    222 220   
  • ■ ■ ■ ■ ■ ■
    pkg/service/websocket.go
    skipped 11 lines
    12 12   "github.com/gorilla/websocket"
    13 13   
    14 14   "github.com/DVKunion/SeaMoon/pkg/api/enum"
    15  - "github.com/DVKunion/SeaMoon/pkg/system/consts"
    16  - "github.com/DVKunion/SeaMoon/pkg/system/errors"
    17 15   "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    18 16   "github.com/DVKunion/SeaMoon/pkg/transfer"
    19 17   "github.com/DVKunion/SeaMoon/pkg/tunnel"
    skipped 94 lines
    114 112   mux.HandleFunc("/vless", s.v2ray("vless"))
    115 113   mux.HandleFunc("/v-shadowsocks", s.v2ray("shadowsocks"))
    116 114   } else {
    117  - xlog.Error(errors.ServiceV2rayInitError, "err", err)
     115 + xlog.Error(xlog.ServiceV2rayInitError, "err", err)
    118 116   }
    119 117   
    120 118   s.startAt = time.Now()
    skipped 15 lines
    136 134   t := tunnel.WsWrapConn(conn)
    137 135   go func() {
    138 136   if err := transfer.AutoTransport(t); err != nil {
    139  - xlog.Error(errors.ServiceTransportError, "type", "auto", "err", err)
     137 + xlog.Error(xlog.ServiceTransportError, "type", "auto", "err", err)
    140 138   }
    141 139   }()
    142 140  }
    skipped 7 lines
    150 148   t := tunnel.WsWrapConn(conn)
    151 149   go func() {
    152 150   if err := transfer.HttpTransport(t); err != nil {
    153  - xlog.Error(errors.ServiceTransportError, "type", "http", "err", err)
     151 + xlog.Error(xlog.ServiceTransportError, "type", "http", "err", err)
    154 152   }
    155 153   }()
    156 154  }
    skipped 10 lines
    167 165   // 检测是否存在 onion 标识,代表着是否要开启 tor 转发
    168 166   if onion != "" {
    169 167   if err := transfer.TorTransport(t); err != nil {
    170  - xlog.Error(errors.ServiceTransportError, "type", "socks5+tor", "err", err)
     168 + xlog.Error(xlog.ServiceTransportError, "type", "socks5+tor", "err", err)
    171 169   }
    172 170   } else {
    173 171   if err := transfer.Socks5Transport(t, false); err != nil {
    174  - xlog.Error(errors.ServiceTransportError, "type", "socks5", "err", err)
     172 + xlog.Error(xlog.ServiceTransportError, "type", "socks5", "err", err)
    175 173   }
    176 174   }
    177 175   }()
    skipped 8 lines
    186 184   t := tunnel.WsWrapConn(conn)
    187 185   go func() {
    188 186   if err := transfer.V2rayTransport(t, proto); err != nil {
    189  - xlog.Error(errors.ServiceTransportError, "type", "v2ray", "proto", proto, "err", err)
     187 + xlog.Error(xlog.ServiceTransportError, "type", "v2ray", "proto", proto, "err", err)
    190 188   }
    191 189   }()
    192 190   }
    skipped 2 lines
    195 193  func (s *WSService) health(w http.ResponseWriter, _ *http.Request) {
    196 194   w.Header().Set("Content-Type", "text/plain")
    197 195   w.WriteHeader(http.StatusOK)
    198  - _, err := w.Write([]byte("OK\n" + s.startAt.Format("2006-01-02 15:04:05") + "\n" + consts.Version + "-" + consts.Commit))
     196 + _, err := w.Write([]byte("OK\n" + s.startAt.Format("2006-01-02 15:04:05") + "\n" + xlog.Version + "-" + xlog.Commit))
    199 197   if err != nil {
    200  - xlog.Error(errors.ServiceStatusError, "err", err)
     198 + xlog.Error(xlog.ServiceStatusError, "err", err)
    201 199   return
    202 200   }
    203 201  }
    skipped 1 lines
  • ■ ■ ■ ■ ■ ■
    pkg/signal/handler.go
     1 +package signal
     2 + 
     3 +import (
     4 + "context"
     5 + "sync"
     6 + 
     7 + "github.com/DVKunion/SeaMoon/pkg/api/enum"
     8 + "github.com/DVKunion/SeaMoon/pkg/api/service"
     9 + "github.com/DVKunion/SeaMoon/pkg/listener"
     10 + "github.com/DVKunion/SeaMoon/pkg/system/xlog"
     11 +)
     12 + 
     13 +func (sb *Bus) proxyHandler(ctx context.Context, pys *proxySignal) {
     14 + // proxy sync change task
     15 + // 如果是需要同步的,记得释放锁
     16 + defer func() {
     17 + if pys.wg != nil {
     18 + pys.wg.Done()
     19 + }
     20 + }()
     21 + proxy, err := service.SVC.GetProxyById(ctx, pys.id)
     22 + if err != nil {
     23 + xlog.Error(xlog.SignalGetObjError, "obj", "proxy", "err", err)
     24 + service.SVC.UpdateProxyStatus(ctx, pys.id, enum.ProxyStatusError, err.Error())
     25 + return
     26 + }
     27 + // 缓冲逻辑:状态没改变时候,不需要处理
     28 + if proxy.Status == &pys.next {
     29 + xlog.Warn(xlog.SignalMissOperationWarn, "id", pys.id, "type", "proxy", "status", pys.next)
     30 + return
     31 + }
     32 + service.SVC.UpdateProxyStatus(ctx, pys.id, pys.next, "")
     33 + switch pys.next {
     34 + case enum.ProxyStatusActive, enum.ProxyStatusRecover:
     35 + sigCtx, cancel := context.WithCancel(ctx)
     36 + if server, err := listener.TCPListen(sigCtx, proxy); err != nil {
     37 + xlog.Error(xlog.SignalListenerError, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr(), "err", err)
     38 + service.SVC.UpdateProxyStatus(ctx, pys.id, enum.ProxyStatusError, err.Error())
     39 + cancel()
     40 + return
     41 + } else {
     42 + sb.canceler[pys.id] = cancel
     43 + sb.listener[pys.id] = server
     44 + }
     45 + xlog.Info(xlog.SignalStartProxy, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr())
     46 + service.SVC.UpdateProxyStatus(ctx, proxy.ID, enum.ProxyStatusActive, "")
     47 + case enum.ProxyStatusInactive:
     48 + if cancel, ok := sb.canceler[pys.id]; ok {
     49 + // 先调一下 cancel
     50 + cancel()
     51 + if ln, exist := sb.listener[pys.id]; exist {
     52 + // 尝试着去停一下 ln, 防止泄漏
     53 + err := ln.Close()
     54 + if err != nil {
     55 + // 错了就错了吧,说明 ctx 挂了一般 goroutines 也跟着挂了
     56 + xlog.Error(xlog.SignalListenerError, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr(), "err", err)
     57 + }
     58 + }
     59 + }
     60 + xlog.Info(xlog.SignalStopProxy, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr())
     61 + case enum.ProxyStatusDelete:
     62 + // 先同步停止服务
     63 + wg := &sync.WaitGroup{}
     64 + wg.Add(1)
     65 + sb.SendProxySignal(pys.id, enum.ProxyStatusInactive, wg)
     66 + wg.Wait()
     67 + // 最后删除数据
     68 + if err = service.SVC.SpeedProxy(ctx, proxy); err != nil {
     69 + xlog.Error(xlog.SignalSpeedProxyError, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr(), "err", err)
     70 + service.SVC.UpdateProxyStatus(ctx, proxy.ID, enum.ProxyStatusError, err.Error())
     71 + return
     72 + }
     73 + xlog.Info(xlog.SignalDeleteProxy, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr())
     74 + case enum.ProxyStatusSpeeding:
     75 + if err = service.SVC.SpeedProxy(ctx, proxy); err != nil {
     76 + xlog.Error(xlog.SignalSpeedProxyError, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr(), "err", err)
     77 + service.SVC.UpdateProxyStatus(ctx, proxy.ID, enum.ProxyStatusError, err.Error())
     78 + return
     79 + }
     80 + xlog.Info(xlog.SignalSpeedProxy, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr())
     81 + service.SVC.UpdateProxyStatus(ctx, proxy.ID, enum.ProxyStatusActive, "")
     82 + }
     83 +}
     84 + 
     85 +func (sb *Bus) providerHandler(ctx context.Context, prs *providerSignal) {
     86 + // proxy sync change task
     87 + // 如果是需要同步的,记得释放锁
     88 + defer func() {
     89 + if prs.wg != nil {
     90 + prs.wg.Done()
     91 + }
     92 + }()
     93 + provider, err := service.SVC.GetProviderById(ctx, prs.id)
     94 + if err != nil {
     95 + xlog.Error(xlog.SignalGetObjError, "obj", "provider", "err", err)
     96 + service.SVC.UpdateProviderStatus(ctx, prs.id, enum.ProvStatusFailed, err.Error())
     97 + return
     98 + }
     99 + // 缓冲逻辑:状态没改变时候,不需要处理
     100 + if provider.Status == &prs.next {
     101 + xlog.Warn(xlog.SignalMissOperationWarn, "id", prs.id, "type", "provider", "status", prs.next)
     102 + return
     103 + }
     104 + service.SVC.UpdateProviderStatus(ctx, provider.ID, prs.next, "")
     105 + switch prs.next {
     106 + case enum.ProvStatusSync:
     107 + if err = service.SVC.SyncProvider(ctx, provider); err != nil {
     108 + xlog.Error(xlog.SignalSyncProviderError, "obj", "provider", "err", err)
     109 + service.SVC.UpdateProviderStatus(ctx, provider.ID, enum.ProvStatusSyncError, err.Error())
     110 + return
     111 + }
     112 + xlog.Info(xlog.SignalSyncProvider, "id", provider.ID, "type", provider.Type)
     113 + service.SVC.UpdateProviderStatus(ctx, provider.ID, enum.ProvStatusSuccess, "")
     114 + case enum.ProvStatusDelete:
     115 + wg := &sync.WaitGroup{}
     116 + for _, tun := range provider.Tunnels {
     117 + wg.Add(1)
     118 + sb.SendTunnelSignal(tun.ID, enum.TunnelDelete, wg)
     119 + }
     120 + wg.Wait()
     121 + // 然后删除数据
     122 + if err = service.SVC.DeleteProvider(ctx, provider.ID); err != nil {
     123 + xlog.Error(xlog.SignalSyncProviderError, "obj", "provider", "err", err)
     124 + service.SVC.UpdateProviderStatus(ctx, provider.ID, enum.ProvStatusSyncError, err.Error())
     125 + return
     126 + }
     127 + xlog.Info(xlog.SignalDeleteProvider, "id", provider.ID, "type", provider.Type)
     128 + }
     129 +}
     130 + 
     131 +func (sb *Bus) tunnelHandler(ctx context.Context, ts *tunnelSignal) {
     132 + // proxy sync change task
     133 + // 如果是需要同步的,记得释放锁
     134 + defer func() {
     135 + if ts.wg != nil {
     136 + ts.wg.Done()
     137 + }
     138 + }()
     139 + tun, err := service.SVC.GetTunnelById(ctx, ts.id)
     140 + if err != nil {
     141 + xlog.Error(xlog.SignalGetObjError, "obj", "tunnel", "err", err)
     142 + service.SVC.UpdateTunnelStatus(ctx, ts.id, enum.TunnelError, err.Error())
     143 + return
     144 + }
     145 + // 缓冲逻辑:状态没改变时候,不需要处理
     146 + if tun.Status == &ts.next {
     147 + xlog.Warn(xlog.SignalMissOperationWarn, "id", ts.id, "type", "tunnel", "status", ts.next)
     148 + return
     149 + }
     150 + service.SVC.UpdateTunnelStatus(ctx, tun.ID, ts.next, "")
     151 + switch ts.next {
     152 + case enum.TunnelActive:
     153 + if addr, err := service.SVC.DeployTunnel(ctx, tun); err != nil {
     154 + xlog.Error(xlog.SignalDeployTunError, "obj", "tunnel", "err", err)
     155 + service.SVC.UpdateTunnelStatus(ctx, tun.ID, enum.TunnelError, err.Error())
     156 + return
     157 + } else {
     158 + service.SVC.UpdateTunnelAddr(ctx, tun.ID, addr)
     159 + }
     160 + xlog.Info(xlog.SignalDeployTunnel, "id", tun.ID, "type", tun.Type)
     161 + case enum.TunnelInactive:
     162 + if err := service.SVC.StopTunnel(ctx, tun); err != nil {
     163 + xlog.Error(xlog.SignalStopTunError, "obj", "tunnel", "err", err)
     164 + service.SVC.UpdateTunnelStatus(ctx, tun.ID, enum.TunnelError, err.Error())
     165 + return
     166 + }
     167 + xlog.Info(xlog.SignalStopTunnel, "id", tun.ID, "type", tun.Type)
     168 + case enum.TunnelDelete:
     169 + // 先停掉本地的服务
     170 + wg := &sync.WaitGroup{}
     171 + for _, py := range tun.Proxies {
     172 + wg.Add(1)
     173 + sb.SendProxySignal(py.ID, enum.ProxyStatusDelete, wg)
     174 + }
     175 + wg.Wait()
     176 + wg = &sync.WaitGroup{}
     177 + // 再停掉远端的服务
     178 + wg.Add(1)
     179 + sb.SendTunnelSignal(tun.ID, enum.TunnelInactive, wg)
     180 + wg.Wait()
     181 + // 最后删除服务即可
     182 + if err := service.SVC.DeleteTunnel(ctx, tun.ID); err != nil {
     183 + xlog.Error(xlog.SignalDeleteTunError, "obj", "tunnel", "err", err)
     184 + service.SVC.UpdateTunnelStatus(ctx, tun.ID, enum.TunnelError, err.Error())
     185 + return
     186 + }
     187 + xlog.Info(xlog.SignalDeleteTunnel, "id", tun.ID, "type", tun.Type)
     188 + }
     189 +}
     190 + 
  • ■ ■ ■ ■ ■
    pkg/signal/signal.go
    skipped 2 lines
    3 3  import (
    4 4   "context"
    5 5   "net"
     6 + "sync"
    6 7   
    7 8   "github.com/DVKunion/SeaMoon/pkg/api/enum"
    8 9   "github.com/DVKunion/SeaMoon/pkg/api/service"
    9  - "github.com/DVKunion/SeaMoon/pkg/listener"
    10  - "github.com/DVKunion/SeaMoon/pkg/system/errors"
    11 10   "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    12 11  )
    13 12   
    skipped 10 lines
    24 23  type proxySignal struct {
    25 24   id uint
    26 25   next enum.ProxyStatus
     26 + wg *sync.WaitGroup
    27 27  }
    28 28   
    29 29  type providerSignal struct {
    30 30   id uint
    31 31   next enum.ProviderStatus
     32 + wg *sync.WaitGroup
    32 33  }
    33 34   
    34 35  type tunnelSignal struct {
    35 36   id uint
    36 37   next enum.TunnelStatus
     38 + wg *sync.WaitGroup
    37 39  }
    38 40   
    39 41  var signalBus = &Bus{
    skipped 13 lines
    53 55   for {
    54 56   select {
    55 57   case pys := <-sb.proxyChannel:
    56  - // proxy sync change task
    57  - proxy, err := service.SVC.GetProxyById(ctx, pys.id)
    58  - if err != nil {
    59  - _ = service.SVC.UpdateProxyStatus(ctx, pys.id, enum.ProxyStatusError, err.Error())
    60  - xlog.Error(errors.SignalGetObjError, "obj", "proxy", "err", err)
    61  - continue
    62  - }
    63  - switch pys.next {
    64  - case enum.ProxyStatusActive:
    65  - sigCtx, cancel := context.WithCancel(ctx)
    66  - tun, err := service.SVC.GetTunnelById(ctx, proxy.TunnelID)
    67  - if err != nil {
    68  - _ = service.SVC.UpdateProxyStatus(ctx, pys.id, enum.ProxyStatusError, err.Error())
    69  - xlog.Error(errors.SignalGetObjError, "obj", "tunnel", "err", err)
    70  - continue
    71  - }
    72  - server, err := listener.TCPListen(sigCtx, proxy, tun)
    73  - if err != nil {
    74  - xlog.Error(errors.SignalListenerError, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr(), "err", err)
    75  - }
    76  - sb.canceler[pys.id] = cancel
    77  - sb.listener[pys.id] = server
    78  - xlog.Info(xlog.SignalListenStart, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr())
    79  - _ = service.SVC.UpdateProxyStatus(ctx, pys.id, enum.ProxyStatusActive, "")
    80  - case enum.ProxyStatusInactive:
    81  - if cancel, ok := sb.canceler[pys.id]; ok {
    82  - // 先调一下 cancel
    83  - cancel()
    84  - if ln, exist := sb.listener[pys.id]; exist {
    85  - // 尝试着去停一下 ln, 防止泄漏
    86  - err := ln.Close()
    87  - if err != nil {
    88  - // 错了就错了吧,说明 ctx 挂了一般 goroutines 也跟着挂了
    89  - xlog.Error(errors.SignalListenerError, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr(), "err", err)
    90  - }
    91  - }
    92  - }
    93  - xlog.Info(xlog.SignalListenStop, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr())
    94  - case enum.ProxyStatusSpeeding:
    95  - if err = service.SVC.SpeedProxy(ctx, proxy); err != nil {
    96  - _ = service.SVC.UpdateProxyStatus(ctx, proxy.ID, enum.ProxyStatusError, err.Error())
    97  - xlog.Error(errors.SignalSpeedTestError, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr(), "err", err)
    98  - continue
    99  - }
    100  - if err = service.SVC.UpdateProxyStatus(ctx, proxy.ID, enum.ProxyStatusActive, ""); err != nil {
    101  - xlog.Error(errors.SignalUpdateObjError, "id", pys.id, "type", proxy.Type, "addr", proxy.Addr(), "err", err)
    102  - }
    103  - }
     58 + sb.proxyHandler(ctx, pys)
    104 59   case prs := <-sb.providerChannel:
    105  - // todo: provider sync change task
    106  - _, err := service.SVC.GetProviderById(ctx, prs.id)
    107  - if err != nil {
    108  - xlog.Error(errors.SignalGetObjError, "obj", "provider", "err", err)
    109  - }
     60 + sb.providerHandler(ctx, prs)
    110 61   case ts := <-sb.tunnelChannel:
    111  - // todo: provider sync change task
    112  - _, err := service.SVC.GetTunnelById(ctx, ts.id)
    113  - if err != nil {
    114  - xlog.Error(errors.SignalGetObjError, "obj", "tunnel", "err", err)
    115  - }
     62 + sb.tunnelHandler(ctx, ts)
    116 63   }
    117 64   }
    118 65  }
    119 66   
    120 67  func (sb *Bus) Recover(ctx context.Context, recover string) {
    121  - // 首先看一下是否需要恢复运行状态的服务
    122  - proxies, err := service.SVC.ListActiveProxies(ctx)
    123  - if err != nil {
    124  - xlog.Error(errors.SignalRecoverProxyError, "err", err)
    125  - }
    126  - for _, p := range proxies {
    127  - if recover == "true" {
    128  - xlog.Info(xlog.SignalListenRecover, "id", p.ID, "type", p.Type, "addr", p.Addr())
    129  - sb.SendProxySignal(p.ID, *p.Status)
    130  - } else {
    131  - _ = service.SVC.UpdateProxyStatus(ctx, p.ID, enum.ProxyStatusInactive, "reboot")
     68 + if recover == "true" {
     69 + // 首先看一下是否需要恢复运行状态的服务
     70 + proxies, err := service.SVC.ListActiveProxies(ctx)
     71 + if err != nil {
     72 + xlog.Error(xlog.SignalRecoverProxyError, "err", err)
     73 + }
     74 + for _, p := range proxies {
     75 + sb.SendProxySignal(p.ID, enum.ProxyStatusRecover, nil)
    132 76   }
    133 77   }
    134 78  }
    135 79   
    136  -func (sb *Bus) SendProxySignal(p uint, tp enum.ProxyStatus) {
     80 +func (sb *Bus) SendProxySignal(p uint, tp enum.ProxyStatus, wg *sync.WaitGroup) {
    137 81   sb.proxyChannel <- &proxySignal{
    138 82   id: p,
    139 83   next: tp,
     84 + wg: wg,
    140 85   }
    141 86  }
    142 87   
    143  -func (sb *Bus) SendProviderSignal(p uint, tp enum.ProviderStatus) {
     88 +func (sb *Bus) SendProviderSignal(p uint, tp enum.ProviderStatus, wg *sync.WaitGroup) {
    144 89   sb.providerChannel <- &providerSignal{
    145 90   id: p,
    146 91   next: tp,
     92 + wg: wg,
    147 93   }
    148 94  }
    149 95   
    150  -func (sb *Bus) SendTunnelSignal(p uint, tp enum.TunnelStatus) {
     96 +func (sb *Bus) SendTunnelSignal(p uint, tp enum.TunnelStatus, wg *sync.WaitGroup) {
    151 97   sb.tunnelChannel <- &tunnelSignal{
    152 98   id: p,
    153 99   next: tp,
     100 + wg: wg,
    154 101   }
    155 102  }
    156 103   
  • ■ ■ ■ ■ ■ ■
    pkg/system/errors/consts.go
    1  -package errors
    2  - 
    3  -// API 相关错误
    4  -const (
    5  - ApiCommonError = "api error"
    6  - ApiServeError = "api serve error"
    7  - ApiParamsError = "api request params error"
    8  - ApiParamsExist = "api request params already exist"
    9  - ApiParamsRequire = "api require params missing"
    10  - ApiServiceError = "api request service error"
    11  - ApiAuthError = "api request auth error"
    12  - ApiAuthRequire = "api require auth missing"
    13  - ApiAuthLimit = "api request auth limit"
    14  -)
    15  - 
    16  -// SERVICE 相关错误
    17  -const (
    18  - // ServiceProtocolNotSupportError * local service
    19  - ServiceProtocolNotSupportError = "service accept proto not support"
    20  - ServiceSocks5ReadMethodError = "service socks5 read method proto error"
    21  - ServiceSocks5WriteMethodError = "service socks5 write method proto error"
    22  - ServiceSocks5ReadCmdError = "service socks5 read command proto error"
    23  - ServiceSocks5DailError = "service socks5 dial to remote error"
    24  - ServiceSocks5ReplyError = "service socks5 write to reply success error"
    25  - 
    26  - // ServiceError remote server
    27  - ServiceError = "service remote error"
    28  - ServiceStatusError = "service remote status error "
    29  - ServiceTransportError = "service remote transport error"
    30  - ServiceV2rayInitError = "service remote init v2ray error"
    31  -)
    32  - 
    33  -// NETWORK 相关错误
    34  -const (
    35  - NetworkVersionError = "network bad version error"
    36  - NetworkAddrTypeError = "network bad address type error"
    37  - NetworkMethodError = "network bad method error"
    38  - NetworkTransportError = "network transport error"
    39  -)
    40  - 
    41  -// SDK 相关错误
    42  -const (
    43  - SDKFCInfoError = "sdk get function info error"
    44  - SDKFCDetailError = "sdk get function detail error"
    45  - SDKTriggerError = "sdk get function trigger error"
    46  - SDKTriggerUnmarshalError = "sdk unmarshal function trigger error"
    47  -)
    48  - 
    49  -// LISTENER 相关错误
    50  -const (
    51  - ListenerAcceptError = "listener unexpect error"
    52  - ListenerDailError = "listener dail to remote error"
    53  - ListenerLagError = "listener latency calculation error"
    54  -)
    55  - 
    56  -// SIGNAL 相关错误
    57  -const (
    58  - SignalGetObjError = "signal try to get object from db error"
    59  - SignalUpdateObjError = "signal try to update object from db error"
    60  - SignalListenerError = "signal listener unexpect error"
    61  - SignalSpeedTestError = "signal try test speed error"
    62  - SignalRecoverProxyError = "signal try recover active proxy error"
    63  -)
    64  - 
  • ■ ■ ■ ■ ■ ■
    pkg/system/xlog/consts.go
    skipped 16 lines
    17 17   
    18 18  // SIGNAL 相关日志
    19 19  const (
    20  - SignalListenStart = "signal start proxy listener"
    21  - SignalListenStop = "signal stop proxy listener"
    22  - SignalListenRecover = "signal send recover proxy signal"
     20 + SignalStartProxy = "signal start proxy listener success"
     21 + SignalSpeedProxy = "signal speed proxy success"
     22 + SignalStopProxy = "signal stop proxy success"
     23 + SignalDeleteProxy = "signal delete proxy success"
     24 + 
     25 + SignalSyncProvider = "signal sync provider success"
     26 + SignalDeleteProvider = "signal delete provider success"
     27 + 
     28 + SignalDeployTunnel = "signal deploy tunnel success"
     29 + SignalStopTunnel = "signal stop tunnel success"
     30 + SignalDeleteTunnel = "signal delete tunnel success"
    23 31  )
    24 32   
    25 33  // DB 相关日志
    skipped 8 lines
    34 42   SDKWaitingFCStatus = "sdk waiting for function create success"
    35 43  )
    36 44   
     45 +// Signal 相关告警
     46 +const (
     47 + SignalMissOperationWarn = "signal received unchanged status"
     48 +)
     49 + 
     50 +// API 相关错误
     51 +const (
     52 + ApiCommonError = "api error"
     53 + ApiServeError = "api serve error"
     54 + ApiParamsError = "api request params error"
     55 + ApiParamsExist = "api request params already exist"
     56 + ApiParamsRequire = "api require params missing"
     57 + ApiServiceError = "api request service error"
     58 + ApiAuthError = "api request auth error"
     59 + ApiAuthRequire = "api require auth missing"
     60 + ApiAuthLimit = "api request auth limit"
     61 +)
     62 + 
     63 +// SERVICE 相关错误
     64 +const (
     65 + // ServiceProtocolNotSupportError * local service
     66 + ServiceProtocolNotSupportError = "service accept proto not support"
     67 + ServiceSocks5ReadMethodError = "service socks5 read method proto error"
     68 + ServiceSocks5WriteMethodError = "service socks5 write method proto error"
     69 + ServiceSocks5ReadCmdError = "service socks5 read command proto error"
     70 + ServiceSocks5DailError = "service socks5 dial to remote error"
     71 + ServiceSocks5ReplyError = "service socks5 write to reply success error"
     72 + 
     73 + // ServiceError remote server
     74 + ServiceError = "service remote error"
     75 + ServiceStatusError = "service remote status error "
     76 + ServiceTransportError = "service remote transport error"
     77 + ServiceV2rayInitError = "service remote init v2ray error"
     78 + 
     79 + // ServiceDBNeedParamsError error
     80 + ServiceDBNeedParamsError = "service operation params missing error"
     81 + ServiceDBUpdateStatusError = "service update status error"
     82 + ServiceDBUpdateFiledError = "service update field error"
     83 + ServiceDBDeleteError = "service delete status error"
     84 +)
     85 + 
     86 +// NETWORK 相关错误
     87 +const (
     88 + NetworkVersionError = "network bad version error"
     89 + NetworkAddrTypeError = "network bad address type error"
     90 + NetworkMethodError = "network bad method error"
     91 + NetworkTransportError = "network transport error"
     92 +)
     93 + 
     94 +// SDK 相关错误
     95 +const (
     96 + SDKFCInfoError = "sdk get function info error"
     97 + SDKFCDetailError = "sdk get function detail error"
     98 + SDKTriggerError = "sdk get function trigger error"
     99 + SDKTriggerUnmarshalError = "sdk unmarshal function trigger error"
     100 +)
     101 + 
     102 +// LISTENER 相关错误
     103 +const (
     104 + ListenerAcceptError = "listener unexpect error"
     105 + ListenerDailError = "listener dail to remote error"
     106 + ListenerLagError = "listener latency calculation error"
     107 +)
     108 + 
     109 +// SIGNAL 相关错误
     110 +const (
     111 + SignalGetObjError = "signal try to get object from db error"
     112 + SignalUpdateObjError = "signal try to update object from db error"
     113 + SignalListenerError = "signal listener unexpect error"
     114 + SignalRecoverProxyError = "signal try recover active proxy error"
     115 + SignalSpeedProxyError = "signal try test speed error"
     116 + SignalSyncProviderError = " signal try sync provider error"
     117 + SignalDeployTunError = "signal try deploy tunnel error"
     118 + SignalStopTunError = "signal try stop tunnel error"
     119 + SignalDeleteTunError = "signal try delete tunnel error"
     120 +)
     121 + 
  • ■ ■ ■ ■ ■ ■
    pkg/system/xlog/handler.go
    1  -package xlog
    2  - 
    3  -//
    4  -//import (
    5  -// "bytes"
    6  -// "context"
    7  -// "fmt"
    8  -// "io"
    9  -// "log/slog"
    10  -// "os"
    11  -//
    12  -// "github.com/gookit/color"
    13  -//)
    14  -//
    15  -//type Handler struct {
    16  -// level slog.Level
    17  -// path string
    18  -//}
    19  -//
    20  -//func (h Handler) Enabled(_ context.Context, level slog.Level) bool {
    21  -// return level >= h.level
    22  -//}
    23  -//
    24  -//func (h Handler) Handle(_ context.Context, r slog.Record) error {
    25  -// var buf bytes.Buffer
    26  -// buf.WriteString(h.color(r.Level, fmt.Sprintf("[%s]", r.Level.String())))
    27  -// buf.WriteByte(' ')
    28  -// buf.WriteString(h.color(r.Level, r.Message))
    29  -// return h.print(&buf)
    30  -//}
    31  -//
    32  -//func (h Handler) WithAttrs(attrs []slog.Attr) slog.Handler {
    33  -// //TODO implement me
    34  -// panic("implement me")
    35  -//}
    36  -//
    37  -//func (h Handler) WithGroup(name string) slog.Handler {
    38  -// //TODO implement me
    39  -// panic("implement me")
    40  -//}
    41  -//
    42  -//func (h Handler) color(level slog.Level, msg string) string {
    43  -// switch level {
    44  -// case slog.LevelDebug:
    45  -// return color.Gray.Sprintf(msg)
    46  -// case slog.LevelInfo:
    47  -// return color.Cyan.Sprintf(msg)
    48  -// case slog.LevelWarn:
    49  -// return color.Yellow.Sprintf(msg)
    50  -// case slog.LevelError:
    51  -// return color.Red.Sprintf(msg)
    52  -// }
    53  -// return ""
    54  -//}
    55  -//
    56  -//func (h Handler) print(reader io.Reader) error {
    57  -// if h.path != "" {
    58  -// file, err := os.OpenFile(h.path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
    59  -// if err != nil {
    60  -// return err
    61  -// }
    62  -// writer := io.MultiWriter(os.Stderr, file)
    63  -// _, err = io.Copy(writer, reader)
    64  -// return err
    65  -// }
    66  -// _, err := io.Copy(os.Stderr, reader)
    67  -// return err
    68  -//}
    69  - 
  • ■ ■ ■ ■ ■ ■
    pkg/system/xlog/logger.go
    skipped 73 lines
    74 74   defaultLog.Error(color.Red.Sprintf("[%s] %s", index, msg), args...)
    75 75  }
    76 76   
    77  -func renderArgs(args ...any) {
    78  - 
    79  -}
    80  - 
  • ■ ■ ■ ■
    pkg/system/consts/version.go pkg/system/xlog/version.go
    1  -package consts
     1 +package xlog
    2 2   
    3 3  var (
    4 4   Version string = "dev"
    skipped 3 lines
  • ■ ■ ■ ■ ■ ■
    pkg/tools/ptr.go
    skipped 111 lines
    112 112   return 0
    113 113  }
    114 114   
     115 +func AnyPtr(v interface{}) interface{} {
     116 + return &v
     117 +}
     118 + 
  • ■ ■ ■ ■ ■ ■
    pkg/transfer/socks5.go
    skipped 14 lines
    15 15   b, err := br.Peek(1)
    16 16   
    17 17   if err != nil || b[0] != network.SOCKS5Version {
    18  - return nil, errors.Wrap(err, errors.ServiceProtocolNotSupportError)
     18 + return nil, errors.Wrap(err, xlog.ServiceProtocolNotSupportError)
    19 19   }
    20 20   return br, nil
    21 21  }
    skipped 10 lines
    32 32   
    33 33   // select method
    34 34   if _, err = network.ReadMethods(conn); err != nil {
    35  - return errors.Wrap(err, errors.ServiceSocks5ReadMethodError)
     35 + return errors.Wrap(err, xlog.ServiceSocks5ReadMethodError)
    36 36   }
    37 37   
    38 38   if err = network.WriteMethod(network.MethodNoAuth, conn); err != nil {
    39  - return errors.Wrap(err, errors.ServiceSocks5WriteMethodError)
     39 + return errors.Wrap(err, xlog.ServiceSocks5WriteMethodError)
    40 40   }
    41 41   
    42 42   // read command
    43 43   request, err := network.ReadSOCKS5Request(conn)
    44 44   if err != nil {
    45  - return errors.Wrap(err, errors.ServiceSocks5ReadCmdError)
     45 + return errors.Wrap(err, xlog.ServiceSocks5ReadCmdError)
    46 46   }
    47 47   switch request.Cmd {
    48 48   case network.SOCKS5CmdConnect:
    skipped 18 lines
    67 67   destConn, err := dialer.Dial("tcp", req.Addr.String())
    68 68   
    69 69   if err != nil {
    70  - xlog.Error(errors.ServiceSocks5DailError, "err", err)
     70 + xlog.Error(xlog.ServiceSocks5DailError, "err", err)
    71 71   return
    72 72   }
    73 73   
    skipped 1 lines
    75 75   defer destConn.Close()
    76 76   
    77 77   if err := network.NewReply(network.SOCKS5RespSucceeded, nil).Write(conn); err != nil {
    78  - xlog.Error(errors.ServiceSocks5ReplyError, "err", err)
     78 + xlog.Error(xlog.ServiceSocks5ReplyError, "err", err)
    79 79   return
    80 80   }
    81 81   
    82 82   xlog.Info(xlog.ServiceSocks5Establish, "src", conn.RemoteAddr(), "dest", req.Addr)
    83 83   
    84 84   if _, _, err := network.Transport(conn, destConn); err != nil {
    85  - xlog.Error(errors.NetworkTransportError, "err", err)
     85 + xlog.Error(xlog.NetworkTransportError, "err", err)
    86 86   }
    87 87   
    88 88   xlog.Info(xlog.ServiceSocks5DisConnect, "src", conn.RemoteAddr(), "dest", req.Addr)
    skipped 10 lines
  • ■ ■ ■ ■ ■
    pkg/transfer/tor.go
    skipped 4 lines
    5 5   "time"
    6 6   
    7 7   "github.com/DVKunion/SeaMoon/pkg/network"
    8  - "github.com/DVKunion/SeaMoon/pkg/system/errors"
    9 8   "github.com/DVKunion/SeaMoon/pkg/system/xlog"
    10 9  )
    11 10   
    skipped 13 lines
    25 24   xlog.Info(xlog.ServiceTorConnectServer, "src", conn.RemoteAddr(), "dest", defaultTorAddr)
    26 25   
    27 26   if _, _, err := network.Transport(conn, destConn); err != nil {
    28  - xlog.Error(errors.NetworkTransportError, "err", err)
     27 + xlog.Error(xlog.NetworkTransportError, "err", err)
    29 28   }
    30 29   
    31 30   xlog.Info(xlog.ServiceTorDisConnect, "src", conn.RemoteAddr(), "dest", defaultTorAddr)
    skipped 4 lines
Please wait...
Page is in error, reload to recover