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