github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/pss/pss.go (about)

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