"Fossies" - the Fresh Open Source Software Archive

Member "frp-0.36.2/cmd/frpc/sub/root.go" (22 Mar 2021, 5957 Bytes) of package /linux/misc/frp-0.36.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "root.go": 0.36.1_vs_0.36.2.

    1 // Copyright 2018 fatedier, fatedier@gmail.com
    2 //
    3 // Licensed under the Apache License, Version 2.0 (the "License");
    4 // you may not use this file except in compliance with the License.
    5 // You may obtain a copy of the License at
    6 //
    7 //     http://www.apache.org/licenses/LICENSE-2.0
    8 //
    9 // Unless required by applicable law or agreed to in writing, software
   10 // distributed under the License is distributed on an "AS IS" BASIS,
   11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12 // See the License for the specific language governing permissions and
   13 // limitations under the License.
   14 
   15 package sub
   16 
   17 import (
   18     "context"
   19     "fmt"
   20     "net"
   21     "os"
   22     "os/signal"
   23     "strconv"
   24     "strings"
   25     "syscall"
   26     "time"
   27 
   28     "github.com/fatedier/frp/client"
   29     "github.com/fatedier/frp/pkg/auth"
   30     "github.com/fatedier/frp/pkg/config"
   31     "github.com/fatedier/frp/pkg/util/log"
   32     "github.com/fatedier/frp/pkg/util/version"
   33 
   34     "github.com/spf13/cobra"
   35 )
   36 
   37 const (
   38     CfgFileTypeIni = iota
   39     CfgFileTypeCmd
   40 )
   41 
   42 var (
   43     cfgFile     string
   44     showVersion bool
   45 
   46     serverAddr      string
   47     user            string
   48     protocol        string
   49     token           string
   50     logLevel        string
   51     logFile         string
   52     logMaxDays      int
   53     disableLogColor bool
   54 
   55     proxyName         string
   56     localIP           string
   57     localPort         int
   58     remotePort        int
   59     useEncryption     bool
   60     useCompression    bool
   61     customDomains     string
   62     subDomain         string
   63     httpUser          string
   64     httpPwd           string
   65     locations         string
   66     hostHeaderRewrite string
   67     role              string
   68     sk                string
   69     multiplexer       string
   70     serverName        string
   71     bindAddr          string
   72     bindPort          int
   73 
   74     tlsEnable bool
   75 
   76     kcpDoneCh chan struct{}
   77 )
   78 
   79 func init() {
   80     rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "./frpc.ini", "config file of frpc")
   81     rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frpc")
   82 
   83     kcpDoneCh = make(chan struct{})
   84 }
   85 
   86 func RegisterCommonFlags(cmd *cobra.Command) {
   87     cmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
   88     cmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
   89     cmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp or websocket")
   90     cmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
   91     cmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
   92     cmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
   93     cmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
   94     cmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
   95     cmd.PersistentFlags().BoolVarP(&tlsEnable, "tls_enable", "", false, "enable frpc tls")
   96 }
   97 
   98 var rootCmd = &cobra.Command{
   99     Use:   "frpc",
  100     Short: "frpc is the client of frp (https://github.com/fatedier/frp)",
  101     RunE: func(cmd *cobra.Command, args []string) error {
  102         if showVersion {
  103             fmt.Println(version.Full())
  104             return nil
  105         }
  106 
  107         // Do not show command usage here.
  108         err := runClient(cfgFile)
  109         if err != nil {
  110             fmt.Println(err)
  111             os.Exit(1)
  112         }
  113         return nil
  114     },
  115 }
  116 
  117 func Execute() {
  118     if err := rootCmd.Execute(); err != nil {
  119         os.Exit(1)
  120     }
  121 }
  122 
  123 func handleSignal(svr *client.Service) {
  124     ch := make(chan os.Signal)
  125     signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
  126     <-ch
  127     svr.Close()
  128     time.Sleep(250 * time.Millisecond)
  129     close(kcpDoneCh)
  130 }
  131 
  132 func parseClientCommonCfg(fileType int, source []byte) (cfg config.ClientCommonConf, err error) {
  133     if fileType == CfgFileTypeIni {
  134         cfg, err = config.UnmarshalClientConfFromIni(source)
  135     } else if fileType == CfgFileTypeCmd {
  136         cfg, err = parseClientCommonCfgFromCmd()
  137     }
  138     if err != nil {
  139         return
  140     }
  141 
  142     cfg.Complete()
  143     err = cfg.Validate()
  144     if err != nil {
  145         err = fmt.Errorf("Parse config error: %v", err)
  146         return
  147     }
  148     return
  149 }
  150 
  151 func parseClientCommonCfgFromCmd() (cfg config.ClientCommonConf, err error) {
  152     cfg = config.GetDefaultClientConf()
  153 
  154     ipStr, portStr, err := net.SplitHostPort(serverAddr)
  155     if err != nil {
  156         err = fmt.Errorf("invalid server_addr: %v", err)
  157         return
  158     }
  159 
  160     cfg.ServerAddr = ipStr
  161     cfg.ServerPort, err = strconv.Atoi(portStr)
  162     if err != nil {
  163         err = fmt.Errorf("invalid server_addr: %v", err)
  164         return
  165     }
  166 
  167     cfg.User = user
  168     cfg.Protocol = protocol
  169     cfg.LogLevel = logLevel
  170     cfg.LogFile = logFile
  171     cfg.LogMaxDays = int64(logMaxDays)
  172     cfg.DisableLogColor = disableLogColor
  173 
  174     // Only token authentication is supported in cmd mode
  175     cfg.ClientConfig = auth.GetDefaultClientConf()
  176     cfg.Token = token
  177     cfg.TLSEnable = tlsEnable
  178 
  179     return
  180 }
  181 
  182 func runClient(cfgFilePath string) (err error) {
  183     var content []byte
  184     content, err = config.GetRenderedConfFromFile(cfgFilePath)
  185     if err != nil {
  186         return err
  187     }
  188 
  189     cfg, err := parseClientCommonCfg(CfgFileTypeIni, content)
  190     if err != nil {
  191         return err
  192     }
  193 
  194     pxyCfgs, visitorCfgs, err := config.LoadAllProxyConfsFromIni(cfg.User, content, cfg.Start)
  195     if err != nil {
  196         return err
  197     }
  198 
  199     return startService(cfg, pxyCfgs, visitorCfgs, cfgFilePath)
  200 }
  201 
  202 func startService(
  203     cfg config.ClientCommonConf,
  204     pxyCfgs map[string]config.ProxyConf,
  205     visitorCfgs map[string]config.VisitorConf,
  206     cfgFile string,
  207 ) (err error) {
  208 
  209     log.InitLog(cfg.LogWay, cfg.LogFile, cfg.LogLevel,
  210         cfg.LogMaxDays, cfg.DisableLogColor)
  211 
  212     if cfg.DNSServer != "" {
  213         s := cfg.DNSServer
  214         if !strings.Contains(s, ":") {
  215             s += ":53"
  216         }
  217         // Change default dns server for frpc
  218         net.DefaultResolver = &net.Resolver{
  219             PreferGo: true,
  220             Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
  221                 return net.Dial("udp", s)
  222             },
  223         }
  224     }
  225     svr, errRet := client.NewService(cfg, pxyCfgs, visitorCfgs, cfgFile)
  226     if errRet != nil {
  227         err = errRet
  228         return
  229     }
  230 
  231     // Capture the exit signal if we use kcp.
  232     if cfg.Protocol == "kcp" {
  233         go handleSignal(svr)
  234     }
  235 
  236     err = svr.Run()
  237     if cfg.Protocol == "kcp" {
  238         <-kcpDoneCh
  239     }
  240     return
  241 }