github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/pss/pss.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:48</date> 10 //</624342678309441536> 11 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 // 25 // 26 // 27 28 package pss 29 30 import ( 31 "bytes" 32 "context" 33 "crypto/ecdsa" 34 "crypto/rand" 35 "errors" 36 "fmt" 37 "sync" 38 "time" 39 40 "github.com/ethereum/go-ethereum/common" 41 "github.com/ethereum/go-ethereum/crypto" 42 "github.com/ethereum/go-ethereum/metrics" 43 "github.com/ethereum/go-ethereum/p2p" 44 "github.com/ethereum/go-ethereum/p2p/discover" 45 "github.com/ethereum/go-ethereum/p2p/protocols" 46 "github.com/ethereum/go-ethereum/rpc" 47 "github.com/ethereum/go-ethereum/swarm/log" 48 "github.com/ethereum/go-ethereum/swarm/network" 49 "github.com/ethereum/go-ethereum/swarm/pot" 50 "github.com/ethereum/go-ethereum/swarm/storage" 51 whisper "github.com/ethereum/go-ethereum/whisper/whisperv5" 52 ) 53 54 const ( 55 defaultPaddingByteSize = 16 56 DefaultMsgTTL = time.Second * 120 57 defaultDigestCacheTTL = time.Second * 10 58 defaultSymKeyCacheCapacity = 512 59 digestLength = 32 // 60 defaultWhisperWorkTime = 3 61 defaultWhisperPoW = 0.0000000001 62 defaultMaxMsgSize = 1024 * 1024 63 defaultCleanInterval = time.Second * 60 * 10 64 defaultOutboxCapacity = 100000 65 pssProtocolName = "pss" 66 pssVersion = 2 67 hasherCount = 8 68 ) 69 70 var ( 71 addressLength = len(pot.Address{}) 72 ) 73 74 // 75 // 76 // 77 type pssCacheEntry struct { 78 expiresAt time.Time 79 } 80 81 // 82 type senderPeer interface { 83 Info() *p2p.PeerInfo 84 ID() discover.NodeID 85 Address() []byte 86 Send(context.Context, interface{}) error 87 } 88 89 // 90 // 91 type pssPeer struct { 92 lastSeen time.Time 93 address *PssAddress 94 protected bool 95 } 96 97 // 98 type PssParams struct { 99 MsgTTL time.Duration 100 CacheTTL time.Duration 101 privateKey *ecdsa.PrivateKey 102 SymKeyCacheCapacity int 103 AllowRaw bool // 104 } 105 106 // 107 func NewPssParams() *PssParams { 108 return &PssParams{ 109 MsgTTL: DefaultMsgTTL, 110 CacheTTL: defaultDigestCacheTTL, 111 SymKeyCacheCapacity: defaultSymKeyCacheCapacity, 112 } 113 } 114 115 func (params *PssParams) WithPrivateKey(privatekey *ecdsa.PrivateKey) *PssParams { 116 params.privateKey = privatekey 117 return params 118 } 119 120 // 121 // 122 // 123 type Pss struct { 124 network.Overlay // 125 privateKey *ecdsa.PrivateKey // 126 w *whisper.Whisper // 127 auxAPIs []rpc.API // 128 129 // 130 fwdPool map[string]*protocols.Peer // 131 fwdPoolMu sync.RWMutex 132 fwdCache map[pssDigest]pssCacheEntry // 133 fwdCacheMu sync.RWMutex 134 cacheTTL time.Duration // 135 msgTTL time.Duration 136 paddingByteSize int 137 capstring string 138 outbox chan *PssMsg 139 140 // 141 pubKeyPool map[string]map[Topic]*pssPeer // 142 pubKeyPoolMu sync.RWMutex 143 symKeyPool map[string]map[Topic]*pssPeer // 144 symKeyPoolMu sync.RWMutex 145 symKeyDecryptCache []*string // 146 symKeyDecryptCacheCursor int // 147 symKeyDecryptCacheCapacity int // 148 149 // 150 handlers map[Topic]map[*Handler]bool // 151 handlersMu sync.RWMutex 152 allowRaw bool 153 hashPool sync.Pool 154 155 // 156 quitC chan struct{} 157 } 158 159 func (p *Pss) String() string { 160 return fmt.Sprintf("pss: addr %x, pubkey %v", p.BaseAddr(), common.ToHex(crypto.FromECDSAPub(&p.privateKey.PublicKey))) 161 } 162 163 // 164 // 165 // 166 // 167 func NewPss(k network.Overlay, params *PssParams) (*Pss, error) { 168 if params.privateKey == nil { 169 return nil, errors.New("missing private key for pss") 170 } 171 cap := p2p.Cap{ 172 Name: pssProtocolName, 173 Version: pssVersion, 174 } 175 ps := &Pss{ 176 Overlay: k, 177 privateKey: params.privateKey, 178 w: whisper.New(&whisper.DefaultConfig), 179 quitC: make(chan struct{}), 180 181 fwdPool: make(map[string]*protocols.Peer), 182 fwdCache: make(map[pssDigest]pssCacheEntry), 183 cacheTTL: params.CacheTTL, 184 msgTTL: params.MsgTTL, 185 paddingByteSize: defaultPaddingByteSize, 186 capstring: cap.String(), 187 outbox: make(chan *PssMsg, defaultOutboxCapacity), 188 189 pubKeyPool: make(map[string]map[Topic]*pssPeer), 190 symKeyPool: make(map[string]map[Topic]*pssPeer), 191 symKeyDecryptCache: make([]*string, params.SymKeyCacheCapacity), 192 symKeyDecryptCacheCapacity: params.SymKeyCacheCapacity, 193 194 handlers: make(map[Topic]map[*Handler]bool), 195 allowRaw: params.AllowRaw, 196 hashPool: sync.Pool{ 197 New: func() interface{} { 198 return storage.MakeHashFunc(storage.DefaultHash)() 199 }, 200 }, 201 } 202 203 for i := 0; i < hasherCount; i++ { 204 hashfunc := storage.MakeHashFunc(storage.DefaultHash)() 205 ps.hashPool.Put(hashfunc) 206 } 207 208 return ps, nil 209 } 210 211 // 212 // 213 // 214 215 func (p *Pss) Start(srv *p2p.Server) error { 216 go func() { 217 ticker := time.NewTicker(defaultCleanInterval) 218 cacheTicker := time.NewTicker(p.cacheTTL) 219 defer ticker.Stop() 220 defer cacheTicker.Stop() 221 for { 222 select { 223 case <-cacheTicker.C: 224 p.cleanFwdCache() 225 case <-ticker.C: 226 p.cleanKeys() 227 case <-p.quitC: 228 return 229 } 230 } 231 }() 232 go func() { 233 for { 234 select { 235 case msg := <-p.outbox: 236 err := p.forward(msg) 237 if err != nil { 238 log.Error(err.Error()) 239 metrics.GetOrRegisterCounter("pss.forward.err", nil).Inc(1) 240 } 241 case <-p.quitC: 242 return 243 } 244 } 245 }() 246 log.Info("Started Pss") 247 log.Info("Loaded EC keys", "pubkey", common.ToHex(crypto.FromECDSAPub(p.PublicKey())), "secp256", common.ToHex(crypto.CompressPubkey(p.PublicKey()))) 248 return nil 249 } 250 251 func (p *Pss) Stop() error { 252 log.Info("Pss shutting down") 253 close(p.quitC) 254 return nil 255 } 256 257 var pssSpec = &protocols.Spec{ 258 Name: pssProtocolName, 259 Version: pssVersion, 260 MaxMsgSize: defaultMaxMsgSize, 261 Messages: []interface{}{ 262 PssMsg{}, 263 }, 264 } 265 266 func (p *Pss) Protocols() []p2p.Protocol { 267 return []p2p.Protocol{ 268 { 269 Name: pssSpec.Name, 270 Version: pssSpec.Version, 271 Length: pssSpec.Length(), 272 Run: p.Run, 273 }, 274 } 275 } 276 277 func (p *Pss) Run(peer *p2p.Peer, rw p2p.MsgReadWriter) error { 278 pp := protocols.NewPeer(peer, rw, pssSpec) 279 p.fwdPoolMu.Lock() 280 p.fwdPool[peer.Info().ID] = pp 281 p.fwdPoolMu.Unlock() 282 return pp.Run(p.handlePssMsg) 283 } 284 285 func (p *Pss) APIs() []rpc.API { 286 apis := []rpc.API{ 287 { 288 Namespace: "pss", 289 Version: "1.0", 290 Service: NewAPI(p), 291 Public: true, 292 }, 293 } 294 apis = append(apis, p.auxAPIs...) 295 return apis 296 } 297 298 // 299 // 300 func (p *Pss) addAPI(api rpc.API) { 301 p.auxAPIs = append(p.auxAPIs, api) 302 } 303 304 // 305 func (p *Pss) BaseAddr() []byte { 306 return p.Overlay.BaseAddr() 307 } 308 309 // 310 func (p *Pss) PublicKey() *ecdsa.PublicKey { 311 return &p.privateKey.PublicKey 312 } 313 314 // 315 // 316 // 317 318 // 319 // 320 // 321 // 322 // 323 // 324 // 325 // 326 // 327 func (p *Pss) Register(topic *Topic, handler Handler) func() { 328 p.handlersMu.Lock() 329 defer p.handlersMu.Unlock() 330 handlers := p.handlers[*topic] 331 if handlers == nil { 332 handlers = make(map[*Handler]bool) 333 p.handlers[*topic] = handlers 334 } 335 handlers[&handler] = true 336 return func() { p.deregister(topic, &handler) } 337 } 338 func (p *Pss) deregister(topic *Topic, h *Handler) { 339 p.handlersMu.Lock() 340 defer p.handlersMu.Unlock() 341 handlers := p.handlers[*topic] 342 if len(handlers) == 1 { 343 delete(p.handlers, *topic) 344 return 345 } 346 delete(handlers, h) 347 } 348 349 // 350 func (p *Pss) getHandlers(topic Topic) map[*Handler]bool { 351 p.handlersMu.RLock() 352 defer p.handlersMu.RUnlock() 353 return p.handlers[topic] 354 } 355 356 // 357 // 358 // 359 // 360 func (p *Pss) handlePssMsg(ctx context.Context, msg interface{}) error { 361 metrics.GetOrRegisterCounter("pss.handlepssmsg", nil).Inc(1) 362 363 pssmsg, ok := msg.(*PssMsg) 364 365 if !ok { 366 return fmt.Errorf("invalid message type. Expected *PssMsg, got %T ", msg) 367 } 368 if int64(pssmsg.Expire) < time.Now().Unix() { 369 metrics.GetOrRegisterCounter("pss.expire", nil).Inc(1) 370 log.Warn("pss filtered expired message", "from", common.ToHex(p.Overlay.BaseAddr()), "to", common.ToHex(pssmsg.To)) 371 return nil 372 } 373 if p.checkFwdCache(pssmsg) { 374 log.Trace("pss relay block-cache match (process)", "from", common.ToHex(p.Overlay.BaseAddr()), "to", (common.ToHex(pssmsg.To))) 375 return nil 376 } 377 p.addFwdCache(pssmsg) 378 379 if !p.isSelfPossibleRecipient(pssmsg) { 380 log.Trace("pss was for someone else :'( ... forwarding", "pss", common.ToHex(p.BaseAddr())) 381 return p.enqueue(pssmsg) 382 } 383 384 log.Trace("pss for us, yay! ... let's process!", "pss", common.ToHex(p.BaseAddr())) 385 if err := p.process(pssmsg); err != nil { 386 qerr := p.enqueue(pssmsg) 387 if qerr != nil { 388 return fmt.Errorf("process fail: processerr %v, queueerr: %v", err, qerr) 389 } 390 } 391 return nil 392 393 } 394 395 // 396 // 397 // 398 func (p *Pss) process(pssmsg *PssMsg) error { 399 metrics.GetOrRegisterCounter("pss.process", nil).Inc(1) 400 401 var err error 402 var recvmsg *whisper.ReceivedMessage 403 var payload []byte 404 var from *PssAddress 405 var asymmetric bool 406 var keyid string 407 var keyFunc func(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, *PssAddress, error) 408 409 envelope := pssmsg.Payload 410 psstopic := Topic(envelope.Topic) 411 if pssmsg.isRaw() { 412 if !p.allowRaw { 413 return errors.New("raw message support disabled") 414 } 415 payload = pssmsg.Payload.Data 416 } else { 417 if pssmsg.isSym() { 418 keyFunc = p.processSym 419 } else { 420 asymmetric = true 421 keyFunc = p.processAsym 422 } 423 424 recvmsg, keyid, from, err = keyFunc(envelope) 425 if err != nil { 426 return errors.New("Decryption failed") 427 } 428 payload = recvmsg.Payload 429 } 430 431 if len(pssmsg.To) < addressLength { 432 if err := p.enqueue(pssmsg); err != nil { 433 return err 434 } 435 } 436 p.executeHandlers(psstopic, payload, from, asymmetric, keyid) 437 438 return nil 439 440 } 441 442 func (p *Pss) executeHandlers(topic Topic, payload []byte, from *PssAddress, asymmetric bool, keyid string) { 443 handlers := p.getHandlers(topic) 444 nid, _ := discover.HexID("0x00") // 445 peer := p2p.NewPeer(nid, fmt.Sprintf("%x", from), []p2p.Cap{}) 446 for f := range handlers { 447 err := (*f)(payload, peer, asymmetric, keyid) 448 if err != nil { 449 log.Warn("Pss handler %p failed: %v", f, err) 450 } 451 } 452 } 453 454 // 455 func (p *Pss) isSelfRecipient(msg *PssMsg) bool { 456 return bytes.Equal(msg.To, p.Overlay.BaseAddr()) 457 } 458 459 // 460 func (p *Pss) isSelfPossibleRecipient(msg *PssMsg) bool { 461 local := p.Overlay.BaseAddr() 462 return bytes.Equal(msg.To[:], local[:len(msg.To)]) 463 } 464 465 // 466 // 467 // 468 469 // 470 // 471 // 472 // 473 // 474 // 475 // 476 func (p *Pss) SetPeerPublicKey(pubkey *ecdsa.PublicKey, topic Topic, address *PssAddress) error { 477 pubkeybytes := crypto.FromECDSAPub(pubkey) 478 if len(pubkeybytes) == 0 { 479 return fmt.Errorf("invalid public key: %v", pubkey) 480 } 481 pubkeyid := common.ToHex(pubkeybytes) 482 psp := &pssPeer{ 483 address: address, 484 } 485 p.pubKeyPoolMu.Lock() 486 if _, ok := p.pubKeyPool[pubkeyid]; !ok { 487 p.pubKeyPool[pubkeyid] = make(map[Topic]*pssPeer) 488 } 489 p.pubKeyPool[pubkeyid][topic] = psp 490 p.pubKeyPoolMu.Unlock() 491 log.Trace("added pubkey", "pubkeyid", pubkeyid, "topic", topic, "address", common.ToHex(*address)) 492 return nil 493 } 494 495 // 496 func (p *Pss) GenerateSymmetricKey(topic Topic, address *PssAddress, addToCache bool) (string, error) { 497 keyid, err := p.w.GenerateSymKey() 498 if err != nil { 499 return "", err 500 } 501 p.addSymmetricKeyToPool(keyid, topic, address, addToCache, false) 502 return keyid, nil 503 } 504 505 // 506 // 507 // 508 // 509 // 510 // 511 // 512 // 513 // 514 // 515 // 516 // 517 func (p *Pss) SetSymmetricKey(key []byte, topic Topic, address *PssAddress, addtocache bool) (string, error) { 518 return p.setSymmetricKey(key, topic, address, addtocache, true) 519 } 520 521 func (p *Pss) setSymmetricKey(key []byte, topic Topic, address *PssAddress, addtocache bool, protected bool) (string, error) { 522 keyid, err := p.w.AddSymKeyDirect(key) 523 if err != nil { 524 return "", err 525 } 526 p.addSymmetricKeyToPool(keyid, topic, address, addtocache, protected) 527 return keyid, nil 528 } 529 530 // 531 // 532 // 533 func (p *Pss) addSymmetricKeyToPool(keyid string, topic Topic, address *PssAddress, addtocache bool, protected bool) { 534 psp := &pssPeer{ 535 address: address, 536 protected: protected, 537 } 538 p.symKeyPoolMu.Lock() 539 if _, ok := p.symKeyPool[keyid]; !ok { 540 p.symKeyPool[keyid] = make(map[Topic]*pssPeer) 541 } 542 p.symKeyPool[keyid][topic] = psp 543 p.symKeyPoolMu.Unlock() 544 if addtocache { 545 p.symKeyDecryptCacheCursor++ 546 p.symKeyDecryptCache[p.symKeyDecryptCacheCursor%cap(p.symKeyDecryptCache)] = &keyid 547 } 548 key, _ := p.GetSymmetricKey(keyid) 549 log.Trace("added symkey", "symkeyid", keyid, "symkey", common.ToHex(key), "topic", topic, "address", fmt.Sprintf("%p", address), "cache", addtocache) 550 } 551 552 // 553 // 554 // 555 // 556 func (p *Pss) GetSymmetricKey(symkeyid string) ([]byte, error) { 557 symkey, err := p.w.GetSymKey(symkeyid) 558 if err != nil { 559 return nil, err 560 } 561 return symkey, nil 562 } 563 564 // 565 func (p *Pss) GetPublickeyPeers(keyid string) (topic []Topic, address []PssAddress, err error) { 566 p.pubKeyPoolMu.RLock() 567 defer p.pubKeyPoolMu.RUnlock() 568 for t, peer := range p.pubKeyPool[keyid] { 569 topic = append(topic, t) 570 address = append(address, *peer.address) 571 } 572 573 return topic, address, nil 574 } 575 576 func (p *Pss) getPeerAddress(keyid string, topic Topic) (PssAddress, error) { 577 p.pubKeyPoolMu.RLock() 578 defer p.pubKeyPoolMu.RUnlock() 579 if peers, ok := p.pubKeyPool[keyid]; ok { 580 if t, ok := peers[topic]; ok { 581 return *t.address, nil 582 } 583 } 584 return nil, fmt.Errorf("peer with pubkey %s, topic %x not found", keyid, topic) 585 } 586 587 // 588 // 589 // 590 // 591 // 592 // 593 func (p *Pss) processSym(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, *PssAddress, error) { 594 metrics.GetOrRegisterCounter("pss.process.sym", nil).Inc(1) 595 596 for i := p.symKeyDecryptCacheCursor; i > p.symKeyDecryptCacheCursor-cap(p.symKeyDecryptCache) && i > 0; i-- { 597 symkeyid := p.symKeyDecryptCache[i%cap(p.symKeyDecryptCache)] 598 symkey, err := p.w.GetSymKey(*symkeyid) 599 if err != nil { 600 continue 601 } 602 recvmsg, err := envelope.OpenSymmetric(symkey) 603 if err != nil { 604 continue 605 } 606 if !recvmsg.Validate() { 607 return nil, "", nil, fmt.Errorf("symmetrically encrypted message has invalid signature or is corrupt") 608 } 609 p.symKeyPoolMu.Lock() 610 from := p.symKeyPool[*symkeyid][Topic(envelope.Topic)].address 611 p.symKeyPoolMu.Unlock() 612 p.symKeyDecryptCacheCursor++ 613 p.symKeyDecryptCache[p.symKeyDecryptCacheCursor%cap(p.symKeyDecryptCache)] = symkeyid 614 return recvmsg, *symkeyid, from, nil 615 } 616 return nil, "", nil, fmt.Errorf("could not decrypt message") 617 } 618 619 // 620 // 621 // 622 // 623 // 624 // 625 func (p *Pss) processAsym(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, *PssAddress, error) { 626 metrics.GetOrRegisterCounter("pss.process.asym", nil).Inc(1) 627 628 recvmsg, err := envelope.OpenAsymmetric(p.privateKey) 629 if err != nil { 630 return nil, "", nil, fmt.Errorf("could not decrypt message: %s", err) 631 } 632 // 633 if !recvmsg.Validate() { 634 return nil, "", nil, fmt.Errorf("invalid message") 635 } 636 pubkeyid := common.ToHex(crypto.FromECDSAPub(recvmsg.Src)) 637 var from *PssAddress 638 p.pubKeyPoolMu.Lock() 639 if p.pubKeyPool[pubkeyid][Topic(envelope.Topic)] != nil { 640 from = p.pubKeyPool[pubkeyid][Topic(envelope.Topic)].address 641 } 642 p.pubKeyPoolMu.Unlock() 643 return recvmsg, pubkeyid, from, nil 644 } 645 646 // 647 // 648 // 649 // 650 func (p *Pss) cleanKeys() (count int) { 651 for keyid, peertopics := range p.symKeyPool { 652 var expiredtopics []Topic 653 for topic, psp := range peertopics { 654 if psp.protected { 655 continue 656 } 657 658 var match bool 659 for i := p.symKeyDecryptCacheCursor; i > p.symKeyDecryptCacheCursor-cap(p.symKeyDecryptCache) && i > 0; i-- { 660 cacheid := p.symKeyDecryptCache[i%cap(p.symKeyDecryptCache)] 661 if *cacheid == keyid { 662 match = true 663 } 664 } 665 if !match { 666 expiredtopics = append(expiredtopics, topic) 667 } 668 } 669 for _, topic := range expiredtopics { 670 p.symKeyPoolMu.Lock() 671 delete(p.symKeyPool[keyid], topic) 672 log.Trace("symkey cleanup deletion", "symkeyid", keyid, "topic", topic, "val", p.symKeyPool[keyid]) 673 p.symKeyPoolMu.Unlock() 674 count++ 675 } 676 } 677 return 678 } 679 680 // 681 // 682 // 683 684 func (p *Pss) enqueue(msg *PssMsg) error { 685 select { 686 case p.outbox <- msg: 687 return nil 688 default: 689 } 690 691 metrics.GetOrRegisterCounter("pss.enqueue.outbox.full", nil).Inc(1) 692 return errors.New("outbox full") 693 } 694 695 // 696 // 697 // 698 func (p *Pss) SendRaw(address PssAddress, topic Topic, msg []byte) error { 699 if !p.allowRaw { 700 return errors.New("Raw messages not enabled") 701 } 702 pssMsgParams := &msgParams{ 703 raw: true, 704 } 705 payload := &whisper.Envelope{ 706 Data: msg, 707 Topic: whisper.TopicType(topic), 708 } 709 pssMsg := newPssMsg(pssMsgParams) 710 pssMsg.To = address 711 pssMsg.Expire = uint32(time.Now().Add(p.msgTTL).Unix()) 712 pssMsg.Payload = payload 713 p.addFwdCache(pssMsg) 714 return p.enqueue(pssMsg) 715 } 716 717 // 718 // 719 // 720 func (p *Pss) SendSym(symkeyid string, topic Topic, msg []byte) error { 721 symkey, err := p.GetSymmetricKey(symkeyid) 722 if err != nil { 723 return fmt.Errorf("missing valid send symkey %s: %v", symkeyid, err) 724 } 725 p.symKeyPoolMu.Lock() 726 psp, ok := p.symKeyPool[symkeyid][topic] 727 p.symKeyPoolMu.Unlock() 728 if !ok { 729 return fmt.Errorf("invalid topic '%s' for symkey '%s'", topic.String(), symkeyid) 730 } else if psp.address == nil { 731 return fmt.Errorf("no address hint for topic '%s' symkey '%s'", topic.String(), symkeyid) 732 } 733 err = p.send(*psp.address, topic, msg, false, symkey) 734 return err 735 } 736 737 // 738 // 739 // 740 func (p *Pss) SendAsym(pubkeyid string, topic Topic, msg []byte) error { 741 if _, err := crypto.UnmarshalPubkey(common.FromHex(pubkeyid)); err != nil { 742 return fmt.Errorf("Cannot unmarshal pubkey: %x", pubkeyid) 743 } 744 p.pubKeyPoolMu.Lock() 745 psp, ok := p.pubKeyPool[pubkeyid][topic] 746 p.pubKeyPoolMu.Unlock() 747 if !ok { 748 return fmt.Errorf("invalid topic '%s' for pubkey '%s'", topic.String(), pubkeyid) 749 } else if psp.address == nil { 750 return fmt.Errorf("no address hint for topic '%s' pubkey '%s'", topic.String(), pubkeyid) 751 } 752 go func() { 753 p.send(*psp.address, topic, msg, true, common.FromHex(pubkeyid)) 754 }() 755 return nil 756 } 757 758 // 759 // 760 // 761 // 762 func (p *Pss) send(to []byte, topic Topic, msg []byte, asymmetric bool, key []byte) error { 763 metrics.GetOrRegisterCounter("pss.send", nil).Inc(1) 764 765 if key == nil || bytes.Equal(key, []byte{}) { 766 return fmt.Errorf("Zero length key passed to pss send") 767 } 768 padding := make([]byte, p.paddingByteSize) 769 c, err := rand.Read(padding) 770 if err != nil { 771 return err 772 } else if c < p.paddingByteSize { 773 return fmt.Errorf("invalid padding length: %d", c) 774 } 775 wparams := &whisper.MessageParams{ 776 TTL: defaultWhisperTTL, 777 Src: p.privateKey, 778 Topic: whisper.TopicType(topic), 779 WorkTime: defaultWhisperWorkTime, 780 PoW: defaultWhisperPoW, 781 Payload: msg, 782 Padding: padding, 783 } 784 if asymmetric { 785 pk, err := crypto.UnmarshalPubkey(key) 786 if err != nil { 787 return fmt.Errorf("Cannot unmarshal pubkey: %x", key) 788 } 789 wparams.Dst = pk 790 } else { 791 wparams.KeySym = key 792 } 793 // 794 woutmsg, err := whisper.NewSentMessage(wparams) 795 if err != nil { 796 return fmt.Errorf("failed to generate whisper message encapsulation: %v", err) 797 } 798 // 799 // 800 // 801 envelope, err := woutmsg.Wrap(wparams) 802 if err != nil { 803 return fmt.Errorf("failed to perform whisper encryption: %v", err) 804 } 805 log.Trace("pssmsg whisper done", "env", envelope, "wparams payload", common.ToHex(wparams.Payload), "to", common.ToHex(to), "asym", asymmetric, "key", common.ToHex(key)) 806 807 // 808 pssMsgParams := &msgParams{ 809 sym: !asymmetric, 810 } 811 pssMsg := newPssMsg(pssMsgParams) 812 pssMsg.To = to 813 pssMsg.Expire = uint32(time.Now().Add(p.msgTTL).Unix()) 814 pssMsg.Payload = envelope 815 return p.enqueue(pssMsg) 816 } 817 818 // 819 // 820 // 821 func (p *Pss) forward(msg *PssMsg) error { 822 metrics.GetOrRegisterCounter("pss.forward", nil).Inc(1) 823 824 to := make([]byte, addressLength) 825 copy(to[:len(msg.To)], msg.To) 826 827 // 828 // 829 sent := 0 830 p.Overlay.EachConn(to, 256, func(op network.OverlayConn, po int, isproxbin bool) bool { 831 // 832 // 833 sp, ok := op.(senderPeer) 834 if !ok { 835 log.Crit("Pss cannot use kademlia peer type") 836 return false 837 } 838 info := sp.Info() 839 840 // 841 var ispss bool 842 for _, cap := range info.Caps { 843 if cap == p.capstring { 844 ispss = true 845 break 846 } 847 } 848 if !ispss { 849 log.Trace("peer doesn't have matching pss capabilities, skipping", "peer", info.Name, "caps", info.Caps) 850 return true 851 } 852 853 // 854 sendMsg := fmt.Sprintf("MSG TO %x FROM %x VIA %x", to, p.BaseAddr(), op.Address()) 855 p.fwdPoolMu.RLock() 856 pp := p.fwdPool[sp.Info().ID] 857 p.fwdPoolMu.RUnlock() 858 859 // 860 err := pp.Send(context.TODO(), msg) 861 if err != nil { 862 metrics.GetOrRegisterCounter("pss.pp.send.error", nil).Inc(1) 863 log.Error(err.Error()) 864 return true 865 } 866 sent++ 867 log.Trace(fmt.Sprintf("%v: successfully forwarded", sendMsg)) 868 869 // 870 // 871 // 872 // 873 if len(msg.To) < addressLength && bytes.Equal(msg.To, op.Address()[:len(msg.To)]) { 874 log.Trace(fmt.Sprintf("Pss keep forwarding: Partial address + full partial match")) 875 return true 876 } else if isproxbin { 877 log.Trace(fmt.Sprintf("%x is in proxbin, keep forwarding", common.ToHex(op.Address()))) 878 return true 879 } 880 // 881 // 882 // 883 // 884 return false 885 }) 886 887 if sent == 0 { 888 log.Debug("unable to forward to any peers") 889 if err := p.enqueue(msg); err != nil { 890 metrics.GetOrRegisterCounter("pss.forward.enqueue.error", nil).Inc(1) 891 log.Error(err.Error()) 892 return err 893 } 894 } 895 896 // 897 p.addFwdCache(msg) 898 return nil 899 } 900 901 // 902 // 903 // 904 905 // 906 func (p *Pss) cleanFwdCache() { 907 metrics.GetOrRegisterCounter("pss.cleanfwdcache", nil).Inc(1) 908 p.fwdCacheMu.Lock() 909 defer p.fwdCacheMu.Unlock() 910 for k, v := range p.fwdCache { 911 if v.expiresAt.Before(time.Now()) { 912 delete(p.fwdCache, k) 913 } 914 } 915 } 916 917 // 918 func (p *Pss) addFwdCache(msg *PssMsg) error { 919 metrics.GetOrRegisterCounter("pss.addfwdcache", nil).Inc(1) 920 921 var entry pssCacheEntry 922 var ok bool 923 924 p.fwdCacheMu.Lock() 925 defer p.fwdCacheMu.Unlock() 926 927 digest := p.digest(msg) 928 if entry, ok = p.fwdCache[digest]; !ok { 929 entry = pssCacheEntry{} 930 } 931 entry.expiresAt = time.Now().Add(p.cacheTTL) 932 p.fwdCache[digest] = entry 933 return nil 934 } 935 936 // 937 func (p *Pss) checkFwdCache(msg *PssMsg) bool { 938 p.fwdCacheMu.Lock() 939 defer p.fwdCacheMu.Unlock() 940 941 digest := p.digest(msg) 942 entry, ok := p.fwdCache[digest] 943 if ok { 944 if entry.expiresAt.After(time.Now()) { 945 log.Trace("unexpired cache", "digest", fmt.Sprintf("%x", digest)) 946 metrics.GetOrRegisterCounter("pss.checkfwdcache.unexpired", nil).Inc(1) 947 return true 948 } 949 metrics.GetOrRegisterCounter("pss.checkfwdcache.expired", nil).Inc(1) 950 } 951 return false 952 } 953 954 // 955 func (p *Pss) digest(msg *PssMsg) pssDigest { 956 hasher := p.hashPool.Get().(storage.SwarmHash) 957 defer p.hashPool.Put(hasher) 958 hasher.Reset() 959 hasher.Write(msg.serialize()) 960 digest := pssDigest{} 961 key := hasher.Sum(nil) 962 copy(digest[:], key[:digestLength]) 963 return digest 964 } 965