Browse Source

Use BlockHandlerList to manage block handlers.

Bernd Fix 3 months ago
parent
commit
4ea9475228
1 changed files with 146 additions and 9 deletions
  1. 146
    9
      src/gnunet/service/gns/block.go

+ 146
- 9
src/gnunet/service/gns/block.go View File

@@ -1,6 +1,7 @@
1 1
 package gns
2 2
 
3 3
 import (
4
+	"encoding/hex"
4 5
 	"fmt"
5 6
 
6 7
 	"gnunet/crypto"
@@ -164,6 +165,82 @@ type BlockHandler interface {
164 165
 	//   =  0: Record is allowed but will be ignored
165 166
 	//   =  1: Record is allowed and will be processed
166 167
 	TypeAction(int) int
168
+
169
+	// Post-process a record: handler can modify/replace a resource
170
+	// record based on their own logic (e.g. BOX)
171
+	PostProcess(*message.GNSResourceRecord) *message.GNSResourceRecord
172
+}
173
+
174
+//----------------------------------------------------------------------
175
+// Manage list of block handlers
176
+// Under normal circumstances there is only one (or none) block handler
177
+// per block, but future constructs may allow multiple block handlers
178
+// to be present. The block handler list implements the BlockHandler
179
+// interface.
180
+//----------------------------------------------------------------------
181
+
182
+// BlockHandlerList is a list of block handlers instantiated.
183
+type BlockHandlerList struct {
184
+	list map[string]BlockHandler
185
+	keys []string
186
+}
187
+
188
+// NewBlockHandlerList instantiates an empty list of block handlers.
189
+func NewBlockHandlerList() *BlockHandlerList {
190
+	return &BlockHandlerList{
191
+		list: make(map[string]BlockHandler),
192
+		keys: make([]string, 0),
193
+	}
194
+}
195
+
196
+// GetHandler returns a BlockHandler for the given key. If no block handler exists
197
+// under the given name, a new one is created and stored in the list. The type of
198
+// the new block handler is derived from the key value.
199
+func (hl *BlockHandlerList) GetHandler(key string) (hdlr BlockHandler) {
200
+	// return handler for given key if it exists
201
+	var ok bool
202
+	if hdlr, ok = hl.list[key]; ok {
203
+		return
204
+	}
205
+	// create a new one
206
+	switch key {
207
+	case "pkey":
208
+		hdlr = NewPkeyHandler()
209
+	case "gns2dns":
210
+		hdlr = NewGns2DnsHandler()
211
+	case "box":
212
+		hdlr = NewBoxHandler()
213
+	}
214
+	hl.list[key] = hdlr
215
+	return hdlr
216
+}
217
+
218
+// TypeAction of the handler list: If any active block handler...
219
+// * ... rejects a record, it gets finally rejected.
220
+// * ... ignores a record, it will be ignored if no other handler rejects it.
221
+func (hl *BlockHandlerList) TypeAction(t int) int {
222
+	rc := 1
223
+	for _, hdlr := range hl.list {
224
+		switch hdlr.TypeAction(t) {
225
+		case -1:
226
+			return -1
227
+		case 0:
228
+			rc = 0
229
+		}
230
+	}
231
+	return rc
232
+}
233
+
234
+// PostProcess a record
235
+func (hl *BlockHandlerList) PostProcess(rec *message.GNSResourceRecord) *message.GNSResourceRecord {
236
+	// Post-process the record through all handlers. Usually no two handlers
237
+	// post-process the same record, but it is not possible to do so. The
238
+	// sequence of post-processing is determined by the sequence
239
+	for _, key := range hl.keys {
240
+		hdlr := hl.list[key]
241
+		rec = hdlr.PostProcess(rec)
242
+	}
243
+	return rec
167 244
 }
168 245
 
169 246
 //----------------------------------------------------------------------
@@ -184,11 +261,17 @@ func NewPkeyHandler() *PkeyHandler {
184 261
 
185 262
 // TypeAction return a flag indicating how a resource record of a given type
186 263
 // is to be treated (see BlockHandler interface)
187
-func (m *PkeyHandler) TypeAction(t int) int {
264
+func (h *PkeyHandler) TypeAction(t int) int {
188 265
 	// everything else is not allowed
189 266
 	return -1
190 267
 }
191 268
 
269
+// PostProcess a record
270
+func (h *PkeyHandler) PostProcess(rec *message.GNSResourceRecord) *message.GNSResourceRecord {
271
+	// no post-processing required
272
+	return rec
273
+}
274
+
192 275
 //----------------------------------------------------------------------
193 276
 // GNS2DNS handler
194 277
 //----------------------------------------------------------------------
@@ -208,8 +291,8 @@ func NewGns2DnsHandler() *Gns2DnsHandler {
208 291
 }
209 292
 
210 293
 // TypeAction return a flag indicating how a resource record of a given type
211
-// is to be treated (see RecordMaster interface)
212
-func (m *Gns2DnsHandler) TypeAction(t int) int {
294
+// is to be treated (see BlockHandler interface)
295
+func (h *Gns2DnsHandler) TypeAction(t int) int {
213 296
 	// only process other GNS2DNS records
214 297
 	if t == enums.GNS_TYPE_GNS2DNS {
215 298
 		return 1
@@ -218,21 +301,75 @@ func (m *Gns2DnsHandler) TypeAction(t int) int {
218 301
 	return 0
219 302
 }
220 303
 
304
+// PostProcess a record
305
+func (h *Gns2DnsHandler) PostProcess(rec *message.GNSResourceRecord) *message.GNSResourceRecord {
306
+	// no post-processing required
307
+	return rec
308
+}
309
+
221 310
 // AddRequest adds the DNS request for "name" at "server" to the list
222 311
 // of requests. All GNS2DNS records must query for the same name
223
-func (m *Gns2DnsHandler) AddRequest(name, server string) bool {
224
-	if len(m.Servers) == 0 {
225
-		m.Name = name
312
+func (h *Gns2DnsHandler) AddRequest(name, server string) bool {
313
+	if len(h.Servers) == 0 {
314
+		h.Name = name
226 315
 	}
227
-	if name != m.Name {
316
+	if name != h.Name {
228 317
 		return false
229 318
 	}
230
-	m.Servers = append(m.Servers, server)
319
+	h.Servers = append(h.Servers, server)
231 320
 	return true
232 321
 }
233 322
 
323
+//----------------------------------------------------------------------
324
+// BOX handler
325
+//----------------------------------------------------------------------
326
+
327
+// BoxHandler implementing the BlockHandler interface
328
+type BoxHandler struct {
329
+	boxes map[string]*Box
330
+}
331
+
332
+// NewBoxHandler returns a new BlockHandler instance
333
+func NewBoxHandler() *BoxHandler {
334
+	return &BoxHandler{
335
+		boxes: make(map[string]*Box),
336
+	}
337
+}
338
+
339
+// TypeAction return a flag indicating how a resource record of a given type
340
+// is to be treated (see BlockHandler interface)
341
+func (h *BoxHandler) TypeAction(t int) int {
342
+	// process record
343
+	return 1
344
+}
345
+
346
+// PostProcess a record
347
+func (h *BoxHandler) PostProcess(rec *message.GNSResourceRecord) *message.GNSResourceRecord {
348
+	// check for boxed record
349
+	if int(rec.Type) == enums.GNS_TYPE_BOX {
350
+		// locate the BOX for the record (that has been validated before)
351
+		key := hex.EncodeToString(rec.Data[:8])
352
+		if box, ok := h.boxes[key]; ok {
353
+			// valid box found: assemble new resource record.
354
+			rr := new(message.GNSResourceRecord)
355
+			rr.Expires = rec.Expires
356
+			rr.Flags = rec.Flags
357
+			rr.Type = box.Type
358
+			rr.Size = uint32(len(box.RR))
359
+			rr.Data = box.RR
360
+			return rr
361
+		}
362
+	}
363
+	return rec
364
+}
365
+
366
+// AddBox adds the BOX instance to the handler
367
+func (h *BoxHandler) AddBox(box *Box) {
368
+	h.boxes[box.key] = box
369
+}
370
+
234 371
 //======================================================================
235
-// Lost of resource records types
372
+// List of resource records types (for GNS/DNS queries)
236 373
 //======================================================================
237 374
 
238 375
 // RRTypeList is a list of integers representing RR types.

Loading…
Cancel
Save