github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/whisper/whisperv6/whisper.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package whisperv6 13 14 import ( 15 "bytes" 16 "crypto/ecdsa" 17 "crypto/sha256" 18 "fmt" 19 "math" 20 "runtime" 21 "sync" 22 "time" 23 24 "github.com/Sberex/go-sberex/common" 25 "github.com/Sberex/go-sberex/crypto" 26 "github.com/Sberex/go-sberex/log" 27 "github.com/Sberex/go-sberex/p2p" 28 "github.com/Sberex/go-sberex/rlp" 29 "github.com/Sberex/go-sberex/rpc" 30 "github.com/syndtr/goleveldb/leveldb/errors" 31 "golang.org/x/crypto/pbkdf2" 32 "golang.org/x/sync/syncmap" 33 set "gopkg.in/fatih/set.v0" 34 ) 35 36 // Statistics holds several message-related counter for analytics 37 // purposes. 38 type Statistics struct { 39 messagesCleared int 40 memoryCleared int 41 memoryUsed int 42 cycles int 43 totalMessagesCleared int 44 } 45 46 const ( 47 maxMsgSizeIdx = iota // Maximal message length allowed by the whisper node 48 overflowIdx // Indicator of message queue overflow 49 minPowIdx // Minimal PoW required by the whisper node 50 minPowToleranceIdx // Minimal PoW tolerated by the whisper node for a limited time 51 bloomFilterIdx // Bloom filter for topics of interest for this node 52 bloomFilterToleranceIdx // Bloom filter tolerated by the whisper node for a limited time 53 ) 54 55 // Whisper represents a dark communication interface through the Sberex 56 // network, using its very own P2P communication layer. 57 type Whisper struct { 58 protocol p2p.Protocol // Protocol description and parameters 59 filters *Filters // Message filters installed with Subscribe function 60 61 privateKeys map[string]*ecdsa.PrivateKey // Private key storage 62 symKeys map[string][]byte // Symmetric key storage 63 keyMu sync.RWMutex // Mutex associated with key storages 64 65 poolMu sync.RWMutex // Mutex to sync the message and expiration pools 66 envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node 67 expirations map[uint32]*set.SetNonTS // Message expiration pool 68 69 peerMu sync.RWMutex // Mutex to sync the active peer set 70 peers map[*Peer]struct{} // Set of currently active peers 71 72 messageQueue chan *Envelope // Message queue for normal whisper messages 73 p2pMsgQueue chan *Envelope // Message queue for peer-to-peer messages (not to be forwarded any further) 74 quit chan struct{} // Channel used for graceful exit 75 76 settings syncmap.Map // holds configuration settings that can be dynamically changed 77 78 syncAllowance int // maximum time in seconds allowed to process the whisper-related messages 79 80 lightClient bool // indicates is this node is pure light client (does not forward any messages) 81 82 statsMu sync.Mutex // guard stats 83 stats Statistics // Statistics of whisper node 84 85 mailServer MailServer // MailServer interface 86 } 87 88 // New creates a Whisper client ready to communicate through the Sberex P2P network. 89 func New(cfg *Config) *Whisper { 90 if cfg == nil { 91 cfg = &DefaultConfig 92 } 93 94 whisper := &Whisper{ 95 privateKeys: make(map[string]*ecdsa.PrivateKey), 96 symKeys: make(map[string][]byte), 97 envelopes: make(map[common.Hash]*Envelope), 98 expirations: make(map[uint32]*set.SetNonTS), 99 peers: make(map[*Peer]struct{}), 100 messageQueue: make(chan *Envelope, messageQueueLimit), 101 p2pMsgQueue: make(chan *Envelope, messageQueueLimit), 102 quit: make(chan struct{}), 103 syncAllowance: DefaultSyncAllowance, 104 } 105 106 whisper.filters = NewFilters(whisper) 107 108 whisper.settings.Store(minPowIdx, cfg.MinimumAcceptedPOW) 109 whisper.settings.Store(maxMsgSizeIdx, cfg.MaxMessageSize) 110 whisper.settings.Store(overflowIdx, false) 111 112 // p2p whisper sub protocol handler 113 whisper.protocol = p2p.Protocol{ 114 Name: ProtocolName, 115 Version: uint(ProtocolVersion), 116 Length: NumberOfMessageCodes, 117 Run: whisper.HandlePeer, 118 NodeInfo: func() interface{} { 119 return map[string]interface{}{ 120 "version": ProtocolVersionStr, 121 "maxMessageSize": whisper.MaxMessageSize(), 122 "minimumPoW": whisper.MinPow(), 123 } 124 }, 125 } 126 127 return whisper 128 } 129 130 // MinPow returns the PoW value required by this node. 131 func (whisper *Whisper) MinPow() float64 { 132 val, exist := whisper.settings.Load(minPowIdx) 133 if !exist || val == nil { 134 return DefaultMinimumPoW 135 } 136 v, ok := val.(float64) 137 if !ok { 138 log.Error("Error loading minPowIdx, using default") 139 return DefaultMinimumPoW 140 } 141 return v 142 } 143 144 // MinPowTolerance returns the value of minimum PoW which is tolerated for a limited 145 // time after PoW was changed. If sufficient time have elapsed or no change of PoW 146 // have ever occurred, the return value will be the same as return value of MinPow(). 147 func (whisper *Whisper) MinPowTolerance() float64 { 148 val, exist := whisper.settings.Load(minPowToleranceIdx) 149 if !exist || val == nil { 150 return DefaultMinimumPoW 151 } 152 return val.(float64) 153 } 154 155 // BloomFilter returns the aggregated bloom filter for all the topics of interest. 156 // The nodes are required to send only messages that match the advertised bloom filter. 157 // If a message does not match the bloom, it will tantamount to spam, and the peer will 158 // be disconnected. 159 func (whisper *Whisper) BloomFilter() []byte { 160 val, exist := whisper.settings.Load(bloomFilterIdx) 161 if !exist || val == nil { 162 return nil 163 } 164 return val.([]byte) 165 } 166 167 // BloomFilterTolerance returns the bloom filter which is tolerated for a limited 168 // time after new bloom was advertised to the peers. If sufficient time have elapsed 169 // or no change of bloom filter have ever occurred, the return value will be the same 170 // as return value of BloomFilter(). 171 func (whisper *Whisper) BloomFilterTolerance() []byte { 172 val, exist := whisper.settings.Load(bloomFilterToleranceIdx) 173 if !exist || val == nil { 174 return nil 175 } 176 return val.([]byte) 177 } 178 179 // MaxMessageSize returns the maximum accepted message size. 180 func (whisper *Whisper) MaxMessageSize() uint32 { 181 val, _ := whisper.settings.Load(maxMsgSizeIdx) 182 return val.(uint32) 183 } 184 185 // Overflow returns an indication if the message queue is full. 186 func (whisper *Whisper) Overflow() bool { 187 val, _ := whisper.settings.Load(overflowIdx) 188 return val.(bool) 189 } 190 191 // APIs returns the RPC descriptors the Whisper implementation offers 192 func (whisper *Whisper) APIs() []rpc.API { 193 return []rpc.API{ 194 { 195 Namespace: ProtocolName, 196 Version: ProtocolVersionStr, 197 Service: NewPublicWhisperAPI(whisper), 198 Public: true, 199 }, 200 } 201 } 202 203 // RegisterServer registers MailServer interface. 204 // MailServer will process all the incoming messages with p2pRequestCode. 205 func (whisper *Whisper) RegisterServer(server MailServer) { 206 whisper.mailServer = server 207 } 208 209 // Protocols returns the whisper sub-protocols ran by this particular client. 210 func (whisper *Whisper) Protocols() []p2p.Protocol { 211 return []p2p.Protocol{whisper.protocol} 212 } 213 214 // Version returns the whisper sub-protocols version number. 215 func (whisper *Whisper) Version() uint { 216 return whisper.protocol.Version 217 } 218 219 // SetMaxMessageSize sets the maximal message size allowed by this node 220 func (whisper *Whisper) SetMaxMessageSize(size uint32) error { 221 if size > MaxMessageSize { 222 return fmt.Errorf("message size too large [%d>%d]", size, MaxMessageSize) 223 } 224 whisper.settings.Store(maxMsgSizeIdx, size) 225 return nil 226 } 227 228 // SetBloomFilter sets the new bloom filter 229 func (whisper *Whisper) SetBloomFilter(bloom []byte) error { 230 if len(bloom) != bloomFilterSize { 231 return fmt.Errorf("invalid bloom filter size: %d", len(bloom)) 232 } 233 234 b := make([]byte, bloomFilterSize) 235 copy(b, bloom) 236 237 whisper.settings.Store(bloomFilterIdx, b) 238 whisper.notifyPeersAboutBloomFilterChange(b) 239 240 go func() { 241 // allow some time before all the peers have processed the notification 242 time.Sleep(time.Duration(whisper.syncAllowance) * time.Second) 243 whisper.settings.Store(bloomFilterToleranceIdx, b) 244 }() 245 246 return nil 247 } 248 249 // SetMinimumPoW sets the minimal PoW required by this node 250 func (whisper *Whisper) SetMinimumPoW(val float64) error { 251 if val < 0.0 { 252 return fmt.Errorf("invalid PoW: %f", val) 253 } 254 255 whisper.settings.Store(minPowIdx, val) 256 whisper.notifyPeersAboutPowRequirementChange(val) 257 258 go func() { 259 // allow some time before all the peers have processed the notification 260 time.Sleep(time.Duration(whisper.syncAllowance) * time.Second) 261 whisper.settings.Store(minPowToleranceIdx, val) 262 }() 263 264 return nil 265 } 266 267 // SetMinimumPowTest sets the minimal PoW in test environment 268 func (whisper *Whisper) SetMinimumPowTest(val float64) { 269 whisper.settings.Store(minPowIdx, val) 270 whisper.notifyPeersAboutPowRequirementChange(val) 271 whisper.settings.Store(minPowToleranceIdx, val) 272 } 273 274 func (whisper *Whisper) notifyPeersAboutPowRequirementChange(pow float64) { 275 arr := whisper.getPeers() 276 for _, p := range arr { 277 err := p.notifyAboutPowRequirementChange(pow) 278 if err != nil { 279 // allow one retry 280 err = p.notifyAboutPowRequirementChange(pow) 281 } 282 if err != nil { 283 log.Warn("failed to notify peer about new pow requirement", "peer", p.ID(), "error", err) 284 } 285 } 286 } 287 288 func (whisper *Whisper) notifyPeersAboutBloomFilterChange(bloom []byte) { 289 arr := whisper.getPeers() 290 for _, p := range arr { 291 err := p.notifyAboutBloomFilterChange(bloom) 292 if err != nil { 293 // allow one retry 294 err = p.notifyAboutBloomFilterChange(bloom) 295 } 296 if err != nil { 297 log.Warn("failed to notify peer about new bloom filter", "peer", p.ID(), "error", err) 298 } 299 } 300 } 301 302 func (whisper *Whisper) getPeers() []*Peer { 303 arr := make([]*Peer, len(whisper.peers)) 304 i := 0 305 whisper.peerMu.Lock() 306 for p := range whisper.peers { 307 arr[i] = p 308 i++ 309 } 310 whisper.peerMu.Unlock() 311 return arr 312 } 313 314 // getPeer retrieves peer by ID 315 func (whisper *Whisper) getPeer(peerID []byte) (*Peer, error) { 316 whisper.peerMu.Lock() 317 defer whisper.peerMu.Unlock() 318 for p := range whisper.peers { 319 id := p.peer.ID() 320 if bytes.Equal(peerID, id[:]) { 321 return p, nil 322 } 323 } 324 return nil, fmt.Errorf("Could not find peer with ID: %x", peerID) 325 } 326 327 // AllowP2PMessagesFromPeer marks specific peer trusted, 328 // which will allow it to send historic (expired) messages. 329 func (whisper *Whisper) AllowP2PMessagesFromPeer(peerID []byte) error { 330 p, err := whisper.getPeer(peerID) 331 if err != nil { 332 return err 333 } 334 p.trusted = true 335 return nil 336 } 337 338 // RequestHistoricMessages sends a message with p2pRequestCode to a specific peer, 339 // which is known to implement MailServer interface, and is supposed to process this 340 // request and respond with a number of peer-to-peer messages (possibly expired), 341 // which are not supposed to be forwarded any further. 342 // The whisper protocol is agnostic of the format and contents of envelope. 343 func (whisper *Whisper) RequestHistoricMessages(peerID []byte, envelope *Envelope) error { 344 p, err := whisper.getPeer(peerID) 345 if err != nil { 346 return err 347 } 348 p.trusted = true 349 return p2p.Send(p.ws, p2pRequestCode, envelope) 350 } 351 352 // SendP2PMessage sends a peer-to-peer message to a specific peer. 353 func (whisper *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error { 354 p, err := whisper.getPeer(peerID) 355 if err != nil { 356 return err 357 } 358 return whisper.SendP2PDirect(p, envelope) 359 } 360 361 // SendP2PDirect sends a peer-to-peer message to a specific peer. 362 func (whisper *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error { 363 return p2p.Send(peer.ws, p2pMessageCode, envelope) 364 } 365 366 // NewKeyPair generates a new cryptographic identity for the client, and injects 367 // it into the known identities for message decryption. Returns ID of the new key pair. 368 func (whisper *Whisper) NewKeyPair() (string, error) { 369 key, err := crypto.GenerateKey() 370 if err != nil || !validatePrivateKey(key) { 371 key, err = crypto.GenerateKey() // retry once 372 } 373 if err != nil { 374 return "", err 375 } 376 if !validatePrivateKey(key) { 377 return "", fmt.Errorf("failed to generate valid key") 378 } 379 380 id, err := GenerateRandomID() 381 if err != nil { 382 return "", fmt.Errorf("failed to generate ID: %s", err) 383 } 384 385 whisper.keyMu.Lock() 386 defer whisper.keyMu.Unlock() 387 388 if whisper.privateKeys[id] != nil { 389 return "", fmt.Errorf("failed to generate unique ID") 390 } 391 whisper.privateKeys[id] = key 392 return id, nil 393 } 394 395 // DeleteKeyPair deletes the specified key if it exists. 396 func (whisper *Whisper) DeleteKeyPair(key string) bool { 397 whisper.keyMu.Lock() 398 defer whisper.keyMu.Unlock() 399 400 if whisper.privateKeys[key] != nil { 401 delete(whisper.privateKeys, key) 402 return true 403 } 404 return false 405 } 406 407 // AddKeyPair imports a asymmetric private key and returns it identifier. 408 func (whisper *Whisper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) { 409 id, err := GenerateRandomID() 410 if err != nil { 411 return "", fmt.Errorf("failed to generate ID: %s", err) 412 } 413 414 whisper.keyMu.Lock() 415 whisper.privateKeys[id] = key 416 whisper.keyMu.Unlock() 417 418 return id, nil 419 } 420 421 // HasKeyPair checks if the the whisper node is configured with the private key 422 // of the specified public pair. 423 func (whisper *Whisper) HasKeyPair(id string) bool { 424 whisper.keyMu.RLock() 425 defer whisper.keyMu.RUnlock() 426 return whisper.privateKeys[id] != nil 427 } 428 429 // GetPrivateKey retrieves the private key of the specified identity. 430 func (whisper *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) { 431 whisper.keyMu.RLock() 432 defer whisper.keyMu.RUnlock() 433 key := whisper.privateKeys[id] 434 if key == nil { 435 return nil, fmt.Errorf("invalid id") 436 } 437 return key, nil 438 } 439 440 // GenerateSymKey generates a random symmetric key and stores it under id, 441 // which is then returned. Will be used in the future for session key exchange. 442 func (whisper *Whisper) GenerateSymKey() (string, error) { 443 key, err := generateSecureRandomData(aesKeyLength) 444 if err != nil { 445 return "", err 446 } else if !validateDataIntegrity(key, aesKeyLength) { 447 return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data") 448 } 449 450 id, err := GenerateRandomID() 451 if err != nil { 452 return "", fmt.Errorf("failed to generate ID: %s", err) 453 } 454 455 whisper.keyMu.Lock() 456 defer whisper.keyMu.Unlock() 457 458 if whisper.symKeys[id] != nil { 459 return "", fmt.Errorf("failed to generate unique ID") 460 } 461 whisper.symKeys[id] = key 462 return id, nil 463 } 464 465 // AddSymKeyDirect stores the key, and returns its id. 466 func (whisper *Whisper) AddSymKeyDirect(key []byte) (string, error) { 467 if len(key) != aesKeyLength { 468 return "", fmt.Errorf("wrong key size: %d", len(key)) 469 } 470 471 id, err := GenerateRandomID() 472 if err != nil { 473 return "", fmt.Errorf("failed to generate ID: %s", err) 474 } 475 476 whisper.keyMu.Lock() 477 defer whisper.keyMu.Unlock() 478 479 if whisper.symKeys[id] != nil { 480 return "", fmt.Errorf("failed to generate unique ID") 481 } 482 whisper.symKeys[id] = key 483 return id, nil 484 } 485 486 // AddSymKeyFromPassword generates the key from password, stores it, and returns its id. 487 func (whisper *Whisper) AddSymKeyFromPassword(password string) (string, error) { 488 id, err := GenerateRandomID() 489 if err != nil { 490 return "", fmt.Errorf("failed to generate ID: %s", err) 491 } 492 if whisper.HasSymKey(id) { 493 return "", fmt.Errorf("failed to generate unique ID") 494 } 495 496 // kdf should run no less than 0.1 seconds on an average computer, 497 // because it's an once in a session experience 498 derived := pbkdf2.Key([]byte(password), nil, 65356, aesKeyLength, sha256.New) 499 if err != nil { 500 return "", err 501 } 502 503 whisper.keyMu.Lock() 504 defer whisper.keyMu.Unlock() 505 506 // double check is necessary, because deriveKeyMaterial() is very slow 507 if whisper.symKeys[id] != nil { 508 return "", fmt.Errorf("critical error: failed to generate unique ID") 509 } 510 whisper.symKeys[id] = derived 511 return id, nil 512 } 513 514 // HasSymKey returns true if there is a key associated with the given id. 515 // Otherwise returns false. 516 func (whisper *Whisper) HasSymKey(id string) bool { 517 whisper.keyMu.RLock() 518 defer whisper.keyMu.RUnlock() 519 return whisper.symKeys[id] != nil 520 } 521 522 // DeleteSymKey deletes the key associated with the name string if it exists. 523 func (whisper *Whisper) DeleteSymKey(id string) bool { 524 whisper.keyMu.Lock() 525 defer whisper.keyMu.Unlock() 526 if whisper.symKeys[id] != nil { 527 delete(whisper.symKeys, id) 528 return true 529 } 530 return false 531 } 532 533 // GetSymKey returns the symmetric key associated with the given id. 534 func (whisper *Whisper) GetSymKey(id string) ([]byte, error) { 535 whisper.keyMu.RLock() 536 defer whisper.keyMu.RUnlock() 537 if whisper.symKeys[id] != nil { 538 return whisper.symKeys[id], nil 539 } 540 return nil, fmt.Errorf("non-existent key ID") 541 } 542 543 // Subscribe installs a new message handler used for filtering, decrypting 544 // and subsequent storing of incoming messages. 545 func (whisper *Whisper) Subscribe(f *Filter) (string, error) { 546 s, err := whisper.filters.Install(f) 547 if err == nil { 548 whisper.updateBloomFilter(f) 549 } 550 return s, err 551 } 552 553 // updateBloomFilter recalculates the new value of bloom filter, 554 // and informs the peers if necessary. 555 func (whisper *Whisper) updateBloomFilter(f *Filter) { 556 aggregate := make([]byte, bloomFilterSize) 557 for _, t := range f.Topics { 558 top := BytesToTopic(t) 559 b := TopicToBloom(top) 560 aggregate = addBloom(aggregate, b) 561 } 562 563 if !bloomFilterMatch(whisper.BloomFilter(), aggregate) { 564 // existing bloom filter must be updated 565 aggregate = addBloom(whisper.BloomFilter(), aggregate) 566 whisper.SetBloomFilter(aggregate) 567 } 568 } 569 570 // GetFilter returns the filter by id. 571 func (whisper *Whisper) GetFilter(id string) *Filter { 572 return whisper.filters.Get(id) 573 } 574 575 // Unsubscribe removes an installed message handler. 576 func (whisper *Whisper) Unsubscribe(id string) error { 577 ok := whisper.filters.Uninstall(id) 578 if !ok { 579 return fmt.Errorf("Unsubscribe: Invalid ID") 580 } 581 return nil 582 } 583 584 // Send injects a message into the whisper send queue, to be distributed in the 585 // network in the coming cycles. 586 func (whisper *Whisper) Send(envelope *Envelope) error { 587 ok, err := whisper.add(envelope, false) 588 if err == nil && !ok { 589 return fmt.Errorf("failed to add envelope") 590 } 591 return err 592 } 593 594 // Start implements node.Service, starting the background data propagation thread 595 // of the Whisper protocol. 596 func (whisper *Whisper) Start(*p2p.Server) error { 597 log.Info("started whisper v." + ProtocolVersionStr) 598 go whisper.update() 599 600 numCPU := runtime.NumCPU() 601 for i := 0; i < numCPU; i++ { 602 go whisper.processQueue() 603 } 604 605 return nil 606 } 607 608 // Stop implements node.Service, stopping the background data propagation thread 609 // of the Whisper protocol. 610 func (whisper *Whisper) Stop() error { 611 close(whisper.quit) 612 log.Info("whisper stopped") 613 return nil 614 } 615 616 // HandlePeer is called by the underlying P2P layer when the whisper sub-protocol 617 // connection is negotiated. 618 func (whisper *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error { 619 // Create the new peer and start tracking it 620 whisperPeer := newPeer(whisper, peer, rw) 621 622 whisper.peerMu.Lock() 623 whisper.peers[whisperPeer] = struct{}{} 624 whisper.peerMu.Unlock() 625 626 defer func() { 627 whisper.peerMu.Lock() 628 delete(whisper.peers, whisperPeer) 629 whisper.peerMu.Unlock() 630 }() 631 632 // Run the peer handshake and state updates 633 if err := whisperPeer.handshake(); err != nil { 634 return err 635 } 636 whisperPeer.start() 637 defer whisperPeer.stop() 638 639 return whisper.runMessageLoop(whisperPeer, rw) 640 } 641 642 // runMessageLoop reads and processes inbound messages directly to merge into client-global state. 643 func (whisper *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { 644 for { 645 // fetch the next packet 646 packet, err := rw.ReadMsg() 647 if err != nil { 648 log.Warn("message loop", "peer", p.peer.ID(), "err", err) 649 return err 650 } 651 if packet.Size > whisper.MaxMessageSize() { 652 log.Warn("oversized message received", "peer", p.peer.ID()) 653 return errors.New("oversized message received") 654 } 655 656 switch packet.Code { 657 case statusCode: 658 // this should not happen, but no need to panic; just ignore this message. 659 log.Warn("unxepected status message received", "peer", p.peer.ID()) 660 case messagesCode: 661 // decode the contained envelopes 662 var envelopes []*Envelope 663 if err := packet.Decode(&envelopes); err != nil { 664 log.Warn("failed to decode envelopes, peer will be disconnected", "peer", p.peer.ID(), "err", err) 665 return errors.New("invalid envelopes") 666 } 667 668 trouble := false 669 for _, env := range envelopes { 670 cached, err := whisper.add(env, whisper.lightClient) 671 if err != nil { 672 trouble = true 673 log.Error("bad envelope received, peer will be disconnected", "peer", p.peer.ID(), "err", err) 674 } 675 if cached { 676 p.mark(env) 677 } 678 } 679 680 if trouble { 681 return errors.New("invalid envelope") 682 } 683 case powRequirementCode: 684 s := rlp.NewStream(packet.Payload, uint64(packet.Size)) 685 i, err := s.Uint() 686 if err != nil { 687 log.Warn("failed to decode powRequirementCode message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 688 return errors.New("invalid powRequirementCode message") 689 } 690 f := math.Float64frombits(i) 691 if math.IsInf(f, 0) || math.IsNaN(f) || f < 0.0 { 692 log.Warn("invalid value in powRequirementCode message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 693 return errors.New("invalid value in powRequirementCode message") 694 } 695 p.powRequirement = f 696 case bloomFilterExCode: 697 var bloom []byte 698 err := packet.Decode(&bloom) 699 if err == nil && len(bloom) != bloomFilterSize { 700 err = fmt.Errorf("wrong bloom filter size %d", len(bloom)) 701 } 702 703 if err != nil { 704 log.Warn("failed to decode bloom filter exchange message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 705 return errors.New("invalid bloom filter exchange message") 706 } 707 p.setBloomFilter(bloom) 708 case p2pMessageCode: 709 // peer-to-peer message, sent directly to peer bypassing PoW checks, etc. 710 // this message is not supposed to be forwarded to other peers, and 711 // therefore might not satisfy the PoW, expiry and other requirements. 712 // these messages are only accepted from the trusted peer. 713 if p.trusted { 714 var envelope Envelope 715 if err := packet.Decode(&envelope); err != nil { 716 log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 717 return errors.New("invalid direct message") 718 } 719 whisper.postEvent(&envelope, true) 720 } 721 case p2pRequestCode: 722 // Must be processed if mail server is implemented. Otherwise ignore. 723 if whisper.mailServer != nil { 724 var request Envelope 725 if err := packet.Decode(&request); err != nil { 726 log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.ID(), "err", err) 727 return errors.New("invalid p2p request") 728 } 729 whisper.mailServer.DeliverMail(p, &request) 730 } 731 default: 732 // New message types might be implemented in the future versions of Whisper. 733 // For forward compatibility, just ignore. 734 } 735 736 packet.Discard() 737 } 738 } 739 740 // add inserts a new envelope into the message pool to be distributed within the 741 // whisper network. It also inserts the envelope into the expiration pool at the 742 // appropriate time-stamp. In case of error, connection should be dropped. 743 // param isP2P indicates whether the message is peer-to-peer (should not be forwarded). 744 func (whisper *Whisper) add(envelope *Envelope, isP2P bool) (bool, error) { 745 now := uint32(time.Now().Unix()) 746 sent := envelope.Expiry - envelope.TTL 747 748 if sent > now { 749 if sent-DefaultSyncAllowance > now { 750 return false, fmt.Errorf("envelope created in the future [%x]", envelope.Hash()) 751 } 752 // recalculate PoW, adjusted for the time difference, plus one second for latency 753 envelope.calculatePoW(sent - now + 1) 754 } 755 756 if envelope.Expiry < now { 757 if envelope.Expiry+DefaultSyncAllowance*2 < now { 758 return false, fmt.Errorf("very old message") 759 } 760 log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex()) 761 return false, nil // drop envelope without error 762 } 763 764 if uint32(envelope.size()) > whisper.MaxMessageSize() { 765 return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash()) 766 } 767 768 if envelope.PoW() < whisper.MinPow() { 769 // maybe the value was recently changed, and the peers did not adjust yet. 770 // in this case the previous value is retrieved by MinPowTolerance() 771 // for a short period of peer synchronization. 772 if envelope.PoW() < whisper.MinPowTolerance() { 773 return false, fmt.Errorf("envelope with low PoW received: PoW=%f, hash=[%v]", envelope.PoW(), envelope.Hash().Hex()) 774 } 775 } 776 777 if !bloomFilterMatch(whisper.BloomFilter(), envelope.Bloom()) { 778 // maybe the value was recently changed, and the peers did not adjust yet. 779 // in this case the previous value is retrieved by BloomFilterTolerance() 780 // for a short period of peer synchronization. 781 if !bloomFilterMatch(whisper.BloomFilterTolerance(), envelope.Bloom()) { 782 return false, fmt.Errorf("envelope does not match bloom filter, hash=[%v], bloom: \n%x \n%x \n%x", 783 envelope.Hash().Hex(), whisper.BloomFilter(), envelope.Bloom(), envelope.Topic) 784 } 785 } 786 787 hash := envelope.Hash() 788 789 whisper.poolMu.Lock() 790 _, alreadyCached := whisper.envelopes[hash] 791 if !alreadyCached { 792 whisper.envelopes[hash] = envelope 793 if whisper.expirations[envelope.Expiry] == nil { 794 whisper.expirations[envelope.Expiry] = set.NewNonTS() 795 } 796 if !whisper.expirations[envelope.Expiry].Has(hash) { 797 whisper.expirations[envelope.Expiry].Add(hash) 798 } 799 } 800 whisper.poolMu.Unlock() 801 802 if alreadyCached { 803 log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex()) 804 } else { 805 log.Trace("cached whisper envelope", "hash", envelope.Hash().Hex()) 806 whisper.statsMu.Lock() 807 whisper.stats.memoryUsed += envelope.size() 808 whisper.statsMu.Unlock() 809 whisper.postEvent(envelope, isP2P) // notify the local node about the new message 810 if whisper.mailServer != nil { 811 whisper.mailServer.Archive(envelope) 812 } 813 } 814 return true, nil 815 } 816 817 // postEvent queues the message for further processing. 818 func (whisper *Whisper) postEvent(envelope *Envelope, isP2P bool) { 819 if isP2P { 820 whisper.p2pMsgQueue <- envelope 821 } else { 822 whisper.checkOverflow() 823 whisper.messageQueue <- envelope 824 } 825 } 826 827 // checkOverflow checks if message queue overflow occurs and reports it if necessary. 828 func (whisper *Whisper) checkOverflow() { 829 queueSize := len(whisper.messageQueue) 830 831 if queueSize == messageQueueLimit { 832 if !whisper.Overflow() { 833 whisper.settings.Store(overflowIdx, true) 834 log.Warn("message queue overflow") 835 } 836 } else if queueSize <= messageQueueLimit/2 { 837 if whisper.Overflow() { 838 whisper.settings.Store(overflowIdx, false) 839 log.Warn("message queue overflow fixed (back to normal)") 840 } 841 } 842 } 843 844 // processQueue delivers the messages to the watchers during the lifetime of the whisper node. 845 func (whisper *Whisper) processQueue() { 846 var e *Envelope 847 for { 848 select { 849 case <-whisper.quit: 850 return 851 852 case e = <-whisper.messageQueue: 853 whisper.filters.NotifyWatchers(e, false) 854 855 case e = <-whisper.p2pMsgQueue: 856 whisper.filters.NotifyWatchers(e, true) 857 } 858 } 859 } 860 861 // update loops until the lifetime of the whisper node, updating its internal 862 // state by expiring stale messages from the pool. 863 func (whisper *Whisper) update() { 864 // Start a ticker to check for expirations 865 expire := time.NewTicker(expirationCycle) 866 867 // Repeat updates until termination is requested 868 for { 869 select { 870 case <-expire.C: 871 whisper.expire() 872 873 case <-whisper.quit: 874 return 875 } 876 } 877 } 878 879 // expire iterates over all the expiration timestamps, removing all stale 880 // messages from the pools. 881 func (whisper *Whisper) expire() { 882 whisper.poolMu.Lock() 883 defer whisper.poolMu.Unlock() 884 885 whisper.statsMu.Lock() 886 defer whisper.statsMu.Unlock() 887 whisper.stats.reset() 888 now := uint32(time.Now().Unix()) 889 for expiry, hashSet := range whisper.expirations { 890 if expiry < now { 891 // Dump all expired messages and remove timestamp 892 hashSet.Each(func(v interface{}) bool { 893 sz := whisper.envelopes[v.(common.Hash)].size() 894 delete(whisper.envelopes, v.(common.Hash)) 895 whisper.stats.messagesCleared++ 896 whisper.stats.memoryCleared += sz 897 whisper.stats.memoryUsed -= sz 898 return true 899 }) 900 whisper.expirations[expiry].Clear() 901 delete(whisper.expirations, expiry) 902 } 903 } 904 } 905 906 // Stats returns the whisper node statistics. 907 func (whisper *Whisper) Stats() Statistics { 908 whisper.statsMu.Lock() 909 defer whisper.statsMu.Unlock() 910 911 return whisper.stats 912 } 913 914 // Envelopes retrieves all the messages currently pooled by the node. 915 func (whisper *Whisper) Envelopes() []*Envelope { 916 whisper.poolMu.RLock() 917 defer whisper.poolMu.RUnlock() 918 919 all := make([]*Envelope, 0, len(whisper.envelopes)) 920 for _, envelope := range whisper.envelopes { 921 all = append(all, envelope) 922 } 923 return all 924 } 925 926 // Messages iterates through all currently floating envelopes 927 // and retrieves all the messages, that this filter could decrypt. 928 func (whisper *Whisper) Messages(id string) []*ReceivedMessage { 929 result := make([]*ReceivedMessage, 0) 930 whisper.poolMu.RLock() 931 defer whisper.poolMu.RUnlock() 932 933 if filter := whisper.filters.Get(id); filter != nil { 934 for _, env := range whisper.envelopes { 935 msg := filter.processEnvelope(env) 936 if msg != nil { 937 result = append(result, msg) 938 } 939 } 940 } 941 return result 942 } 943 944 // isEnvelopeCached checks if envelope with specific hash has already been received and cached. 945 func (whisper *Whisper) isEnvelopeCached(hash common.Hash) bool { 946 whisper.poolMu.Lock() 947 defer whisper.poolMu.Unlock() 948 949 _, exist := whisper.envelopes[hash] 950 return exist 951 } 952 953 // reset resets the node's statistics after each expiry cycle. 954 func (s *Statistics) reset() { 955 s.cycles++ 956 s.totalMessagesCleared += s.messagesCleared 957 958 s.memoryCleared = 0 959 s.messagesCleared = 0 960 } 961 962 // ValidatePublicKey checks the format of the given public key. 963 func ValidatePublicKey(k *ecdsa.PublicKey) bool { 964 return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0 965 } 966 967 // validatePrivateKey checks the format of the given private key. 968 func validatePrivateKey(k *ecdsa.PrivateKey) bool { 969 if k == nil || k.D == nil || k.D.Sign() == 0 { 970 return false 971 } 972 return ValidatePublicKey(&k.PublicKey) 973 } 974 975 // validateDataIntegrity returns false if the data have the wrong or contains all zeros, 976 // which is the simplest and the most common bug. 977 func validateDataIntegrity(k []byte, expectedSize int) bool { 978 if len(k) != expectedSize { 979 return false 980 } 981 if expectedSize > 3 && containsOnlyZeros(k) { 982 return false 983 } 984 return true 985 } 986 987 // containsOnlyZeros checks if the data contain only zeros. 988 func containsOnlyZeros(data []byte) bool { 989 for _, b := range data { 990 if b != 0 { 991 return false 992 } 993 } 994 return true 995 } 996 997 // bytesToUintLittleEndian converts the slice to 64-bit unsigned integer. 998 func bytesToUintLittleEndian(b []byte) (res uint64) { 999 mul := uint64(1) 1000 for i := 0; i < len(b); i++ { 1001 res += uint64(b[i]) * mul 1002 mul *= 256 1003 } 1004 return res 1005 } 1006 1007 // BytesToUintBigEndian converts the slice to 64-bit unsigned integer. 1008 func BytesToUintBigEndian(b []byte) (res uint64) { 1009 for i := 0; i < len(b); i++ { 1010 res *= 256 1011 res += uint64(b[i]) 1012 } 1013 return res 1014 } 1015 1016 // GenerateRandomID generates a random string, which is then returned to be used as a key id 1017 func GenerateRandomID() (id string, err error) { 1018 buf, err := generateSecureRandomData(keyIDSize) 1019 if err != nil { 1020 return "", err 1021 } 1022 if !validateDataIntegrity(buf, keyIDSize) { 1023 return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data") 1024 } 1025 id = common.Bytes2Hex(buf) 1026 return id, err 1027 } 1028 1029 func isFullNode(bloom []byte) bool { 1030 if bloom == nil { 1031 return true 1032 } 1033 for _, b := range bloom { 1034 if b != 255 { 1035 return false 1036 } 1037 } 1038 return true 1039 } 1040 1041 func bloomFilterMatch(filter, sample []byte) bool { 1042 if filter == nil { 1043 return true 1044 } 1045 1046 for i := 0; i < bloomFilterSize; i++ { 1047 f := filter[i] 1048 s := sample[i] 1049 if (f | s) != f { 1050 return false 1051 } 1052 } 1053 1054 return true 1055 } 1056 1057 func addBloom(a, b []byte) []byte { 1058 c := make([]byte, bloomFilterSize) 1059 for i := 0; i < bloomFilterSize; i++ { 1060 c[i] = a[i] | b[i] 1061 } 1062 return c 1063 }