aboutsummaryrefslogtreecommitdiff
path: root/src/gnunet/service/gns/block_handler.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnunet/service/gns/block_handler.go')
-rw-r--r--src/gnunet/service/gns/block_handler.go172
1 files changed, 113 insertions, 59 deletions
diff --git a/src/gnunet/service/gns/block_handler.go b/src/gnunet/service/gns/block_handler.go
index 860b4a7..bf65e95 100644
--- a/src/gnunet/service/gns/block_handler.go
+++ b/src/gnunet/service/gns/block_handler.go
@@ -6,6 +6,7 @@ import (
6 6
7 "gnunet/enums" 7 "gnunet/enums"
8 "gnunet/message" 8 "gnunet/message"
9 "gnunet/util"
9 10
10 "github.com/bfix/gospel/crypto/ed25519" 11 "github.com/bfix/gospel/crypto/ed25519"
11 "github.com/bfix/gospel/logger" 12 "github.com/bfix/gospel/logger"
@@ -16,17 +17,22 @@ type HdlrInst func(*message.GNSResourceRecord, []string) (BlockHandler, error)
16 17
17// Error codes 18// Error codes
18var ( 19var (
19 ErrInvalidRecordMix = fmt.Errorf("Invalid mix of RR types in block") 20 ErrInvalidRecordType = fmt.Errorf("Invalid resource record type")
20 ErrBlockHandler = fmt.Errorf("Internal block handler failure") 21 ErrInvalidRecordBody = fmt.Errorf("Invalid resource record body")
22 ErrInvalidPKEY = fmt.Errorf("Invalid PKEY resource record")
23 ErrInvalidCNAME = fmt.Errorf("Invalid CNAME resource record")
24 ErrInvalidRecordMix = fmt.Errorf("Invalid mix of RR types in block")
25 ErrBlockHandler = fmt.Errorf("Internal block handler failure")
21) 26)
22 27
23// Mapping of RR types to BlockHandler instanciation functions 28// Mapping of RR types to BlockHandler instanciation functions
24var ( 29var (
25 customHandler = map[int]HdlrInst{ 30 customHandler = map[int]HdlrInst{
26 enums.GNS_TYPE_PKEY: NewPkeyHandler, 31 enums.GNS_TYPE_PKEY: NewPkeyHandler,
27 enums.GNS_TYPE_GNS2DNS: NewGns2DnsHandler, 32 enums.GNS_TYPE_GNS2DNS: NewGns2DnsHandler,
28 enums.GNS_TYPE_BOX: NewBoxHandler, 33 enums.GNS_TYPE_BOX: NewBoxHandler,
29 enums.GNS_TYPE_LEHO: NewLehoHandler, 34 enums.GNS_TYPE_LEHO: NewLehoHandler,
35 enums.GNS_TYPE_DNS_CNAME: NewCnameHandler,
30 } 36 }
31) 37)
32 38
@@ -39,17 +45,17 @@ var (
39 45
40// BlockHandler interface. 46// BlockHandler interface.
41type BlockHandler interface { 47type BlockHandler interface {
42 // AddRecord inserts a RR into the BlockHandler for (later) processing. 48 // AddRecord inserts an associated RR into the BlockHandler for (later)
43 // The handler can inspect the remaining labels in a path if required. 49 // processing. The handler can inspect the remaining labels in a path
44 // It returns an error if a record is not accepted by the block handler. 50 // if required. The method returns an error if a record is not accepted
51 // by the block handler (RR not of required type).
45 AddRecord(rr *message.GNSResourceRecord, labels []string) error 52 AddRecord(rr *message.GNSResourceRecord, labels []string) error
46 53
47 // TypeAction returns a flag indicating how a resource record of a 54 // Coexist checks if a custom block handler can co-exist with other
48 // given type is to be treated by a custom block handler: 55 // resource records in the same block. 'cm' maps the resource type
49 // = -1: Record is not allowed 56 // to an integer count (how many records of a type are present in the
50 // = 0: Record is allowed but will be ignored 57 // GNS block).
51 // = 1: Record is allowed and will be processed 58 Coexist(cm util.CounterMap) bool
52 TypeAction(t int) int
53 59
54 // Records returns a list of RR of the given types associated with 60 // Records returns a list of RR of the given types associated with
55 // the custom handler 61 // the custom handler
@@ -69,7 +75,8 @@ type BlockHandler interface {
69 75
70// BlockHandlerList is a list of block handlers instantiated. 76// BlockHandlerList is a list of block handlers instantiated.
71type BlockHandlerList struct { 77type BlockHandlerList struct {
72 list map[int]BlockHandler // list of handler instances 78 list map[int]BlockHandler // list of handler instances
79 counts util.CounterMap // count number of RRs by type
73} 80}
74 81
75// NewBlockHandlerList instantiates an a list of active block handlers 82// NewBlockHandlerList instantiates an a list of active block handlers
@@ -77,24 +84,21 @@ type BlockHandlerList struct {
77func NewBlockHandlerList(records []*message.GNSResourceRecord, labels []string) (*BlockHandlerList, error) { 84func NewBlockHandlerList(records []*message.GNSResourceRecord, labels []string) (*BlockHandlerList, error) {
78 // initialize block handler list 85 // initialize block handler list
79 hl := &BlockHandlerList{ 86 hl := &BlockHandlerList{
80 list: make(map[int]BlockHandler), 87 list: make(map[int]BlockHandler),
88 counts: make(util.CounterMap),
81 } 89 }
82 // build a list of record types that are handled by a custom handler.
83 rrList := NewRRTypeList(
84 enums.GNS_TYPE_PKEY,
85 enums.GNS_TYPE_GNS2DNS,
86 enums.GNS_TYPE_BOX,
87 enums.GNS_TYPE_LEHO)
88 90
89 // Traverse record list and build list of handler instances 91 // Traverse record list and build list of handler instances
90 for _, rec := range records { 92 for _, rec := range records {
91 // check for custom handler type 93 // update counter map
92 rrType := int(rec.Type) 94 rrType := int(rec.Type)
93 if rrList.HasType(rrType) { 95 hl.counts.Add(rrType)
96
97 // check for custom handler type
98 if creat, ok := customHandler[rrType]; ok {
94 // check if a handler for given type already exists 99 // check if a handler for given type already exists
95 var ( 100 var (
96 hdlr BlockHandler 101 hdlr BlockHandler
97 ok bool
98 err error 102 err error
99 ) 103 )
100 if hdlr, ok = hl.list[rrType]; ok { 104 if hdlr, ok = hl.list[rrType]; ok {
@@ -105,23 +109,22 @@ func NewBlockHandlerList(records []*message.GNSResourceRecord, labels []string)
105 continue 109 continue
106 } 110 }
107 // create a new handler instance 111 // create a new handler instance
108 switch rrType { 112 if hdlr, err = creat(rec, labels); err != nil {
109 case enums.GNS_TYPE_PKEY:
110 hdlr, err = NewPkeyHandler(rec, labels)
111 case enums.GNS_TYPE_GNS2DNS:
112 hdlr, err = NewGns2DnsHandler(rec, labels)
113 case enums.GNS_TYPE_BOX:
114 hdlr, err = NewBoxHandler(rec, labels)
115 case enums.GNS_TYPE_LEHO:
116 hdlr, err = NewLehoHandler(rec, labels)
117 }
118 if err != nil {
119 return nil, err 113 return nil, err
120 } 114 }
121 // store handler in list 115 // store handler in list
122 hl.list[rrType] = hdlr 116 hl.list[rrType] = hdlr
123 } 117 }
124 } 118 }
119
120 // Check if all registered handlers in list can co-exist with
121 // all the other records of varying type
122 for _, hdlr := range hl.list {
123 if !hdlr.Coexist(hl.counts) {
124 return nil, ErrInvalidRecordMix
125 }
126 }
127 // return assembled handler list
125 return hl, nil 128 return hl, nil
126} 129}
127 130
@@ -179,14 +182,11 @@ func (h *PkeyHandler) AddRecord(rec *message.GNSResourceRecord, labels []string)
179 return nil 182 return nil
180} 183}
181 184
182// TypeAction return a flag indicating how a resource record of a given type 185// Coexist return a flag indicating how a resource record of a given type
183// is to be treated (see BlockHandler interface) 186// is to be treated (see BlockHandler interface)
184func (h *PkeyHandler) TypeAction(t int) int { 187func (h *PkeyHandler) Coexist(cm util.CounterMap) bool {
185 // no other resource record type is not allowed 188 // only one type (GNS_TYPE_PKEY) is present
186 if t == enums.GNS_TYPE_PKEY { 189 return len(cm) == 1 && cm.Num(enums.GNS_TYPE_PKEY) == 1
187 return 1
188 }
189 return -1
190} 190}
191 191
192// Records returns a list of RR of the given type associated with this handler 192// Records returns a list of RR of the given type associated with this handler
@@ -252,11 +252,11 @@ func (h *Gns2DnsHandler) AddRecord(rec *message.GNSResourceRecord, labels []stri
252 return nil 252 return nil
253} 253}
254 254
255// TypeAction return a flag indicating how a resource record of a given type 255// Coexist return a flag indicating how a resource record of a given type
256// is to be treated (see BlockHandler interface) 256// is to be treated (see BlockHandler interface)
257func (h *Gns2DnsHandler) TypeAction(t int) int { 257func (h *Gns2DnsHandler) Coexist(cm util.CounterMap) bool {
258 // anything goes... 258 // only one type (GNS_TYPE_GNS2DNS) is present
259 return 1 259 return len(cm) == 1 && cm.Num(enums.GNS_TYPE_GNS2DNS) > 0
260} 260}
261 261
262// Records returns a list of RR of the given type associated with this handler 262// Records returns a list of RR of the given type associated with this handler
@@ -317,11 +317,11 @@ func (h *BoxHandler) AddRecord(rec *message.GNSResourceRecord, labels []string)
317 return nil 317 return nil
318} 318}
319 319
320// TypeAction return a flag indicating how a resource record of a given type 320// Coexist return a flag indicating how a resource record of a given type
321// is to be treated (see BlockHandler interface) 321// is to be treated (see BlockHandler interface)
322func (h *BoxHandler) TypeAction(t int) int { 322func (h *BoxHandler) Coexist(cm util.CounterMap) bool {
323 // anything goes... 323 // anything goes...
324 return 1 324 return true
325} 325}
326 326
327// Records returns a list of RR of the given type associated with this handler 327// Records returns a list of RR of the given type associated with this handler
@@ -376,16 +376,17 @@ func (h *LehoHandler) AddRecord(rec *message.GNSResourceRecord, labels []string)
376 return nil 376 return nil
377} 377}
378 378
379// TypeAction return a flag indicating how a resource record of a given type 379// Coexist return a flag indicating how a resource record of a given type
380// is to be treated (see BlockHandler interface) 380// is to be treated (see BlockHandler interface)
381func (h *LehoHandler) TypeAction(t int) int { 381func (h *LehoHandler) Coexist(cm util.CounterMap) bool {
382 // only A and AAAA records allowed beside LEHO 382 // requires exactly one A/AAAA record alongside single LEHO
383 switch t { 383 if len(cm) != 2 {
384 case enums.GNS_TYPE_LEHO, enums.GNS_TYPE_DNS_A, enums.GNS_TYPE_DNS_AAAA: 384 return false
385 return 1
386 default:
387 return -1
388 } 385 }
386 if cm.Num(enums.GNS_TYPE_LEHO) != 1 {
387 return false
388 }
389 return cm.Num(enums.GNS_TYPE_DNS_A) == 1 || cm.Num(enums.GNS_TYPE_DNS_AAAA) == 1
389} 390}
390 391
391// Records returns a list of RR of the given type associated with this handler 392// Records returns a list of RR of the given type associated with this handler
@@ -396,3 +397,56 @@ func (h *LehoHandler) Records(kind RRTypeList) *GNSRecordSet {
396 } 397 }
397 return rs 398 return rs
398} 399}
400
401//----------------------------------------------------------------------
402// CNAME handler
403//----------------------------------------------------------------------
404
405// CnameHandler implementing the BlockHandler interface
406type CnameHandler struct {
407 name string
408 rec *message.GNSResourceRecord
409}
410
411// NewCnameHandler returns a new BlockHandler instance
412func NewCnameHandler(rec *message.GNSResourceRecord, labels []string) (BlockHandler, error) {
413 if int(rec.Type) != enums.GNS_TYPE_DNS_CNAME {
414 return nil, ErrInvalidRecordType
415 }
416 h := &CnameHandler{
417 name: "",
418 }
419 if err := h.AddRecord(rec, labels); err != nil {
420 return nil, err
421 }
422 return h, nil
423}
424
425// AddRecord inserts a CNAME record into the handler.
426func (h *CnameHandler) AddRecord(rec *message.GNSResourceRecord, labels []string) error {
427 if int(rec.Type) != enums.GNS_TYPE_DNS_CNAME {
428 return ErrInvalidRecordType
429 }
430 if h.rec != nil {
431 return ErrInvalidCNAME
432 }
433 _, h.name = DNSNameFromBytes(rec.Data, 0)
434 h.rec = rec
435 return nil
436}
437
438// Coexist return a flag indicating how a resource record of a given type
439// is to be treated (see BlockHandler interface)
440func (h *CnameHandler) Coexist(cm util.CounterMap) bool {
441 // anything goes
442 return true
443}
444
445// Records returns a list of RR of the given type associated with this handler
446func (h *CnameHandler) Records(kind RRTypeList) *GNSRecordSet {
447 rs := NewGNSRecordSet()
448 if kind.HasType(enums.GNS_TYPE_DNS_CNAME) {
449 rs.AddRecord(h.rec)
450 }
451 return rs
452}