aboutsummaryrefslogtreecommitdiff
path: root/src/gnunet/cmd/gnunet-service-gns-go/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnunet/cmd/gnunet-service-gns-go/main.go')
-rw-r--r--src/gnunet/cmd/gnunet-service-gns-go/main.go139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/gnunet/cmd/gnunet-service-gns-go/main.go b/src/gnunet/cmd/gnunet-service-gns-go/main.go
new file mode 100644
index 0000000..6eb027b
--- /dev/null
+++ b/src/gnunet/cmd/gnunet-service-gns-go/main.go
@@ -0,0 +1,139 @@
1// This file is part of gnunet-go, a GNUnet-implementation in Golang.
2// Copyright (C) 2019, 2020 Bernd Fix >Y<
3//
4// gnunet-go is free software: you can redistribute it and/or modify it
5// under the terms of the GNU Affero General Public License as published
6// by the Free Software Foundation, either version 3 of the License,
7// or (at your option) any later version.
8//
9// gnunet-go is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Affero General Public License for more details.
13//
14// You should have received a copy of the GNU Affero General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16//
17// SPDX-License-Identifier: AGPL3.0-or-later
18
19package main
20
21import (
22 "context"
23 "flag"
24 "os"
25 "os/signal"
26 "strings"
27 "syscall"
28 "time"
29
30 "gnunet/config"
31 "gnunet/rpc"
32 "gnunet/service"
33 "gnunet/service/gns"
34
35 "github.com/bfix/gospel/logger"
36)
37
38func main() {
39 defer func() {
40 logger.Println(logger.INFO, "[gns] Bye.")
41 // flush last messages
42 logger.Flush()
43 }()
44 logger.Println(logger.INFO, "[gns] Starting service...")
45
46 var (
47 cfgFile string
48 socket string
49 param string
50 err error
51 logLevel int
52 rpcEndp string
53 )
54 // handle command line arguments
55 flag.StringVar(&cfgFile, "c", "gnunet-config.json", "GNUnet configuration file")
56 flag.StringVar(&socket, "s", "", "GNS service socket")
57 flag.StringVar(&param, "p", "", "socket parameters (<key>=<value>,...)")
58 flag.IntVar(&logLevel, "L", logger.INFO, "GNS log level (default: INFO)")
59 flag.StringVar(&rpcEndp, "R", "", "JSON-RPC endpoint (default: none)")
60 flag.Parse()
61
62 // read configuration file and set missing arguments.
63 if err = config.ParseConfig(cfgFile); err != nil {
64 logger.Printf(logger.ERROR, "[gns] Invalid configuration file: %s\n", err.Error())
65 return
66 }
67
68 // apply configuration (from file and command-line)
69 logger.SetLogLevel(logLevel)
70 if len(socket) == 0 {
71 socket = config.Cfg.GNS.Service.Socket
72 }
73 params := make(map[string]string)
74 if len(param) == 0 {
75 for _, p := range strings.Split(param, ",") {
76 kv := strings.SplitN(p, "=", 2)
77 params[kv[0]] = kv[1]
78 }
79 } else {
80 params = config.Cfg.GNS.Service.Params
81 }
82
83 // start a new GNS service
84 ctx, cancel := context.WithCancel(context.Background())
85 gns := gns.NewService()
86 srv := service.NewSocketHandler("gns", gns)
87 if err = srv.Start(ctx, socket, params); err != nil {
88 logger.Printf(logger.ERROR, "[gns] Error: '%s'", err.Error())
89 return
90 }
91
92 // start JSON-RPC server on request
93 if len(rpcEndp) > 0 {
94 parts := strings.Split(rpcEndp, ":")
95 if parts[0] != "tcp" {
96 logger.Println(logger.ERROR, "[gns] RPC must have a TCP/IP endpoint")
97 return
98 }
99 config.Cfg.RPC.Endpoint = parts[1]
100 if err = rpc.Start(ctx); err != nil {
101 logger.Printf(logger.ERROR, "[gns] RPC failed to start: %s", err.Error())
102 return
103 }
104 rpc.Register(gns)
105 }
106
107 // handle OS signals
108 sigCh := make(chan os.Signal, 5)
109 signal.Notify(sigCh)
110
111 // heart beat
112 tick := time.NewTicker(5 * time.Minute)
113
114loop:
115 for {
116 select {
117 // handle OS signals
118 case sig := <-sigCh:
119 switch sig {
120 case syscall.SIGKILL, syscall.SIGINT, syscall.SIGTERM:
121 logger.Printf(logger.INFO, "[gns] Terminating service (on signal '%s')\n", sig)
122 break loop
123 case syscall.SIGHUP:
124 logger.Println(logger.INFO, "[gns] SIGHUP")
125 case syscall.SIGURG:
126 // TODO: https://github.com/golang/go/issues/37942
127 default:
128 logger.Println(logger.INFO, "[gns] Unhandled signal: "+sig.String())
129 }
130 // handle heart beat
131 case now := <-tick.C:
132 logger.Println(logger.INFO, "[gns] Heart beat at "+now.String())
133 }
134 }
135
136 // terminating service
137 cancel()
138 srv.Stop()
139}