aboutsummaryrefslogtreecommitdiff
path: root/src/gnunet/cmd/gnunet-service-dht-test-go/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnunet/cmd/gnunet-service-dht-test-go/main.go')
-rw-r--r--src/gnunet/cmd/gnunet-service-dht-test-go/main.go152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/gnunet/cmd/gnunet-service-dht-test-go/main.go b/src/gnunet/cmd/gnunet-service-dht-test-go/main.go
new file mode 100644
index 0000000..cd2bd1a
--- /dev/null
+++ b/src/gnunet/cmd/gnunet-service-dht-test-go/main.go
@@ -0,0 +1,152 @@
1// This file is part of gnunet-go, a GNUnet-implementation in Golang.
2// Copyright (C) 2019-2022 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/core"
32 "gnunet/rpc"
33 "gnunet/service"
34 "gnunet/service/dht"
35
36 "github.com/bfix/gospel/logger"
37)
38
39func main() {
40 defer func() {
41 logger.Println(logger.INFO, "[dht] Bye.")
42 // flush last messages
43 logger.Flush()
44 }()
45 logger.Println(logger.INFO, "[dht] Starting service...")
46
47 var (
48 cfgFile string
49 socket string
50 param string
51 err error
52 logLevel int
53 rpcEndp string
54 )
55 // handle command line arguments
56 flag.StringVar(&cfgFile, "c", "gnunet-config.json", "GNUnet configuration file")
57 flag.StringVar(&socket, "s", "", "GNS service socket")
58 flag.StringVar(&param, "p", "", "socket parameters (<key>=<value>,...)")
59 flag.IntVar(&logLevel, "L", logger.INFO, "DHT log level (default: INFO)")
60 flag.StringVar(&rpcEndp, "R", "", "JSON-RPC endpoint (default: none)")
61 flag.Parse()
62
63 // read configuration file and set missing arguments.
64 if err = config.ParseConfig(cfgFile); err != nil {
65 logger.Printf(logger.ERROR, "[dht] Invalid configuration file: %s\n", err.Error())
66 return
67 }
68
69 // apply configuration
70 logger.SetLogLevel(logLevel)
71 if len(socket) == 0 {
72 socket = config.Cfg.GNS.Service.Socket
73 }
74 params := make(map[string]string)
75 if len(param) == 0 {
76 for _, p := range strings.Split(param, ",") {
77 kv := strings.SplitN(p, "=", 2)
78 params[kv[0]] = kv[1]
79 }
80 } else {
81 params = config.Cfg.GNS.Service.Params
82 }
83
84 // instantiate core service
85 ctx, cancel := context.WithCancel(context.Background())
86 var local *core.Peer
87 if local, err = core.NewLocalPeer(config.Cfg.Local); err != nil {
88 logger.Printf(logger.ERROR, "[dht] No local peer: %s\n", err.Error())
89 return
90 }
91 var c *core.Core
92 if c, err = core.NewCore(ctx, local); err != nil {
93 logger.Printf(logger.ERROR, "[dht] core failed: %s\n", err.Error())
94 return
95 }
96
97 // start a new DHT service
98 dht := dht.NewService(ctx, c)
99 srv := service.NewSocketHandler("dht", dht)
100 if err = srv.Start(ctx, socket, params); err != nil {
101 logger.Printf(logger.ERROR, "[dht] Failed to start DHT service: '%s'", err.Error())
102 return
103 }
104
105 // start JSON-RPC server on request
106 if len(rpcEndp) > 0 {
107 parts := strings.Split(rpcEndp, ":")
108 if parts[0] != "tcp" {
109 logger.Println(logger.ERROR, "[dht] RPC must have a TCP/IP endpoint")
110 return
111 }
112 config.Cfg.RPC.Endpoint = parts[1]
113 if err = rpc.Start(ctx); err != nil {
114 logger.Printf(logger.ERROR, "[dht] RPC failed to start: %s", err.Error())
115 return
116 }
117 rpc.Register(dht)
118 }
119
120 // handle OS signals
121 sigCh := make(chan os.Signal, 5)
122 signal.Notify(sigCh)
123
124 // heart beat
125 tick := time.NewTicker(5 * time.Minute)
126
127loop:
128 for {
129 select {
130 // handle OS signals
131 case sig := <-sigCh:
132 switch sig {
133 case syscall.SIGKILL, syscall.SIGINT, syscall.SIGTERM:
134 logger.Printf(logger.INFO, "[dht] Terminating service (on signal '%s')\n", sig)
135 break loop
136 case syscall.SIGHUP:
137 logger.Println(logger.INFO, "[dht] SIGHUP")
138 case syscall.SIGURG:
139 // TODO: https://github.com/golang/go/issues/37942
140 default:
141 logger.Println(logger.INFO, "[dht] Unhandled signal: "+sig.String())
142 }
143 // handle heart beat
144 case now := <-tick.C:
145 logger.Println(logger.INFO, "[dht] Heart beat at "+now.String())
146 }
147 }
148
149 // terminating service
150 cancel()
151 srv.Stop()
152}