diff options
Diffstat (limited to 'src/gnunet/service/dht/service.go')
-rw-r--r-- | src/gnunet/service/dht/service.go | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/gnunet/service/dht/service.go b/src/gnunet/service/dht/service.go new file mode 100644 index 0000000..2a189bb --- /dev/null +++ b/src/gnunet/service/dht/service.go | |||
@@ -0,0 +1,134 @@ | |||
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 | |||
19 | package dht | ||
20 | |||
21 | import ( | ||
22 | "context" | ||
23 | "fmt" | ||
24 | "io" | ||
25 | |||
26 | "gnunet/core" | ||
27 | "gnunet/message" | ||
28 | "gnunet/service" | ||
29 | |||
30 | "github.com/bfix/gospel/logger" | ||
31 | ) | ||
32 | |||
33 | // Error codes | ||
34 | var ( | ||
35 | ErrInvalidID = fmt.Errorf("invalid/unassociated ID") | ||
36 | ErrBlockExpired = fmt.Errorf("block expired") | ||
37 | ErrInvalidResponseType = fmt.Errorf("invald response type") | ||
38 | ) | ||
39 | |||
40 | //---------------------------------------------------------------------- | ||
41 | // "GNUnet R5N DHT" service implementation | ||
42 | //---------------------------------------------------------------------- | ||
43 | |||
44 | // Service implements a DHT service | ||
45 | type Service struct { | ||
46 | Module | ||
47 | } | ||
48 | |||
49 | // NewService creates a new DHT service instance | ||
50 | func NewService(ctx context.Context, c *core.Core) service.Service { | ||
51 | return &Service{ | ||
52 | Module: *NewModule(ctx, c), | ||
53 | } | ||
54 | } | ||
55 | |||
56 | // ServeClient processes a client channel. | ||
57 | func (s *Service) ServeClient(ctx context.Context, id int, mc *service.Connection) { | ||
58 | reqID := 0 | ||
59 | var cancel context.CancelFunc | ||
60 | ctx, cancel = context.WithCancel(ctx) | ||
61 | |||
62 | loop: | ||
63 | for { | ||
64 | // receive next message from client | ||
65 | reqID++ | ||
66 | logger.Printf(logger.DBG, "[dht:%d:%d] Waiting for client request...\n", id, reqID) | ||
67 | msg, err := mc.Receive(ctx) | ||
68 | if err != nil { | ||
69 | if err == io.EOF { | ||
70 | logger.Printf(logger.INFO, "[dht:%d:%d] Client channel closed.\n", id, reqID) | ||
71 | } else if err == service.ErrConnectionInterrupted { | ||
72 | logger.Printf(logger.INFO, "[dht:%d:%d] Service operation interrupted.\n", id, reqID) | ||
73 | } else { | ||
74 | logger.Printf(logger.ERROR, "[dht:%d:%d] Message-receive failed: %s\n", id, reqID, err.Error()) | ||
75 | } | ||
76 | break loop | ||
77 | } | ||
78 | logger.Printf(logger.INFO, "[dht:%d:%d] Received request: %v\n", id, reqID, msg) | ||
79 | |||
80 | // handle message | ||
81 | s.HandleMessage(context.WithValue(ctx, "label", fmt.Sprintf(":%d:%d", id, reqID)), msg, mc) | ||
82 | } | ||
83 | // close client connection | ||
84 | mc.Close() | ||
85 | |||
86 | // cancel all tasks running for this session/connection | ||
87 | logger.Printf(logger.INFO, "[dht:%d] Start closing session...\n", id) | ||
88 | cancel() | ||
89 | } | ||
90 | |||
91 | // HandleMessage handles a DHT request/response message. If the transport channel | ||
92 | // is nil, responses are send directly via the transport layer. | ||
93 | func (s *Service) HandleMessage(ctx context.Context, msg message.Message, back service.Responder) bool { | ||
94 | // assemble log label | ||
95 | label := "" | ||
96 | if v := ctx.Value("label"); v != nil { | ||
97 | label = v.(string) | ||
98 | } | ||
99 | // process message | ||
100 | switch msg.(type) { | ||
101 | case *message.DHTClientPutMsg: | ||
102 | //---------------------------------------------------------- | ||
103 | // DHT PUT | ||
104 | //---------------------------------------------------------- | ||
105 | |||
106 | case *message.DHTClientGetMsg: | ||
107 | //---------------------------------------------------------- | ||
108 | // DHT GET | ||
109 | //---------------------------------------------------------- | ||
110 | |||
111 | case *message.DHTClientGetResultsKnownMsg: | ||
112 | //---------------------------------------------------------- | ||
113 | // DHT GET-RESULTS-KNOWN | ||
114 | //---------------------------------------------------------- | ||
115 | |||
116 | case *message.DHTClientGetStopMsg: | ||
117 | //---------------------------------------------------------- | ||
118 | // DHT GET-STOP | ||
119 | //---------------------------------------------------------- | ||
120 | |||
121 | case *message.DHTClientResultMsg: | ||
122 | //---------------------------------------------------------- | ||
123 | // DHT RESULT | ||
124 | //---------------------------------------------------------- | ||
125 | |||
126 | default: | ||
127 | //---------------------------------------------------------- | ||
128 | // UNKNOWN message type received | ||
129 | //---------------------------------------------------------- | ||
130 | logger.Printf(logger.ERROR, "[dht%s] Unhandled message of type (%d)\n", label, msg.Header().MsgType) | ||
131 | return false | ||
132 | } | ||
133 | return true | ||
134 | } | ||