aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBernd Fix <brf@hoi-polloi.org>2019-12-23 12:21:56 +0100
committerBernd Fix <brf@hoi-polloi.org>2019-12-23 12:21:56 +0100
commit8e4c1501b82cdbba6c545a4b49eb5b65050579ba (patch)
tree8b7bae3a79d6b4f69bc9290e6fe279b05493dc2a /src
parent96e32f827e626dac13bb7615cd473998ce2ce3a9 (diff)
downloadgnunet-go-8e4c1501b82cdbba6c545a4b49eb5b65050579ba.tar.gz
gnunet-go-8e4c1501b82cdbba6c545a4b49eb5b65050579ba.zip
Changes after review feedback.
Diffstat (limited to 'src')
-rw-r--r--src/gnunet/enums/gns.go5
-rw-r--r--src/gnunet/service/gns/block_handler.go147
-rw-r--r--src/gnunet/service/gns/module.go19
3 files changed, 157 insertions, 14 deletions
diff --git a/src/gnunet/enums/gns.go b/src/gnunet/enums/gns.go
index d5b1f7a..1d45fff 100644
--- a/src/gnunet/enums/gns.go
+++ b/src/gnunet/enums/gns.go
@@ -4,6 +4,11 @@ package enums
4var ( 4var (
5 GNS_MAX_BLOCK_SIZE = (63 * 1024) // Maximum size of a value that can be stored in a GNS block. 5 GNS_MAX_BLOCK_SIZE = (63 * 1024) // Maximum size of a value that can be stored in a GNS block.
6 6
7 // GNS record flags
8 GNS_FLAG_PRIVATE = 2
9 GNS_FLAGS_EXPREL = 8
10 GNS_FLAG_SHADOW = 16
11
7 // GNS record types 12 // GNS record types
8 GNS_TYPE_ANY = 0 // Record type indicating any record/'*' 13 GNS_TYPE_ANY = 0 // Record type indicating any record/'*'
9 GNS_TYPE_DNS_A = 1 // [RFC1035] IPv4 Address record 14 GNS_TYPE_DNS_A = 1 // [RFC1035] IPv4 Address record
diff --git a/src/gnunet/service/gns/block_handler.go b/src/gnunet/service/gns/block_handler.go
index bf65e95..c3372f2 100644
--- a/src/gnunet/service/gns/block_handler.go
+++ b/src/gnunet/service/gns/block_handler.go
@@ -21,6 +21,7 @@ var (
21 ErrInvalidRecordBody = fmt.Errorf("Invalid resource record body") 21 ErrInvalidRecordBody = fmt.Errorf("Invalid resource record body")
22 ErrInvalidPKEY = fmt.Errorf("Invalid PKEY resource record") 22 ErrInvalidPKEY = fmt.Errorf("Invalid PKEY resource record")
23 ErrInvalidCNAME = fmt.Errorf("Invalid CNAME resource record") 23 ErrInvalidCNAME = fmt.Errorf("Invalid CNAME resource record")
24 ErrInvalidVPN = fmt.Errorf("Invalid VPN resource record")
24 ErrInvalidRecordMix = fmt.Errorf("Invalid mix of RR types in block") 25 ErrInvalidRecordMix = fmt.Errorf("Invalid mix of RR types in block")
25 ErrBlockHandler = fmt.Errorf("Internal block handler failure") 26 ErrBlockHandler = fmt.Errorf("Internal block handler failure")
26) 27)
@@ -33,6 +34,7 @@ var (
33 enums.GNS_TYPE_BOX: NewBoxHandler, 34 enums.GNS_TYPE_BOX: NewBoxHandler,
34 enums.GNS_TYPE_LEHO: NewLehoHandler, 35 enums.GNS_TYPE_LEHO: NewLehoHandler,
35 enums.GNS_TYPE_DNS_CNAME: NewCnameHandler, 36 enums.GNS_TYPE_DNS_CNAME: NewCnameHandler,
37 enums.GNS_TYPE_VPN: NewVpnHandler,
36 } 38 }
37) 39)
38 40
@@ -60,6 +62,9 @@ type BlockHandler interface {
60 // Records returns a list of RR of the given types associated with 62 // Records returns a list of RR of the given types associated with
61 // the custom handler 63 // the custom handler
62 Records(kind RRTypeList) *GNSRecordSet 64 Records(kind RRTypeList) *GNSRecordSet
65
66 // Name returns the human-readable name of the handler
67 Name() string
63} 68}
64 69
65//---------------------------------------------------------------------- 70//----------------------------------------------------------------------
@@ -71,6 +76,9 @@ type BlockHandler interface {
71// The BlockHandlerList maintains a map of actually instantiated handlers 76// The BlockHandlerList maintains a map of actually instantiated handlers
72// (indexed by record type) and a list of record types (with occurrence 77// (indexed by record type) and a list of record types (with occurrence
73// count) in the block. 78// count) in the block.
79// The instance is also responsible for any required post-processing like
80// filtering out expired records (and eventually "activating" associated
81// shadow records collect from the same block).
74//---------------------------------------------------------------------- 82//----------------------------------------------------------------------
75 83
76// BlockHandlerList is a list of block handlers instantiated. 84// BlockHandlerList is a list of block handlers instantiated.
@@ -81,15 +89,46 @@ type BlockHandlerList struct {
81 89
82// NewBlockHandlerList instantiates an a list of active block handlers 90// NewBlockHandlerList instantiates an a list of active block handlers
83// for a given set of records (GNS block). 91// for a given set of records (GNS block).
84func NewBlockHandlerList(records []*message.GNSResourceRecord, labels []string) (*BlockHandlerList, error) { 92func NewBlockHandlerList(records []*message.GNSResourceRecord, labels []string) (*BlockHandlerList, []*message.GNSResourceRecord, error) {
85 // initialize block handler list 93 // initialize block handler list
86 hl := &BlockHandlerList{ 94 hl := &BlockHandlerList{
87 list: make(map[int]BlockHandler), 95 list: make(map[int]BlockHandler),
88 counts: make(util.CounterMap), 96 counts: make(util.CounterMap),
89 } 97 }
90 98
91 // Traverse record list and build list of handler instances 99 // first pass: build list of shadow records in this block
100 shadows := make([]*message.GNSResourceRecord, 0)
101 for _, rec := range records {
102 // filter out shadow records...
103 if (int(rec.Flags) & enums.GNS_FLAG_SHADOW) != 0 {
104 shadows = append(shadows, rec)
105 }
106 }
107 // second pass: normalize block by filtering out expired records (and
108 // replacing them with shadow records if available
109 active := make([]*message.GNSResourceRecord, 0)
92 for _, rec := range records { 110 for _, rec := range records {
111 // don't process shadow records again
112 if (int(rec.Flags) & enums.GNS_FLAG_SHADOW) != 0 {
113 continue
114 }
115 // check for expired record
116 if rec.Expires.Expired() {
117 // do we have an associated shadow record?
118 for _, shadow := range shadows {
119 if shadow.Type == rec.Type && !shadow.Expires.Expired() {
120 // deliver un-expired shadow record instead.
121 shadow.Flags &^= uint32(enums.GNS_FLAG_SHADOW)
122 active = append(active, shadow)
123 }
124 }
125 } else {
126 active = append(active, rec)
127 }
128 }
129
130 // Third pass: Traverse active list and build list of handler instances.
131 for _, rec := range active {
93 // update counter map 132 // update counter map
94 rrType := int(rec.Type) 133 rrType := int(rec.Type)
95 hl.counts.Add(rrType) 134 hl.counts.Add(rrType)
@@ -104,13 +143,13 @@ func NewBlockHandlerList(records []*message.GNSResourceRecord, labels []string)
104 if hdlr, ok = hl.list[rrType]; ok { 143 if hdlr, ok = hl.list[rrType]; ok {
105 // add record to existing handler 144 // add record to existing handler
106 if err = hdlr.AddRecord(rec, labels); err != nil { 145 if err = hdlr.AddRecord(rec, labels); err != nil {
107 return nil, err 146 return nil, active, err
108 } 147 }
109 continue 148 continue
110 } 149 }
111 // create a new handler instance 150 // create a new handler instance
112 if hdlr, err = creat(rec, labels); err != nil { 151 if hdlr, err = creat(rec, labels); err != nil {
113 return nil, err 152 return nil, active, err
114 } 153 }
115 // store handler in list 154 // store handler in list
116 hl.list[rrType] = hdlr 155 hl.list[rrType] = hdlr
@@ -121,11 +160,12 @@ func NewBlockHandlerList(records []*message.GNSResourceRecord, labels []string)
121 // all the other records of varying type 160 // all the other records of varying type
122 for _, hdlr := range hl.list { 161 for _, hdlr := range hl.list {
123 if !hdlr.Coexist(hl.counts) { 162 if !hdlr.Coexist(hl.counts) {
124 return nil, ErrInvalidRecordMix 163 logger.Printf(logger.ERROR, "[gns] %s.Coexist() failed!\n", hdlr.Name())
164 return nil, active, ErrInvalidRecordMix
125 } 165 }
126 } 166 }
127 // return assembled handler list 167 // return assembled handler list
128 return hl, nil 168 return hl, active, nil
129} 169}
130 170
131// GetHandler returns a BlockHandler for the given key. If no block handler exists 171// GetHandler returns a BlockHandler for the given key. If no block handler exists
@@ -139,6 +179,12 @@ func (hl *BlockHandlerList) GetHandler(t int) BlockHandler {
139 return nil 179 return nil
140} 180}
141 181
182// FinalizeRecord post-processes records
183func (hl *BlockHandlerList) FinalizeRecord(rec *message.GNSResourceRecord) *message.GNSResourceRecord {
184 // no implementation yet
185 return rec
186}
187
142//---------------------------------------------------------------------- 188//----------------------------------------------------------------------
143// PKEY handler: Only one PKEY as sole record in a block 189// PKEY handler: Only one PKEY as sole record in a block
144//---------------------------------------------------------------------- 190//----------------------------------------------------------------------
@@ -198,13 +244,18 @@ func (h *PkeyHandler) Records(kind RRTypeList) *GNSRecordSet {
198 return rs 244 return rs
199} 245}
200 246
247// Name returns the human-readable name of the handler.
248func (h *PkeyHandler) Name() string {
249 return "PKEY_Handler"
250}
251
201//---------------------------------------------------------------------- 252//----------------------------------------------------------------------
202// GNS2DNS handler 253// GNS2DNS handler
203//---------------------------------------------------------------------- 254//----------------------------------------------------------------------
204 255
205// Gns2DnsHandler implementing the BlockHandler interface 256// Gns2DnsHandler implementing the BlockHandler interface
206type Gns2DnsHandler struct { 257type Gns2DnsHandler struct {
207 Name string // DNS query name 258 Query string // DNS query name
208 Servers []string // DNS servers to ask 259 Servers []string // DNS servers to ask
209 recs []*message.GNSResourceRecord // list of rersource records 260 recs []*message.GNSResourceRecord // list of rersource records
210} 261}
@@ -215,7 +266,7 @@ func NewGns2DnsHandler(rec *message.GNSResourceRecord, labels []string) (BlockHa
215 return nil, ErrInvalidRecordType 266 return nil, ErrInvalidRecordType
216 } 267 }
217 h := &Gns2DnsHandler{ 268 h := &Gns2DnsHandler{
218 Name: "", 269 Query: "",
219 Servers: make([]string, 0), 270 Servers: make([]string, 0),
220 recs: make([]*message.GNSResourceRecord, 0), 271 recs: make([]*message.GNSResourceRecord, 0),
221 } 272 }
@@ -242,9 +293,9 @@ func (h *Gns2DnsHandler) AddRecord(rec *message.GNSResourceRecord, labels []stri
242 293
243 // check if all GNS2DNS records refer to the same query name 294 // check if all GNS2DNS records refer to the same query name
244 if len(h.Servers) == 0 { 295 if len(h.Servers) == 0 {
245 h.Name = dnsQuery 296 h.Query = dnsQuery
246 } 297 }
247 if dnsQuery != h.Name { 298 if dnsQuery != h.Query {
248 return ErrInvalidRecordBody 299 return ErrInvalidRecordBody
249 } 300 }
250 h.Servers = append(h.Servers, dnsServer) 301 h.Servers = append(h.Servers, dnsServer)
@@ -270,6 +321,11 @@ func (h *Gns2DnsHandler) Records(kind RRTypeList) *GNSRecordSet {
270 return rs 321 return rs
271} 322}
272 323
324// Name returns the human-readable name of the handler.
325func (h *Gns2DnsHandler) Name() string {
326 return "GNS2DNS_Handler"
327}
328
273//---------------------------------------------------------------------- 329//----------------------------------------------------------------------
274// BOX handler 330// BOX handler
275//---------------------------------------------------------------------- 331//----------------------------------------------------------------------
@@ -342,6 +398,11 @@ func (h *BoxHandler) Records(kind RRTypeList) *GNSRecordSet {
342 return rs 398 return rs
343} 399}
344 400
401// Name returns the human-readable name of the handler.
402func (h *BoxHandler) Name() string {
403 return "BOX_Handler"
404}
405
345//---------------------------------------------------------------------- 406//----------------------------------------------------------------------
346// LEHO handler 407// LEHO handler
347//---------------------------------------------------------------------- 408//----------------------------------------------------------------------
@@ -386,7 +447,7 @@ func (h *LehoHandler) Coexist(cm util.CounterMap) bool {
386 if cm.Num(enums.GNS_TYPE_LEHO) != 1 { 447 if cm.Num(enums.GNS_TYPE_LEHO) != 1 {
387 return false 448 return false
388 } 449 }
389 return cm.Num(enums.GNS_TYPE_DNS_A) == 1 || cm.Num(enums.GNS_TYPE_DNS_AAAA) == 1 450 return (cm.Num(enums.GNS_TYPE_DNS_A) + cm.Num(enums.GNS_TYPE_DNS_AAAA)) > 1
390} 451}
391 452
392// Records returns a list of RR of the given type associated with this handler 453// Records returns a list of RR of the given type associated with this handler
@@ -398,6 +459,11 @@ func (h *LehoHandler) Records(kind RRTypeList) *GNSRecordSet {
398 return rs 459 return rs
399} 460}
400 461
462// Name returns the human-readable name of the handler.
463func (h *LehoHandler) Name() string {
464 return "LEHO_Handler"
465}
466
401//---------------------------------------------------------------------- 467//----------------------------------------------------------------------
402// CNAME handler 468// CNAME handler
403//---------------------------------------------------------------------- 469//----------------------------------------------------------------------
@@ -450,3 +516,62 @@ func (h *CnameHandler) Records(kind RRTypeList) *GNSRecordSet {
450 } 516 }
451 return rs 517 return rs
452} 518}
519
520// Name returns the human-readable name of the handler.
521func (h *CnameHandler) Name() string {
522 return "CNAME_Handler"
523}
524
525//----------------------------------------------------------------------
526// VPN handler
527//----------------------------------------------------------------------
528
529// VpnHandler implementing the BlockHandler interface
530type VpnHandler struct {
531 rec *message.GNSResourceRecord
532}
533
534// NewVpnHandler returns a new BlockHandler instance
535func NewVpnHandler(rec *message.GNSResourceRecord, labels []string) (BlockHandler, error) {
536 if int(rec.Type) != enums.GNS_TYPE_VPN {
537 return nil, ErrInvalidRecordType
538 }
539 h := &VpnHandler{}
540 if err := h.AddRecord(rec, labels); err != nil {
541 return nil, err
542 }
543 return h, nil
544}
545
546// AddRecord inserts a VPN record into the handler.
547func (h *VpnHandler) AddRecord(rec *message.GNSResourceRecord, labels []string) error {
548 if int(rec.Type) != enums.GNS_TYPE_VPN {
549 return ErrInvalidRecordType
550 }
551 if h.rec != nil {
552 return ErrInvalidVPN
553 }
554 h.rec = rec
555 return nil
556}
557
558// Coexist return a flag indicating how a resource record of a given type
559// is to be treated (see BlockHandler interface)
560func (h *VpnHandler) Coexist(cm util.CounterMap) bool {
561 // anything goes
562 return true
563}
564
565// Records returns a list of RR of the given type associated with this handler
566func (h *VpnHandler) Records(kind RRTypeList) *GNSRecordSet {
567 rs := NewGNSRecordSet()
568 if kind.HasType(enums.GNS_TYPE_VPN) {
569 rs.AddRecord(h.rec)
570 }
571 return rs
572}
573
574// Name returns the human-readable name of the handler.
575func (h *VpnHandler) Name() string {
576 return "VPN_Handler"
577}
diff --git a/src/gnunet/service/gns/module.go b/src/gnunet/service/gns/module.go
index 6732e08..b5583ac 100644
--- a/src/gnunet/service/gns/module.go
+++ b/src/gnunet/service/gns/module.go
@@ -167,7 +167,7 @@ func (gns *GNSModule) ResolveRelative(labels []string, pkey *ed25519.PublicKey,
167 // assemble a list of block handlers for this block: if multiple 167 // assemble a list of block handlers for this block: if multiple
168 // block handlers are present, they are consistent with all block 168 // block handlers are present, they are consistent with all block
169 // records. 169 // records.
170 if hdlrs, err = NewBlockHandlerList(records, labels[1:]); err != nil { 170 if hdlrs, records, err = NewBlockHandlerList(records, labels[1:]); err != nil {
171 // conflicting block handler records found: terminate with error. 171 // conflicting block handler records found: terminate with error.
172 // (N.B.: The BlockHandlerList class executes the logic which mix 172 // (N.B.: The BlockHandlerList class executes the logic which mix
173 // of resource records in a single block is considered valid.) 173 // of resource records in a single block is considered valid.)
@@ -203,7 +203,7 @@ func (gns *GNSModule) ResolveRelative(labels []string, pkey *ed25519.PublicKey,
203 if len(lbls) > 0 { 203 if len(lbls) > 0 {
204 lbls += "." 204 lbls += "."
205 } 205 }
206 fqdn := lbls + inst.Name 206 fqdn := lbls + inst.Query
207 if set, err = gns.ResolveDNS(fqdn, inst.Servers, kind, pkey); err != nil { 207 if set, err = gns.ResolveDNS(fqdn, inst.Servers, kind, pkey); err != nil {
208 logger.Println(logger.ERROR, "[gns] GNS2DNS resolution failed.") 208 logger.Println(logger.ERROR, "[gns] GNS2DNS resolution failed.")
209 return 209 return
@@ -243,7 +243,20 @@ func (gns *GNSModule) ResolveRelative(labels []string, pkey *ed25519.PublicKey,
243 // is this the record type we are looking for? 243 // is this the record type we are looking for?
244 if kind.HasType(int(rec.Type)) { 244 if kind.HasType(int(rec.Type)) {
245 // add it to the result 245 // add it to the result
246 set.AddRecord(rec) 246 if rec = hdlrs.FinalizeRecord(rec); rec != nil {
247 set.AddRecord(rec)
248 }
249 }
250 }
251
252 // if no records of the requested type (either A or AAAA) have been found,
253 // and we have a VPN record, return this instead.
254 if set.Count == 0 && (kind.HasType(enums.GNS_TYPE_DNS_A) || kind.HasType(enums.GNS_TYPE_DNS_AAAA)) {
255 // check for VPN record
256 if hdlr := hdlrs.GetHandler(enums.GNS_TYPE_VPN); hdlr != nil {
257 // add VPN record to result set
258 inst := hdlr.(*VpnHandler)
259 set.AddRecord(inst.rec)
247 } 260 }
248 } 261 }
249 return 262 return