From cb1e30ec9a910aec0941aeed2b988a63df3cdbc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=8F=E4=B8=96=E9=BE=99?= Date: Mon, 9 Apr 2018 14:08:16 +0800 Subject: [PATCH] add service mode for frp --- Makefile | 2 + service/frpc/main.go | 130 +++++++++++++++++++++++++++++++++++++++++++ service/frps/main.go | 109 ++++++++++++++++++++++++++++++++++++ 3 files changed, 241 insertions(+) create mode 100644 service/frpc/main.go create mode 100644 service/frps/main.go diff --git a/Makefile b/Makefile index b91b3348..82d48cf9 100644 --- a/Makefile +++ b/Makefile @@ -19,10 +19,12 @@ fmt: frps: go build -o bin/frps ./cmd/frps + go build -o bin/frps_service ./service/frps @cp -rf ./assets/static ./bin frpc: go build -o bin/frpc ./cmd/frpc + go build -o bin/frpc_service ./service/frpc test: gotest diff --git a/service/frpc/main.go b/service/frpc/main.go new file mode 100644 index 00000000..ff90f4da --- /dev/null +++ b/service/frpc/main.go @@ -0,0 +1,130 @@ +// Copyright 2016 fatedier, fatedier@gmail.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "os" + "os/signal" + "path/filepath" + "syscall" + "time" + + ini "github.com/vaughan0/go-ini" + + "github.com/fatedier/frp/client" + "github.com/fatedier/frp/models/config" + "github.com/fatedier/frp/utils/log" + "github.com/kardianos/service" +) + +var logger service.Logger + +type program struct{} + +func (p *program) Start(s service.Service) error { + // Start should not block. Do the actual work async. + go p.run() + return nil +} + +func (p *program) run() { + var err error + fileDir := filepath.Dir(os.Args[0]) + confFile := filepath.Join(fileDir, "frpc.ini") + + logger.Infof("get config file path:%s", confFile) + + conf, err := ini.LoadFile(confFile) + if err != nil { + logger.Error(err) + os.Exit(1) + } + + config.ClientCommonCfg, err = config.LoadClientCommonConf(conf) + if err != nil { + logger.Error(err) + os.Exit(1) + } + config.ClientCommonCfg.ConfigFile = confFile + + pxyCfgs, visitorCfgs, err := config.LoadProxyConfFromFile(config.ClientCommonCfg.User, conf, config.ClientCommonCfg.Start) + if err != nil { + logger.Error(err) + os.Exit(1) + } + + log.InitLog(config.ClientCommonCfg.LogWay, config.ClientCommonCfg.LogFile, + config.ClientCommonCfg.LogLevel, config.ClientCommonCfg.LogMaxDays) + + svr := client.NewService(pxyCfgs, visitorCfgs) + + // Capture the exit signal if we use kcp. + if config.ClientCommonCfg.Protocol == "kcp" { + go HandleSignal(svr) + } + + err = svr.Run() + if err != nil { + logger.Error(err) + os.Exit(1) + } +} + +func HandleSignal(svr *client.Service) { + ch := make(chan os.Signal) + signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) + <-ch + svr.Close() + time.Sleep(250 * time.Millisecond) + os.Exit(0) +} + +func (p *program) Stop(s service.Service) error { + // Stop should not block. Return with a few seconds. + return nil +} + +func main() { + svcConfig := &service.Config{ + Name: "frpc service", + DisplayName: "frpc service", + Description: "config file frpc.ini", + } + + prg := &program{} + s, err := service.New(prg, svcConfig) + if err != nil { + log.Error(err.Error()) + } + logger, err = s.Logger(nil) + if err != nil { + log.Error(err.Error()) + } + + if len(os.Args) == 2 { //如果有命令则执行 + err = service.Control(s, os.Args[1]) + if err != nil { + logger.Error(err) + } + } else { //否则说明是方法启动了 + err = s.Run() + if err != nil { + logger.Error(err) + } + } + if err != nil { + logger.Error(err) + } +} diff --git a/service/frps/main.go b/service/frps/main.go new file mode 100644 index 00000000..5af242ef --- /dev/null +++ b/service/frps/main.go @@ -0,0 +1,109 @@ +// Copyright 2016 fatedier, fatedier@gmail.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "os" + "path/filepath" + + ini "github.com/vaughan0/go-ini" + + "github.com/fatedier/frp/models/config" + "github.com/fatedier/frp/server" + "github.com/fatedier/frp/utils/log" + "github.com/kardianos/service" +) + +var logger service.Logger + +type program struct{} + +func (p *program) Start(s service.Service) error { + // Start should not block. Do the actual work async. + go p.run() + return nil +} + +func (p *program) run() { + // Do work here + var err error + fileDir := filepath.Dir(os.Args[0]) + confFile := filepath.Join(fileDir, "frps.ini") + logger.Infof("get config file path:%s", confFile) + + conf, err := ini.LoadFile(confFile) + if err != nil { + logger.Info(err) + os.Exit(1) + } + config.ServerCommonCfg, err = config.LoadServerCommonConf(conf) + if err != nil { + logger.Info(err) + os.Exit(1) + } + + log.InitLog(config.ServerCommonCfg.LogWay, config.ServerCommonCfg.LogFile, + config.ServerCommonCfg.LogLevel, config.ServerCommonCfg.LogMaxDays) + + svr, err := server.NewService() + if err != nil { + logger.Info(err) + os.Exit(1) + } + log.Info("Start frps success") + if config.ServerCommonCfg.PrivilegeMode == true { + log.Info("PrivilegeMode is enabled, you should pay more attention to security issues") + } + server.ServerService = svr + svr.Run() +} + +func (p *program) Stop(s service.Service) error { + // Stop should not block. Return with a few seconds. + return nil +} + +func main() { + svcConfig := &service.Config{ + Name: "frps service", + DisplayName: "frps service", + Description: "config file frps.ini", + } + + prg := &program{} + s, err := service.New(prg, svcConfig) + if err != nil { + log.Error(err.Error()) + } + logger, err = s.Logger(nil) + if err != nil { + log.Error(err.Error()) + } + + if len(os.Args) == 2 { //如果有命令则执行 + err = service.Control(s, os.Args[1]) + if err != nil { + logger.Error(err) + } + } else { //否则说明是方法启动了 + err = s.Run() + if err != nil { + logger.Error(err) + } + } + if err != nil { + logger.Error(err) + } +}