diff options
Diffstat (limited to 'src/gnunet/cmd/peer_mockup/main.go')
-rw-r--r-- | src/gnunet/cmd/peer_mockup/main.go | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/gnunet/cmd/peer_mockup/main.go b/src/gnunet/cmd/peer_mockup/main.go new file mode 100644 index 0000000..4288fb1 --- /dev/null +++ b/src/gnunet/cmd/peer_mockup/main.go | |||
@@ -0,0 +1,178 @@ | |||
1 | package main | ||
2 | |||
3 | import ( | ||
4 | "context" | ||
5 | "flag" | ||
6 | "fmt" | ||
7 | "os" | ||
8 | "os/signal" | ||
9 | "syscall" | ||
10 | "time" | ||
11 | |||
12 | "gnunet/config" | ||
13 | "gnunet/core" | ||
14 | "gnunet/crypto" | ||
15 | "gnunet/message" | ||
16 | "gnunet/service" | ||
17 | |||
18 | "github.com/bfix/gospel/logger" | ||
19 | ) | ||
20 | |||
21 | var ( | ||
22 | // configuration for local node | ||
23 | localCfg = &config.NodeConfig{ | ||
24 | PrivateSeed: "YGoe6XFH3XdvFRl+agx9gIzPTvxA229WFdkazEMdcOs=", | ||
25 | Endpoints: []string{ | ||
26 | "udp:127.0.0.1:2086", | ||
27 | }, | ||
28 | } | ||
29 | // configuration for remote node | ||
30 | remoteCfg = "3GXXMNb5YpIUO7ejIR2Yy0Cf5texuLfDjHkXcqbPxkc=" | ||
31 | remoteAddr = "udp:172.17.0.5:2086" | ||
32 | |||
33 | // top-level variables used accross functions | ||
34 | local *core.Peer // local peer (with private key) | ||
35 | remote *core.Peer // remote peer | ||
36 | c *core.Core | ||
37 | secret *crypto.HashCode | ||
38 | ) | ||
39 | |||
40 | func main() { | ||
41 | ctx, cancel := context.WithCancel(context.Background()) | ||
42 | defer cancel() | ||
43 | |||
44 | // handle command line arguments | ||
45 | var ( | ||
46 | asServer bool | ||
47 | err error | ||
48 | ) | ||
49 | flag.BoolVar(&asServer, "s", false, "wait for incoming connections") | ||
50 | flag.Parse() | ||
51 | |||
52 | // setup peer and core instances | ||
53 | if local, err = core.NewLocalPeer(localCfg); err != nil { | ||
54 | fmt.Println("local failed: " + err.Error()) | ||
55 | return | ||
56 | } | ||
57 | if c, err = core.NewCore(ctx, local); err != nil { | ||
58 | fmt.Println("core failed: " + err.Error()) | ||
59 | return | ||
60 | } | ||
61 | if remote, err = core.NewPeer(remoteCfg); err != nil { | ||
62 | fmt.Println("remote failed: " + err.Error()) | ||
63 | return | ||
64 | } | ||
65 | |||
66 | fmt.Println("======================================================================") | ||
67 | fmt.Println("GNUnet peer mock-up (EXPERIMENTAL) (c) 2018-2022 by Bernd Fix, >Y<") | ||
68 | fmt.Printf(" Identity '%s'\n", local.GetIDString()) | ||
69 | fmt.Printf(" [%s]\n", local.GetID().String()) | ||
70 | fmt.Println("======================================================================") | ||
71 | |||
72 | // handle messages coming from network | ||
73 | module := service.NewModuleImpl() | ||
74 | listener := module.Run(ctx, process, nil) | ||
75 | c.Register("mockup", listener) | ||
76 | |||
77 | if !asServer { | ||
78 | // we start the message exchange | ||
79 | c.Send(ctx, remote.GetID(), message.NewTransportTCPWelcomeMsg(c.PeerID())) | ||
80 | } | ||
81 | |||
82 | // handle OS signals | ||
83 | sigCh := make(chan os.Signal, 5) | ||
84 | signal.Notify(sigCh) | ||
85 | |||
86 | // heart beat | ||
87 | tick := time.NewTicker(5 * time.Minute) | ||
88 | |||
89 | loop: | ||
90 | for { | ||
91 | select { | ||
92 | // handle OS signals | ||
93 | case sig := <-sigCh: | ||
94 | switch sig { | ||
95 | case syscall.SIGKILL, syscall.SIGINT, syscall.SIGTERM: | ||
96 | logger.Printf(logger.INFO, "Terminating service (on signal '%s')\n", sig) | ||
97 | break loop | ||
98 | case syscall.SIGHUP: | ||
99 | logger.Println(logger.INFO, "SIGHUP") | ||
100 | case syscall.SIGURG: | ||
101 | // TODO: https://github.com/golang/go/issues/37942 | ||
102 | default: | ||
103 | logger.Println(logger.INFO, "Unhandled signal: "+sig.String()) | ||
104 | } | ||
105 | // handle heart beat | ||
106 | case now := <-tick.C: | ||
107 | logger.Println(logger.INFO, "Heart beat at "+now.String()) | ||
108 | } | ||
109 | } | ||
110 | // terminate pending routines | ||
111 | cancel() | ||
112 | } | ||
113 | |||
114 | // process incoming messages and send responses; it is used for protocol exploration only. | ||
115 | // it tries to mimick the message flow between "real" GNUnet peers. | ||
116 | func process(ctx context.Context, ev *core.Event) { | ||
117 | |||
118 | logger.Printf(logger.DBG, "<<< %s", ev.Msg.String()) | ||
119 | |||
120 | switch msg := ev.Msg.(type) { | ||
121 | |||
122 | case *message.TransportTCPWelcomeMsg: | ||
123 | c.Send(ctx, ev.Peer, message.NewTransportPingMsg(ev.Peer, nil)) | ||
124 | |||
125 | case *message.HelloMsg: | ||
126 | |||
127 | case *message.TransportPingMsg: | ||
128 | mOut := message.NewTransportPongMsg(msg.Challenge, nil) | ||
129 | if err := mOut.Sign(local.PrvKey()); err != nil { | ||
130 | logger.Println(logger.ERROR, "PONG: signing failed") | ||
131 | return | ||
132 | } | ||
133 | c.Send(ctx, ev.Peer, mOut) | ||
134 | logger.Printf(logger.DBG, ">>> %s", mOut) | ||
135 | |||
136 | case *message.TransportPongMsg: | ||
137 | rc, err := msg.Verify(remote.PubKey()) | ||
138 | if err != nil { | ||
139 | logger.Println(logger.ERROR, "PONG verification: "+err.Error()) | ||
140 | } | ||
141 | if !rc { | ||
142 | logger.Println(logger.ERROR, "PONG verification failed") | ||
143 | } | ||
144 | |||
145 | case *message.SessionSynMsg: | ||
146 | mOut := message.NewSessionSynAckMsg() | ||
147 | mOut.Timestamp = msg.Timestamp | ||
148 | c.Send(ctx, ev.Peer, mOut) | ||
149 | logger.Printf(logger.DBG, ">>> %s", mOut) | ||
150 | |||
151 | case *message.SessionQuotaMsg: | ||
152 | |||
153 | case *message.SessionAckMsg: | ||
154 | |||
155 | case *message.SessionKeepAliveMsg: | ||
156 | mOut := message.NewSessionKeepAliveRespMsg(msg.Nonce) | ||
157 | c.Send(ctx, ev.Peer, mOut) | ||
158 | logger.Printf(logger.DBG, ">>> %s", mOut) | ||
159 | |||
160 | case *message.EphemeralKeyMsg: | ||
161 | rc, err := msg.Verify(remote.PubKey()) | ||
162 | if err != nil { | ||
163 | logger.Println(logger.ERROR, "EPHKEY verification: "+err.Error()) | ||
164 | return | ||
165 | } else if !rc { | ||
166 | logger.Println(logger.ERROR, "EPHKEY verification failed") | ||
167 | return | ||
168 | } | ||
169 | remote.SetEphKeyMsg(msg) | ||
170 | mOut := local.EphKeyMsg() | ||
171 | c.Send(ctx, ev.Peer, mOut) | ||
172 | logger.Printf(logger.DBG, ">>> %s", mOut) | ||
173 | secret = crypto.SharedSecret(local.EphPrvKey(), remote.EphKeyMsg().Public()) | ||
174 | |||
175 | default: | ||
176 | fmt.Printf("!!! %v\n", msg) | ||
177 | } | ||
178 | } | ||