Skip to content

Commit

Permalink
Update | 远程关闭隧道和客户端
Browse files Browse the repository at this point in the history
  • Loading branch information
Daiyangcheng committed Aug 24, 2024
1 parent 1a15264 commit 0ca3d94
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 55 deletions.
71 changes: 29 additions & 42 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,41 @@ name: golangci-lint
on:
push:
branches:
- master
- dev
- master
- dev
pull_request:

permissions:
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
# pull-requests: read

pull-requests: read
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.20'
cache: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
# Require: The version of golangci-lint to use.
# When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version.
# When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit.
version: v1.54

# Optional: working directory, useful for monorepos
# working-directory: somedir

# Optional: golangci-lint command line arguments.
#
# Note: By default, the `.golangci.yml` file should be at the root of the repository.
# The location of the configuration file can be changed by using `--config=`
# args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0

# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true

# Optional: if set to true, then all caching functionality will be completely disabled,
# takes precedence over all other caching options.
# skip-cache: true

# Optional: if set to true, then the action won't cache or restore ~/go/pkg.
# skip-pkg-cache: true

# Optional: if set to true, then the action won't cache or restore ~/.cache/go-build.
# skip-build-cache: true

# Optional: The mode to install golangci-lint. It can be 'binary' or 'goinstall'.
# install-mode: "goinstall"
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.23'
cache: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v4
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: v1.57

# Optional: golangci-lint command line arguments.
# args: --issues-exit-code=0

# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true

# Optional: if set to true then the all caching functionality will be complete disabled,
# takes precedence over all other caching options.
# skip-cache: true

# Optional: if set to true then the action don't cache or restore ~/go/pkg.
# skip-pkg-cache: true

# Optional: if set to true then the action don't cache or restore ~/.cache/go-build.
# skip-build-cache: true
18 changes: 16 additions & 2 deletions client/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import (
"context"
"io"
"net"
"os"
"runtime/debug"
"strings"
"time"

"github.com/fatedier/golib/control/shutdown"
Expand Down Expand Up @@ -172,10 +174,10 @@ func (ctl *Control) HandleNewProxyResp(inMsg *msg.NewProxyResp) {
// http(s) 隧道规则
if ctl.pxyCfgs[inMsg.ProxyName].GetBaseConfig().ProxyType == "https" || ctl.pxyCfgs[inMsg.ProxyName].GetBaseConfig().ProxyType == "http" {
xl.Info("[%s] 映射启动成功, 感谢您使用LCF!", inMsg.ProxyName)
xl.Info("你可以使用 [%s] 连接至您的隧道: %s", inMsg.RemoteAddr, inMsg.ProxyName)
xl.Info("您可以使用 [%s] 连接至您的隧道: %s", inMsg.RemoteAddr, strings.Split(inMsg.ProxyName, ".")[1])
} else {
xl.Info("[%s] 映射启动成功, 感谢您使用LCF!", inMsg.ProxyName)
xl.Info("你可以使用 [%s] 连接至您的隧道: %s", ctl.clientCfg.ServerAddr+inMsg.RemoteAddr, inMsg.ProxyName)
xl.Info("您可以使用 [%s] 连接至您的隧道: %s", ctl.clientCfg.ServerAddr+inMsg.RemoteAddr, strings.Split(inMsg.ProxyName, ".")[1])
}
}
}
Expand Down Expand Up @@ -326,6 +328,8 @@ func (ctl *Control) msgHandler() {
ctl.HandleNewProxyResp(m)
case *msg.NatHoleResp:
ctl.HandleNatHoleResp(m)
case *msg.CloseClient:
ctl.HandleCloseClient(m)
case *msg.Pong:
if m.Error != "" {
xl.Error("Pong contains error: %s", m.Error)
Expand All @@ -339,6 +343,16 @@ func (ctl *Control) msgHandler() {
}
}

func (ctl *Control) HandleCloseClient(ClientInfo *msg.CloseClient) {
xl := ctl.xl
if ClientInfo.Token != ctl.clientCfg.User {
xl.Warn("客户端 User 与传递的 User 不符")
return
}
xl.Info("您的客户端已被服务端强制下线")
os.Exit(0)
}

// If controler is notified by closedCh, reader and writer and handler will exit
func (ctl *Control) worker() {
go ctl.msgHandler()
Expand Down
2 changes: 1 addition & 1 deletion cmd/frpc/sub/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ var rootCmd = &cobra.Command{
return nil
}

log.Info("欢迎使用LoCyanFrp, Stable Version: v0.51.3 - #2024021801")
log.Info("欢迎使用 LoCyanFrp, Stable Version: v0.51.3 - #2024082401")

// If cfgDir is not empty, run multiple frpc service for each config file in cfgDir.
// Note that it's only designed for testing. It's not guaranteed to be stable.
Expand Down
11 changes: 5 additions & 6 deletions frpc.ini
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
[common]
server_addr = hk-50-2.lcf.icu
server_port = 2333
server_addr = 127.0.0.1
server_port = 7000
tcp_mux = true
protocol = tcp
user = 2dee0462938afc8a98cb761f321463a0
token = LoCyanToken
dns_server = 223.6.6.6
tls_enable = false

[SFSEGSEG]
privilege_mode = true
type = http
type = tcp
local_ip = 127.0.0.1
local_port = 80
custom_domains = www.daiyangcheng.cn
remote_port = 12345
use_encryption = false
use_compression = false

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/fatedier/frp

go 1.20
go 1.23

require (
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
Expand Down
6 changes: 6 additions & 0 deletions pkg/msg/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const (
TypeNewProxy = 'p'
TypeNewProxyResp = '2'
TypeCloseProxy = 'c'
TypeCloseClient = 'd'
TypeNewWorkConn = 'w'
TypeReqWorkConn = 'r'
TypeStartWorkConn = 's'
Expand All @@ -46,6 +47,7 @@ var msgTypeMap = map[byte]interface{}{
TypeNewProxy: NewProxy{},
TypeNewProxyResp: NewProxyResp{},
TypeCloseProxy: CloseProxy{},
TypeCloseClient: CloseClient{},
TypeNewWorkConn: NewWorkConn{},
TypeReqWorkConn: ReqWorkConn{},
TypeStartWorkConn: StartWorkConn{},
Expand Down Expand Up @@ -230,3 +232,7 @@ type NatHoleReport struct {
Sid string `json:"sid,omitempty"`
Success bool `json:"success,omitempty"`
}

type CloseClient struct {
Token string `json:"token,omitempty"`
}
14 changes: 14 additions & 0 deletions server/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ func (cm *ControlManager) SearchByID(runID string) (ctl *Control, ok bool) {
return
}

func (cm *ControlManager) SearchByProxyRunID(runID string) (ctl *Control, ok bool) {
cm.mu.RLock()
defer cm.mu.RUnlock()
for k, v := range cm.ctlsByRunID {
if strings.Contains(k, runID) {
if v == nil {
return
}
ctl, ok = cm.ctlsByRunID[k]
}
}
return
}

func (cm *ControlManager) Close() error {
cm.mu.Lock()
defer cm.mu.Unlock()
Expand Down
3 changes: 2 additions & 1 deletion server/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ func (svr *Service) RunDashboardServer(address string) (err error) {
subRouter.HandleFunc("/api/proxy/{type}", svr.APIProxyByType).Methods("GET")
subRouter.HandleFunc("/api/proxy/{type}/{name}", svr.APIProxyByTypeAndName).Methods("GET")
subRouter.HandleFunc("/api/traffic/{name}", svr.APIProxyTraffic).Methods("GET")
subRouter.HandleFunc("/api/client/close/{user}", svr.APICloseClient).Methods("GET")
subRouter.HandleFunc("/api/close/client/{user}", svr.APICloseClient).Methods("GET")
subRouter.HandleFunc("/api/close/proxy/{run_id}", svr.APICloseProxy).Methods("GET")

// view
subRouter.Handle("/favicon.ico", http.FileServer(assets.FileSystem)).Methods("GET")
Expand Down
28 changes: 27 additions & 1 deletion server/dashboard_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ func (svr *Service) APICloseClient(w http.ResponseWriter, r *http.Request) {
log.Info("Http response [/api/client/close/{user}]: code [%d]", resp.Status)
}()
log.Info("Http request: [/api/client/close/{user}] %#v", user)
err := svr.CloseUser(user)
err := svr.CloseClient(user)
if err != nil {
resp.Status = 404
resp.Msg = err.Error()
Expand All @@ -377,3 +377,29 @@ func (svr *Service) APICloseClient(w http.ResponseWriter, r *http.Request) {

_, _ = w.Write(buf)
}

func (svr *Service) APICloseProxy(w http.ResponseWriter, r *http.Request) {
var (
buf []byte
resp = CloseUserResp{}
)
params := mux.Vars(r)
runID := params["run_id"]
defer func() {
log.Info("Http response [/api/proxy/close/{run_id}]: code [%d]", resp.Status)
}()
log.Info("Http request: [/api/proxy/close/{run_id}] %#v", runID)
err := svr.CloseProxy(runID)
if err != nil {
resp.Status = 404
resp.Msg = err.Error()
resp.RunID = "nan"
} else {
resp.Status = 200
resp.Msg = "OK"
resp.RunID = runID
}
buf, _ = json.Marshal(&resp)

_, _ = w.Write(buf)
}
13 changes: 12 additions & 1 deletion server/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -656,11 +656,22 @@ func (svr *Service) RegisterVisitorConn(visitorConn net.Conn, newMsg *msg.NewVis
newMsg.UseEncryption, newMsg.UseCompression, visitorUser)
}

func (svr *Service) CloseUser(user string) error {
func (svr *Service) CloseClient(user string) error {
ctl, ok := svr.ctlManager.SearchByID(user)
if !ok {
return fmt.Errorf("user not login")
}
// 发送关闭客户端指令并由 Client 的 Control 处理
CloseInfo := &msg.CloseClient{Token: user}
ctl.sendCh <- CloseInfo
return nil
}

func (svr *Service) CloseProxy(runID string) error {
ctl, ok := svr.ctlManager.SearchByProxyRunID(runID)
if !ok {
return fmt.Errorf("user not login")
}
ctl.allShutdown.Start()
return nil
}

0 comments on commit 0ca3d94

Please sign in to comment.