aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBernd Fix <brf@hoi-polloi.org>2022-10-26 17:59:46 +0200
committerBernd Fix <brf@hoi-polloi.org>2022-10-26 17:59:46 +0200
commitbcc6ce0be0d9c240dce80c42af5b56e8ee805aff (patch)
treec8a78e0e37822e9709aa31202641d54cad01084b /src
parentcc143998695474cbe91941b91eaa9c8fa41d6700 (diff)
downloadgnunet-go-bcc6ce0be0d9c240dce80c42af5b56e8ee805aff.tar.gz
gnunet-go-bcc6ce0be0d9c240dce80c42af5b56e8ee805aff.zip
Identity service added to zone master.v0.1.37
Diffstat (limited to 'src')
-rw-r--r--src/gnunet/cmd/zonemaster-go/main.go14
-rw-r--r--src/gnunet/config/gnunet-config.json2
-rw-r--r--src/gnunet/crypto/gns.go158
-rw-r--r--src/gnunet/crypto/gns_edkey.go15
-rw-r--r--src/gnunet/crypto/gns_edkey_test.go4
-rw-r--r--src/gnunet/crypto/gns_pkey.go21
-rw-r--r--src/gnunet/crypto/gns_test.go51
-rw-r--r--src/gnunet/enums/results.go31
-rw-r--r--src/gnunet/go.mod4
-rw-r--r--src/gnunet/go.sum4
-rw-r--r--src/gnunet/message/factory.go32
-rw-r--r--src/gnunet/message/message.go3
-rw-r--r--src/gnunet/message/msg_core.go5
-rw-r--r--src/gnunet/message/msg_dht.go15
-rw-r--r--src/gnunet/message/msg_dht_p2p.go61
-rw-r--r--src/gnunet/message/msg_gns.go8
-rw-r--r--src/gnunet/message/msg_hello.go41
-rw-r--r--src/gnunet/message/msg_identity.go473
-rw-r--r--src/gnunet/message/msg_namecache.go18
-rw-r--r--src/gnunet/message/msg_namestore.go57
-rw-r--r--src/gnunet/message/msg_revocation.go16
-rw-r--r--src/gnunet/message/msg_transport.go27
-rw-r--r--src/gnunet/service/connection.go3
-rw-r--r--src/gnunet/service/dht/blocks/gns.go7
-rw-r--r--src/gnunet/service/dht/blocks/gns_test.go75
-rw-r--r--src/gnunet/service/namecache/module.go2
-rw-r--r--src/gnunet/service/revocation/pow_test.go8
-rw-r--r--src/gnunet/service/store/store_zonemaster.go201
-rw-r--r--src/gnunet/service/store/store_zonemaster.sql30
-rw-r--r--src/gnunet/service/zonemaster/gui.go46
-rw-r--r--src/gnunet/service/zonemaster/gui.htpl4
-rw-r--r--src/gnunet/service/zonemaster/gui_css.htpl27
-rw-r--r--src/gnunet/service/zonemaster/gui_new.htpl6
-rw-r--r--src/gnunet/service/zonemaster/gui_rr.htpl40
-rw-r--r--src/gnunet/service/zonemaster/records.go25
-rw-r--r--src/gnunet/service/zonemaster/rpc.go2
-rw-r--r--src/gnunet/service/zonemaster/service.go186
-rw-r--r--src/gnunet/service/zonemaster/service_identity.go135
-rw-r--r--src/gnunet/service/zonemaster/service_namestore.go90
-rw-r--r--src/gnunet/service/zonemaster/zonemaster.go137
-rw-r--r--src/gnunet/transport/reader_writer.go5
41 files changed, 1722 insertions, 367 deletions
diff --git a/src/gnunet/cmd/zonemaster-go/main.go b/src/gnunet/cmd/zonemaster-go/main.go
index 1e4b985..6380db0 100644
--- a/src/gnunet/cmd/zonemaster-go/main.go
+++ b/src/gnunet/cmd/zonemaster-go/main.go
@@ -73,13 +73,11 @@ func main() {
73 config.Cfg.ZoneMaster.GUI = gui 73 config.Cfg.ZoneMaster.GUI = gui
74 } 74 }
75 75
76 // start a new namestore service under zonemaster umbrella 76 // start services under zonemaster umbrella
77 ctx, cancel := context.WithCancel(context.Background()) 77 ctx, cancel := context.WithCancel(context.Background())
78 srv, ok := zonemaster.NewService(ctx, nil).(*zonemaster.Service) 78 srv := zonemaster.NewService(ctx, nil)
79 if !ok { 79 go srv.Run(ctx)
80 logger.Println(logger.ERROR, "[zonemaster] Failed to create service") 80
81 return
82 }
83 // start UDS listener if service is specified 81 // start UDS listener if service is specified
84 if config.Cfg.ZoneMaster.Service != nil { 82 if config.Cfg.ZoneMaster.Service != nil {
85 sockHdlr := service.NewSocketHandler("zonemaster", srv) 83 sockHdlr := service.NewSocketHandler("zonemaster", srv)
@@ -89,10 +87,6 @@ func main() {
89 } 87 }
90 } 88 }
91 89
92 // start a new ZONEMASTER (background service with HTTPS backend)
93 zm := zonemaster.NewZoneMaster(config.Cfg, srv)
94 go zm.Run(ctx)
95
96 // handle command-line arguments for RPC 90 // handle command-line arguments for RPC
97 if len(rpcEndp) > 0 { 91 if len(rpcEndp) > 0 {
98 parts := strings.Split(rpcEndp, ":") 92 parts := strings.Split(rpcEndp, ":")
diff --git a/src/gnunet/config/gnunet-config.json b/src/gnunet/config/gnunet-config.json
index 5e9ec99..cd19450 100644
--- a/src/gnunet/config/gnunet-config.json
+++ b/src/gnunet/config/gnunet-config.json
@@ -91,7 +91,7 @@
91 }, 91 },
92 "gui": "127.0.0.1:8100", 92 "gui": "127.0.0.1:8100",
93 "service": { 93 "service": {
94 "socket": "${RT_USER}/gnunet-service-namestore-go.sock", 94 "socket": "${RT_USER}/gnunet-service-zonemaster-go.sock",
95 "params": { 95 "params": {
96 "perm": "0770" 96 "perm": "0770"
97 } 97 }
diff --git a/src/gnunet/crypto/gns.go b/src/gnunet/crypto/gns.go
index 301acb1..a1c26f6 100644
--- a/src/gnunet/crypto/gns.go
+++ b/src/gnunet/crypto/gns.go
@@ -129,6 +129,10 @@ type ZoneKeyImpl interface {
129type ZonePrivateImpl interface { 129type ZonePrivateImpl interface {
130 ZoneAbstractImpl 130 ZoneAbstractImpl
131 131
132 // Prepare a random byte array to be used as a random
133 // private key of given type.
134 Prepare(rnd []byte) []byte
135
132 // Derive a private key from this zone key based on a big integer 136 // Derive a private key from this zone key based on a big integer
133 // (key blinding). Returns the derived key and the blinding value. 137 // (key blinding). Returns the derived key and the blinding value.
134 Derive(h *math.Int) (ZonePrivateImpl, *math.Int, error) 138 Derive(h *math.Int) (ZonePrivateImpl, *math.Int, error)
@@ -211,46 +215,80 @@ func GetImplementation(ztype enums.GNSType) *ZoneImplementation {
211 215
212// ZonePrivate represents the possible types of private zone keys (PKEY, EDKEY,...) 216// ZonePrivate represents the possible types of private zone keys (PKEY, EDKEY,...)
213type ZonePrivate struct { 217type ZonePrivate struct {
214 ZoneKey 218 Type enums.GNSType `json:"type" order:"big"`
219 KeyData []byte `json:"key" size:"(KeySize)"`
215 220
216 impl ZonePrivateImpl // reference to implementation 221 impl ZonePrivateImpl // reference to implementation
217} 222}
218 223
219// NewZonePrivate returns a new initialized ZonePrivate instance. If no data is 224// NewZonePrivate returns a new initialized ZonePrivate instance of given ztype.
220// provided, a new random key is created 225// If no data is provided, a new random key is created. If data is provided, it
221func NewZonePrivate(ztype enums.GNSType, d []byte) (zp *ZonePrivate, err error) { 226// must be in the correct format specified by a ZonePrivate implementation.
227func NewZonePrivate(ztype enums.GNSType, zdata []byte) (zp *ZonePrivate, err error) {
222 // get factory for given zone type 228 // get factory for given zone type
223 impl, ok := zoneImpl[ztype] 229 impl, ok := zoneImpl[ztype]
224 if !ok { 230 if !ok {
225 return nil, ErrNoImplementation 231 return nil, ErrNoImplementation
226 } 232 }
233 prvImpl := impl.NewPrivate()
234
227 // init data available? 235 // init data available?
228 if d == nil { 236 if zdata == nil {
229 // no: create random seed 237 // no: create random seed
230 d = make([]byte, impl.PrivateSize) 238 zdata = make([]byte, impl.PrivateSize)
231 if _, err = rand.Read(d); err != nil { 239 if _, err = rand.Read(zdata); err != nil {
232 return 240 return
233 } 241 }
242 zdata = prvImpl.Prepare(zdata)
234 } 243 }
235 // assemble private zone key 244 // assemble private zone key
236 zp = &ZonePrivate{ 245 zp = &ZonePrivate{
237 ZoneKey{ 246 Type: ztype,
238 ztype, 247 KeyData: zdata,
239 nil, 248 impl: prvImpl,
240 nil,
241 },
242 nil,
243 } 249 }
244 zp.impl = impl.NewPrivate() 250 err = zp.impl.Init(zdata)
245 if err = zp.impl.Init(d); err != nil { 251 return
246 return 252}
253
254// Init is called to setup internal state after unmarshalling object
255func (zp *ZonePrivate) Init() (err error) {
256 // check for initialized key
257 if zp.impl == nil {
258 impl, ok := zoneImpl[zp.Type]
259 if !ok {
260 return ErrNoImplementation
261 }
262 zp.impl = impl.NewPrivate()
263 err = zp.impl.Init(zp.KeyData)
247 } 264 }
248 zp.ZoneKey.KeyData = zp.impl.Public().Bytes()
249 zp.ZoneKey.impl = impl.NewPublic()
250 err = zp.ZoneKey.impl.Init(zp.ZoneKey.KeyData)
251 return 265 return
252} 266}
253 267
268// Null returns a "NULL" ZonePrivate for a given key
269func NullZonePrivate(ztype enums.GNSType) (*ZonePrivate, uint16) {
270 // get factory for given zone type
271 impl, ok := zoneImpl[ztype]
272 if !ok {
273 return nil, 0
274 }
275 kd := make([]byte, impl.PrivateSize)
276 zp := &ZonePrivate{
277 Type: ztype, // need key type for length calculation
278 KeyData: kd, // untyped key data (all 0)
279 impl: nil, // no implementation!
280 }
281 return zp, uint16(len(zp.KeyData) + 4)
282}
283
284// Bytes returns the binary representation
285func (zp *ZonePrivate) Bytes() []byte {
286 buf := new(bytes.Buffer)
287 _ = binary.Write(buf, binary.BigEndian, zp.Type)
288 _, _ = buf.Write(zp.KeyData)
289 return buf.Bytes()
290}
291
254// KeySize returns the number of bytes of a key representation. 292// KeySize returns the number of bytes of a key representation.
255// This method is used during serialization (Unmarshal). 293// This method is used during serialization (Unmarshal).
256func (zp *ZonePrivate) KeySize() uint { 294func (zp *ZonePrivate) KeySize() uint {
@@ -263,7 +301,7 @@ func (zp *ZonePrivate) KeySize() uint {
263// Derive key (key blinding) 301// Derive key (key blinding)
264func (zp *ZonePrivate) Derive(label, context string) (dzp *ZonePrivate, h *math.Int, err error) { 302func (zp *ZonePrivate) Derive(label, context string) (dzp *ZonePrivate, h *math.Int, err error) {
265 // calculate derived key 303 // calculate derived key
266 key := zp.Public().Bytes() 304 key := zp.Public().KeyData
267 h = deriveH(key, label, context) 305 h = deriveH(key, label, context)
268 var derived ZonePrivateImpl 306 var derived ZonePrivateImpl
269 if derived, h, err = zp.impl.Derive(h); err != nil { 307 if derived, h, err = zp.impl.Derive(h); err != nil {
@@ -271,15 +309,10 @@ func (zp *ZonePrivate) Derive(label, context string) (dzp *ZonePrivate, h *math.
271 } 309 }
272 // assemble derived pivate key 310 // assemble derived pivate key
273 dzp = &ZonePrivate{ 311 dzp = &ZonePrivate{
274 ZoneKey{ 312 Type: zp.Type,
275 zp.Type, 313 KeyData: derived.Bytes(),
276 nil, 314 impl: derived,
277 nil,
278 },
279 derived,
280 } 315 }
281 dzp.ZoneKey.KeyData = derived.Public().Bytes()
282 err = dzp.Init()
283 return 316 return
284} 317}
285 318
@@ -290,7 +323,12 @@ func (zp *ZonePrivate) Sign(data []byte) (sig *ZoneSignature, err error) {
290 323
291// Public returns the associated public key 324// Public returns the associated public key
292func (zp *ZonePrivate) Public() *ZoneKey { 325func (zp *ZonePrivate) Public() *ZoneKey {
293 return &zp.ZoneKey 326 impl := zp.impl.Public()
327 return &ZoneKey{
328 Type: zp.Type,
329 KeyData: impl.Bytes(),
330 impl: impl,
331 }
294} 332}
295 333
296// ID returns the human-readable zone private key. 334// ID returns the human-readable zone private key.
@@ -310,7 +348,7 @@ type ZoneKey struct {
310 impl ZoneKeyImpl // reference to implementation 348 impl ZoneKeyImpl // reference to implementation
311} 349}
312 350
313// Init a zone key where only the attributes have been read/deserialized. 351// Init is called to setup internal state after unmarshalling object
314func (zk *ZoneKey) Init() (err error) { 352func (zk *ZoneKey) Init() (err error) {
315 if zk.impl == nil { 353 if zk.impl == nil {
316 // initialize implementation 354 // initialize implementation
@@ -335,6 +373,14 @@ func NewZoneKey(d []byte) (zk *ZoneKey, err error) {
335 return 373 return
336} 374}
337 375
376// Bytes returns the binary representation (can be used with 'init()')
377func (zk *ZoneKey) Bytes() []byte {
378 buf := new(bytes.Buffer)
379 _ = binary.Write(buf, binary.BigEndian, zk.Type)
380 _, _ = buf.Write(zk.KeyData)
381 return buf.Bytes()
382}
383
338// KeySize returns the number of bytes of a key representation. 384// KeySize returns the number of bytes of a key representation.
339// This method is used during serialization (Unmarshal). 385// This method is used during serialization (Unmarshal).
340func (zk *ZoneKey) KeySize() uint { 386func (zk *ZoneKey) KeySize() uint {
@@ -346,7 +392,7 @@ func (zk *ZoneKey) KeySize() uint {
346 392
347// Derive key (key blinding) 393// Derive key (key blinding)
348func (zk *ZoneKey) Derive(label, context string) (dzk *ZoneKey, h *math.Int, err error) { 394func (zk *ZoneKey) Derive(label, context string) (dzk *ZoneKey, h *math.Int, err error) {
349 key := zk.Bytes() 395 key := zk.KeyData
350 h = deriveH(key, label, context) 396 h = deriveH(key, label, context)
351 var derived ZoneKeyImpl 397 var derived ZoneKeyImpl
352 if derived, h, err = zk.impl.Derive(h); err != nil { 398 if derived, h, err = zk.impl.Derive(h); err != nil {
@@ -388,12 +434,6 @@ func (zk *ZoneKey) ID() string {
388 return zk.impl.ID() 434 return zk.impl.ID()
389} 435}
390 436
391// Bytes returns all bytes of a zone key
392func (zk *ZoneKey) Bytes() []byte {
393 data, _ := data.Marshal(zk)
394 return data
395}
396
397// Equal checks if two zone keys are equal 437// Equal checks if two zone keys are equal
398func (zk *ZoneKey) Equal(k *ZoneKey) bool { 438func (zk *ZoneKey) Equal(k *ZoneKey) bool {
399 return bytes.Equal(zk.KeyData, k.KeyData) 439 return bytes.Equal(zk.KeyData, k.KeyData)
@@ -420,23 +460,26 @@ type ZoneSignature struct {
420 impl ZoneSigImpl // reference to implementation 460 impl ZoneSigImpl // reference to implementation
421} 461}
422 462
463// Init is called to setup internal state after unmarshalling object
423func (zs *ZoneSignature) Init() (err error) { 464func (zs *ZoneSignature) Init() (err error) {
424 // initialize implementations 465 if zs.impl == nil {
425 impl, ok := zoneImpl[zs.Type] 466 // initialize implementations
426 if !ok { 467 impl, ok := zoneImpl[zs.Type]
427 err = ErrUnknownZoneType 468 if !ok {
428 return 469 err = ErrUnknownZoneType
429 } 470 return
430 // set signature implementation 471 }
431 sig := impl.NewSignature() 472 // set signature implementation
432 if err = sig.Init(zs.Signature); err != nil { 473 sig := impl.NewSignature()
433 return 474 if err = sig.Init(zs.Signature); err != nil {
475 return
476 }
477 zs.impl = sig
478 // set public key implementation
479 zk := impl.NewPublic()
480 err = zk.Init(zs.KeyData)
481 zs.ZoneKey.impl = zk
434 } 482 }
435 zs.impl = sig
436 // set public key implementation
437 zk := impl.NewPublic()
438 err = zk.Init(zs.KeyData)
439 zs.ZoneKey.impl = zk
440 return 483 return
441} 484}
442 485
@@ -460,6 +503,11 @@ func (zs *ZoneSignature) SigSize() uint {
460 return 0 503 return 0
461} 504}
462 505
506// Bytes returns the binary representation (can be used with 'init()')
507func (zs *ZoneSignature) Bytes() []byte {
508 return zs.impl.Bytes()
509}
510
463// Key returns the associated zone key object 511// Key returns the associated zone key object
464func (zs *ZoneSignature) Key() *ZoneKey { 512func (zs *ZoneSignature) Key() *ZoneKey {
465 return &zs.ZoneKey 513 return &zs.ZoneKey
@@ -486,10 +534,10 @@ func deriveH(key []byte, label, context string) *math.Int {
486 return math.NewIntFromBytes(b) 534 return math.NewIntFromBytes(b)
487} 535}
488 536
489// convert (type|data) to GNUnet identifier 537// convert (type|data) to bytes
490func asID(t enums.GNSType, data []byte) string { 538func asBytes(t enums.GNSType, data []byte) []byte {
491 buf := new(bytes.Buffer) 539 buf := new(bytes.Buffer)
492 _ = binary.Write(buf, binary.BigEndian, t) 540 _ = binary.Write(buf, binary.BigEndian, t)
493 _, _ = buf.Write(data) 541 _, _ = buf.Write(data)
494 return util.EncodeBinaryToString(buf.Bytes()) 542 return buf.Bytes()
495} 543}
diff --git a/src/gnunet/crypto/gns_edkey.go b/src/gnunet/crypto/gns_edkey.go
index 08dbc55..0054ca5 100644
--- a/src/gnunet/crypto/gns_edkey.go
+++ b/src/gnunet/crypto/gns_edkey.go
@@ -79,8 +79,8 @@ func (pk *EDKEYPublicImpl) Bytes() []byte {
79// Derive a public key from this key based on a big integer 79// Derive a public key from this key based on a big integer
80// (key blinding). Returns the derived key and the blinding value. 80// (key blinding). Returns the derived key and the blinding value.
81func (pk *EDKEYPublicImpl) Derive(h *math.Int) (dPk ZoneKeyImpl, hOut *math.Int, err error) { 81func (pk *EDKEYPublicImpl) Derive(h *math.Int) (dPk ZoneKeyImpl, hOut *math.Int, err error) {
82 // limit to allowed value range 82 // limit to allowed value range (see LSD0001 spec)
83 hOut = h.Mod(ed25519.GetCurve().N) 83 hOut = h.SetBit(255, 0)
84 derived := pk.pub.Mult(hOut) 84 derived := pk.pub.Mult(hOut)
85 dPk = &EDKEYPublicImpl{ 85 dPk = &EDKEYPublicImpl{
86 pk.ztype, 86 pk.ztype,
@@ -162,7 +162,7 @@ func (pk *EDKEYPublicImpl) BlockKey(label string, expire util.AbsoluteTime) (ske
162 162
163// ID returns the GNUnet identifier for a public zone key 163// ID returns the GNUnet identifier for a public zone key
164func (pk *EDKEYPublicImpl) ID() string { 164func (pk *EDKEYPublicImpl) ID() string {
165 return asID(enums.GNS_TYPE_EDKEY, pk.pub.Bytes()) 165 return util.EncodeBinaryToString(asBytes(enums.GNS_TYPE_EDKEY, pk.pub.Bytes()))
166} 166}
167 167
168//---------------------------------------------------------------------- 168//----------------------------------------------------------------------
@@ -187,6 +187,11 @@ func (pk *EDKEYPrivateImpl) Init(data []byte) error {
187 return nil 187 return nil
188} 188}
189 189
190// Prepare a random byte array to be used as a random private EDKEY
191func (pk *EDKEYPrivateImpl) Prepare(rnd []byte) []byte {
192 return rnd
193}
194
190// Bytes returns a binary representation of the instance suitable for 195// Bytes returns a binary representation of the instance suitable for
191// consumption in 'Init()'. 196// consumption in 'Init()'.
192func (pk *EDKEYPrivateImpl) Bytes() []byte { 197func (pk *EDKEYPrivateImpl) Bytes() []byte {
@@ -201,7 +206,7 @@ func (pk *EDKEYPrivateImpl) Public() ZoneKeyImpl {
201// Derive a public key from this key based on a big integer 206// Derive a public key from this key based on a big integer
202// (key blinding). Returns the derived key and the blinding value. 207// (key blinding). Returns the derived key and the blinding value.
203func (pk *EDKEYPrivateImpl) Derive(h *math.Int) (dPk ZonePrivateImpl, hOut *math.Int, err error) { 208func (pk *EDKEYPrivateImpl) Derive(h *math.Int) (dPk ZonePrivateImpl, hOut *math.Int, err error) {
204 // limit to allowed value range 209 // limit to allowed value range (see LSD0001 spec)
205 hOut = h.SetBit(255, 0) 210 hOut = h.SetBit(255, 0)
206 // derive private key 211 // derive private key
207 derived := pk.prv.Mult(hOut) 212 derived := pk.prv.Mult(hOut)
@@ -243,7 +248,7 @@ func (pk *EDKEYPrivateImpl) Sign(data []byte) (sig *ZoneSignature, err error) {
243 248
244// ID returns the GNUnet identifier for a private zone key 249// ID returns the GNUnet identifier for a private zone key
245func (pk *EDKEYPrivateImpl) ID() string { 250func (pk *EDKEYPrivateImpl) ID() string {
246 return asID(enums.GNS_TYPE_EDKEY, pk.seed) 251 return util.EncodeBinaryToString(asBytes(enums.GNS_TYPE_EDKEY, pk.seed))
247} 252}
248 253
249//---------------------------------------------------------------------- 254//----------------------------------------------------------------------
diff --git a/src/gnunet/crypto/gns_edkey_test.go b/src/gnunet/crypto/gns_edkey_test.go
index aa9728f..b5ba700 100644
--- a/src/gnunet/crypto/gns_edkey_test.go
+++ b/src/gnunet/crypto/gns_edkey_test.go
@@ -20,6 +20,7 @@ package crypto
20 20
21import ( 21import (
22 "bytes" 22 "bytes"
23 "encoding/hex"
23 "gnunet/enums" 24 "gnunet/enums"
24 "testing" 25 "testing"
25) 26)
@@ -50,7 +51,10 @@ func TestDeriveEDKEY(t *testing.T) {
50 if err != nil { 51 if err != nil {
51 t.Fatal(err) 52 t.Fatal(err)
52 } 53 }
54 // check resuts
53 if !bytes.Equal(dzp.Public().Bytes(), dzk.Bytes()) { 55 if !bytes.Equal(dzp.Public().Bytes(), dzk.Bytes()) {
56 t.Logf("dzp.Public = %s", hex.EncodeToString(dzp.Public().Bytes()))
57 t.Logf("dzk = %s", hex.EncodeToString(dzk.Bytes()))
54 t.Fatal("derive mismatch") 58 t.Fatal("derive mismatch")
55 } 59 }
56} 60}
diff --git a/src/gnunet/crypto/gns_pkey.go b/src/gnunet/crypto/gns_pkey.go
index 8184483..d2c08ba 100644
--- a/src/gnunet/crypto/gns_pkey.go
+++ b/src/gnunet/crypto/gns_pkey.go
@@ -158,7 +158,7 @@ func (pk *PKEYPublicImpl) cipher(encrypt bool, data []byte, label string, expire
158 158
159// ID returns the GNUnet identifier for a public zone key 159// ID returns the GNUnet identifier for a public zone key
160func (pk *PKEYPublicImpl) ID() string { 160func (pk *PKEYPublicImpl) ID() string {
161 return asID(enums.GNS_TYPE_PKEY, pk.pub.Bytes()) 161 return util.EncodeBinaryToString(asBytes(enums.GNS_TYPE_PKEY, pk.pub.Bytes()))
162} 162}
163 163
164//---------------------------------------------------------------------- 164//----------------------------------------------------------------------
@@ -173,15 +173,25 @@ type PKEYPrivateImpl struct {
173} 173}
174 174
175// Init instance from binary data. The data represents a big integer 175// Init instance from binary data. The data represents a big integer
176// (in big-endian notation) for the private scalar d. 176// (in little-endian notation) for the private scalar d (clamped).
177func (pk *PKEYPrivateImpl) Init(data []byte) error { 177func (pk *PKEYPrivateImpl) Init(data []byte) error {
178 d := math.NewIntFromBytes(data) 178 // generate key material
179 d := math.NewIntFromBytes(util.Reverse(data))
179 pk.prv = ed25519.NewPrivateKeyFromD(d) 180 pk.prv = ed25519.NewPrivateKeyFromD(d)
180 pk.ztype = enums.GNS_TYPE_PKEY 181 pk.ztype = enums.GNS_TYPE_PKEY
181 pk.pub = pk.prv.Public() 182 pk.pub = pk.prv.Public()
182 return nil 183 return nil
183} 184}
184 185
186// Prepare a random byte array to be used as a random private PKEY
187func (pk *PKEYPrivateImpl) Prepare(rnd []byte) []byte {
188 // clamp little-endian skalar
189 d := util.Clone(rnd)
190 d[31] = (d[31] & 0x3f) | 0x40
191 d[0] &= 0xf8
192 return d
193}
194
185// Bytes returns a binary representation of the instance suitable for 195// Bytes returns a binary representation of the instance suitable for
186// consumption in 'Init()'. 196// consumption in 'Init()'.
187func (pk *PKEYPrivateImpl) Bytes() []byte { 197func (pk *PKEYPrivateImpl) Bytes() []byte {
@@ -232,8 +242,11 @@ func (pk *PKEYPrivateImpl) Sign(data []byte) (sig *ZoneSignature, err error) {
232} 242}
233 243
234// ID returns the GNUnet identifier for a private zone key 244// ID returns the GNUnet identifier for a private zone key
245// (little-endian big integer)
235func (pk *PKEYPrivateImpl) ID() string { 246func (pk *PKEYPrivateImpl) ID() string {
236 return asID(enums.GNS_TYPE_PKEY, pk.prv.D.Bytes()) 247 return util.EncodeBinaryToString(asBytes(
248 enums.GNS_TYPE_PKEY,
249 util.Reverse(pk.prv.D.Bytes())))
237} 250}
238 251
239//---------------------------------------------------------------------- 252//----------------------------------------------------------------------
diff --git a/src/gnunet/crypto/gns_test.go b/src/gnunet/crypto/gns_test.go
index 2cccb4d..f910dcf 100644
--- a/src/gnunet/crypto/gns_test.go
+++ b/src/gnunet/crypto/gns_test.go
@@ -202,12 +202,13 @@ func TestVerifyBlock(t *testing.T) {
202func TestDeriveH(t *testing.T) { 202func TestDeriveH(t *testing.T) {
203 var ( 203 var (
204 D = []byte{ 204 D = []byte{
205 // private scalar (big-endian) 205 // private scalar (clamped little-endian)
206 0x74, 0x50, 0xf7, 0x1d, 0xef, 0x64, 0x11, 0xe0, 206 0xc8, 0x93, 0xb0, 0x5d, 0xac, 0xff, 0x85, 0x1b,
207 0xab, 0x0e, 0x6a, 0x1d, 0xfd, 0x1d, 0x9c, 0xcd, 207 0xf5, 0xcc, 0x94, 0x24, 0x95, 0x71, 0xaf, 0x0e,
208 0x0e, 0xaf, 0x71, 0x95, 0x24, 0x94, 0xcc, 0xf5, 208 0xcd, 0x9c, 0x1d, 0xfd, 0x1d, 0x6a, 0x0e, 0xab,
209 0x1b, 0x85, 0xff, 0xac, 0x5d, 0xb0, 0x93, 0xc8, 209 0xe0, 0x11, 0x64, 0xef, 0x1d, 0xf7, 0x50, 0x74,
210 } 210 }
211
211 PUB = []byte{ 212 PUB = []byte{
212 // zone type 213 // zone type
213 0x00, 0x01, 0x00, 0x00, 214 0x00, 0x01, 0x00, 0x00,
@@ -223,29 +224,19 @@ func TestDeriveH(t *testing.T) {
223 CONTEXT = "gns" 224 CONTEXT = "gns"
224 225
225 H = []byte{ 226 H = []byte{
226 0x06, 0x5b, 0xb7, 0x42, 0x12, 0xa1, 0xae, 0xc3, 227 0x07, 0x1e, 0xfc, 0xa7, 0xdb, 0x28, 0x50, 0xbd,
227 0x59, 0x68, 0xdd, 0xdb, 0xca, 0xa3, 0x48, 0xfc, 228 0x6f, 0x35, 0x4e, 0xbf, 0xe3, 0x8c, 0x5b, 0xbf,
228 0xb0, 0xcd, 0x89, 0xd4, 0xcf, 0x9a, 0xe0, 0xfe, 229 0xd6, 0xba, 0x2f, 0x80, 0x5c, 0xd8, 0xd3, 0xb5,
229 0xd1, 0xf9, 0xab, 0x6b, 0xd4, 0x28, 0xf4, 0x95, 230 0x4e, 0xdd, 0x7f, 0x3d, 0xd0, 0x73, 0x0d, 0x1a,
230 } 231 }
231 Q = []byte{ 232 Q = []byte{
232 // zone type 233 // zone type (PKEY)
233 0x00, 0x01, 0x00, 0x00, 234 0x00, 0x01, 0x00, 0x00,
234 // derived public key data 235 // derived public key data
235 0xb1, 0x0e, 0x88, 0xd5, 0x17, 0x02, 0xf3, 0x3d, 236 0x9f, 0x27, 0xad, 0x25, 0xb5, 0x95, 0x4a, 0x46,
236 0xc9, 0xcb, 0xa1, 0xe9, 0x16, 0x65, 0x9c, 0x44, 237 0x7b, 0xc6, 0x5a, 0x67, 0x6b, 0x7a, 0x6d, 0x23,
237 0x47, 0x9c, 0xc8, 0xdb, 0x83, 0x32, 0xd1, 0xd1, 238 0xb2, 0xef, 0x30, 0x0f, 0x7f, 0xc7, 0x00, 0x58,
238 0xc5, 0x03, 0xdb, 0x50, 0x0e, 0xbd, 0x2d, 0x67, 239 0x05, 0x9e, 0x7f, 0x29, 0xe5, 0x94, 0xb5, 0xc1,
239 }
240 QUERY = []byte{
241 0xa9, 0x47, 0x81, 0x8a, 0xaf, 0x45, 0x94, 0xda,
242 0x89, 0x41, 0xfa, 0x29, 0x77, 0x53, 0x94, 0x9d,
243 0xcb, 0xc5, 0xfb, 0x41, 0xea, 0x77, 0xc6, 0x25,
244 0x11, 0x3a, 0x59, 0x09, 0x32, 0xfe, 0xeb, 0xb4,
245 0x59, 0x98, 0x69, 0xe2, 0x83, 0xe9, 0xdb, 0xd9,
246 0xc7, 0x24, 0xeb, 0xf2, 0xd5, 0x30, 0x3b, 0x73,
247 0xd7, 0xda, 0x9a, 0x2c, 0xd1, 0xd7, 0x95, 0x70,
248 0xc5, 0x9d, 0x71, 0xb8, 0x32, 0x68, 0xc9, 0xd1,
249 } 240 }
250 ) 241 )
251 242
@@ -255,7 +246,7 @@ func TestDeriveH(t *testing.T) {
255 t.Fatal(err) 246 t.Fatal(err)
256 } 247 }
257 248
258 // derive and checkpublic key 249 // derive and check public key
259 pub := prv.Public() 250 pub := prv.Public()
260 if !bytes.Equal(pub.Bytes(), PUB) { 251 if !bytes.Equal(pub.Bytes(), PUB) {
261 t.Fatal("wrong public key") 252 t.Fatal("wrong public key")
@@ -290,16 +281,6 @@ func TestDeriveH(t *testing.T) {
290 } 281 }
291 t.Fatal("x-coordinate mismatch") 282 t.Fatal("x-coordinate mismatch")
292 } 283 }
293
294 // test query
295 out := sha512.Sum512(dpub.Bytes())
296 if !bytes.Equal(out[:], QUERY) {
297 if testing.Verbose() {
298 t.Log("query(computed) = " + hex.EncodeToString(out[:]))
299 t.Log("query(expected) = " + hex.EncodeToString(QUERY))
300 }
301 t.Fatal("Query mismatch")
302 }
303} 284}
304 285
305func TestHKDF_gnunet(t *testing.T) { 286func TestHKDF_gnunet(t *testing.T) {
diff --git a/src/gnunet/enums/results.go b/src/gnunet/enums/results.go
new file mode 100644
index 0000000..ea93b0e
--- /dev/null
+++ b/src/gnunet/enums/results.go
@@ -0,0 +1,31 @@
1// This file is part of gnunet-go, a GNUnet-implementation in Golang.
2// Copyright (C) 2019-2022 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//nolint:stylecheck // allow non-camel-case for constants
20package enums
21
22// ResultCode type
23type ResultCode int32
24
25// ResultCode values
26const (
27 RC_SYSERR ResultCode = -1
28 RC_NO ResultCode = 0
29 RC_YES ResultCode = 1
30 RC_OK ResultCode = 1
31)
diff --git a/src/gnunet/go.mod b/src/gnunet/go.mod
index 185eaad..6e0021b 100644
--- a/src/gnunet/go.mod
+++ b/src/gnunet/go.mod
@@ -3,7 +3,7 @@ module gnunet
3go 1.18 3go 1.18
4 4
5require ( 5require (
6 github.com/bfix/gospel v1.2.20 6 github.com/bfix/gospel v1.2.21
7 github.com/go-redis/redis/v8 v8.11.5 7 github.com/go-redis/redis/v8 v8.11.5
8 github.com/go-sql-driver/mysql v1.6.0 8 github.com/go-sql-driver/mysql v1.6.0
9 github.com/gorilla/mux v1.8.0 9 github.com/gorilla/mux v1.8.0
@@ -24,4 +24,4 @@ require (
24 golang.org/x/tools v0.1.11 // indirect 24 golang.org/x/tools v0.1.11 // indirect
25) 25)
26 26
27// replace github.com/bfix/gospel v1.2.20 => ../gospel 27// replace github.com/bfix/gospel v1.2.21 => ../gospel
diff --git a/src/gnunet/go.sum b/src/gnunet/go.sum
index a8e3d7e..26ce2b7 100644
--- a/src/gnunet/go.sum
+++ b/src/gnunet/go.sum
@@ -1,5 +1,5 @@
1github.com/bfix/gospel v1.2.20 h1:e/IxmTiC579jIQlIxpMzCX/MIKHNsBzJ1WdMKheCgBw= 1github.com/bfix/gospel v1.2.21 h1:rgllMlR+2AZt6+x0uaBF67a+pM7fJxHiO93amhKXZNU=
2github.com/bfix/gospel v1.2.20/go.mod h1:cdu63bA9ZdfeDoqZ+vnWOcbY9Puwdzmf5DMxMGMznRI= 2github.com/bfix/gospel v1.2.21/go.mod h1:cdu63bA9ZdfeDoqZ+vnWOcbY9Puwdzmf5DMxMGMznRI=
3github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= 3github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
4github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 4github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
5github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= 5github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
diff --git a/src/gnunet/message/factory.go b/src/gnunet/message/factory.go
index 82af6e9..e3a2943 100644
--- a/src/gnunet/message/factory.go
+++ b/src/gnunet/message/factory.go
@@ -31,6 +31,7 @@ func NewEmptyMessage(msgType enums.MsgType) (Message, error) {
31 //------------------------------------------------------------------ 31 //------------------------------------------------------------------
32 // Transport 32 // Transport
33 //------------------------------------------------------------------ 33 //------------------------------------------------------------------
34
34 case enums.MSG_TRANSPORT_TCP_WELCOME: 35 case enums.MSG_TRANSPORT_TCP_WELCOME:
35 return NewTransportTCPWelcomeMsg(nil), nil 36 return NewTransportTCPWelcomeMsg(nil), nil
36 case enums.MSG_HELLO: 37 case enums.MSG_HELLO:
@@ -53,12 +54,14 @@ func NewEmptyMessage(msgType enums.MsgType) (Message, error) {
53 //------------------------------------------------------------------ 54 //------------------------------------------------------------------
54 // Core 55 // Core
55 //------------------------------------------------------------------ 56 //------------------------------------------------------------------
57
56 case enums.MSG_CORE_EPHEMERAL_KEY: 58 case enums.MSG_CORE_EPHEMERAL_KEY:
57 return NewEphemeralKeyMsg(), nil 59 return NewEphemeralKeyMsg(), nil
58 60
59 //------------------------------------------------------------------ 61 //------------------------------------------------------------------
60 // DHT 62 // DHT
61 //------------------------------------------------------------------ 63 //------------------------------------------------------------------
64
62 case enums.MSG_DHT_CLIENT_PUT: 65 case enums.MSG_DHT_CLIENT_PUT:
63 return NewDHTClientPutMsg(nil, 0, nil), nil 66 return NewDHTClientPutMsg(nil, 0, nil), nil
64 case enums.MSG_DHT_CLIENT_GET: 67 case enums.MSG_DHT_CLIENT_GET:
@@ -73,6 +76,7 @@ func NewEmptyMessage(msgType enums.MsgType) (Message, error) {
73 //------------------------------------------------------------------ 76 //------------------------------------------------------------------
74 // DHT-P2P 77 // DHT-P2P
75 //------------------------------------------------------------------ 78 //------------------------------------------------------------------
79
76 case enums.MSG_DHT_P2P_HELLO: 80 case enums.MSG_DHT_P2P_HELLO:
77 return NewDHTP2PHelloMsg(), nil 81 return NewDHTP2PHelloMsg(), nil
78 case enums.MSG_DHT_P2P_GET: 82 case enums.MSG_DHT_P2P_GET:
@@ -85,6 +89,7 @@ func NewEmptyMessage(msgType enums.MsgType) (Message, error) {
85 //------------------------------------------------------------------ 89 //------------------------------------------------------------------
86 // GNS 90 // GNS
87 //------------------------------------------------------------------ 91 //------------------------------------------------------------------
92
88 case enums.MSG_GNS_LOOKUP: 93 case enums.MSG_GNS_LOOKUP:
89 return NewGNSLookupMsg(), nil 94 return NewGNSLookupMsg(), nil
90 case enums.MSG_GNS_LOOKUP_RESULT: 95 case enums.MSG_GNS_LOOKUP_RESULT:
@@ -93,6 +98,7 @@ func NewEmptyMessage(msgType enums.MsgType) (Message, error) {
93 //------------------------------------------------------------------ 98 //------------------------------------------------------------------
94 // Namecache 99 // Namecache
95 //------------------------------------------------------------------ 100 //------------------------------------------------------------------
101
96 case enums.MSG_NAMECACHE_LOOKUP_BLOCK: 102 case enums.MSG_NAMECACHE_LOOKUP_BLOCK:
97 return NewNamecacheLookupMsg(nil), nil 103 return NewNamecacheLookupMsg(nil), nil
98 case enums.MSG_NAMECACHE_LOOKUP_BLOCK_RESPONSE: 104 case enums.MSG_NAMECACHE_LOOKUP_BLOCK_RESPONSE:
@@ -105,6 +111,7 @@ func NewEmptyMessage(msgType enums.MsgType) (Message, error) {
105 //------------------------------------------------------------------ 111 //------------------------------------------------------------------
106 // Revocation 112 // Revocation
107 //------------------------------------------------------------------ 113 //------------------------------------------------------------------
114
108 case enums.MSG_REVOCATION_QUERY: 115 case enums.MSG_REVOCATION_QUERY:
109 return NewRevocationQueryMsg(nil), nil 116 return NewRevocationQueryMsg(nil), nil
110 case enums.MSG_REVOCATION_QUERY_RESPONSE: 117 case enums.MSG_REVOCATION_QUERY_RESPONSE:
@@ -115,8 +122,32 @@ func NewEmptyMessage(msgType enums.MsgType) (Message, error) {
115 return NewRevocationRevokeResponseMsg(false), nil 122 return NewRevocationRevokeResponseMsg(false), nil
116 123
117 //------------------------------------------------------------------ 124 //------------------------------------------------------------------
125 // Identity service
126 //------------------------------------------------------------------
127
128 case enums.MSG_IDENTITY_START:
129 return NewIdentityStartMsg(), nil
130 case enums.MSG_IDENTITY_RESULT_CODE:
131 return NewIdentityResultCodeMsg(enums.RC_OK, ""), nil
132 case enums.MSG_IDENTITY_UPDATE:
133 return NewIdentityUpdateMsg("", nil), nil
134 case enums.MSG_IDENTITY_CREATE:
135 return NewIdentityCreateMsg(nil, ""), nil
136 case enums.MSG_IDENTITY_RENAME:
137 return NewIdentityRenameMsg("", ""), nil
138 case enums.MSG_IDENTITY_DELETE:
139 return NewIdentityDeleteMsg(""), nil
140 case enums.MSG_IDENTITY_LOOKUP:
141 return NewIdentityLookupMsg(""), nil
142 case enums.MSG_IDENTITY_GET_DEFAULT:
143 return NewIdentityGetDefaultMsg(""), nil
144 case enums.MSG_IDENTITY_SET_DEFAULT:
145 return NewIdentitySetDefaultMsg(nil, ""), nil
146
147 //------------------------------------------------------------------
118 // Namestore service 148 // Namestore service
119 //------------------------------------------------------------------ 149 //------------------------------------------------------------------
150
120 case enums.MSG_NAMESTORE_ZONE_ITERATION_START: 151 case enums.MSG_NAMESTORE_ZONE_ITERATION_START:
121 return NewNamestoreZoneIterStartMsg(nil), nil 152 return NewNamestoreZoneIterStartMsg(nil), nil
122 case enums.MSG_NAMESTORE_ZONE_ITERATION_NEXT: 153 case enums.MSG_NAMESTORE_ZONE_ITERATION_NEXT:
@@ -130,6 +161,7 @@ func NewEmptyMessage(msgType enums.MsgType) (Message, error) {
130 case enums.MSG_NAMESTORE_MONITOR_START: 161 case enums.MSG_NAMESTORE_MONITOR_START:
131 case enums.MSG_NAMESTORE_MONITOR_SYNC: 162 case enums.MSG_NAMESTORE_MONITOR_SYNC:
132 case enums.MSG_NAMESTORE_RECORD_RESULT: 163 case enums.MSG_NAMESTORE_RECORD_RESULT:
164 return NewNamestoreRecordResultMsg(nil, ""), nil
133 case enums.MSG_NAMESTORE_MONITOR_NEXT: 165 case enums.MSG_NAMESTORE_MONITOR_NEXT:
134 } 166 }
135 return nil, fmt.Errorf("unknown message type %d", msgType) 167 return nil, fmt.Errorf("unknown message type %d", msgType)
diff --git a/src/gnunet/message/message.go b/src/gnunet/message/message.go
index 946dd6e..7e9b2d1 100644
--- a/src/gnunet/message/message.go
+++ b/src/gnunet/message/message.go
@@ -43,6 +43,9 @@ type Message interface {
43 43
44 // String returns a human-readable message 44 // String returns a human-readable message
45 String() string 45 String() string
46
47 // Init called after unmarshalling a message to setup internal state
48 Init() error
46} 49}
47 50
48//---------------------------------------------------------------------- 51//----------------------------------------------------------------------
diff --git a/src/gnunet/message/msg_core.go b/src/gnunet/message/msg_core.go
index 6ebb30e..227b901 100644
--- a/src/gnunet/message/msg_core.go
+++ b/src/gnunet/message/msg_core.go
@@ -45,7 +45,7 @@ type EphKeyBlock struct {
45type EphemeralKeyMsg struct { 45type EphemeralKeyMsg struct {
46 MsgHeader 46 MsgHeader
47 SenderStatus uint32 `order:"big"` // enum PeerStateMachine 47 SenderStatus uint32 `order:"big"` // enum PeerStateMachine
48 Signature *util.PeerSignature `` // EdDSA signature 48 Signature *util.PeerSignature `init:"Init"` // EdDSA signature
49 SignedBlock *EphKeyBlock 49 SignedBlock *EphKeyBlock
50} 50}
51 51
@@ -68,6 +68,9 @@ func NewEphemeralKeyMsg() *EphemeralKeyMsg {
68 } 68 }
69} 69}
70 70
71// Init called after unmarshalling a message to setup internal state
72func (m *EphemeralKeyMsg) Init() error { return nil }
73
71// String returns a human-readable representation of the message. 74// String returns a human-readable representation of the message.
72func (m *EphemeralKeyMsg) String() string { 75func (m *EphemeralKeyMsg) String() string {
73 return fmt.Sprintf("EphKeyMsg{peer=%s,ephkey=%s,create=%s,expire=%s,status=%d}", 76 return fmt.Sprintf("EphKeyMsg{peer=%s,ephkey=%s,create=%s,expire=%s,status=%d}",
diff --git a/src/gnunet/message/msg_dht.go b/src/gnunet/message/msg_dht.go
index 0f8b9cc..2e99d40 100644
--- a/src/gnunet/message/msg_dht.go
+++ b/src/gnunet/message/msg_dht.go
@@ -67,6 +67,9 @@ func (m *DHTClientPutMsg) String() string {
67 m.BType, m.Expire, m.Options, m.ReplLevel, m.Key) 67 m.BType, m.Expire, m.Options, m.ReplLevel, m.Key)
68} 68}
69 69
70// Init called after unmarshalling a message to setup internal state
71func (m *DHTClientPutMsg) Init() error { return nil }
72
70//---------------------------------------------------------------------- 73//----------------------------------------------------------------------
71// DHT_CLIENT_GET 74// DHT_CLIENT_GET
72//---------------------------------------------------------------------- 75//----------------------------------------------------------------------
@@ -113,6 +116,9 @@ func (m *DHTClientGetMsg) String() string {
113 m.ID, m.BType, m.Options, m.ReplLevel, m.Key) 116 m.ID, m.BType, m.Options, m.ReplLevel, m.Key)
114} 117}
115 118
119// Init called after unmarshalling a message to setup internal state
120func (m *DHTClientGetMsg) Init() error { return nil }
121
116//---------------------------------------------------------------------- 122//----------------------------------------------------------------------
117// DHT_CLIENT_RESULT 123// DHT_CLIENT_RESULT
118//---------------------------------------------------------------------- 124//----------------------------------------------------------------------
@@ -153,6 +159,9 @@ func (m *DHTClientResultMsg) String() string {
153 return fmt.Sprintf("DHTClientResultMsg{id:%d,type=%s,expire=%s}", m.ID, m.BType, m.Expire) 159 return fmt.Sprintf("DHTClientResultMsg{id:%d,type=%s,expire=%s}", m.ID, m.BType, m.Expire)
154} 160}
155 161
162// Init called after unmarshalling a message to setup internal state
163func (m *DHTClientResultMsg) Init() error { return nil }
164
156//---------------------------------------------------------------------- 165//----------------------------------------------------------------------
157// DHT_CLIENT_GET_STOP 166// DHT_CLIENT_GET_STOP
158//---------------------------------------------------------------------- 167//----------------------------------------------------------------------
@@ -183,6 +192,9 @@ func (m *DHTClientGetStopMsg) String() string {
183 return fmt.Sprintf("DHTClientGetStopMsg{Id:%d,Key=%s}", m.ID, m.Key) 192 return fmt.Sprintf("DHTClientGetStopMsg{Id:%d,Key=%s}", m.ID, m.Key)
184} 193}
185 194
195// Init called after unmarshalling a message to setup internal state
196func (m *DHTClientGetStopMsg) Init() error { return nil }
197
186//---------------------------------------------------------------------- 198//----------------------------------------------------------------------
187// DHT_CLIENT_GET_RESULTS_KNOWN 199// DHT_CLIENT_GET_RESULTS_KNOWN
188//---------------------------------------------------------------------- 200//----------------------------------------------------------------------
@@ -220,3 +232,6 @@ func (m *DHTClientGetResultsKnownMsg) String() string {
220 return fmt.Sprintf("DHTClientGetResultsKnownMsg{Id:%d,Key=%s,Num=%d}", 232 return fmt.Sprintf("DHTClientGetResultsKnownMsg{Id:%d,Key=%s,Num=%d}",
221 m.ID, m.Key.Data, len(m.Known)) 233 m.ID, m.Key.Data, len(m.Known))
222} 234}
235
236// Init called after unmarshalling a message to setup internal state
237func (m *DHTClientGetResultsKnownMsg) Init() error { return nil }
diff --git a/src/gnunet/message/msg_dht_p2p.go b/src/gnunet/message/msg_dht_p2p.go
index d4a474c..f7c24fd 100644
--- a/src/gnunet/message/msg_dht_p2p.go
+++ b/src/gnunet/message/msg_dht_p2p.go
@@ -76,6 +76,9 @@ func NewDHTP2PGetMsg() *DHTP2PGetMsg {
76 } 76 }
77} 77}
78 78
79// Init called after unmarshalling a message to setup internal state
80func (m *DHTP2PGetMsg) Init() (err error) { return nil }
81
79// String returns a human-readable representation of the message. 82// String returns a human-readable representation of the message.
80func (m *DHTP2PGetMsg) String() string { 83func (m *DHTP2PGetMsg) String() string {
81 return fmt.Sprintf("DHTP2PGetMsg{btype=%s,hops=%d,flags=%s}", 84 return fmt.Sprintf("DHTP2PGetMsg{btype=%s,hops=%d,flags=%s}",
@@ -167,6 +170,11 @@ func (m *DHTP2PPutMsg) IsUsed(field string) bool {
167 return false 170 return false
168} 171}
169 172
173// Init called after unmarshalling a message to setup internal state
174func (m *DHTP2PPutMsg) Init() (err error) {
175 return nil
176}
177
170//---------------------------------------------------------------------- 178//----------------------------------------------------------------------
171 179
172// Update message (forwarding) 180// Update message (forwarding)
@@ -287,17 +295,17 @@ func (m *DHTP2PPutMsg) String() string {
287// DHTP2PResultMsg wire layout 295// DHTP2PResultMsg wire layout
288type DHTP2PResultMsg struct { 296type DHTP2PResultMsg struct {
289 MsgHeader 297 MsgHeader
290 BType enums.BlockType `order:"big"` // Block type of result 298 BType enums.BlockType `order:"big"` // Block type of result
291 Reserved uint16 `order:"big"` // Reserved 299 Reserved uint16 `order:"big"` // Reserved
292 Flags uint16 `order:"big"` // Message flags 300 Flags uint16 `order:"big"` // Message flags
293 PutPathL uint16 `order:"big"` // size of PUTPATH field 301 PutPathL uint16 `order:"big"` // size of PUTPATH field
294 GetPathL uint16 `order:"big"` // size of GETPATH field 302 GetPathL uint16 `order:"big"` // size of GETPATH field
295 Expire util.AbsoluteTime `` // expiration date 303 Expire util.AbsoluteTime `` // expiration date
296 Query *crypto.HashCode `` // Query key for block 304 Query *crypto.HashCode `` // Query key for block
297 TruncOrigin *util.PeerID `opt:"(IsUsed)"` // truncated origin (if TRUNCATED flag set) 305 TruncOrigin *util.PeerID `opt:"(IsUsed)"` // truncated origin (if TRUNCATED flag set)
298 PathList []*path.Entry `size:"(NumPath)"` // PATH 306 PathList []*path.Entry `size:"(NumPath)"` // PATH
299 LastSig *util.PeerSignature `opt:"(IsUsed)"` // signature of last hop (if RECORD_ROUTE flag is set) 307 LastSig *util.PeerSignature `opt:"(IsUsed)" init:"Init"` // signature of last hop (if RECORD_ROUTE flag is set)
300 Block []byte `size:"*"` // block data 308 Block []byte `size:"*"` // block data
301} 309}
302 310
303// NewDHTP2PResultMsg creates a new empty DHTP2PResultMsg 311// NewDHTP2PResultMsg creates a new empty DHTP2PResultMsg
@@ -330,6 +338,11 @@ func (m *DHTP2PResultMsg) NumPath(field string) uint {
330 return uint(m.GetPathL + m.PutPathL) 338 return uint(m.GetPathL + m.PutPathL)
331} 339}
332 340
341// Init called after unmarshalling a message to setup internal state
342func (m *DHTP2PResultMsg) Init() (err error) {
343 return nil
344}
345
333//---------------------------------------------------------------------- 346//----------------------------------------------------------------------
334// Path handling (get/set path in message) 347// Path handling (get/set path in message)
335//---------------------------------------------------------------------- 348//----------------------------------------------------------------------
@@ -471,9 +484,12 @@ type DHTP2PHelloMsg struct {
471 MsgHeader 484 MsgHeader
472 Reserved uint16 `order:"big"` // Reserved for further use 485 Reserved uint16 `order:"big"` // Reserved for further use
473 NumAddr uint16 `order:"big"` // Number of addresses in list 486 NumAddr uint16 `order:"big"` // Number of addresses in list
474 Signature *util.PeerSignature `` // Signature 487 Signature *util.PeerSignature `init:"Init"` // Signature
475 Expire util.AbsoluteTime `` // expiration time 488 Expire util.AbsoluteTime `` // expiration time
476 AddrList []byte `size:"*"` // List of end-point addresses (HelloAddress) 489 AddrList []byte `size:"*"` // List of end-point addresses (HelloAddress)
490
491 // transient state
492 addresses []*util.Address // list of converted addresses
477} 493}
478 494
479// NewHelloMsgDHT creates an empty DHT_P2P_HELLO message. 495// NewHelloMsgDHT creates an empty DHT_P2P_HELLO message.
@@ -492,8 +508,12 @@ func NewDHTP2PHelloMsg() *DHTP2PHelloMsg {
492 } 508 }
493} 509}
494 510
495// Addresses returns the list of HelloAddress 511// Init called after unmarshalling a message to setup internal state
496func (m *DHTP2PHelloMsg) Addresses() (list []*util.Address, err error) { 512func (m *DHTP2PHelloMsg) Init() (err error) {
513 if m.addresses != nil {
514 return
515 }
516 m.addresses = make([]*util.Address, 0)
497 var addr *util.Address 517 var addr *util.Address
498 var as string 518 var as string
499 num, pos := 0, 0 519 num, pos := 0, 0
@@ -506,16 +526,25 @@ func (m *DHTP2PHelloMsg) Addresses() (list []*util.Address, err error) {
506 return 526 return
507 } 527 }
508 addr.Expire = m.Expire 528 addr.Expire = m.Expire
509 list = append(list, addr) 529 m.addresses = append(m.addresses, addr)
510 num++ 530 num++
511 } 531 }
512 // check numbers 532 // check numbers
513 if num != int(m.NumAddr) { 533 if num != int(m.NumAddr) {
514 logger.Printf(logger.WARN, "[DHTP2PHelloMsg] Number of addresses does not match (got %d, expected %d)", num, m.NumAddr) 534 err = errors.New("number of addresses does not match")
515 } 535 }
516 return 536 return
517} 537}
518 538
539// Addresses returns the list of HelloAddress
540func (m *DHTP2PHelloMsg) Addresses() (list []*util.Address, err error) {
541 if m.addresses == nil {
542 err = errors.New("no addresses available")
543 return
544 }
545 return m.addresses, nil
546}
547
519// SetAddresses adds addresses to the HELLO message. 548// SetAddresses adds addresses to the HELLO message.
520func (m *DHTP2PHelloMsg) SetAddresses(list []*util.Address) { 549func (m *DHTP2PHelloMsg) SetAddresses(list []*util.Address) {
521 // write addresses as blob and track earliest expiration 550 // write addresses as blob and track earliest expiration
diff --git a/src/gnunet/message/msg_gns.go b/src/gnunet/message/msg_gns.go
index 1c7f9af..64f58a4 100644
--- a/src/gnunet/message/msg_gns.go
+++ b/src/gnunet/message/msg_gns.go
@@ -37,7 +37,7 @@ import (
37type LookupMsg struct { 37type LookupMsg struct {
38 MsgHeader 38 MsgHeader
39 ID uint32 `order:"big"` // Unique identifier for this request (for key collisions). 39 ID uint32 `order:"big"` // Unique identifier for this request (for key collisions).
40 Zone *crypto.ZoneKey `` // Zone that is to be used for lookup 40 Zone *crypto.ZoneKey `init:"Init"` // Zone that is to be used for lookup
41 Options uint16 `order:"big"` // Local options for where to look for results 41 Options uint16 `order:"big"` // Local options for where to look for results
42 Reserved uint16 `order:"big"` // Always 0 42 Reserved uint16 `order:"big"` // Always 0
43 RType enums.GNSType `order:"big"` // the type of record to look up 43 RType enums.GNSType `order:"big"` // the type of record to look up
@@ -81,6 +81,9 @@ func (m *LookupMsg) String() string {
81 m.ID, m.Zone.ID(), m.Options, m.RType, m.GetName()) 81 m.ID, m.Zone.ID(), m.Options, m.RType, m.GetName())
82} 82}
83 83
84// Init called after unmarshalling a message to setup internal state
85func (m *LookupMsg) Init() error { return nil }
86
84//---------------------------------------------------------------------- 87//----------------------------------------------------------------------
85// GNS_LOOKUP_RESULT 88// GNS_LOOKUP_RESULT
86//---------------------------------------------------------------------- 89//----------------------------------------------------------------------
@@ -124,3 +127,6 @@ func (m *LookupResultMsg) String() string {
124func (m *LookupResultMsg) Header() *MsgHeader { 127func (m *LookupResultMsg) Header() *MsgHeader {
125 return &MsgHeader{m.MsgSize, m.MsgType} 128 return &MsgHeader{m.MsgSize, m.MsgType}
126} 129}
130
131// Init called after unmarshalling a message to setup internal state
132func (m *LookupResultMsg) Init() error { return nil }
diff --git a/src/gnunet/message/msg_hello.go b/src/gnunet/message/msg_hello.go
index 4cc8712..73f2d9e 100644
--- a/src/gnunet/message/msg_hello.go
+++ b/src/gnunet/message/msg_hello.go
@@ -145,6 +145,32 @@ type HelloMsg struct {
145 FriendsOnly uint32 `order:"big"` // Do not gossip this HELLO message 145 FriendsOnly uint32 `order:"big"` // Do not gossip this HELLO message
146 Peer *util.PeerID `` // peer identifier for addresses 146 Peer *util.PeerID `` // peer identifier for addresses
147 AddrList []byte `size:"*"` // List of end-point addresses (HelloAddress) 147 AddrList []byte `size:"*"` // List of end-point addresses (HelloAddress)
148
149 // transient state
150 addresses []*HelloAddress // list of converted addresses
151}
152
153// Init called after unmarshalling a message to setup internal state
154func (m *HelloMsg) Init() (err error) {
155 // check for initialized state
156 if m.addresses != nil {
157 return nil
158 }
159 // convert addresses
160 m.addresses = make([]*HelloAddress, 0)
161 rdr := bytes.NewReader(m.AddrList)
162 var addr *HelloAddress
163 for {
164 // parse address from stream
165 if addr, err = ParseHelloAddr(rdr); err != nil {
166 // end of stream: no more addresses
167 if err == io.EOF {
168 err = nil
169 }
170 return
171 }
172 m.addresses = append(m.addresses, addr)
173 }
148} 174}
149 175
150// NewHelloMsg creates a new HELLO msg for a given peer. 176// NewHelloMsg creates a new HELLO msg for a given peer.
@@ -164,19 +190,10 @@ func NewHelloMsg(peer *util.PeerID) *HelloMsg {
164 190
165// Addresses returns the list of HelloAddress 191// Addresses returns the list of HelloAddress
166func (m *HelloMsg) Addresses() (list []*HelloAddress, err error) { 192func (m *HelloMsg) Addresses() (list []*HelloAddress, err error) {
167 rdr := bytes.NewReader(m.AddrList) 193 if m.addresses == nil {
168 var addr *HelloAddress 194 return
169 for {
170 // parse address from stream
171 if addr, err = ParseHelloAddr(rdr); err != nil {
172 // end of stream: no more addresses
173 if err == io.EOF {
174 err = nil
175 }
176 return
177 }
178 list = append(list, addr)
179 } 195 }
196 return m.addresses, nil
180} 197}
181 198
182// String returns a human-readable representation of the message. 199// String returns a human-readable representation of the message.
diff --git a/src/gnunet/message/msg_identity.go b/src/gnunet/message/msg_identity.go
new file mode 100644
index 0000000..fb8bba5
--- /dev/null
+++ b/src/gnunet/message/msg_identity.go
@@ -0,0 +1,473 @@
1// This file is part of gnunet-go, a GNUnet-implementation in Golang.
2// Copyright (C) 2019-2022 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
19package message
20
21import (
22 "fmt"
23 "gnunet/crypto"
24 "gnunet/enums"
25 "gnunet/util"
26)
27
28//----------------------------------------------------------------------
29// MSG_IDENTITY_START
30//
31// Start client connection for update notification. Triggers sending
32// all identities as update messages to client.
33//----------------------------------------------------------------------
34
35// IdentityStartMsg to initiate session.
36type IdentityStartMsg struct {
37 MsgHeader
38}
39
40// NewIdentityStartMsg creates an empty message
41func NewIdentityStartMsg() *IdentityStartMsg {
42 return &IdentityStartMsg{
43 MsgHeader: MsgHeader{4, enums.MSG_IDENTITY_START},
44 }
45}
46
47// Init called after unmarshalling a message to setup internal state
48func (msg *IdentityStartMsg) Init() error { return nil }
49
50// String returns a human-readable representation of the message.
51func (msg *IdentityStartMsg) String() string {
52 return "IdentityStartMsg{}"
53}
54
55//----------------------------------------------------------------------
56// MSG_IDENTITY_UPDATE
57//
58// IdentityStore changed (send to all clients with started session)
59//----------------------------------------------------------------------
60
61// IdentityUpdateMsg notifies about changes in identity store
62type IdentityUpdateMsg struct {
63 MsgHeader
64
65 NameLen uint16 `order:"big"`
66 EOL uint16 `order:"big"`
67 ZoneKey *crypto.ZonePrivate `init:"Init"`
68 Name_ []byte `size:"NameLen"`
69
70 // transient state
71 name string
72}
73
74// NewIdentityUpdateMsg creates an update message. If the zone key is nil,
75// a End-Of-List is triggered so the client knows we are done.
76func NewIdentityUpdateMsg(name string, zk *crypto.ZonePrivate) *IdentityUpdateMsg {
77 msg := &IdentityUpdateMsg{
78 MsgHeader: MsgHeader{8, enums.MSG_IDENTITY_UPDATE},
79 }
80 if zk == nil {
81 // tag end-of-list
82 msg.EOL = uint16(enums.RC_YES)
83 var size uint16
84 // assemble an empty zonekey
85 msg.ZoneKey, size = crypto.NullZonePrivate(enums.GNS_TYPE_PKEY)
86 msg.MsgSize += size
87 } else {
88 msg.name = name
89 msg.Name_ = util.WriteCString(name)
90 msg.NameLen = uint16(len(msg.Name_))
91 msg.MsgSize += msg.NameLen
92 msg.ZoneKey = zk
93 msg.MsgSize += uint16(zk.KeySize() + 4)
94 }
95 return msg
96}
97
98// Init called after unmarshalling a message to setup internal state
99func (msg *IdentityUpdateMsg) Init() error {
100 msg.name, _ = util.ReadCString(msg.Name_, 0)
101 return nil
102}
103
104// String returns a human-readable representation of the message.
105func (msg *IdentityUpdateMsg) String() string {
106 if msg.EOL == uint16(enums.RC_OK) {
107 return "IdentityUpdateMsg{end-of-list}"
108 }
109 return fmt.Sprintf("IdentityUpdateMsg{'%s'@%s}", msg.Name(), msg.ZoneKey.ID())
110}
111
112// Name of the new identity
113func (msg *IdentityUpdateMsg) Name() string {
114 return msg.name
115}
116
117//----------------------------------------------------------------------
118// MSG_IDENTITY_RESULT_CODE
119//
120// Returned by CREATE and RENAME (and by GET_DEFAULT on failure).
121//----------------------------------------------------------------------
122
123// IdentityResultCodeMsg is a response message
124type IdentityResultCodeMsg struct {
125 MsgHeader
126
127 ResultCode enums.ResultCode `order:"big"`
128 Error string `opt:"(OnError)"`
129}
130
131// OnError returns true if an error message is attached
132func (msg *IdentityResultCodeMsg) OnError() bool {
133 return msg.ResultCode != enums.RC_OK
134}
135
136// Init called after unmarshalling a message to setup internal state
137func (msg *IdentityResultCodeMsg) Init() error { return nil }
138
139// NewIdentityResultCodeMsg creates a new default message.
140func NewIdentityResultCodeMsg(rc enums.ResultCode, err string) *IdentityResultCodeMsg {
141 msg := &IdentityResultCodeMsg{
142 MsgHeader: MsgHeader{
143 MsgSize: 8,
144 MsgType: enums.MSG_IDENTITY_RESULT_CODE,
145 },
146 ResultCode: rc,
147 }
148 if rc != enums.RC_OK {
149 msg.Error = err
150 msg.MsgSize += uint16(len(err) + 1)
151 }
152 return msg
153}
154
155// String returns a human-readable representation of the message.
156func (msg *IdentityResultCodeMsg) String() string {
157 return fmt.Sprintf("IdentityResultCodeMsg{rc=%d,err='%s'}", msg.ResultCode, msg.Error)
158}
159
160//----------------------------------------------------------------------
161// MSG_IDENTITY_CREATE
162//
163// Create new identity with service association
164//----------------------------------------------------------------------
165
166// IdentityCreateMsg to create a new identity for given service
167type IdentityCreateMsg struct {
168 MsgHeader
169
170 NameLen uint16 `order:"big"`
171 Reserved uint16 `order:"big"`
172 ZoneKey *crypto.ZonePrivate `init:"Init"`
173 Name_ []byte `size:"NameLen"`
174
175 // transient state
176 name string
177}
178
179// Init called after unmarshalling a message to setup internal state
180func (msg *IdentityCreateMsg) Init() error {
181 msg.name, _ = util.ReadCString(msg.Name_, 0)
182 return nil
183}
184
185// NewIdentityCreateMsg creates a new default message.
186func NewIdentityCreateMsg(zk *crypto.ZonePrivate, name string) *IdentityCreateMsg {
187 var size uint16
188 if zk == nil {
189 zk, size = crypto.NullZonePrivate(enums.GNS_TYPE_PKEY)
190 } else {
191 size = uint16(zk.KeySize() + 4)
192 }
193 msg := &IdentityCreateMsg{
194 MsgHeader: MsgHeader{
195 MsgSize: size + 8,
196 MsgType: enums.MSG_IDENTITY_CREATE,
197 },
198 ZoneKey: zk,
199 }
200 if len(name) > 0 {
201 msg.Name_ = util.WriteCString(name)
202 msg.MsgSize += uint16(len(msg.Name_))
203 msg.name = name
204 }
205 return msg
206}
207
208// String returns a human-readable representation of the message.
209func (msg *IdentityCreateMsg) String() string {
210 return fmt.Sprintf("IdentityCreateMsg{name='%s',key=%s}", msg.name, msg.ZoneKey.ID())
211}
212
213// Name of the new identity
214func (msg *IdentityCreateMsg) Name() string {
215 return msg.name
216}
217
218//----------------------------------------------------------------------
219// MSG_IDENTITY_RENAME
220//
221// Rename identity
222//----------------------------------------------------------------------
223
224// IdentitRenameMsg to rename an identity
225type IdentityRenameMsg struct {
226 MsgHeader
227
228 OldNameLen uint16 `order:"big"`
229 NewNameLen uint16 `order:"big"`
230 OldName_ []byte `size:"OldNameLen"`
231 NewName_ []byte `size:"NewNameLen"`
232
233 // transient state
234 oldName string
235 newName string
236}
237
238// Init called after unmarshalling a message to setup internal state
239func (msg *IdentityRenameMsg) Init() error {
240 msg.oldName, _ = util.ReadCString(msg.OldName_, 0)
241 msg.newName, _ = util.ReadCString(msg.NewName_, 0)
242 return nil
243}
244
245// NewIdentityRenameMsg renames an identity
246func NewIdentityRenameMsg(oldName, newName string) *IdentityRenameMsg {
247 msg := &IdentityRenameMsg{
248 MsgHeader: MsgHeader{
249 MsgSize: 8,
250 MsgType: enums.MSG_IDENTITY_RENAME,
251 },
252 }
253 if len(oldName) > 0 {
254 msg.OldName_ = util.WriteCString(oldName)
255 msg.MsgSize += uint16(len(msg.OldName_))
256 msg.oldName = oldName
257 }
258 if len(newName) > 0 {
259 msg.NewName_ = util.WriteCString(newName)
260 msg.MsgSize += uint16(len(msg.NewName_))
261 msg.newName = newName
262 }
263 return msg
264}
265
266// String returns a human-readable representation of the message.
267func (msg *IdentityRenameMsg) String() string {
268 return fmt.Sprintf("IdentityRenameMsg{'%s'->'%s'}", msg.oldName, msg.newName)
269}
270
271// OldName of the identity
272func (msg *IdentityRenameMsg) OldName() string {
273 return msg.oldName
274}
275
276// NewName of the identity
277func (msg *IdentityRenameMsg) NewName() string {
278 return msg.newName
279}
280
281//----------------------------------------------------------------------
282// MSG_IDENTITY_DELETE
283//
284// Remove named identity
285//----------------------------------------------------------------------
286
287// IdentityDeleteMsg requests the deletion of an identity
288type IdentityDeleteMsg struct {
289 MsgHeader
290
291 NameLen uint16 `order:"big"`
292 Reserved uint16 `order:"big"`
293 Name_ []byte `size:"NameLen"`
294
295 // transient state
296 name string
297}
298
299// Init called after unmarshalling a message to setup internal state
300func (msg *IdentityDeleteMsg) Init() error {
301 msg.name, _ = util.ReadCString(msg.Name_, 0)
302 return nil
303}
304
305// NewIdentityDeleteMsg renames an identity
306func NewIdentityDeleteMsg(name string) *IdentityDeleteMsg {
307 msg := &IdentityDeleteMsg{
308 MsgHeader: MsgHeader{
309 MsgSize: 8,
310 MsgType: enums.MSG_IDENTITY_DELETE,
311 },
312 }
313 if len(name) > 0 {
314 msg.Name_ = util.WriteCString(name)
315 msg.MsgSize += uint16(len(msg.Name_))
316 msg.name = name
317 }
318 return msg
319}
320
321// String returns a human-readable representation of the message.
322func (msg *IdentityDeleteMsg) String() string {
323 return fmt.Sprintf("IdentityDeleteMsg{name='%s'}", msg.name)
324}
325
326// Name of the removed identity
327func (msg *IdentityDeleteMsg) Name() string {
328 return msg.name
329}
330
331//----------------------------------------------------------------------
332// MSG_IDENTITY_LOOKUP
333//
334// Return default identity
335//----------------------------------------------------------------------
336
337// IdentityLookupMsg to lookup named identity
338type IdentityLookupMsg struct {
339 MsgHeader
340
341 Name string
342}
343
344// Init called after unmarshalling a message to setup internal state
345func (msg *IdentityLookupMsg) Init() error {
346 return nil
347}
348
349// NewIdentityLookupMsg renames an identity
350func NewIdentityLookupMsg(name string) *IdentityLookupMsg {
351 return &IdentityLookupMsg{
352 MsgHeader: MsgHeader{
353 MsgSize: uint16(len(name) + 9),
354 MsgType: enums.MSG_IDENTITY_DELETE,
355 },
356 Name: name,
357 }
358}
359
360// String returns a human-readable representation of the message.
361func (msg *IdentityLookupMsg) String() string {
362 return fmt.Sprintf("IdentityLookupMsg{name='%s'}", msg.Name)
363}
364
365//----------------------------------------------------------------------
366// MSG_IDENTITY_GET_DEFAULT
367//
368// Get the default identity for named subsystem
369//----------------------------------------------------------------------
370
371// IdentityGetDefault to retrieve the default identity for a service
372type IdentityGetDefaultMsg struct {
373 MsgHeader
374
375 SrvLen uint16 `order:"big"`
376 Reserved uint16 `order:"big"`
377 Service_ []byte `size:"SrvLen"`
378
379 // transient state
380 service string
381}
382
383// Init called after unmarshalling a message to setup internal state
384func (msg *IdentityGetDefaultMsg) Init() error {
385 msg.service, _ = util.ReadCString(msg.Service_, 0)
386 return nil
387}
388
389// NewIdentityGetDefaultMsg creates a new message
390func NewIdentityGetDefaultMsg(svc string) *IdentityGetDefaultMsg {
391 msg := &IdentityGetDefaultMsg{
392 MsgHeader: MsgHeader{
393 MsgSize: 8,
394 MsgType: enums.MSG_IDENTITY_DELETE,
395 },
396 }
397 if len(svc) > 0 {
398 msg.Service_ = util.WriteCString(svc)
399 msg.MsgSize += uint16(len(msg.Service_))
400 msg.service = svc
401 }
402 return msg
403}
404
405// String returns a human-readable representation of the message.
406func (msg *IdentityGetDefaultMsg) String() string {
407 return fmt.Sprintf("IdentityGetDefaultMsg{svc='%s'}", msg.service)
408}
409
410// Service name
411func (msg *IdentityGetDefaultMsg) Service() string {
412 return msg.service
413}
414
415//----------------------------------------------------------------------
416// MSG_IDENTITY_SET_DEFAULT
417//
418// Set default identity for named subsystem
419//----------------------------------------------------------------------
420
421// IdentitySetDefaultMsg sets a default identity (key) for a service
422type IdentitySetDefaultMsg struct {
423 MsgHeader
424
425 SrvLen uint16 `order:"big"`
426 Reserved uint16 `order:"big"`
427 ZoneKey *crypto.ZonePrivate `init:"Init"`
428 Service_ []byte `size:"SrvLen"`
429
430 // transient state
431 service string
432}
433
434// Init called after unmarshalling a message to setup internal state
435func (msg *IdentitySetDefaultMsg) Init() error {
436 msg.service, _ = util.ReadCString(msg.Service_, 0)
437 return nil
438}
439
440// NewIdentitySetDefaultMsg renames an identity
441func NewIdentitySetDefaultMsg(zk *crypto.ZonePrivate, svc string) *IdentitySetDefaultMsg {
442 msg := &IdentitySetDefaultMsg{
443 MsgHeader: MsgHeader{
444 MsgSize: 8,
445 MsgType: enums.MSG_IDENTITY_DELETE,
446 },
447 }
448 if zk == nil {
449 // assemble an empty zonekey
450 var size uint16
451 msg.ZoneKey, size = crypto.NullZonePrivate(enums.GNS_TYPE_PKEY)
452 msg.MsgSize += size
453 } else {
454 msg.ZoneKey = zk
455 msg.MsgSize += uint16(zk.KeySize() + 4)
456 }
457 if len(svc) > 0 {
458 msg.Service_ = util.WriteCString(svc)
459 msg.MsgSize += uint16(len(msg.Service_))
460 msg.service = svc
461 }
462 return msg
463}
464
465// String returns a human-readable representation of the message.
466func (msg *IdentitySetDefaultMsg) String() string {
467 return fmt.Sprintf("IdentitySetDefaultMsg{key=%s,svc='%s'}", msg.ZoneKey.ID(), msg.service)
468}
469
470// Service name
471func (msg *IdentitySetDefaultMsg) Service() string {
472 return msg.service
473}
diff --git a/src/gnunet/message/msg_namecache.go b/src/gnunet/message/msg_namecache.go
index 53b2f4c..61309aa 100644
--- a/src/gnunet/message/msg_namecache.go
+++ b/src/gnunet/message/msg_namecache.go
@@ -67,6 +67,9 @@ func NewNamecacheLookupMsg(query *crypto.HashCode) *NamecacheLookupMsg {
67 } 67 }
68} 68}
69 69
70// Init called after unmarshalling a message to setup internal state
71func (m *NamecacheLookupMsg) Init() error { return nil }
72
70// String returns a human-readable representation of the message. 73// String returns a human-readable representation of the message.
71func (m *NamecacheLookupMsg) String() string { 74func (m *NamecacheLookupMsg) String() string {
72 return fmt.Sprintf("NamecacheLookupMsg{Id=%d,Query=%s}", 75 return fmt.Sprintf("NamecacheLookupMsg{Id=%d,Query=%s}",
@@ -81,11 +84,14 @@ func (m *NamecacheLookupMsg) String() string {
81type NamecacheLookupResultMsg struct { 84type NamecacheLookupResultMsg struct {
82 GenericNamecacheMsg 85 GenericNamecacheMsg
83 86
84 Expire util.AbsoluteTime `` // Expiration time 87 Expire util.AbsoluteTime `` // Expiration time
85 DerivedKeySig *crypto.ZoneSignature `` // Derived public key 88 DerivedKeySig *crypto.ZoneSignature `init:"Init"` // Derived public key
86 EncData []byte `size:"*"` // Encrypted block data 89 EncData []byte `size:"*"` // Encrypted block data
87} 90}
88 91
92// Init called after unmarshalling a message to setup internal state
93func (m *NamecacheLookupResultMsg) Init() error { return nil }
94
89// NewNamecacheLookupResultMsg creates a new default message. 95// NewNamecacheLookupResultMsg creates a new default message.
90func NewNamecacheLookupResultMsg() *NamecacheLookupResultMsg { 96func NewNamecacheLookupResultMsg() *NamecacheLookupResultMsg {
91 return &NamecacheLookupResultMsg{ 97 return &NamecacheLookupResultMsg{
@@ -116,6 +122,9 @@ type NamecacheCacheMsg struct {
116 EncData []byte `size:"*"` // Encrypted block data 122 EncData []byte `size:"*"` // Encrypted block data
117} 123}
118 124
125// Init called after unmarshalling a message to setup internal state
126func (m *NamecacheCacheMsg) Init() error { return nil }
127
119// Size returns buffer sizes for fields 128// Size returns buffer sizes for fields
120func (m *NamecacheCacheMsg) FldSize(field string) uint { 129func (m *NamecacheCacheMsg) FldSize(field string) uint {
121 switch field { 130 switch field {
@@ -174,6 +183,9 @@ func NewNamecacheCacheResponseMsg() *NamecacheCacheResponseMsg {
174 } 183 }
175} 184}
176 185
186// Init called after unmarshalling a message to setup internal state
187func (m *NamecacheCacheResponseMsg) Init() error { return nil }
188
177// String returns a human-readable representation of the message. 189// String returns a human-readable representation of the message.
178func (m *NamecacheCacheResponseMsg) String() string { 190func (m *NamecacheCacheResponseMsg) String() string {
179 return fmt.Sprintf("NamecacheCacheResponseMsg{id=%d,result=%d}", 191 return fmt.Sprintf("NamecacheCacheResponseMsg{id=%d,result=%d}",
diff --git a/src/gnunet/message/msg_namestore.go b/src/gnunet/message/msg_namestore.go
index a682ef1..f03ef2c 100644
--- a/src/gnunet/message/msg_namestore.go
+++ b/src/gnunet/message/msg_namestore.go
@@ -52,7 +52,7 @@ func newGenericNamestoreMsg(size uint16, mtype enums.MsgType) GenericNamestoreMs
52type NamestoreZoneIterStartMsg struct { 52type NamestoreZoneIterStartMsg struct {
53 GenericNamestoreMsg 53 GenericNamestoreMsg
54 54
55 ZoneKey *crypto.ZonePrivate // private zone key 55 ZoneKey *crypto.ZonePrivate `init:"Init"` // private zone key
56} 56}
57 57
58// NewNamecacheCacheMsg creates a new default message. 58// NewNamecacheCacheMsg creates a new default message.
@@ -63,6 +63,9 @@ func NewNamestoreZoneIterStartMsg(zone *crypto.ZonePrivate) *NamestoreZoneIterSt
63 } 63 }
64} 64}
65 65
66// Init called after unmarshalling a message to setup internal state
67func (m *NamestoreZoneIterStartMsg) Init() error { return nil }
68
66// String returns a human-readable representation of the message. 69// String returns a human-readable representation of the message.
67func (m *NamestoreZoneIterStartMsg) String() string { 70func (m *NamestoreZoneIterStartMsg) String() string {
68 return fmt.Sprintf("NamestoreZoneIterStartMsg{id=%d,zone=%s}", m.ID, m.ZoneKey.ID()) 71 return fmt.Sprintf("NamestoreZoneIterStartMsg{id=%d,zone=%s}", m.ID, m.ZoneKey.ID())
@@ -82,6 +85,9 @@ func NewNamestoreZoneIterNextMsg() *NamestoreZoneIterNextMsg {
82 return &NamestoreZoneIterNextMsg{} 85 return &NamestoreZoneIterNextMsg{}
83} 86}
84 87
88// Init called after unmarshalling a message to setup internal state
89func (m *NamestoreZoneIterNextMsg) Init() error { return nil }
90
85// String returns a human-readable representation of the message. 91// String returns a human-readable representation of the message.
86func (m *NamestoreZoneIterNextMsg) String() string { 92func (m *NamestoreZoneIterNextMsg) String() string {
87 return fmt.Sprintf("NamestoreZoneIterNextMsg{id=%d,limit=%d}", m.ID, m.Limit) 93 return fmt.Sprintf("NamestoreZoneIterNextMsg{id=%d,limit=%d}", m.ID, m.Limit)
@@ -96,6 +102,42 @@ type NamestoreZoneIterStopMsg struct {
96} 102}
97 103
98//---------------------------------------------------------------------- 104//----------------------------------------------------------------------
105// MSG_NAMESTORE_RECORD_RESULT
106//----------------------------------------------------------------------
107
108type NamestoreRecordResultMsg struct {
109 GenericNamestoreMsg
110
111 Expire util.AbsoluteTime `` // expiration date
112 NameLen uint16 `order:"big"` // length of name
113 RdLen uint16 `order:"big"` // size of record data
114 RdCount uint16 `order:"big"` // number of records
115 Reserved uint16 `order:"big"` // alignment
116 ZoneKey *crypto.ZonePrivate `init:"Init"` // private zone key
117 Name []byte `size:"NameLen"` // name string
118 Records []byte `size:"RdLen"` // serialized record data
119}
120
121func NewNamestoreRecordResultMsg(zk *crypto.ZonePrivate, label string) *NamestoreRecordResultMsg {
122 return &NamestoreRecordResultMsg{
123 Expire: util.AbsoluteTimeNever(),
124 ZoneKey: zk,
125 NameLen: uint16(len(label)),
126 Name: []byte(label),
127 RdLen: 0,
128 RdCount: 0,
129 }
130}
131
132// Init called after unmarshalling a message to setup internal state
133func (m *NamestoreRecordResultMsg) Init() error { return nil }
134
135// String returns a human-readable representation of the message.
136func (m *NamestoreRecordResultMsg) String() string {
137 return fmt.Sprintf("NamestoreRecordResultMsg{id=%d,zone=%s,label='%s'}", m.ID, m.ZoneKey.ID(), string(m.Name))
138}
139
140//----------------------------------------------------------------------
99//---------------------------------------------------------------------- 141//----------------------------------------------------------------------
100 142
101type NamestoreRecordStoreMsg struct { 143type NamestoreRecordStoreMsg struct {
@@ -154,19 +196,6 @@ type NamestoreZoneToNameRespMsg struct {
154 Records []byte `size:"RdLen"` // serialized record data 196 Records []byte `size:"RdLen"` // serialized record data
155} 197}
156 198
157type NamestoreRecordResultMsg struct {
158 GenericNamestoreMsg
159
160 Expire util.AbsoluteTime `` // expiration date
161 NameLen uint16 `order:"big"` // length of name
162 RdLen uint16 `order:"big"` // size of record data
163 RdCount uint16 `order:"big"` // number of records
164 Reserved uint16 `order:"big"` // alignment
165 ZoneKey *crypto.ZonePrivate // private zone key
166 Name []byte `size:"NameLen"` // name string
167 Records []byte `size:"RdLen"` // serialized record data
168}
169
170type NamestoreTxControlMsg struct { 199type NamestoreTxControlMsg struct {
171 GenericNamestoreMsg 200 GenericNamestoreMsg
172 201
diff --git a/src/gnunet/message/msg_revocation.go b/src/gnunet/message/msg_revocation.go
index aaef0d4..1fa891e 100644
--- a/src/gnunet/message/msg_revocation.go
+++ b/src/gnunet/message/msg_revocation.go
@@ -34,7 +34,7 @@ import (
34type RevocationQueryMsg struct { 34type RevocationQueryMsg struct {
35 MsgHeader 35 MsgHeader
36 Reserved uint32 `order:"big"` // Reserved for future use 36 Reserved uint32 `order:"big"` // Reserved for future use
37 Zone *crypto.ZoneKey // Zone that is to be checked for revocation 37 Zone *crypto.ZoneKey `init:"Init"` // Zone that is to be checked for revocation
38} 38}
39 39
40// NewRevocationQueryMsg creates a new message for a given zone. 40// NewRevocationQueryMsg creates a new message for a given zone.
@@ -46,6 +46,9 @@ func NewRevocationQueryMsg(zkey *crypto.ZoneKey) *RevocationQueryMsg {
46 } 46 }
47} 47}
48 48
49// Init called after unmarshalling a message to setup internal state
50func (m *RevocationQueryMsg) Init() error { return nil }
51
49// String returns a human-readable representation of the message. 52// String returns a human-readable representation of the message.
50func (m *RevocationQueryMsg) String() string { 53func (m *RevocationQueryMsg) String() string {
51 return fmt.Sprintf("RevocationQueryMsg{zone=%s}", m.Zone.ID()) 54 return fmt.Sprintf("RevocationQueryMsg{zone=%s}", m.Zone.ID())
@@ -73,6 +76,9 @@ func NewRevocationQueryResponseMsg(revoked bool) *RevocationQueryResponseMsg {
73 } 76 }
74} 77}
75 78
79// Init called after unmarshalling a message to setup internal state
80func (m *RevocationQueryResponseMsg) Init() error { return nil }
81
76// String returns a human-readable representation of the message. 82// String returns a human-readable representation of the message.
77func (m *RevocationQueryResponseMsg) String() string { 83func (m *RevocationQueryResponseMsg) String() string {
78 return fmt.Sprintf("RevocationQueryResponseMsg{valid=%d}", m.Valid) 84 return fmt.Sprintf("RevocationQueryResponseMsg{valid=%d}", m.Valid)
@@ -88,7 +94,7 @@ type RevocationRevokeMsg struct {
88 Timestamp util.AbsoluteTime `` // Timestamp of revocation creation 94 Timestamp util.AbsoluteTime `` // Timestamp of revocation creation
89 TTL util.RelativeTime `` // TTL of revocation 95 TTL util.RelativeTime `` // TTL of revocation
90 PoWs []uint64 `size:"32" order:"big"` // (Sorted) list of PoW values 96 PoWs []uint64 `size:"32" order:"big"` // (Sorted) list of PoW values
91 ZoneKeySig *crypto.ZoneSignature `` // public zone key (with signature) to be revoked 97 ZoneKeySig *crypto.ZoneSignature `init:"Init"` // public zone key (with signature) to be revoked
92} 98}
93 99
94// NewRevocationRevokeMsg creates a new message for a given zone. 100// NewRevocationRevokeMsg creates a new message for a given zone.
@@ -102,6 +108,9 @@ func NewRevocationRevokeMsg(zsig *crypto.ZoneSignature) *RevocationRevokeMsg {
102 } 108 }
103} 109}
104 110
111// Init called after unmarshalling a message to setup internal state
112func (m *RevocationRevokeMsg) Init() error { return nil }
113
105// String returns a human-readable representation of the message. 114// String returns a human-readable representation of the message.
106func (m *RevocationRevokeMsg) String() string { 115func (m *RevocationRevokeMsg) String() string {
107 return fmt.Sprintf("RevocationRevokeMsg{zone=%s,expire=%s}", 116 return fmt.Sprintf("RevocationRevokeMsg{zone=%s,expire=%s}",
@@ -130,6 +139,9 @@ func NewRevocationRevokeResponseMsg(success bool) *RevocationRevokeResponseMsg {
130 } 139 }
131} 140}
132 141
142// Init called after unmarshalling a message to setup internal state
143func (m *RevocationRevokeResponseMsg) Init() error { return nil }
144
133// String returns a human-readable representation of the message. 145// String returns a human-readable representation of the message.
134func (m *RevocationRevokeResponseMsg) String() string { 146func (m *RevocationRevokeResponseMsg) String() string {
135 return fmt.Sprintf("RevocationRevokeResponseMsg{success=%v}", m.Success == 1) 147 return fmt.Sprintf("RevocationRevokeResponseMsg{success=%v}", m.Success == 1)
diff --git a/src/gnunet/message/msg_transport.go b/src/gnunet/message/msg_transport.go
index 5369ca7..e02e3e6 100644
--- a/src/gnunet/message/msg_transport.go
+++ b/src/gnunet/message/msg_transport.go
@@ -57,6 +57,9 @@ func (m *TransportTCPWelcomeMsg) String() string {
57 return fmt.Sprintf("TransportTcpWelcomeMsg{peer=%s}", m.PeerID) 57 return fmt.Sprintf("TransportTcpWelcomeMsg{peer=%s}", m.PeerID)
58} 58}
59 59
60// Init called after unmarshalling a message to setup internal state
61func (m *TransportTCPWelcomeMsg) Init() error { return nil }
62
60//---------------------------------------------------------------------- 63//----------------------------------------------------------------------
61// TRANSPORT_PING 64// TRANSPORT_PING
62// 65//
@@ -105,6 +108,9 @@ func (m *TransportPingMsg) String() string {
105 m.Target, a, m.Challenge) 108 m.Target, a, m.Challenge)
106} 109}
107 110
111// Init called after unmarshalling a message to setup internal state
112func (m *TransportPingMsg) Init() error { return nil }
113
108//---------------------------------------------------------------------- 114//----------------------------------------------------------------------
109// TRANSPORT_PONG 115// TRANSPORT_PONG
110// 116//
@@ -206,6 +212,9 @@ func (m *TransportPongMsg) Verify(pub *ed25519.PublicKey) (bool, error) {
206 return pub.EdVerify(data, sig) 212 return pub.EdVerify(data, sig)
207} 213}
208 214
215// Init called after unmarshalling a message to setup internal state
216func (m *TransportPongMsg) Init() error { return nil }
217
209//---------------------------------------------------------------------- 218//----------------------------------------------------------------------
210// TRANSPORT_SESSION_ACK 219// TRANSPORT_SESSION_ACK
211//---------------------------------------------------------------------- 220//----------------------------------------------------------------------
@@ -227,6 +236,9 @@ func (m *SessionAckMsg) String() string {
227 return "SessionAck{}" 236 return "SessionAck{}"
228} 237}
229 238
239// Init called after unmarshalling a message to setup internal state
240func (m *SessionAckMsg) Init() error { return nil }
241
230//---------------------------------------------------------------------- 242//----------------------------------------------------------------------
231// TRANSPORT_SESSION_SYN 243// TRANSPORT_SESSION_SYN
232//---------------------------------------------------------------------- 244//----------------------------------------------------------------------
@@ -252,6 +264,9 @@ func (m *SessionSynMsg) String() string {
252 return fmt.Sprintf("SessionSyn{timestamp=%s}", m.Timestamp) 264 return fmt.Sprintf("SessionSyn{timestamp=%s}", m.Timestamp)
253} 265}
254 266
267// Init called after unmarshalling a message to setup internal state
268func (m *SessionSynMsg) Init() error { return nil }
269
255//---------------------------------------------------------------------- 270//----------------------------------------------------------------------
256// TRANSPORT_SESSION_SYN_ACK 271// TRANSPORT_SESSION_SYN_ACK
257//---------------------------------------------------------------------- 272//----------------------------------------------------------------------
@@ -277,6 +292,9 @@ func (m *SessionSynAckMsg) String() string {
277 return fmt.Sprintf("SessionSynAck{timestamp=%s}", m.Timestamp) 292 return fmt.Sprintf("SessionSynAck{timestamp=%s}", m.Timestamp)
278} 293}
279 294
295// Init called after unmarshalling a message to setup internal state
296func (m *SessionSynAckMsg) Init() error { return nil }
297
280//---------------------------------------------------------------------- 298//----------------------------------------------------------------------
281// TRANSPORT_SESSION_QUOTA 299// TRANSPORT_SESSION_QUOTA
282//---------------------------------------------------------------------- 300//----------------------------------------------------------------------
@@ -303,6 +321,9 @@ func (m *SessionQuotaMsg) String() string {
303 return fmt.Sprintf("SessionQuotaMsg{%sB/s}", util.Scale1024(uint64(m.Quota))) 321 return fmt.Sprintf("SessionQuotaMsg{%sB/s}", util.Scale1024(uint64(m.Quota)))
304} 322}
305 323
324// Init called after unmarshalling a message to setup internal state
325func (m *SessionQuotaMsg) Init() error { return nil }
326
306//---------------------------------------------------------------------- 327//----------------------------------------------------------------------
307// TRANSPORT_SESSION_KEEPALIVE 328// TRANSPORT_SESSION_KEEPALIVE
308//---------------------------------------------------------------------- 329//----------------------------------------------------------------------
@@ -327,6 +348,9 @@ func (m *SessionKeepAliveMsg) String() string {
327 return fmt.Sprintf("SessionKeepAliveMsg{%d}", m.Nonce) 348 return fmt.Sprintf("SessionKeepAliveMsg{%d}", m.Nonce)
328} 349}
329 350
351// Init called after unmarshalling a message to setup internal state
352func (m *SessionKeepAliveMsg) Init() error { return nil }
353
330//---------------------------------------------------------------------- 354//----------------------------------------------------------------------
331// TRANSPORT_SESSION_KEEPALIVE_RESPONSE 355// TRANSPORT_SESSION_KEEPALIVE_RESPONSE
332//---------------------------------------------------------------------- 356//----------------------------------------------------------------------
@@ -350,3 +374,6 @@ func NewSessionKeepAliveRespMsg(nonce uint32) *SessionKeepAliveRespMsg {
350func (m *SessionKeepAliveRespMsg) String() string { 374func (m *SessionKeepAliveRespMsg) String() string {
351 return fmt.Sprintf("SessionKeepAliveRespMsg{%d}", m.Nonce) 375 return fmt.Sprintf("SessionKeepAliveRespMsg{%d}", m.Nonce)
352} 376}
377
378// Init called after unmarshalling a message to setup internal state
379func (m *SessionKeepAliveRespMsg) Init() error { return nil }
diff --git a/src/gnunet/service/connection.go b/src/gnunet/service/connection.go
index fbc24d0..a008bdb 100644
--- a/src/gnunet/service/connection.go
+++ b/src/gnunet/service/connection.go
@@ -134,6 +134,9 @@ func (s *Connection) Receive(ctx context.Context) (message.Message, error) {
134 if err = data.Unmarshal(msg, s.buf[:mh.MsgSize]); err != nil { 134 if err = data.Unmarshal(msg, s.buf[:mh.MsgSize]); err != nil {
135 return nil, err 135 return nil, err
136 } 136 }
137 if err = msg.Init(); err != nil {
138 return nil, err
139 }
137 return msg, nil 140 return msg, nil
138} 141}
139 142
diff --git a/src/gnunet/service/dht/blocks/gns.go b/src/gnunet/service/dht/blocks/gns.go
index 0c32085..b504bc5 100644
--- a/src/gnunet/service/dht/blocks/gns.go
+++ b/src/gnunet/service/dht/blocks/gns.go
@@ -235,7 +235,7 @@ func NewRecordSet() *RecordSet {
235 return &RecordSet{ 235 return &RecordSet{
236 Count: 0, 236 Count: 0,
237 Records: make([]*ResourceRecord, 0), 237 Records: make([]*ResourceRecord, 0),
238 Padding: make([]byte, 0), 238 Padding: nil,
239 } 239 }
240} 240}
241 241
@@ -273,6 +273,11 @@ func (rs *RecordSet) Expire() util.AbsoluteTime {
273 273
274// Bytes returns the binary representation 274// Bytes returns the binary representation
275func (rs *RecordSet) Bytes() []byte { 275func (rs *RecordSet) Bytes() []byte {
276 // make sure padding exists
277 if rs.Padding == nil {
278 rs.SetPadding()
279 }
280 // unmarshal record set
276 buf, err := data.Marshal(rs) 281 buf, err := data.Marshal(rs)
277 if err != nil { 282 if err != nil {
278 return nil 283 return nil
diff --git a/src/gnunet/service/dht/blocks/gns_test.go b/src/gnunet/service/dht/blocks/gns_test.go
index 260d83b..bc1703b 100644
--- a/src/gnunet/service/dht/blocks/gns_test.go
+++ b/src/gnunet/service/dht/blocks/gns_test.go
@@ -31,41 +31,41 @@ import (
31 31
32func TestGNSBlock(t *testing.T) { 32func TestGNSBlock(t *testing.T) {
33 var ( 33 var (
34 ZONEKEY = "000G054G4G3HWZP2WFNVS1XJ4VXWY85G49AVYBZ7TV4EWP5J5V59H5QN40" 34 ZONEKEY = "000G051J6AZ48NAJP94HD6CNBXNN9C85YT8GYVVXFKGY2516YGF7HRXKR4"
35 LABEL = "@" 35 LABEL = "@"
36 36
37 QKEY = []byte{ 37 QKEY = []byte{
38 0xb6, 0x48, 0xfd, 0x0c, 0x4a, 0x6c, 0xaa, 0x87, 38 0xb5, 0xbb, 0xf8, 0x43, 0xfa, 0x6f, 0x7d, 0x53,
39 0x33, 0x2f, 0xf5, 0x12, 0x90, 0xe4, 0xbd, 0x55, 39 0xb9, 0x84, 0x9a, 0xa1, 0x61, 0xc9, 0x44, 0x4f,
40 0x0f, 0x8c, 0xe7, 0x9b, 0xc9, 0x5b, 0x3a, 0xfb, 40 0x29, 0x68, 0x98, 0x02, 0x36, 0x26, 0xc5, 0xd2,
41 0xbb, 0xe2, 0xd7, 0x33, 0xbc, 0x32, 0xc9, 0x7d, 41 0xd3, 0x06, 0x21, 0x99, 0xf7, 0x39, 0x06, 0x46,
42 0xc5, 0x4a, 0x56, 0x22, 0xbf, 0xfa, 0x49, 0x1a, 42 0xdb, 0x32, 0x07, 0xa6, 0x0d, 0xd2, 0xea, 0x03,
43 0x60, 0xd6, 0xdb, 0x77, 0x5d, 0x3d, 0x18, 0x99, 43 0xce, 0x74, 0x93, 0x86, 0x78, 0x3a, 0x70, 0xaa,
44 0x5b, 0x4f, 0xc3, 0x7d, 0x86, 0x00, 0x15, 0x76, 44 0xa0, 0x75, 0xf1, 0x18, 0xf7, 0xb3, 0xc6, 0x0b,
45 0x42, 0x03, 0x98, 0xcc, 0xdf, 0x83, 0x4d, 0x21, 45 0x12, 0x98, 0xbb, 0x1b, 0x58, 0x53, 0xe6, 0x87,
46 } 46 }
47 BLK = []byte{ 47 BLK = []byte{
48 0x00, 0x01, 0x00, 0x14, 0xe0, 0x6b, 0xea, 0x2b, 48 0x00, 0x01, 0x00, 0x14, 0x64, 0x0e, 0x2f, 0x4b,
49 0x1b, 0xd6, 0xc6, 0x9a, 0xd4, 0x30, 0xa5, 0x0f, 49 0x8e, 0x7e, 0x7f, 0x54, 0x43, 0xb4, 0x7c, 0xdc,
50 0x81, 0x16, 0x89, 0xe1, 0x9f, 0xca, 0x1f, 0x86, 50 0x84, 0xd4, 0x89, 0xfc, 0x87, 0x6e, 0x08, 0x6c,
51 0x3f, 0x83, 0x6e, 0xe6, 0xa7, 0x54, 0x97, 0xde, 51 0xd9, 0x55, 0xab, 0xc6, 0x0a, 0x7d, 0xfe, 0x1b,
52 0xf2, 0xc4, 0x2a, 0x84, 0xb6, 0x89, 0xe6, 0x7e, 52 0xfe, 0x88, 0xa7, 0x13, 0x72, 0x2b, 0xfa, 0xb1,
53 0xff, 0x0c, 0xae, 0x84, 0xe6, 0xb1, 0x6c, 0x72, 53 0x70, 0xc4, 0x8c, 0xeb, 0xe3, 0x2b, 0x08, 0x9f,
54 0x83, 0x09, 0x68, 0x5b, 0x2f, 0xa2, 0x9f, 0xbe, 54 0x07, 0xea, 0x77, 0x51, 0x2d, 0xf1, 0x02, 0x89,
55 0xfa, 0xef, 0x43, 0x52, 0x20, 0x48, 0xe5, 0x57, 55 0x73, 0xa8, 0xd0, 0xe0, 0x94, 0x2a, 0x16, 0x05,
56 0x1e, 0x65, 0x21, 0x86, 0xd4, 0x9f, 0x96, 0x51, 56 0xdb, 0x06, 0x0e, 0xd4, 0x0f, 0xdc, 0xac, 0x48,
57 0x4f, 0xa9, 0x6d, 0xa9, 0x98, 0xaa, 0x2d, 0xf6, 57 0xde, 0x05, 0x2c, 0x0f, 0x29, 0x81, 0xd6, 0x70,
58 0x92, 0xd7, 0x86, 0x36, 0xc0, 0x84, 0x90, 0x00, 58 0x17, 0x95, 0x76, 0x79, 0x75, 0xce, 0x0d, 0x4b,
59 0x42, 0x2e, 0x4e, 0xc1, 0xaf, 0x6f, 0xe0, 0x7e, 59 0x98, 0xd7, 0xe5, 0x44, 0x70, 0x3b, 0xbd, 0x50,
60 0x71, 0xe3, 0xc4, 0x0d, 0x00, 0x00, 0x00, 0x10, 60 0xba, 0xfa, 0x5d, 0x01, 0x00, 0x00, 0x00, 0x10,
61 0x00, 0x00, 0x00, 0x0f, 0x00, 0x06, 0x08, 0x00, 61 0x00, 0x00, 0x00, 0x0f, 0x00, 0x06, 0x09, 0x70,
62 0xb5, 0x99, 0x2a, 0x00, 0xd0, 0x7a, 0x2b, 0x9e, 62 0x48, 0xa4, 0xa2, 0x00, 0x45, 0xb0, 0xd0, 0xdc,
63 0x02, 0x45, 0x54, 0x0d, 0x65, 0x26, 0xa1, 0x05, 63 0x1d, 0x60, 0xd8, 0x1c, 0x4f, 0xd3, 0x50, 0xc4,
64 0x80, 0x26, 0xce, 0xc2, 0x70, 0xd5, 0x22, 0x38, 64 0x73, 0x20, 0xc6, 0xd5, 0x28, 0x19, 0x8e, 0xa6,
65 0x80, 0x9a, 0xed, 0x63, 0x2f, 0x96, 0x60, 0x4d, 65 0x89, 0x56, 0x9f, 0x8c, 0x48, 0xf4, 0xd6, 0x76,
66 0x02, 0x59, 0xd0, 0x9a, 0x4e, 0x71, 0xfa, 0x30, 66 0xf4, 0xb9, 0x70, 0xbd, 0x01, 0x2e, 0xd1, 0x4f,
67 0xd6, 0xf9, 0xf4, 0x84, 0x5d, 0xb8, 0x60, 0xa4, 67 0x84, 0x96, 0x1b, 0xbf, 0x6c, 0xe4, 0xdb, 0x7a,
68 0xdf, 0xea, 0x34, 0x06, 0x3f, 0x6f, 0x76, 0x9e, 68 0x32, 0xc1, 0x50, 0xc4, 0xb1, 0x6b, 0x08, 0x59,
69 } 69 }
70 ) 70 )
71 // unmarshal block 71 // unmarshal block
@@ -89,7 +89,10 @@ func TestGNSBlock(t *testing.T) {
89 query := NewGNSQuery(zk, LABEL) 89 query := NewGNSQuery(zk, LABEL)
90 90
91 // check query key 91 // check query key
92 if !bytes.Equal(QKEY, query.Key().Data) { 92 qkey := query.Key().Data
93 if !bytes.Equal(QKEY, qkey) {
94 t.Logf("expected: %s", hex.EncodeToString(QKEY))
95 t.Logf("got: %s", hex.EncodeToString(qkey))
93 t.Fatal("query key mismatch") 96 t.Fatal("query key mismatch")
94 } 97 }
95 98
@@ -125,11 +128,11 @@ func TestGNSBlock(t *testing.T) {
125func TestRecordsetPKEY(t *testing.T) { 128func TestRecordsetPKEY(t *testing.T) {
126 var ( 129 var (
127 D = []byte{ 130 D = []byte{
128 // PKEY private scalar 131 // PKEY private scalar (clamped little-endian)
129 0x50, 0xd7, 0xb6, 0x52, 0xa4, 0xef, 0xea, 0xdf, 132 0x98, 0xfd, 0xfa, 0x25, 0x79, 0x90, 0xfa, 0x50,
130 0xf3, 0x73, 0x96, 0x90, 0x97, 0x85, 0xe5, 0x95, 133 0xd4, 0xe7, 0xc8, 0x78, 0x21, 0xa0, 0x71, 0x21,
131 0x21, 0x71, 0xa0, 0x21, 0x78, 0xc8, 0xe7, 0xd4, 134 0x95, 0xe5, 0x85, 0x97, 0x90, 0x96, 0x73, 0xf3,
132 0x50, 0xfa, 0x90, 0x79, 0x25, 0xfa, 0xfd, 0x98, 135 0xdf, 0xea, 0xef, 0xa4, 0x52, 0xb6, 0xd7, 0x50,
133 } 136 }
134 ZKEY = []byte{ 137 ZKEY = []byte{
135 // zone type 138 // zone type
diff --git a/src/gnunet/service/namecache/module.go b/src/gnunet/service/namecache/module.go
index 0e8053a..ee3a325 100644
--- a/src/gnunet/service/namecache/module.go
+++ b/src/gnunet/service/namecache/module.go
@@ -77,7 +77,7 @@ func (m *Module) Get(ctx context.Context, query *blocks.GNSQuery) (block *blocks
77 return 77 return
78 } 78 }
79 if len(e) != 1 { 79 if len(e) != 1 {
80 err = errors.New("only one DHT entry exppected") 80 err = errors.New("only one namecache entry expected")
81 } else { 81 } else {
82 err = blocks.Unwrap(e[0].Blk, block) 82 err = blocks.Unwrap(e[0].Blk, block)
83 } 83 }
diff --git a/src/gnunet/service/revocation/pow_test.go b/src/gnunet/service/revocation/pow_test.go
index 41c17b4..a3bd5e6 100644
--- a/src/gnunet/service/revocation/pow_test.go
+++ b/src/gnunet/service/revocation/pow_test.go
@@ -13,7 +13,7 @@ import (
13// Test revocation with test vector defined in the RFC draft. 13// Test revocation with test vector defined in the RFC draft.
14func TestRevocationRFC(t *testing.T) { 14func TestRevocationRFC(t *testing.T) {
15 var ( 15 var (
16 D = "6fea32c05af58bfa979553d188605fd57d8bf9cc263b78d5f7478c07b998ed70" 16 D = "70ed98b9078c47f7d5783b26ccf98b7dd55f6088d1539597fa8bf55ac032ea6f"
17 ZKEY = "000100002ca223e879ecc4bbdeb5da17319281d63b2e3b6955f1c3775c804a98d5f8ddaa" 17 ZKEY = "000100002ca223e879ecc4bbdeb5da17319281d63b2e3b6955f1c3775c804a98d5f8ddaa"
18 PROOF = "" + 18 PROOF = "" +
19 "0005d66da3598127" + 19 "0005d66da3598127" +
@@ -86,7 +86,11 @@ func TestRevocationRFC(t *testing.T) {
86 if err = data.Unmarshal(revData, revD); err != nil { 86 if err = data.Unmarshal(revData, revD); err != nil {
87 t.Fatal(err) 87 t.Fatal(err)
88 } 88 }
89 if !bytes.Equal(revData.ZoneKeySig.Bytes(), zkey) { 89 if err = revData.ZoneKeySig.Init(); err != nil {
90 t.Fatal(err)
91 }
92 // check sigature
93 if !bytes.Equal(revData.ZoneKeySig.ZoneKey.Bytes(), zkey) {
90 t.Logf("zkey = %s\n", hex.EncodeToString(revData.ZoneKeySig.Bytes())) 94 t.Logf("zkey = %s\n", hex.EncodeToString(revData.ZoneKeySig.Bytes()))
91 t.Logf("ZKEY = %s\n", hex.EncodeToString(zkey)) 95 t.Logf("ZKEY = %s\n", hex.EncodeToString(zkey))
92 t.Fatal("Wrong zone key in test revocation") 96 t.Fatal("Wrong zone key in test revocation")
diff --git a/src/gnunet/service/store/store_zonemaster.go b/src/gnunet/service/store/store_zonemaster.go
index 44b1a68..1338c01 100644
--- a/src/gnunet/service/store/store_zonemaster.go
+++ b/src/gnunet/service/store/store_zonemaster.go
@@ -32,11 +32,15 @@ import (
32) 32)
33 33
34//============================================================ 34//============================================================
35// Local zone records stored in SQLite3 database 35// Local identities and zone records (SQLite3 database)
36// Identities are named ZonePrivate keys that are associated
37// with a GNUnet subsystem (like GNS, CADET and others).
38// Identities for the subsystem "gns" are called zones and
39// are collections of labeled resource record sets. All other
40// identities are usuall called "egos".
36//============================================================ 41//============================================================
37 42
38// Zone is the definition of a local GNS zone 43// Zone is the definition of a local GNS zone
39// and is stored in a SQL database for faster access.
40type Zone struct { 44type Zone struct {
41 ID int64 // database identifier 45 ID int64 // database identifier
42 Name string // zone name 46 Name string // zone name
@@ -59,6 +63,23 @@ func NewZone(name string, sk *crypto.ZonePrivate) *Zone {
59 63
60//---------------------------------------------------------------------- 64//----------------------------------------------------------------------
61 65
66// Identity is a Zone associated with a service
67type Identity struct {
68 Zone
69
70 Svc string // associated service
71}
72
73// NewIdentity creates an initialize instance for database access
74func NewIdentity(name string, sk *crypto.ZonePrivate, svc string) *Identity {
75 return &Identity{
76 Zone: *NewZone(name, sk),
77 Svc: svc,
78 }
79}
80
81//----------------------------------------------------------------------
82
62type Label struct { 83type Label struct {
63 ID int64 // database id of label 84 ID int64 // database id of label
64 Zone int64 // database ID of parent zone 85 Zone int64 // database ID of parent zone
@@ -136,7 +157,7 @@ func OpenZoneDB(fname string) (db *ZoneDB, err error) {
136 return 157 return
137 } 158 }
138 // check for initialized database 159 // check for initialized database
139 res := db.conn.QueryRow("select name from sqlite_master where type='table' and name='zones'") 160 res := db.conn.QueryRow("select name from sqlite_master where type='table' and name='identities'")
140 var s string 161 var s string
141 if res.Scan(&s) != nil { 162 if res.Scan(&s) != nil {
142 // initialize database 163 // initialize database
@@ -153,6 +174,152 @@ func (db *ZoneDB) Close() error {
153} 174}
154 175
155//---------------------------------------------------------------------- 176//----------------------------------------------------------------------
177// Identity handling
178//----------------------------------------------------------------------
179
180// SetIdentity inserts, updates or deletes a zone in the database.
181// The function does not change timestamps which are in the
182// responsibility of the caller.
183// - insert: Identity.ID is nil (0)
184// - update: Identity.Name is set
185// - remove: otherwise
186func (db *ZoneDB) SetIdentity(id *Identity) error {
187 // GNS zones are handled by Zone instances
188 if id.Svc == "gns" {
189 return db.SetZone(&id.Zone)
190 }
191 // check for identity insert
192 if id.ID == 0 {
193 stmt := "insert into identities(svc,name,created,modified,ztype,zdata) values(?,?,?,?,?,?)"
194 result, err := db.conn.Exec(stmt,
195 id.Svc, id.Name, id.Created.Val, id.Modified.Val, id.Key.Type, id.Key.KeyData)
196 if err != nil {
197 return err
198 }
199 id.ID, err = result.LastInsertId()
200 return err
201 }
202 // check for identity update (name and service only only)
203 if len(id.Name) > 0 {
204 stmt := "update identities set svc=?,name=?,modified=? where id=?"
205 result, err := db.conn.Exec(stmt, id.Svc, id.Name, id.Modified.Val, id.ID)
206 if err != nil {
207 return err
208 }
209 var num int64
210 if num, err = result.RowsAffected(); err == nil {
211 if num != 1 {
212 err = errors.New("update identity failed")
213 }
214 }
215 return err
216 }
217 // remove identity from database
218 _, err := db.conn.Exec("delete from identities where id=?", id.ID)
219 return err
220}
221
222// GetIdentity gets an identifier with given database id
223func (db *ZoneDB) GetIdentity(id int64) (ident *Identity, err error) {
224 // assemble identity from database row
225 stmt := "select svc,name,created,modified,ztype,zdata from identities where id=?"
226 ident = new(Identity)
227 ident.ID = id
228 row := db.conn.QueryRow(stmt, id)
229 var ztype enums.GNSType
230 var zdata []byte
231 if err = row.Scan(&ident.Svc, &ident.Name, &ident.Created.Val, &ident.Modified.Val, &ztype, &zdata); err == nil {
232 // reconstruct private zone key
233 ident.Key, err = crypto.NewZonePrivate(ztype, zdata)
234 }
235 return
236}
237
238// GetIdentity gets an identifier with given (name,svc)
239func (db *ZoneDB) GetIdentityByName(name, svc string) (ident *Identity, err error) {
240 // assemble identity from database row
241 var row *sql.Row
242 stmt := "select id,created,modified,ztype,zdata from identities where name=?"
243 if len(svc) > 0 {
244 stmt += " and svc=?"
245 row = db.conn.QueryRow(stmt, name, svc)
246 } else {
247 row = db.conn.QueryRow(stmt, name)
248 }
249 ident = new(Identity)
250 ident.Name = name
251 ident.Svc = svc
252 var ztype enums.GNSType
253 var zdata []byte
254 if err = row.Scan(&ident.ID, &ident.Created.Val, &ident.Modified.Val, &ztype, &zdata); err == nil {
255 // reconstruct private zone key
256 ident.Key, err = crypto.NewZonePrivate(ztype, zdata)
257 }
258 return
259}
260
261func (db *ZoneDB) GetIdentities(filter string, args ...any) (list []*Identity, err error) {
262 // assemble query
263 stmt := "select id,name,svc,created,modified,ztype,zdata from identities"
264 if len(filter) > 0 {
265 stmt += " where " + fmt.Sprintf(filter, args...)
266 }
267 // select zones
268 var rows *sql.Rows
269 if rows, err = db.conn.Query(stmt); err != nil {
270 return
271 }
272 // process zones
273 defer rows.Close()
274 for rows.Next() {
275 // assemble identity from database row
276 i := new(Identity)
277 var ztype enums.GNSType
278 var zdata []byte
279 if err = rows.Scan(&i.ID, &i.Name, &i.Svc, &i.Created.Val, &i.Modified.Val, &ztype, &zdata); err != nil {
280 // terminate on error; return list so far
281 return
282 }
283 // reconstruct private key
284 if i.Key, err = crypto.NewZonePrivate(ztype, zdata); err != nil {
285 return
286 }
287 // append to result list
288 list = append(list, i)
289 }
290 return
291}
292
293func (db *ZoneDB) GetDefaultIdentity(svc string) (ident *Identity, err error) {
294 // assemble identity from database row
295 stmt := "select id,name,created,modified,ztype,zdata from v_defaults where svc=?"
296 row := db.conn.QueryRow(stmt, svc)
297 ident = new(Identity)
298 ident.Svc = svc
299 var ztype enums.GNSType
300 var zdata []byte
301 if err = row.Scan(&ident.ID, &ident.Name, &ident.Created.Val, &ident.Modified.Val, &ztype, &zdata); err == nil {
302 // reconstruct private zone key
303 ident.Key, err = crypto.NewZonePrivate(ztype, zdata)
304 }
305 return
306}
307
308func (db *ZoneDB) SetDefaultIdentity(zk *crypto.ZonePrivate, svc string) (err error) {
309 // get database id of identity
310 stmt := "select id from identities where zdata=?"
311 row := db.conn.QueryRow(stmt, zk.KeyData)
312 var id int64
313 if err = row.Scan(&id); err != nil {
314 return
315 }
316 // set default
317 stmt = "insert into defaults(svc,ident) values(?,?) on conflict(svc) do update set ident=?"
318 _, err = db.conn.Exec(stmt, svc, id, id)
319 return
320}
321
322//----------------------------------------------------------------------
156// Zone handling 323// Zone handling
157//---------------------------------------------------------------------- 324//----------------------------------------------------------------------
158 325
@@ -165,7 +332,7 @@ func (db *ZoneDB) Close() error {
165func (db *ZoneDB) SetZone(z *Zone) error { 332func (db *ZoneDB) SetZone(z *Zone) error {
166 // check for zone insert 333 // check for zone insert
167 if z.ID == 0 { 334 if z.ID == 0 {
168 stmt := "insert into zones(name,created,modified,ztype,zdata) values(?,?,?,?,?)" 335 stmt := "insert into identities(svc,name,created,modified,ztype,zdata) values('gns',?,?,?,?,?)"
169 result, err := db.conn.Exec(stmt, z.Name, z.Created.Val, z.Modified.Val, z.Key.Type, z.Key.KeyData) 336 result, err := db.conn.Exec(stmt, z.Name, z.Created.Val, z.Modified.Val, z.Key.Type, z.Key.KeyData)
170 if err != nil { 337 if err != nil {
171 return err 338 return err
@@ -175,7 +342,7 @@ func (db *ZoneDB) SetZone(z *Zone) error {
175 } 342 }
176 // check for zone update (name only) 343 // check for zone update (name only)
177 if len(z.Name) > 0 { 344 if len(z.Name) > 0 {
178 stmt := "update zones set name=?,modified=? where id=?" 345 stmt := "update identities set name=?,modified=? where id=? and svc='gns'"
179 result, err := db.conn.Exec(stmt, z.Name, z.Modified.Val, z.ID) 346 result, err := db.conn.Exec(stmt, z.Name, z.Modified.Val, z.ID)
180 if err != nil { 347 if err != nil {
181 return err 348 return err
@@ -202,6 +369,7 @@ func (db *ZoneDB) GetZone(id int64) (zone *Zone, err error) {
202 // assemble zone from database row 369 // assemble zone from database row
203 stmt := "select name,created,modified,ztype,zdata from zones where id=?" 370 stmt := "select name,created,modified,ztype,zdata from zones where id=?"
204 zone = new(Zone) 371 zone = new(Zone)
372 zone.ID = id
205 var ztype enums.GNSType 373 var ztype enums.GNSType
206 var zdata []byte 374 var zdata []byte
207 row := db.conn.QueryRow(stmt, id) 375 row := db.conn.QueryRow(stmt, id)
@@ -329,6 +497,29 @@ func (db *ZoneDB) GetLabels(filter string, args ...any) (list []*Label, err erro
329 return 497 return
330} 498}
331 499
500func (db *ZoneDB) GetLabelIDs(zk *crypto.ZonePrivate) (list []int64, err error) {
501 // get zone database id
502 row := db.conn.QueryRow("select id from zones where ztype=? and zdata=?", zk.Type, zk.KeyData)
503 var zid int64
504 if err = row.Scan(&zid); err != nil {
505 return
506 }
507 // select all labels for zone
508 var rows *sql.Rows
509 if rows, err = db.conn.Query("select id from labels where zid=?", zid); err != nil {
510 return
511 }
512 defer rows.Close()
513 var id int64
514 for rows.Next() {
515 if err = rows.Scan(&id); err != nil {
516 return
517 }
518 list = append(list, id)
519 }
520 return
521}
522
332//---------------------------------------------------------------------- 523//----------------------------------------------------------------------
333// Record handling 524// Record handling
334//---------------------------------------------------------------------- 525//----------------------------------------------------------------------
diff --git a/src/gnunet/service/store/store_zonemaster.sql b/src/gnunet/service/store/store_zonemaster.sql
index 169fefd..69b8ab5 100644
--- a/src/gnunet/service/store/store_zonemaster.sql
+++ b/src/gnunet/service/store/store_zonemaster.sql
@@ -16,15 +16,37 @@
16-- 16--
17-- SPDX-License-Identifier: AGPL3.0-or-later 17-- SPDX-License-Identifier: AGPL3.0-or-later
18 18
19create table zones ( 19create table identities (
20 id integer primary key autoincrement, 20 id integer primary key autoincrement,
21 name text unique, 21 svc text,
22 name text,
22 created integer, 23 created integer,
23 modified integer, 24 modified integer,
24 ztype integer, 25 ztype integer,
25 zdata blob 26 zdata blob,
27 unique (svc,name)
26); 28);
27 29
30create table defaults (
31 svc text unique,
32 ident integer references identities(id)
33);
34
35create view v_defaults as select
36 i.id as id,
37 d.svc as svc,
38 i.name as name,
39 i.created as created,
40 i.modified as modified,
41 i.ztype as ztype,
42 i.zdata as zdata
43from identities i, defaults d
44where i.id = d.ident;
45
46create view zones as select
47 id, name, created, modified, ztype, zdata
48from identities
49where svc = 'gns';
28 50
29create table labels ( 51create table labels (
30 id integer primary key autoincrement, 52 id integer primary key autoincrement,
diff --git a/src/gnunet/service/zonemaster/gui.go b/src/gnunet/service/zonemaster/gui.go
index 3885d01..5a2f17d 100644
--- a/src/gnunet/service/zonemaster/gui.go
+++ b/src/gnunet/service/zonemaster/gui.go
@@ -21,10 +21,10 @@ package zonemaster
21import ( 21import (
22 "bytes" 22 "bytes"
23 "context" 23 "context"
24 "crypto/rand"
25 "embed" 24 "embed"
26 "errors" 25 "errors"
27 "fmt" 26 "fmt"
27 "gnunet/config"
28 "gnunet/crypto" 28 "gnunet/crypto"
29 "gnunet/enums" 29 "gnunet/enums"
30 "gnunet/service/gns/rr" 30 "gnunet/service/gns/rr"
@@ -122,6 +122,13 @@ func (zm *ZoneMaster) startGUI(ctx context.Context) {
122 "rrdata": func(t enums.GNSType, buf []byte) string { 122 "rrdata": func(t enums.GNSType, buf []byte) string {
123 return guiRRdata(t, buf) 123 return guiRRdata(t, buf)
124 }, 124 },
125 "tabSetList": func(num int) (list map[int]int) {
126 list = make(map[int]int)
127 for i := 0; i < num; i++ {
128 list[i+1] = 2*i + 1
129 }
130 return
131 },
125 }) 132 })
126 if _, err := tpl.ParseFS(fsys, "*.htpl"); err != nil { 133 if _, err := tpl.ParseFS(fsys, "*.htpl"); err != nil {
127 logger.Println(logger.ERROR, "[zonemaster] GUI templates failed: "+err.Error()) 134 logger.Println(logger.ERROR, "[zonemaster] GUI templates failed: "+err.Error())
@@ -136,7 +143,7 @@ func (zm *ZoneMaster) startGUI(ctx context.Context) {
136 router.HandleFunc("/action/{cmd}/{mode}/{id}", zm.action) 143 router.HandleFunc("/action/{cmd}/{mode}/{id}", zm.action)
137 router.HandleFunc("/", zm.dashboard) 144 router.HandleFunc("/", zm.dashboard)
138 srv := &http.Server{ 145 srv := &http.Server{
139 Addr: zm.cfg.ZoneMaster.GUI, 146 Addr: config.Cfg.ZoneMaster.GUI,
140 ReadTimeout: 10 * time.Second, 147 ReadTimeout: 10 * time.Second,
141 ReadHeaderTimeout: 5 * time.Second, 148 ReadHeaderTimeout: 5 * time.Second,
142 Handler: router, 149 Handler: router,
@@ -205,17 +212,17 @@ func (zm *ZoneMaster) actionNew(w http.ResponseWriter, r *http.Request, mode str
205 // new zone 212 // new zone
206 case "zone": 213 case "zone":
207 name := r.FormValue("name") 214 name := r.FormValue("name")
208 // create private key 215 // get key type
209 seed := make([]byte, 32) 216 var kt enums.GNSType
210 if _, err = rand.Read(seed); err != nil { 217 switch r.FormValue("keytype") {
211 return 218 case "EDKEY":
212 }
213 var zp *crypto.ZonePrivate
214 kt := enums.GNS_TYPE_PKEY
215 if r.FormValue("keytype") == "EDKEY" {
216 kt = enums.GNS_TYPE_EDKEY 219 kt = enums.GNS_TYPE_EDKEY
220 case "PKEY":
221 kt = enums.GNS_TYPE_PKEY
217 } 222 }
218 zp, err = crypto.NewZonePrivate(kt, seed) 223 // cretae private key
224 var zp *crypto.ZonePrivate
225 zp, err = crypto.NewZonePrivate(kt, nil)
219 if err != nil { 226 if err != nil {
220 return 227 return
221 } 228 }
@@ -366,7 +373,7 @@ func (zm *ZoneMaster) updRec(w http.ResponseWriter, r *http.Request, id int64) e
366} 373}
367 374
368//---------------------------------------------------------------------- 375//----------------------------------------------------------------------
369// Create new zone. label or resource record 376// Create new zone, label or resource record
370//---------------------------------------------------------------------- 377//----------------------------------------------------------------------
371 378
372type NewEditData struct { 379type NewEditData struct {
@@ -630,8 +637,15 @@ func (zm *ZoneMaster) remove(w http.ResponseWriter, r *http.Request) {
630// Helper methods 637// Helper methods
631//====================================================================== 638//======================================================================
632 639
640// MainData for the template "main"
641type MainData struct {
642 Content string // Page content
643 Params any // reference to parameters
644 NumRR int // number of RR types supported
645}
646
633// render a webpage with given data and template reference 647// render a webpage with given data and template reference
634func renderPage(w io.Writer, data interface{}, page string) { 648func renderPage(w io.Writer, data any, page string) {
635 // create content section 649 // create content section
636 t := tpl.Lookup(page) 650 t := tpl.Lookup(page)
637 if t == nil { 651 if t == nil {
@@ -649,7 +663,11 @@ func renderPage(w io.Writer, data interface{}, page string) {
649 _, _ = io.WriteString(w, "No main template found") 663 _, _ = io.WriteString(w, "No main template found")
650 return 664 return
651 } 665 }
652 if err := t.Execute(w, content.String()); err != nil { 666 md := new(MainData)
667 md.Params = data
668 md.Content = content.String()
669 md.NumRR = len(rrtypes)
670 if err := t.Execute(w, md); err != nil {
653 _, _ = io.WriteString(w, err.Error()) 671 _, _ = io.WriteString(w, err.Error())
654 } 672 }
655} 673}
diff --git a/src/gnunet/service/zonemaster/gui.htpl b/src/gnunet/service/zonemaster/gui.htpl
index ffa9720..de51ee3 100644
--- a/src/gnunet/service/zonemaster/gui.htpl
+++ b/src/gnunet/service/zonemaster/gui.htpl
@@ -3,12 +3,12 @@
3<html lang="en"> 3<html lang="en">
4 <head> 4 <head>
5 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> 5 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6 {{template "css"}} 6 {{template "css" .NumRR}}
7 </head> 7 </head>
8 <body> 8 <body>
9 <h1>GNUnet Zone Master</h1> 9 <h1>GNUnet Zone Master</h1>
10 <hr/> 10 <hr/>
11 {{.}} 11 {{.Content}}
12 <script> 12 <script>
13 function notify(msg) { 13 function notify(msg) {
14 if ('Notification' in window) { 14 if ('Notification' in window) {
diff --git a/src/gnunet/service/zonemaster/gui_css.htpl b/src/gnunet/service/zonemaster/gui_css.htpl
index b31e714..8a26b30 100644
--- a/src/gnunet/service/zonemaster/gui_css.htpl
+++ b/src/gnunet/service/zonemaster/gui_css.htpl
@@ -165,9 +165,6 @@
165 .nested { 165 .nested {
166 display: none; 166 display: none;
167 } 167 }
168 .active {
169 display: block;
170 }
171 .tabset > input[type="radio"] { 168 .tabset > input[type="radio"] {
172 position: absolute; 169 position: absolute;
173 left: -200vw; 170 left: -200vw;
@@ -175,26 +172,10 @@
175 .tabset .tab-panel { 172 .tabset .tab-panel {
176 display: none; 173 display: none;
177 } 174 }
178 .tabset > input:first-child:checked ~ .tab-panels > .tab-panel:first-child, 175 {{range $i,$j := tabSetList .}}
179 .tabset > input:nth-child(3):checked ~ .tab-panels > .tab-panel:nth-child(2), 176 .tabset > input:nth-child({{$j}}):checked ~ .tab-panels > .tab-panel:nth-child({{$i}}),
180 .tabset > input:nth-child(5):checked ~ .tab-panels > .tab-panel:nth-child(3), 177 {{end}}
181 .tabset > input:nth-child(7):checked ~ .tab-panels > .tab-panel:nth-child(4), 178 .active {
182 .tabset > input:nth-child(9):checked ~ .tab-panels > .tab-panel:nth-child(5),
183 .tabset > input:nth-child(11):checked ~ .tab-panels > .tab-panel:nth-child(6),
184 .tabset > input:nth-child(13):checked ~ .tab-panels > .tab-panel:nth-child(7),
185 .tabset > input:nth-child(15):checked ~ .tab-panels > .tab-panel:nth-child(8),
186 .tabset > input:nth-child(17):checked ~ .tab-panels > .tab-panel:nth-child(9),
187 .tabset > input:nth-child(19):checked ~ .tab-panels > .tab-panel:nth-child(10),
188 .tabset > input:nth-child(21):checked ~ .tab-panels > .tab-panel:nth-child(11),
189 .tabset > input:nth-child(23):checked ~ .tab-panels > .tab-panel:nth-child(12),
190 .tabset > input:nth-child(25):checked ~ .tab-panels > .tab-panel:nth-child(13),
191 .tabset > input:nth-child(27):checked ~ .tab-panels > .tab-panel:nth-child(14),
192 .tabset > input:nth-child(29):checked ~ .tab-panels > .tab-panel:nth-child(15),
193 .tabset > input:nth-child(31):checked ~ .tab-panels > .tab-panel:nth-child(16),
194 .tabset > input:nth-child(33):checked ~ .tab-panels > .tab-panel:nth-child(17),
195 .tabset > input:nth-child(35):checked ~ .tab-panels > .tab-panel:nth-child(18),
196 .tabset > input:nth-child(37):checked ~ .tab-panels > .tab-panel:nth-child(19),
197 .tabset > input:nth-child(39):checked ~ .tab-panels > .tab-panel:nth-child(20) {
198 display: block; 179 display: block;
199 } 180 }
200 .tabset > label { 181 .tabset > label {
diff --git a/src/gnunet/service/zonemaster/gui_new.htpl b/src/gnunet/service/zonemaster/gui_new.htpl
index f470de9..81d32e8 100644
--- a/src/gnunet/service/zonemaster/gui_new.htpl
+++ b/src/gnunet/service/zonemaster/gui_new.htpl
@@ -31,7 +31,7 @@
31 alert("Empty zone name not allowed"); 31 alert("Empty zone name not allowed");
32 return false; 32 return false;
33 } 33 }
34 for (var i = 0; i < names.length; i++) { 34 for (var i = 0; i < zone_names.length; i++) {
35 if (zone_names[i] == name) { 35 if (zone_names[i] == name) {
36 alert("Zone name already used"); 36 alert("Zone name already used");
37 return false; 37 return false;
@@ -45,7 +45,7 @@
45{{define "new_label"}} 45{{define "new_label"}}
46<div> 46<div>
47 <h3>Creating a new GNS label for zone "{{index .Params "zone"}}":</h3> 47 <h3>Creating a new GNS label for zone "{{index .Params "zone"}}":</h3>
48 <form action="/action/new/label/{{.Ref}}" onsubmit="return(label_validate());"> 48 <form action="/action/new/label/{{.Ref}}" method="post" onsubmit="return(label_validate());">
49 <table> 49 <table>
50 <tr> 50 <tr>
51 <td align="right">Name:</td> 51 <td align="right">Name:</td>
@@ -68,7 +68,7 @@
68 alert("Empty labels not allowed"); 68 alert("Empty labels not allowed");
69 return false; 69 return false;
70 } 70 }
71 for (var i = 0; i < names.length; i++) { 71 for (var i = 0; i < label_names.length; i++) {
72 if (label_names[i] == name) { 72 if (label_names[i] == name) {
73 alert("Label already used"); 73 alert("Label already used");
74 return false; 74 return false;
diff --git a/src/gnunet/service/zonemaster/gui_rr.htpl b/src/gnunet/service/zonemaster/gui_rr.htpl
index 360a734..00b9148 100644
--- a/src/gnunet/service/zonemaster/gui_rr.htpl
+++ b/src/gnunet/service/zonemaster/gui_rr.htpl
@@ -1,19 +1,19 @@
1{{define "RRCommon"}} 1{{define "RRCommon"}}
2 <input type="hidden" name="lid" value="{{index . "lid"}}"> 2 <input type="hidden" name="lid" value="{{index .Params "lid"}}">
3 {{range $k, $v := .}} 3 {{range $k, $v := .Params}}
4 <input type="hidden" name="old_{{$k}}" value="{{$v}}"> 4 <input type="hidden" name="old_{{$k}}" value="{{$v}}">
5 {{end}} 5 {{end}}
6 {{$pf := index . "prefix"}} 6 {{$pf := index .Params "prefix"}}
7 <tr> 7 <tr>
8 <td align="right" valign="top"><b>Expires:</b></td> 8 <td align="right" valign="top"><b>Expires:</b></td>
9 <td> 9 <td>
10 Never <input type="checkbox" class="alternate" name="{{$pf}}never" 10 Never <input type="checkbox" class="alternate" name="{{$pf}}never"
11 {{if eq "on" (index . (print $pf "never"))}}checked="checked"{{end}} 11 {{if eq "on" (index .Params (print $pf "never"))}}checked="checked"{{end}}
12 > 12 >
13 <div class="alternate"> 13 <div class="alternate">
14 At given date and time: 14 At given date and time:
15 <input type="datetime-local" id="{{$pf}}expires" name="{{$pf}}expires" required 15 <input type="datetime-local" id="{{$pf}}expires" name="{{$pf}}expires" required
16 value="{{index . (print $pf "expires")}}" 16 value="{{index .Params (print $pf "expires")}}"
17 > 17 >
18 </div> 18 </div>
19 </td> 19 </td>
@@ -22,13 +22,13 @@
22 <td align="right" valign="top"><b>Flags:</b></td> 22 <td align="right" valign="top"><b>Flags:</b></td>
23 <td> 23 <td>
24 <input type="checkbox" name="{{$pf}}private" 24 <input type="checkbox" name="{{$pf}}private"
25 {{if eq "on" (index . (print $pf "private"))}}checked="checked" class="disabled"{{end}} 25 {{if eq "on" (index .Params (print $pf "private"))}}checked="checked" class="disabled"{{end}}
26 > Private<br> 26 > Private<br>
27 <input type="checkbox" name="{{$pf}}shadow" 27 <input type="checkbox" name="{{$pf}}shadow"
28 {{if eq "on" (index . (print $pf "shadow"))}}checked="checked" class="disabled"{{end}} 28 {{if eq "on" (index .Params (print $pf "shadow"))}}checked="checked" class="disabled"{{end}}
29 > Shadow<br> 29 > Shadow<br>
30 <input type="checkbox" name="{{$pf}}suppl" 30 <input type="checkbox" name="{{$pf}}suppl"
31 {{if eq "on" (index . (print $pf "suppl"))}}checked="checked" class="disabled"{{end}} 31 {{if eq "on" (index .Params (print $pf "suppl"))}}checked="checked" class="disabled"{{end}}
32 > Supplemental<br> 32 > Supplemental<br>
33 </td> 33 </td>
34 </tr> 34 </tr>
@@ -68,7 +68,7 @@
68 > 68 >
69 </td> 69 </td>
70 </tr> 70 </tr>
71 {{template "RRCommon" .Params}} 71 {{template "RRCommon" .}}
72 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr> 72 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr>
73 </table> 73 </table>
74 </form> 74 </form>
@@ -98,7 +98,7 @@
98 > 98 >
99 </td> 99 </td>
100 </tr> 100 </tr>
101 {{template "RRCommon" .Params}} 101 {{template "RRCommon" .}}
102 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr> 102 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr>
103 </table> 103 </table>
104 </form> 104 </form>
@@ -125,7 +125,7 @@
125 > 125 >
126 </td> 126 </td>
127 </tr> 127 </tr>
128 {{template "RRCommon" .Params}} 128 {{template "RRCommon" .}}
129 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr> 129 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr>
130 </table> 130 </table>
131 </form> 131 </form>
@@ -145,7 +145,7 @@
145 > 145 >
146 </td> 146 </td>
147 </tr> 147 </tr>
148 {{template "RRCommon" .Params}} 148 {{template "RRCommon" .}}
149 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr> 149 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr>
150 </table> 150 </table>
151 </form> 151 </form>
@@ -165,7 +165,7 @@
165 > 165 >
166 </td> 166 </td>
167 </tr> 167 </tr>
168 {{template "RRCommon" .Params}} 168 {{template "RRCommon" .}}
169 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr> 169 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr>
170 </table> 170 </table>
171 </form> 171 </form>
@@ -200,7 +200,7 @@
200 > 200 >
201 </td> 201 </td>
202 </tr> 202 </tr>
203 {{template "RRCommon" .Params}} 203 {{template "RRCommon" .}}
204 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr> 204 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr>
205 </table> 205 </table>
206 </form> 206 </form>
@@ -302,7 +302,7 @@
302 </div> 302 </div>
303 </td> 303 </td>
304 </tr> 304 </tr>
305 {{template "RRCommon" .Params}} 305 {{template "RRCommon" .}}
306 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr> 306 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr>
307 </table> 307 </table>
308 </form> 308 </form>
@@ -323,7 +323,7 @@
323 > 323 >
324 </td> 324 </td>
325 </tr> 325 </tr>
326 {{template "RRCommon" .Params}} 326 {{template "RRCommon" .}}
327 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr> 327 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr>
328 </table> 328 </table>
329 </form> 329 </form>
@@ -344,7 +344,7 @@
344 > 344 >
345 </td> 345 </td>
346 </tr> 346 </tr>
347 {{template "RRCommon" .Params}} 347 {{template "RRCommon" .}}
348 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr> 348 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr>
349 </table> 349 </table>
350 </form> 350 </form>
@@ -364,7 +364,7 @@
364 > 364 >
365 </td> 365 </td>
366 </tr> 366 </tr>
367 {{template "RRCommon" .Params}} 367 {{template "RRCommon" .}}
368 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr> 368 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr>
369 </table> 369 </table>
370 </form> 370 </form>
@@ -384,7 +384,7 @@
384 > 384 >
385 </td> 385 </td>
386 </tr> 386 </tr>
387 {{template "RRCommon" .Params}} 387 {{template "RRCommon" .}}
388 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr> 388 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr>
389 </table> 389 </table>
390 </form> 390 </form>
@@ -413,7 +413,7 @@
413 > 413 >
414 </td> 414 </td>
415 </tr> 415 </tr>
416 {{template "RRCommon" .Params}} 416 {{template "RRCommon" .}}
417 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr> 417 <tr><td/><td><button id="submit">{{.Button}} record</button></td></tr>
418 </table> 418 </table>
419 </form> 419 </form>
diff --git a/src/gnunet/service/zonemaster/records.go b/src/gnunet/service/zonemaster/records.go
index 3015893..a10ee05 100644
--- a/src/gnunet/service/zonemaster/records.go
+++ b/src/gnunet/service/zonemaster/records.go
@@ -22,8 +22,11 @@ import (
22 "encoding/hex" 22 "encoding/hex"
23 "errors" 23 "errors"
24 "fmt" 24 "fmt"
25 "gnunet/crypto"
25 "gnunet/enums" 26 "gnunet/enums"
27 "gnunet/service/dht/blocks"
26 "gnunet/service/gns/rr" 28 "gnunet/service/gns/rr"
29 "gnunet/service/store"
27 "gnunet/util" 30 "gnunet/util"
28 "net" 31 "net"
29 "time" 32 "time"
@@ -330,7 +333,7 @@ func Map2RRData(t enums.GNSType, set map[string]string) (buf []byte, err error)
330} 333}
331 334
332//====================================================================== 335//======================================================================
333// Get list of allowed new RRs given a set of existing RRs. 336// ResourceRecord helpers
334//====================================================================== 337//======================================================================
335 338
336// Create a list of compatible record types from list of 339// Create a list of compatible record types from list of
@@ -346,3 +349,23 @@ func compatibleRR(in []*enums.GNSSpec, label string) (out []*enums.GNSSpec) {
346 } 349 }
347 return 350 return
348} 351}
352
353// get a list of resource records for a given label in a zone.
354func (zm *ZoneMaster) getRecords(zk *crypto.ZoneKey, label int64) (rs *blocks.RecordSet, expire util.AbsoluteTime, err error) {
355 // collect records for zone label
356 var recs []*store.Record
357 if recs, err = zm.zdb.GetRecords("lid=%d", label); err != nil {
358 return
359 }
360 // assemble record set and find earliest expiration
361 expire = util.AbsoluteTimeNever()
362 rs = blocks.NewRecordSet()
363 for _, r := range recs {
364 if r.Expire.Compare(expire) < 0 {
365 expire = r.Expire
366 }
367 rs.AddRecord(&r.ResourceRecord)
368 }
369 // do not add padding yet as record set may be filtered before use.
370 return
371}
diff --git a/src/gnunet/service/zonemaster/rpc.go b/src/gnunet/service/zonemaster/rpc.go
index 2060e56..4df5b21 100644
--- a/src/gnunet/service/zonemaster/rpc.go
+++ b/src/gnunet/service/zonemaster/rpc.go
@@ -20,5 +20,5 @@ package zonemaster
20 20
21import "gnunet/service" 21import "gnunet/service"
22 22
23func (s *Service) InitRPC(rpc *service.JRPCServer) { 23func (zm *ZoneMaster) InitRPC(rpc *service.JRPCServer) {
24} 24}
diff --git a/src/gnunet/service/zonemaster/service.go b/src/gnunet/service/zonemaster/service.go
index c73857f..5725ec8 100644
--- a/src/gnunet/service/zonemaster/service.go
+++ b/src/gnunet/service/zonemaster/service.go
@@ -25,7 +25,7 @@ import (
25 25
26 "gnunet/config" 26 "gnunet/config"
27 "gnunet/core" 27 "gnunet/core"
28 "gnunet/crypto" 28 "gnunet/enums"
29 "gnunet/message" 29 "gnunet/message"
30 "gnunet/service" 30 "gnunet/service"
31 "gnunet/service/dht/blocks" 31 "gnunet/service/dht/blocks"
@@ -35,43 +35,20 @@ import (
35 "github.com/bfix/gospel/logger" 35 "github.com/bfix/gospel/logger"
36) 36)
37 37
38type ZoneIterator struct {
39 zk *crypto.ZonePrivate
40}
41
42//---------------------------------------------------------------------- 38//----------------------------------------------------------------------
43// "GNUnet Zonemaster" service implementation: 39// "GNUnet Zonemaster" socket service implementation:
44// The zonemaster service handles Namestore messages 40// Zonemaster handles Namestore and Identity messages.
45//---------------------------------------------------------------------- 41//----------------------------------------------------------------------
46 42
47// Service implements a GNS service
48type Service struct {
49 Module
50
51 ZoneIters *util.Map[uint32, *ZoneIterator]
52}
53
54// NewService creates a new GNS service instance
55func NewService(ctx context.Context, c *core.Core) service.Service {
56 // instantiate service
57 mod := NewModule(ctx, c)
58 srv := &Service{
59 Module: *mod,
60 ZoneIters: util.NewMap[uint32, *ZoneIterator](),
61 }
62 // set external function references (external services)
63 srv.StoreLocal = srv.StoreNamecache
64 srv.StoreRemote = srv.StoreDHT
65
66 return srv
67}
68
69// ServeClient processes a client channel. 43// ServeClient processes a client channel.
70func (s *Service) ServeClient(ctx context.Context, id int, mc *service.Connection) { 44func (zm *ZoneMaster) ServeClient(ctx context.Context, id int, mc *service.Connection) {
71 reqID := 0 45 reqID := 0
72 var cancel context.CancelFunc 46 var cancel context.CancelFunc
73 ctx, cancel = context.WithCancel(ctx) 47 ctx, cancel = context.WithCancel(ctx)
74 48
49 // inform sub-service about new session
50 zm.identity.NewSession(id, mc)
51
75 for { 52 for {
76 // receive next message from client 53 // receive next message from client
77 reqID++ 54 reqID++
@@ -89,33 +66,158 @@ func (s *Service) ServeClient(ctx context.Context, id int, mc *service.Connectio
89 } 66 }
90 logger.Printf(logger.INFO, "[zonemaster:%d:%d] Received request: %v\n", id, reqID, msg) 67 logger.Printf(logger.INFO, "[zonemaster:%d:%d] Received request: %v\n", id, reqID, msg)
91 68
69 // context with values
70 values := make(util.ParameterSet)
71 values["id"] = id
72 values["label"] = fmt.Sprintf(":%d:%d", id, reqID)
73 valueCtx := context.WithValue(ctx, core.CtxKey("params"), values)
74
92 // handle message 75 // handle message
93 valueCtx := context.WithValue(ctx, core.CtxKey("label"), fmt.Sprintf(":%d:%d", id, reqID)) 76 zm.HandleMessage(valueCtx, nil, msg, mc)
94 s.HandleMessage(valueCtx, nil, msg, mc)
95 } 77 }
78 // inform sub.services about closed session
79 zm.identity.CloseSession(id)
80
96 // close client connection 81 // close client connection
97 mc.Close() 82 mc.Close()
98 83
99 // cancel all tasks running for this session/connection 84 // cancel all tasks running for this session/connection
100 logger.Printf(logger.INFO, "[zonemaster:%d] Start closing session...\n", id) 85 logger.Printf(logger.INFO, "[zonemaster:%d] Closing session...\n", id)
101 cancel() 86 cancel()
102} 87}
103 88
104// Handle a single incoming message 89// Handle a single incoming message
105func (s *Service) HandleMessage(ctx context.Context, sender *util.PeerID, msg message.Message, back transport.Responder) bool { 90func (zm *ZoneMaster) HandleMessage(ctx context.Context, sender *util.PeerID, msg message.Message, back transport.Responder) bool {
106 // assemble log label 91 // assemble log label
107 label := "" 92 var id int
108 if v := ctx.Value("label"); v != nil { 93 var label string
109 label, _ = v.(string) 94 if v := ctx.Value(core.CtxKey("params")); v != nil {
95 if ps, ok := v.(util.ParameterSet); ok {
96 label, _ = util.GetParam[string](ps, "label")
97 id, _ = util.GetParam[int](ps, "id")
98 }
110 } 99 }
111 // perform lookup 100 // perform lookup
112 switch m := msg.(type) { 101 switch m := msg.(type) {
113 102
103 //------------------------------------------------------------------
104 // Identity service
105 //------------------------------------------------------------------
106
107 // start identity update listener
108 case *message.IdentityStartMsg:
109 if err := zm.identity.Start(ctx, id); err != nil {
110 logger.Printf(logger.ERROR, "[zonemaster%s] Identity session for %d failed: %v\n", label, id, err)
111 return false
112 }
113
114 // create a new identity with given private key
115 case *message.IdentityCreateMsg:
116 if err := zm.identity.Create(ctx, id, m.ZoneKey, m.Name()); err != nil {
117 logger.Printf(logger.ERROR, "[zonemaster%s] Identity create failed: %v\n", label, err)
118 return false
119 }
120
121 // rename identity
122 case *message.IdentityRenameMsg:
123 id, err := zm.zdb.GetIdentityByName(m.OldName(), IDENT_DEFAULT_SERVICE)
124 if err != nil {
125 logger.Printf(logger.ERROR, "[zonemaster%s] Identity lookup failed: %v\n", label, err)
126 return false
127 }
128 // change name
129 id.Name = m.NewName()
130 err = zm.zdb.SetIdentity(id)
131
132 // send response
133 rc := enums.RC_OK
134 msg := ""
135 if err != nil {
136 rc = enums.RC_NO
137 msg = err.Error()
138 }
139 resp := message.NewIdentityResultCodeMsg(rc, msg)
140 if err = back.Send(ctx, resp); err != nil {
141 logger.Printf(logger.ERROR, "[identity:%s] Can't send response (%v): %v\n", label, resp, err)
142 }
143
144 // delete identity
145 case *message.IdentityDeleteMsg:
146 id, err := zm.zdb.GetIdentityByName(m.Name(), IDENT_DEFAULT_SERVICE)
147 if err != nil {
148 logger.Printf(logger.ERROR, "[zonemaster%s] Identity lookup failed: %v\n", label, err)
149 return false
150 }
151 // delete in database
152 id.Name = ""
153 err = zm.zdb.SetIdentity(id)
154
155 // send response
156 rc := enums.RC_OK
157 msg := ""
158 if err != nil {
159 rc = enums.RC_NO
160 msg = err.Error()
161 }
162 resp := message.NewIdentityResultCodeMsg(rc, msg)
163 if err = back.Send(ctx, resp); err != nil {
164 logger.Printf(logger.ERROR, "[identity:%s] Can't send response (%v): %v\n", label, resp, err)
165 }
166
167 // lookup identity
168 case *message.IdentityLookupMsg:
169 id, err := zm.zdb.GetIdentityByName(m.Name, IDENT_DEFAULT_SERVICE)
170 if err != nil {
171 logger.Printf(logger.ERROR, "[zonemaster%s] Identity lookup failed: %v\n", label, err)
172 return false
173 }
174 resp := message.NewIdentityUpdateMsg(id.Name, id.Key)
175 logger.Printf(logger.DBG, "[identity:%s] Sending %v", label, resp)
176 if err = back.Send(ctx, resp); err != nil {
177 logger.Printf(logger.ERROR, "[identity:%s] Can't send response (%v): %v\n", label, resp, err)
178 }
179
180 // get default identity for service
181 case *message.IdentityGetDefaultMsg:
182 id, err := zm.zdb.GetDefaultIdentity(m.Service())
183 if err != nil {
184 logger.Printf(logger.ERROR, "[zonemaster%s] Identity lookup failed: %v\n", label, err)
185 return false
186 }
187 resp := message.NewIdentityUpdateMsg(id.Name, id.Key)
188 logger.Printf(logger.DBG, "[identity:%s] Sending %v", label, resp)
189 if err = back.Send(ctx, resp); err != nil {
190 logger.Printf(logger.ERROR, "[identity:%s] Can't send response (%v): %v\n", label, resp, err)
191 }
192
193 // set default identity for service
194 case *message.IdentitySetDefaultMsg:
195 err := zm.zdb.SetDefaultIdentity(m.ZoneKey, m.Service())
196
197 // send response
198 rc := enums.RC_OK
199 msg := ""
200 if err != nil {
201 rc = enums.RC_NO
202 msg = err.Error()
203 }
204 resp := message.NewIdentityResultCodeMsg(rc, msg)
205 if err = back.Send(ctx, resp); err != nil {
206 logger.Printf(logger.ERROR, "[identity:%s] Can't send response (%v): %v\n", label, resp, err)
207 }
208
209 //------------------------------------------------------------------
210 // Namestore service
211 //------------------------------------------------------------------
212
114 // start new zone iteration 213 // start new zone iteration
115 case *message.NamestoreZoneIterStartMsg: 214 case *message.NamestoreZoneIterStartMsg:
116 zi := new(ZoneIterator) 215 iter := zm.namestore.NewIterator(m.ID, m.ZoneKey)
117 zi.zk = m.ZoneKey 216 resp := iter.Next()
118 s.ZoneIters.Put(m.ID, zi, 0) 217 if err := back.Send(ctx, resp); err != nil {
218 logger.Printf(logger.ERROR, "[zonemaster%s] Can't send response (%v)\n", label, resp)
219 return false
220 }
119 221
120 default: 222 default:
121 //---------------------------------------------------------- 223 //----------------------------------------------------------
@@ -128,7 +230,7 @@ func (s *Service) HandleMessage(ctx context.Context, sender *util.PeerID, msg me
128} 230}
129 231
130// storeDHT stores a GNS block in the DHT. 232// storeDHT stores a GNS block in the DHT.
131func (s *Service) StoreDHT(ctx context.Context, query blocks.Query, block blocks.Block) (err error) { 233func (zm *ZoneMaster) StoreDHT(ctx context.Context, query blocks.Query, block blocks.Block) (err error) {
132 // assemble DHT request 234 // assemble DHT request
133 req := message.NewDHTP2PPutMsg(block) 235 req := message.NewDHTP2PPutMsg(block)
134 req.Flags = query.Flags() 236 req.Flags = query.Flags()
@@ -140,7 +242,7 @@ func (s *Service) StoreDHT(ctx context.Context, query blocks.Query, block blocks
140} 242}
141 243
142// storeNamecache stores a GNS block in the local namecache. 244// storeNamecache stores a GNS block in the local namecache.
143func (s *Service) StoreNamecache(ctx context.Context, query *blocks.GNSQuery, block *blocks.GNSBlock) (err error) { 245func (zm *ZoneMaster) StoreNamecache(ctx context.Context, query *blocks.GNSQuery, block *blocks.GNSBlock) (err error) {
144 // assemble Namecache request 246 // assemble Namecache request
145 req := message.NewNamecacheCacheMsg(block) 247 req := message.NewNamecacheCacheMsg(block)
146 248
diff --git a/src/gnunet/service/zonemaster/service_identity.go b/src/gnunet/service/zonemaster/service_identity.go
new file mode 100644
index 0000000..b7777be
--- /dev/null
+++ b/src/gnunet/service/zonemaster/service_identity.go
@@ -0,0 +1,135 @@
1// This file is part of gnunet-go, a GNUnet-implementation in Golang.
2// Copyright (C) 2019-2022 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
19package zonemaster
20
21import (
22 "context"
23 "fmt"
24 "gnunet/crypto"
25 "gnunet/enums"
26 "gnunet/message"
27 "gnunet/service/store"
28 "gnunet/transport"
29 "gnunet/util"
30
31 "github.com/bfix/gospel/logger"
32)
33
34//nolint:stylecheck // my style is my style...
35const (
36 IDENT_DEFAULT_SERVICE = "ego"
37)
38
39//----------------------------------------------------------------------
40// "GNUnet Identity" service implementation:
41//----------------------------------------------------------------------
42
43type IdentitySession struct {
44 id int
45 updates bool
46 back transport.Responder
47}
48
49type Identity struct{}
50
51type IdentityService struct {
52 zm *ZoneMaster // reference to main service
53 clients *util.Map[int, *IdentitySession] // client sessions
54}
55
56func NewIdentityService(zm *ZoneMaster) *IdentityService {
57 srv := new(IdentityService)
58 srv.zm = zm
59 srv.clients = util.NewMap[int, *IdentitySession]()
60 return srv
61}
62
63func (ident *IdentityService) NewSession(id int, back transport.Responder) {
64 sess := &IdentitySession{
65 id: id,
66 updates: false,
67 back: back,
68 }
69 ident.clients.Put(id, sess, 0)
70}
71
72func (ident *IdentityService) CloseSession(id int) {
73 ident.clients.Delete(id, 0)
74}
75
76func (ident *IdentityService) FollowUpdates(id int) *IdentitySession {
77 if sess, ok := ident.clients.Get(id, 0); ok {
78 sess.updates = true
79 return sess
80 }
81 return nil
82}
83
84func (ident *IdentityService) Start(ctx context.Context, id int) (err error) {
85 // flag client as update receiver
86 sess := ident.FollowUpdates(id)
87 if sess == nil {
88 err = fmt.Errorf("no session available for client %d", id)
89 return
90 }
91 // initial update is to send all existing identites
92 var list []*store.Identity
93 if list, err = ident.zm.zdb.GetIdentities(""); err != nil {
94 return
95 }
96 for _, ident := range list {
97 resp := message.NewIdentityUpdateMsg(ident.Name, ident.Key)
98 logger.Printf(logger.DBG, "[identity:%d] Sending %v", id, resp)
99 if err = sess.back.Send(ctx, resp); err != nil {
100 logger.Printf(logger.ERROR, "[identity:%d] Can't send response (%v): %v\n", id, resp, err)
101 return
102 }
103 }
104 // terminate with EOL
105 resp := message.NewIdentityUpdateMsg("", nil)
106 if err = sess.back.Send(ctx, resp); err != nil {
107 logger.Printf(logger.ERROR, "[identity:%d] Can't send response (%v): %v\n", id, resp, err)
108 return
109 }
110 return
111}
112
113func (ident *IdentityService) Create(ctx context.Context, cid int, zk *crypto.ZonePrivate, name string) (err error) {
114 // get client session
115 sess, ok := ident.clients.Get(cid, 0)
116 if !ok {
117 err = fmt.Errorf("no session available for client %d", cid)
118 return
119 }
120 // add identity
121 id := store.NewIdentity(name, zk, IDENT_DEFAULT_SERVICE)
122 err = ident.zm.zdb.SetIdentity(id)
123 rc := enums.RC_OK
124 msg := ""
125 if err != nil {
126 rc = enums.RC_NO
127 msg = err.Error()
128 }
129 resp := message.NewIdentityResultCodeMsg(rc, msg)
130 if err = sess.back.Send(ctx, resp); err != nil {
131 logger.Printf(logger.ERROR, "[identity:%d] Can't send response (%v): %v\n", cid, resp, err)
132 return
133 }
134 return
135}
diff --git a/src/gnunet/service/zonemaster/service_namestore.go b/src/gnunet/service/zonemaster/service_namestore.go
new file mode 100644
index 0000000..2c6d7d1
--- /dev/null
+++ b/src/gnunet/service/zonemaster/service_namestore.go
@@ -0,0 +1,90 @@
1// This file is part of gnunet-go, a GNUnet-implementation in Golang.
2// Copyright (C) 2019-2022 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
19package zonemaster
20
21import (
22 "gnunet/crypto"
23 "gnunet/message"
24 "gnunet/service/store"
25 "gnunet/util"
26)
27
28//----------------------------------------------------------------------
29// "GNUnet Namestore" service implementation:
30//----------------------------------------------------------------------
31
32type ZoneIterator struct {
33 id uint32
34 zk *crypto.ZonePrivate
35 lastUsed util.AbsoluteTime
36 db *store.ZoneDB
37
38 labels []int64
39 pos int
40}
41
42func NewZoneIterator(id uint32, zk *crypto.ZonePrivate, db *store.ZoneDB) (zi *ZoneIterator, err error) {
43 // get list of labels to handle
44 var labels []int64
45 if labels, err = db.GetLabelIDs(zk); err != nil {
46 return
47 }
48 // assemble zone iterator
49 zi = &ZoneIterator{
50 id: id,
51 zk: zk,
52 lastUsed: util.AbsoluteTimeNow(),
53 db: db,
54 pos: 0,
55 labels: labels,
56 }
57 return
58}
59
60func (zi *ZoneIterator) Next() *message.NamestoreRecordResultMsg {
61 if zi.pos == len(zi.labels)-1 {
62 // end of list reached
63 return nil
64 }
65
66 return nil
67}
68
69// NamestoreService to handle namestore requests
70type NamestoreService struct {
71 zm *ZoneMaster
72 iters *util.Map[uint32, *ZoneIterator]
73}
74
75func NewNamestoreService(zm *ZoneMaster) *NamestoreService {
76 return &NamestoreService{
77 zm: zm,
78 iters: util.NewMap[uint32, *ZoneIterator](),
79 }
80}
81
82func (s *NamestoreService) NewIterator(id uint32, zk *crypto.ZonePrivate) *ZoneIterator {
83 zi := &ZoneIterator{
84 id: id,
85 zk: zk,
86 lastUsed: util.AbsoluteTimeNow(),
87 }
88 s.iters.Put(id, zi, 0)
89 return zi
90}
diff --git a/src/gnunet/service/zonemaster/zonemaster.go b/src/gnunet/service/zonemaster/zonemaster.go
index 7c2a13c..4703d2c 100644
--- a/src/gnunet/service/zonemaster/zonemaster.go
+++ b/src/gnunet/service/zonemaster/zonemaster.go
@@ -21,6 +21,7 @@ package zonemaster
21import ( 21import (
22 "context" 22 "context"
23 "gnunet/config" 23 "gnunet/config"
24 "gnunet/core"
24 "gnunet/enums" 25 "gnunet/enums"
25 "gnunet/service/dht/blocks" 26 "gnunet/service/dht/blocks"
26 "gnunet/service/store" 27 "gnunet/service/store"
@@ -31,22 +32,36 @@ import (
31) 32)
32 33
33//====================================================================== 34//======================================================================
34// "GNS ZoneMaster" implementation: 35// "GNS ZoneMaster" implementation (extended):
35// Manage and publish local zone records 36// Manage local identities for subsystems. Manage and publish
37// local GNS zone records.
36//====================================================================== 38//======================================================================
37 39
38// ZoneMaster instance 40// ZoneMaster implements
39type ZoneMaster struct { 41type ZoneMaster struct {
40 cfg *config.Config // Zonemaster configuration 42 Module
41 zdb *store.ZoneDB // ZoneDB connection 43
42 srv *Service // NameStore service 44 zdb *store.ZoneDB // ZoneDB connection
45 namestore *NamestoreService // namestore subservice
46 identity *IdentityService // identity subservice
43} 47}
44 48
45// NewZoneMaster initializes a new zone master instance. 49// NewService initializes a new zone master service.
46func NewZoneMaster(cfg *config.Config, srv *Service) *ZoneMaster { 50func NewService(ctx context.Context, c *core.Core) *ZoneMaster {
47 zm := new(ZoneMaster) 51 mod := NewModule(ctx, c)
48 zm.cfg = cfg 52 srv := &ZoneMaster{
49 return zm 53 Module: *mod,
54 }
55
56 // set external function references (external services)
57 srv.StoreLocal = srv.StoreNamecache
58 srv.StoreRemote = srv.StoreDHT
59
60 // instantiate sub-services
61 srv.namestore = NewNamestoreService(srv)
62 srv.identity = NewIdentityService(srv)
63
64 return srv
50} 65}
51 66
52// Run zone master: connect to zone database and start the RPC/HTTP 67// Run zone master: connect to zone database and start the RPC/HTTP
@@ -55,12 +70,8 @@ func NewZoneMaster(cfg *config.Config, srv *Service) *ZoneMaster {
55func (zm *ZoneMaster) Run(ctx context.Context) { 70func (zm *ZoneMaster) Run(ctx context.Context) {
56 // connect to database 71 // connect to database
57 logger.Println(logger.INFO, "[zonemaster] Connecting to zone database...") 72 logger.Println(logger.INFO, "[zonemaster] Connecting to zone database...")
58 dbFile, ok := util.GetParam[string](zm.cfg.ZoneMaster.Storage, "file")
59 if !ok {
60 logger.Printf(logger.ERROR, "[zonemaster] missing database file specification")
61 return
62 }
63 var err error 73 var err error
74 dbFile, _ := util.GetParam[string](config.Cfg.ZoneMaster.Storage, "file")
64 if zm.zdb, err = store.OpenZoneDB(dbFile); err != nil { 75 if zm.zdb, err = store.OpenZoneDB(dbFile); err != nil {
65 logger.Printf(logger.ERROR, "[zonemaster] open database: %v", err) 76 logger.Printf(logger.ERROR, "[zonemaster] open database: %v", err)
66 return 77 return
@@ -69,15 +80,15 @@ func (zm *ZoneMaster) Run(ctx context.Context) {
69 80
70 // start HTTP GUI 81 // start HTTP GUI
71 zm.startGUI(ctx) 82 zm.startGUI(ctx)
72 /* 83
73 // publish on start-up 84 // publish on start-up
74 if err = zm.Publish(ctx); err != nil { 85 if err = zm.Publish(ctx); err != nil {
75 logger.Printf(logger.ERROR, "[zonemaster] initial publish failed: %s", err.Error()) 86 logger.Printf(logger.ERROR, "[zonemaster] initial publish failed: %s", err.Error())
76 return 87 return
77 } 88 }
78 */ 89
79 // periodically publish GNS blocks to the DHT 90 // periodically publish GNS blocks to the DHT
80 tick := time.NewTicker(time.Duration(zm.cfg.ZoneMaster.Period) * time.Second) 91 tick := time.NewTicker(time.Duration(config.Cfg.ZoneMaster.Period) * time.Second)
81loop: 92loop:
82 for { 93 for {
83 select { 94 select {
@@ -125,34 +136,44 @@ func (zm *ZoneMaster) PublishZoneLabel(ctx context.Context, zone *store.Zone, la
125 zk := zone.Key.Public() 136 zk := zone.Key.Public()
126 logger.Printf(logger.INFO, "[zonemaster] Publishing label '%s' of zone %s", label.Name, zk.ID()) 137 logger.Printf(logger.INFO, "[zonemaster] Publishing label '%s' of zone %s", label.Name, zk.ID())
127 138
128 // collect public records for zone label 139 // collect all records for label
129 recs, err := zm.zdb.GetRecords("lid=%d and flags&%d = 0", label.ID, enums.GNS_FLAG_PRIVATE) 140 rrSet, expire, err := zm.getRecords(zk, label.ID)
130 if err != nil { 141 if err != nil {
131 return err 142 return err
132 } 143 }
133 // assemble record set and find earliest expiration
134 expire := util.AbsoluteTimeNever()
135 rrSet := blocks.NewRecordSet()
136 for _, r := range recs {
137 if r.Expire.Compare(expire) < 0 {
138 expire = r.Expire
139 }
140 rrSet.AddRecord(&r.ResourceRecord)
141 }
142 rrSet.SetPadding()
143 if rrSet.Count == 0 { 144 if rrSet.Count == 0 {
144 logger.Println(logger.INFO, "[zonemaster] No resource records -- skipped") 145 logger.Println(logger.INFO, "[zonemaster] No resource records -- skipped")
145 return nil 146 return nil
146 } 147 }
147 148
148 // assemble GNS query 149 // assemble GNS query (common for DHT and Namecache)
149 query := blocks.NewGNSQuery(zk, label.Name) 150 query := blocks.NewGNSQuery(zk, label.Name)
150 151
151 // assemble, encrypt and sign GNS block 152 //------------------------------------------------------------------
152 blk, _ := blocks.NewGNSBlock().(*blocks.GNSBlock) 153 // Publish to DHT
154 //------------------------------------------------------------------
155
156 // filter out private resource records.
157 recsDHT := util.Clone(rrSet.Records)
158 num := uint32(len(recsDHT))
159 for i, rec := range recsDHT {
160 if rec.Flags&enums.GNS_FLAG_PRIVATE != 0 {
161 copy(recsDHT[i:], recsDHT[i+1:])
162 num--
163 recsDHT = recsDHT[:num]
164 }
165 }
166 rrsDHT := &blocks.RecordSet{
167 Count: num,
168 Records: recsDHT,
169 Padding: nil,
170 }
171 rrsDHT.SetPadding()
153 172
154 blk.Body.Expire = expire 173 // build block for DHT
155 blk.Body.Data, err = zk.Encrypt(rrSet.Bytes(), label.Name, expire) 174 blkDHT, _ := blocks.NewGNSBlock().(*blocks.GNSBlock)
175 blkDHT.Body.Expire = expire
176 blkDHT.Body.Data, err = zk.Encrypt(rrSet.Bytes(), label.Name, expire)
156 if err != nil { 177 if err != nil {
157 return err 178 return err
158 } 179 }
@@ -160,19 +181,39 @@ func (zm *ZoneMaster) PublishZoneLabel(ctx context.Context, zone *store.Zone, la
160 if err != nil { 181 if err != nil {
161 return err 182 return err
162 } 183 }
163 if err = blk.Sign(dzk); err != nil { 184 if err = blkDHT.Sign(dzk); err != nil {
185 return err
186 }
187 // publish GNS block to DHT
188 if err = zm.StoreDHT(ctx, query, blkDHT); err != nil {
164 return err 189 return err
165 } 190 }
166 191
167 // DEBUG: 192 // DEBUG
168 // logger.Printf(logger.DBG, "[zonemaster] Query key = %s", hex.EncodeToString(query.Key().Data)) 193 /*
169 // logger.Printf(logger.DBG, "[zonemaster] Block data = %s", hex.EncodeToString(blk.Bytes())) 194 logger.Printf(logger.DBG, "[zonemaster] pub = %s", util.EncodeBinaryToString(zk.Bytes()))
195 logger.Printf(logger.DBG, "[zonemaster] query = %s", hex.EncodeToString(query.Key().Data))
196 logger.Printf(logger.DBG, "[zonemaster] blk = %s", hex.EncodeToString(blkDHT.Bytes()))
197 */
198
199 //------------------------------------------------------------------
200 // Publish to Namecache
201 //------------------------------------------------------------------
170 202
171 // publish GNS block to DHT and Namecache 203 // build block for Namecache
172 if err = zm.srv.StoreDHT(ctx, query, blk); err != nil { 204 blkNC, _ := blocks.NewGNSBlock().(*blocks.GNSBlock)
205 blkNC.Body.Expire = expire
206 blkNC.Body.Data = rrSet.Bytes()
207 // sign block
208 if dzk, _, err = zone.Key.Derive(label.Name, "gns"); err != nil {
173 return err 209 return err
174 } 210 }
175 if err = zm.srv.StoreNamecache(ctx, query, blk); err != nil { 211 if err = blkNC.Sign(dzk); err != nil {
212 return err
213 }
214
215 // publish GNS block to namecache
216 if err = zm.StoreNamecache(ctx, query, blkNC); err != nil {
176 return err 217 return err
177 } 218 }
178 return nil 219 return nil
diff --git a/src/gnunet/transport/reader_writer.go b/src/gnunet/transport/reader_writer.go
index 2cee0a9..a1a7bbe 100644
--- a/src/gnunet/transport/reader_writer.go
+++ b/src/gnunet/transport/reader_writer.go
@@ -116,7 +116,10 @@ func ReadMessage(ctx context.Context, rdr io.ReadCloser, buf []byte) (msg messag
116 err = fmt.Errorf("message{%d} is nil", mh.MsgType) 116 err = fmt.Errorf("message{%d} is nil", mh.MsgType)
117 return 117 return
118 } 118 }
119 err = data.Unmarshal(msg, buf[:mh.MsgSize]) 119 if err = data.Unmarshal(msg, buf[:mh.MsgSize]); err != nil {
120 return
121 }
122 err = msg.Init()
120 /* 123 /*
121 // DEBUG: incoming messages 124 // DEBUG: incoming messages
122 if mh.MsgType == enums.MSG_DHT_P2P_RESULT { 125 if mh.MsgType == enums.MSG_DHT_P2P_RESULT {