github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/pss/pss.go (about)

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