diff options
author | Bernd Fix <brf@hoi-polloi.org> | 2022-10-26 17:59:46 +0200 |
---|---|---|
committer | Bernd Fix <brf@hoi-polloi.org> | 2022-10-26 17:59:46 +0200 |
commit | bcc6ce0be0d9c240dce80c42af5b56e8ee805aff (patch) | |
tree | c8a78e0e37822e9709aa31202641d54cad01084b /src | |
parent | cc143998695474cbe91941b91eaa9c8fa41d6700 (diff) | |
download | gnunet-go-bcc6ce0be0d9c240dce80c42af5b56e8ee805aff.tar.gz gnunet-go-bcc6ce0be0d9c240dce80c42af5b56e8ee805aff.zip |
Identity service added to zone master.v0.1.37
Diffstat (limited to 'src')
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 { | |||
129 | type ZonePrivateImpl interface { | 129 | type 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,...) |
213 | type ZonePrivate struct { | 217 | type 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 |
221 | func NewZonePrivate(ztype enums.GNSType, d []byte) (zp *ZonePrivate, err error) { | 226 | // must be in the correct format specified by a ZonePrivate implementation. |
227 | func 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 | ||
255 | func (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 | ||
269 | func 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 | ||
285 | func (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). |
256 | func (zp *ZonePrivate) KeySize() uint { | 294 | func (zp *ZonePrivate) KeySize() uint { |
@@ -263,7 +301,7 @@ func (zp *ZonePrivate) KeySize() uint { | |||
263 | // Derive key (key blinding) | 301 | // Derive key (key blinding) |
264 | func (zp *ZonePrivate) Derive(label, context string) (dzp *ZonePrivate, h *math.Int, err error) { | 302 | func (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 |
292 | func (zp *ZonePrivate) Public() *ZoneKey { | 325 | func (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 |
314 | func (zk *ZoneKey) Init() (err error) { | 352 | func (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()') | ||
377 | func (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). |
340 | func (zk *ZoneKey) KeySize() uint { | 386 | func (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) |
348 | func (zk *ZoneKey) Derive(label, context string) (dzk *ZoneKey, h *math.Int, err error) { | 394 | func (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 | ||
392 | func (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 |
398 | func (zk *ZoneKey) Equal(k *ZoneKey) bool { | 438 | func (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 | ||
423 | func (zs *ZoneSignature) Init() (err error) { | 464 | func (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()') | ||
507 | func (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 |
464 | func (zs *ZoneSignature) Key() *ZoneKey { | 512 | func (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 |
490 | func asID(t enums.GNSType, data []byte) string { | 538 | func 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. |
81 | func (pk *EDKEYPublicImpl) Derive(h *math.Int) (dPk ZoneKeyImpl, hOut *math.Int, err error) { | 81 | func (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 |
164 | func (pk *EDKEYPublicImpl) ID() string { | 164 | func (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 | ||
191 | func (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()'. |
192 | func (pk *EDKEYPrivateImpl) Bytes() []byte { | 197 | func (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. |
203 | func (pk *EDKEYPrivateImpl) Derive(h *math.Int) (dPk ZonePrivateImpl, hOut *math.Int, err error) { | 208 | func (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 |
245 | func (pk *EDKEYPrivateImpl) ID() string { | 250 | func (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 | ||
21 | import ( | 21 | import ( |
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 |
160 | func (pk *PKEYPublicImpl) ID() string { | 160 | func (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). |
177 | func (pk *PKEYPrivateImpl) Init(data []byte) error { | 177 | func (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 | ||
187 | func (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()'. |
187 | func (pk *PKEYPrivateImpl) Bytes() []byte { | 197 | func (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) | ||
235 | func (pk *PKEYPrivateImpl) ID() string { | 246 | func (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) { | |||
202 | func TestDeriveH(t *testing.T) { | 202 | func 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 | ||
305 | func TestHKDF_gnunet(t *testing.T) { | 286 | func 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 | ||
20 | package enums | ||
21 | |||
22 | // ResultCode type | ||
23 | type ResultCode int32 | ||
24 | |||
25 | // ResultCode values | ||
26 | const ( | ||
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 | |||
3 | go 1.18 | 3 | go 1.18 |
4 | 4 | ||
5 | require ( | 5 | require ( |
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 @@ | |||
1 | github.com/bfix/gospel v1.2.20 h1:e/IxmTiC579jIQlIxpMzCX/MIKHNsBzJ1WdMKheCgBw= | 1 | github.com/bfix/gospel v1.2.21 h1:rgllMlR+2AZt6+x0uaBF67a+pM7fJxHiO93amhKXZNU= |
2 | github.com/bfix/gospel v1.2.20/go.mod h1:cdu63bA9ZdfeDoqZ+vnWOcbY9Puwdzmf5DMxMGMznRI= | 2 | github.com/bfix/gospel v1.2.21/go.mod h1:cdu63bA9ZdfeDoqZ+vnWOcbY9Puwdzmf5DMxMGMznRI= |
3 | github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= | 3 | github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= |
4 | github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | 4 | github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= |
5 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= | 5 | github.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 { | |||
45 | type EphemeralKeyMsg struct { | 45 | type 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 | ||
72 | func (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. |
72 | func (m *EphemeralKeyMsg) String() string { | 75 | func (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 | ||
71 | func (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 | ||
120 | func (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 | ||
163 | func (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 | ||
196 | func (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 | ||
237 | func (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 | ||
80 | func (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. |
80 | func (m *DHTP2PGetMsg) String() string { | 83 | func (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 | ||
174 | func (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 |
288 | type DHTP2PResultMsg struct { | 296 | type 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 | ||
342 | func (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 |
496 | func (m *DHTP2PHelloMsg) Addresses() (list []*util.Address, err error) { | 512 | func (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 | ||
540 | func (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. |
520 | func (m *DHTP2PHelloMsg) SetAddresses(list []*util.Address) { | 549 | func (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 ( | |||
37 | type LookupMsg struct { | 37 | type 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 | ||
85 | func (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 { | |||
124 | func (m *LookupResultMsg) Header() *MsgHeader { | 127 | func (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 | ||
132 | func (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 | ||
154 | func (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 |
166 | func (m *HelloMsg) Addresses() (list []*HelloAddress, err error) { | 192 | func (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 | |||
19 | package message | ||
20 | |||
21 | import ( | ||
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. | ||
36 | type IdentityStartMsg struct { | ||
37 | MsgHeader | ||
38 | } | ||
39 | |||
40 | // NewIdentityStartMsg creates an empty message | ||
41 | func 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 | ||
48 | func (msg *IdentityStartMsg) Init() error { return nil } | ||
49 | |||
50 | // String returns a human-readable representation of the message. | ||
51 | func (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 | ||
62 | type 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. | ||
76 | func 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 | ||
99 | func (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. | ||
105 | func (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 | ||
113 | func (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 | ||
124 | type 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 | ||
132 | func (msg *IdentityResultCodeMsg) OnError() bool { | ||
133 | return msg.ResultCode != enums.RC_OK | ||
134 | } | ||
135 | |||
136 | // Init called after unmarshalling a message to setup internal state | ||
137 | func (msg *IdentityResultCodeMsg) Init() error { return nil } | ||
138 | |||
139 | // NewIdentityResultCodeMsg creates a new default message. | ||
140 | func 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. | ||
156 | func (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 | ||
167 | type 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 | ||
180 | func (msg *IdentityCreateMsg) Init() error { | ||
181 | msg.name, _ = util.ReadCString(msg.Name_, 0) | ||
182 | return nil | ||
183 | } | ||
184 | |||
185 | // NewIdentityCreateMsg creates a new default message. | ||
186 | func 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. | ||
209 | func (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 | ||
214 | func (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 | ||
225 | type 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 | ||
239 | func (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 | ||
246 | func 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. | ||
267 | func (msg *IdentityRenameMsg) String() string { | ||
268 | return fmt.Sprintf("IdentityRenameMsg{'%s'->'%s'}", msg.oldName, msg.newName) | ||
269 | } | ||
270 | |||
271 | // OldName of the identity | ||
272 | func (msg *IdentityRenameMsg) OldName() string { | ||
273 | return msg.oldName | ||
274 | } | ||
275 | |||
276 | // NewName of the identity | ||
277 | func (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 | ||
288 | type 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 | ||
300 | func (msg *IdentityDeleteMsg) Init() error { | ||
301 | msg.name, _ = util.ReadCString(msg.Name_, 0) | ||
302 | return nil | ||
303 | } | ||
304 | |||
305 | // NewIdentityDeleteMsg renames an identity | ||
306 | func 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. | ||
322 | func (msg *IdentityDeleteMsg) String() string { | ||
323 | return fmt.Sprintf("IdentityDeleteMsg{name='%s'}", msg.name) | ||
324 | } | ||
325 | |||
326 | // Name of the removed identity | ||
327 | func (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 | ||
338 | type IdentityLookupMsg struct { | ||
339 | MsgHeader | ||
340 | |||
341 | Name string | ||
342 | } | ||
343 | |||
344 | // Init called after unmarshalling a message to setup internal state | ||
345 | func (msg *IdentityLookupMsg) Init() error { | ||
346 | return nil | ||
347 | } | ||
348 | |||
349 | // NewIdentityLookupMsg renames an identity | ||
350 | func 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. | ||
361 | func (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 | ||
372 | type 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 | ||
384 | func (msg *IdentityGetDefaultMsg) Init() error { | ||
385 | msg.service, _ = util.ReadCString(msg.Service_, 0) | ||
386 | return nil | ||
387 | } | ||
388 | |||
389 | // NewIdentityGetDefaultMsg creates a new message | ||
390 | func 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. | ||
406 | func (msg *IdentityGetDefaultMsg) String() string { | ||
407 | return fmt.Sprintf("IdentityGetDefaultMsg{svc='%s'}", msg.service) | ||
408 | } | ||
409 | |||
410 | // Service name | ||
411 | func (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 | ||
422 | type 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 | ||
435 | func (msg *IdentitySetDefaultMsg) Init() error { | ||
436 | msg.service, _ = util.ReadCString(msg.Service_, 0) | ||
437 | return nil | ||
438 | } | ||
439 | |||
440 | // NewIdentitySetDefaultMsg renames an identity | ||
441 | func 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. | ||
466 | func (msg *IdentitySetDefaultMsg) String() string { | ||
467 | return fmt.Sprintf("IdentitySetDefaultMsg{key=%s,svc='%s'}", msg.ZoneKey.ID(), msg.service) | ||
468 | } | ||
469 | |||
470 | // Service name | ||
471 | func (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 | ||
71 | func (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. |
71 | func (m *NamecacheLookupMsg) String() string { | 74 | func (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 { | |||
81 | type NamecacheLookupResultMsg struct { | 84 | type 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 | ||
93 | func (m *NamecacheLookupResultMsg) Init() error { return nil } | ||
94 | |||
89 | // NewNamecacheLookupResultMsg creates a new default message. | 95 | // NewNamecacheLookupResultMsg creates a new default message. |
90 | func NewNamecacheLookupResultMsg() *NamecacheLookupResultMsg { | 96 | func 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 | ||
126 | func (m *NamecacheCacheMsg) Init() error { return nil } | ||
127 | |||
119 | // Size returns buffer sizes for fields | 128 | // Size returns buffer sizes for fields |
120 | func (m *NamecacheCacheMsg) FldSize(field string) uint { | 129 | func (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 | ||
187 | func (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. |
178 | func (m *NamecacheCacheResponseMsg) String() string { | 190 | func (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 | |||
52 | type NamestoreZoneIterStartMsg struct { | 52 | type 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 | ||
67 | func (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. |
67 | func (m *NamestoreZoneIterStartMsg) String() string { | 70 | func (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 | ||
89 | func (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. |
86 | func (m *NamestoreZoneIterNextMsg) String() string { | 92 | func (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 | |||
108 | type 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 | |||
121 | func 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 | ||
133 | func (m *NamestoreRecordResultMsg) Init() error { return nil } | ||
134 | |||
135 | // String returns a human-readable representation of the message. | ||
136 | func (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 | ||
101 | type NamestoreRecordStoreMsg struct { | 143 | type 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 | ||
157 | type 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 | |||
170 | type NamestoreTxControlMsg struct { | 199 | type 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 ( | |||
34 | type RevocationQueryMsg struct { | 34 | type 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 | ||
50 | func (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. |
50 | func (m *RevocationQueryMsg) String() string { | 53 | func (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 | ||
80 | func (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. |
77 | func (m *RevocationQueryResponseMsg) String() string { | 83 | func (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 | ||
112 | func (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. |
106 | func (m *RevocationRevokeMsg) String() string { | 115 | func (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 | ||
143 | func (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. |
134 | func (m *RevocationRevokeResponseMsg) String() string { | 146 | func (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 | ||
61 | func (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 | ||
112 | func (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 | ||
216 | func (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 | ||
240 | func (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 | ||
268 | func (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 | ||
296 | func (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 | ||
325 | func (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 | ||
352 | func (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 { | |||
350 | func (m *SessionKeepAliveRespMsg) String() string { | 374 | func (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 | ||
379 | func (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 |
275 | func (rs *RecordSet) Bytes() []byte { | 275 | func (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 | ||
32 | func TestGNSBlock(t *testing.T) { | 32 | func 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) { | |||
125 | func TestRecordsetPKEY(t *testing.T) { | 128 | func 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. |
14 | func TestRevocationRFC(t *testing.T) { | 14 | func 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. | ||
40 | type Zone struct { | 44 | type 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 | ||
67 | type Identity struct { | ||
68 | Zone | ||
69 | |||
70 | Svc string // associated service | ||
71 | } | ||
72 | |||
73 | // NewIdentity creates an initialize instance for database access | ||
74 | func 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 | |||
62 | type Label struct { | 83 | type 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 | ||
186 | func (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 | ||
223 | func (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) | ||
239 | func (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 | |||
261 | func (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 | |||
293 | func (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 | |||
308 | func (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 { | |||
165 | func (db *ZoneDB) SetZone(z *Zone) error { | 332 | func (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 | ||
500 | func (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 | ||
19 | create table zones ( | 19 | create 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 | ||
30 | create table defaults ( | ||
31 | svc text unique, | ||
32 | ident integer references identities(id) | ||
33 | ); | ||
34 | |||
35 | create 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 | ||
43 | from identities i, defaults d | ||
44 | where i.id = d.ident; | ||
45 | |||
46 | create view zones as select | ||
47 | id, name, created, modified, ztype, zdata | ||
48 | from identities | ||
49 | where svc = 'gns'; | ||
28 | 50 | ||
29 | create table labels ( | 51 | create 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 | |||
21 | import ( | 21 | import ( |
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 | ||
372 | type NewEditData struct { | 379 | type 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" | ||
641 | type 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 |
634 | func renderPage(w io.Writer, data interface{}, page string) { | 648 | func 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. | ||
354 | func (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 | ||
21 | import "gnunet/service" | 21 | import "gnunet/service" |
22 | 22 | ||
23 | func (s *Service) InitRPC(rpc *service.JRPCServer) { | 23 | func (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 | ||
38 | type 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 | ||
48 | type Service struct { | ||
49 | Module | ||
50 | |||
51 | ZoneIters *util.Map[uint32, *ZoneIterator] | ||
52 | } | ||
53 | |||
54 | // NewService creates a new GNS service instance | ||
55 | func 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. |
70 | func (s *Service) ServeClient(ctx context.Context, id int, mc *service.Connection) { | 44 | func (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 |
105 | func (s *Service) HandleMessage(ctx context.Context, sender *util.PeerID, msg message.Message, back transport.Responder) bool { | 90 | func (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. |
131 | func (s *Service) StoreDHT(ctx context.Context, query blocks.Query, block blocks.Block) (err error) { | 233 | func (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. |
143 | func (s *Service) StoreNamecache(ctx context.Context, query *blocks.GNSQuery, block *blocks.GNSBlock) (err error) { | 245 | func (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 | |||
19 | package zonemaster | ||
20 | |||
21 | import ( | ||
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... | ||
35 | const ( | ||
36 | IDENT_DEFAULT_SERVICE = "ego" | ||
37 | ) | ||
38 | |||
39 | //---------------------------------------------------------------------- | ||
40 | // "GNUnet Identity" service implementation: | ||
41 | //---------------------------------------------------------------------- | ||
42 | |||
43 | type IdentitySession struct { | ||
44 | id int | ||
45 | updates bool | ||
46 | back transport.Responder | ||
47 | } | ||
48 | |||
49 | type Identity struct{} | ||
50 | |||
51 | type IdentityService struct { | ||
52 | zm *ZoneMaster // reference to main service | ||
53 | clients *util.Map[int, *IdentitySession] // client sessions | ||
54 | } | ||
55 | |||
56 | func NewIdentityService(zm *ZoneMaster) *IdentityService { | ||
57 | srv := new(IdentityService) | ||
58 | srv.zm = zm | ||
59 | srv.clients = util.NewMap[int, *IdentitySession]() | ||
60 | return srv | ||
61 | } | ||
62 | |||
63 | func (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 | |||
72 | func (ident *IdentityService) CloseSession(id int) { | ||
73 | ident.clients.Delete(id, 0) | ||
74 | } | ||
75 | |||
76 | func (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 | |||
84 | func (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 | |||
113 | func (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 | |||
19 | package zonemaster | ||
20 | |||
21 | import ( | ||
22 | "gnunet/crypto" | ||
23 | "gnunet/message" | ||
24 | "gnunet/service/store" | ||
25 | "gnunet/util" | ||
26 | ) | ||
27 | |||
28 | //---------------------------------------------------------------------- | ||
29 | // "GNUnet Namestore" service implementation: | ||
30 | //---------------------------------------------------------------------- | ||
31 | |||
32 | type 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 | |||
42 | func 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 | |||
60 | func (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 | ||
70 | type NamestoreService struct { | ||
71 | zm *ZoneMaster | ||
72 | iters *util.Map[uint32, *ZoneIterator] | ||
73 | } | ||
74 | |||
75 | func NewNamestoreService(zm *ZoneMaster) *NamestoreService { | ||
76 | return &NamestoreService{ | ||
77 | zm: zm, | ||
78 | iters: util.NewMap[uint32, *ZoneIterator](), | ||
79 | } | ||
80 | } | ||
81 | |||
82 | func (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 | |||
21 | import ( | 21 | import ( |
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 |
39 | type ZoneMaster struct { | 41 | type 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. |
46 | func NewZoneMaster(cfg *config.Config, srv *Service) *ZoneMaster { | 50 | func 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 { | |||
55 | func (zm *ZoneMaster) Run(ctx context.Context) { | 70 | func (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) |
81 | loop: | 92 | loop: |
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 { |