gopkg.in/dedis/onet.v2@v2.0.0-20181115163211-c8f3724038a7/overlay.go (about)

     1  package onet
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"sync"
     7  	"time"
     8  
     9  	"gopkg.in/dedis/onet.v2/log"
    10  	"gopkg.in/dedis/onet.v2/network"
    11  	"gopkg.in/satori/go.uuid.v1"
    12  )
    13  
    14  const expirationTime = 1 * time.Minute
    15  const cacheSize = 1000
    16  
    17  // Overlay keeps all trees and entity-lists for a given Server. It creates
    18  // Nodes and ProtocolInstances upon request and dispatches the messages.
    19  type Overlay struct {
    20  	server *Server
    21  
    22  	treeCache   *treeCacheTTL
    23  	rosterCache *rosterCacheTTL
    24  	// cache for relating token(~Node) to TreeNode
    25  	treeNodeCache *treeNodeCacheTTL
    26  
    27  	// TreeNodeInstance part
    28  	instances         map[TokenID]*TreeNodeInstance
    29  	instancesInfo     map[TokenID]bool
    30  	instancesLock     sync.Mutex
    31  	protocolInstances map[TokenID]ProtocolInstance
    32  
    33  	// treeMarshal that needs to be converted to Tree but host does not have the
    34  	// entityList associated yet.
    35  	// map from Roster.ID => trees that use this entity list
    36  	pendingTreeMarshal map[RosterID][]*TreeMarshal
    37  	// lock associated with pending TreeMarshal
    38  	pendingTreeLock sync.Mutex
    39  
    40  	// pendingMsg is a list of message we received that does not correspond
    41  	// to any local Tree or/and Roster. We first request theses so we can
    42  	// instantiate properly protocolInstance that will use these ProtocolMsg msg.
    43  	pendingMsg []pendingMsg
    44  	// lock associated with pending ProtocolMsg
    45  	pendingMsgLock sync.Mutex
    46  
    47  	transmitMux sync.Mutex
    48  
    49  	protoIO *messageProxyStore
    50  
    51  	pendingConfigs    map[TokenID]*GenericConfig
    52  	pendingConfigsMut sync.Mutex
    53  }
    54  
    55  // NewOverlay creates a new overlay-structure
    56  func NewOverlay(c *Server) *Overlay {
    57  	o := &Overlay{
    58  		server:             c,
    59  		treeCache:          newTreeCache(expirationTime, cacheSize),
    60  		rosterCache:        newRosterCache(expirationTime, cacheSize),
    61  		treeNodeCache:      newTreeNodeCache(expirationTime, cacheSize),
    62  		instances:          make(map[TokenID]*TreeNodeInstance),
    63  		instancesInfo:      make(map[TokenID]bool),
    64  		protocolInstances:  make(map[TokenID]ProtocolInstance),
    65  		pendingTreeMarshal: make(map[RosterID][]*TreeMarshal),
    66  		pendingConfigs:     make(map[TokenID]*GenericConfig),
    67  	}
    68  	o.protoIO = newMessageProxyStore(c.suite, c, o)
    69  	// messages going to protocol instances
    70  	c.RegisterProcessor(o,
    71  		ProtocolMsgID,      // protocol instance's messages
    72  		RequestTreeMsgID,   // request a tree
    73  		SendTreeMsgID,      // send a tree back to a request
    74  		RequestRosterMsgID, // request a roster
    75  		SendRosterMsgID,    // send a roster back to request
    76  		ConfigMsgID)        // fetch config information
    77  	return o
    78  }
    79  
    80  // Process implements the Processor interface so it process the messages that it
    81  // wants.
    82  func (o *Overlay) Process(env *network.Envelope) {
    83  	// Messages handled by the overlay directly without any messageProxyIO
    84  	if env.MsgType.Equal(ConfigMsgID) {
    85  		o.handleConfigMessage(env)
    86  		return
    87  	}
    88  
    89  	// get messageProxy or default one
    90  	io := o.protoIO.getByPacketType(env.MsgType)
    91  	inner, info, err := io.Unwrap(env.Msg)
    92  	if err != nil {
    93  		log.Error("unwrapping: ", err)
    94  		return
    95  	}
    96  	switch {
    97  	case info.RequestTree != nil:
    98  		o.handleRequestTree(env.ServerIdentity, info.RequestTree, io)
    99  	case info.TreeMarshal != nil:
   100  		o.handleSendTree(env.ServerIdentity, info.TreeMarshal, io)
   101  	case info.RequestRoster != nil:
   102  		o.handleRequestRoster(env.ServerIdentity, info.RequestRoster, io)
   103  	case info.Roster != nil:
   104  		o.handleSendRoster(env.ServerIdentity, info.Roster)
   105  	default:
   106  		typ := network.MessageType(inner)
   107  		protoMsg := &ProtocolMsg{
   108  			From:           info.TreeNodeInfo.From,
   109  			To:             info.TreeNodeInfo.To,
   110  			ServerIdentity: env.ServerIdentity,
   111  			Msg:            inner,
   112  			MsgType:        typ,
   113  			Size:           env.Size,
   114  		}
   115  		err = o.TransmitMsg(protoMsg, io)
   116  		if err != nil {
   117  			log.Errorf("Msg %s from %s produced error: %s", protoMsg.MsgType,
   118  				protoMsg.ServerIdentity, err.Error())
   119  		}
   120  	}
   121  }
   122  
   123  // TransmitMsg takes a message received from the host and treats it. It might
   124  // - ask for the identityList
   125  // - ask for the Tree
   126  // - create a new protocolInstance
   127  // - pass it to a given protocolInstance
   128  // io is the messageProxy to use if a specific wireformat protocol is used.
   129  // It can be nil: in that case it fall backs to default wire protocol.
   130  func (o *Overlay) TransmitMsg(onetMsg *ProtocolMsg, io MessageProxy) error {
   131  	tree := o.treeCache.Get(onetMsg.To.TreeID)
   132  	if tree == nil {
   133  		return o.requestTree(onetMsg.ServerIdentity, onetMsg, io)
   134  	}
   135  
   136  	o.transmitMux.Lock()
   137  	defer o.transmitMux.Unlock()
   138  	// TreeNodeInstance
   139  	var pi ProtocolInstance
   140  	o.instancesLock.Lock()
   141  	pi, ok := o.protocolInstances[onetMsg.To.ID()]
   142  	done := o.instancesInfo[onetMsg.To.ID()]
   143  	o.instancesLock.Unlock()
   144  	if done {
   145  		log.Lvl5("Message for TreeNodeInstance that is already finished")
   146  		return nil
   147  	}
   148  	// if the TreeNodeInstance is not there, creates it
   149  	if !ok {
   150  		log.Lvlf4("Creating TreeNodeInstance at %s %x", o.server.ServerIdentity, onetMsg.To.ID())
   151  		tn, err := o.TreeNodeFromToken(onetMsg.To)
   152  		if err != nil {
   153  			return errors.New("No TreeNode defined in this tree here")
   154  		}
   155  		tni := o.newTreeNodeInstanceFromToken(tn, onetMsg.To, io)
   156  		// retrieve the possible generic config for this message
   157  		config := o.getConfig(onetMsg.To.ID())
   158  		// request the PI from the Service and binds the two
   159  		pi, err = o.server.serviceManager.newProtocol(tni, config)
   160  		if err != nil {
   161  			return err
   162  		}
   163  		if pi == nil {
   164  			return nil
   165  		}
   166  		go pi.Dispatch()
   167  		if err := o.RegisterProtocolInstance(pi); err != nil {
   168  			return errors.New("Error Binding TreeNodeInstance and ProtocolInstance:" +
   169  				err.Error())
   170  		}
   171  		log.Lvl4(o.server.Address(), "Overlay created new ProtocolInstace msg => ",
   172  			fmt.Sprintf("%+v", onetMsg.To))
   173  	}
   174  	// TODO Check if TreeNodeInstance is already Done
   175  	pi.ProcessProtocolMsg(onetMsg)
   176  	return nil
   177  }
   178  
   179  // addPendingTreeMarshal adds a treeMarshal to the list.
   180  // This list is checked each time we receive a new Roster
   181  // so trees using this Roster can be constructed.
   182  func (o *Overlay) addPendingTreeMarshal(tm *TreeMarshal) {
   183  	o.pendingTreeLock.Lock()
   184  	var sl []*TreeMarshal
   185  	var ok bool
   186  	// initiate the slice before adding
   187  	if sl, ok = o.pendingTreeMarshal[tm.RosterID]; !ok {
   188  		sl = make([]*TreeMarshal, 0)
   189  	}
   190  	sl = append(sl, tm)
   191  	o.pendingTreeMarshal[tm.RosterID] = sl
   192  	o.pendingTreeLock.Unlock()
   193  }
   194  
   195  // checkPendingMessages is called each time we receive a new tree if there are
   196  // some pending ProtocolMessage messages using this tree. If there are, we can
   197  // make an instance of a protocolinstance and give it the message.
   198  func (o *Overlay) checkPendingMessages(t *Tree) {
   199  	go func() {
   200  		o.pendingMsgLock.Lock()
   201  
   202  		var newPending []pendingMsg
   203  		var remaining []pendingMsg
   204  		// Keep msg not related to that tree in the pending list
   205  		for _, msg := range o.pendingMsg {
   206  			if t.ID.Equal(msg.To.TreeID) {
   207  				remaining = append(remaining, msg)
   208  			} else {
   209  				newPending = append(newPending, msg)
   210  			}
   211  		}
   212  
   213  		o.pendingMsg = newPending
   214  		o.pendingMsgLock.Unlock()
   215  
   216  		for _, msg := range remaining {
   217  			err := o.TransmitMsg(msg.ProtocolMsg, msg.MessageProxy)
   218  			if err != nil {
   219  				log.Error("TransmitMsg failed:", err)
   220  				continue
   221  			}
   222  		}
   223  	}()
   224  }
   225  
   226  // checkPendingTreeMarshal is called each time we add a new Roster to the
   227  // system. It checks if some treeMarshal use this entityList so they can be
   228  // converted to Tree.
   229  func (o *Overlay) checkPendingTreeMarshal(el *Roster) {
   230  	o.pendingTreeLock.Lock()
   231  	sl, ok := o.pendingTreeMarshal[el.ID]
   232  	if !ok {
   233  		// no tree for this entitty list
   234  		return
   235  	}
   236  	for _, tm := range sl {
   237  		tree, err := tm.MakeTree(el)
   238  		if err != nil {
   239  			log.Error("Tree from Roster failed")
   240  			continue
   241  		}
   242  		// add the tree into our "database"
   243  		o.RegisterTree(tree)
   244  	}
   245  	o.pendingTreeLock.Unlock()
   246  }
   247  
   248  func (o *Overlay) savePendingMsg(onetMsg *ProtocolMsg, io MessageProxy) {
   249  	o.pendingMsgLock.Lock()
   250  	o.pendingMsg = append(o.pendingMsg, pendingMsg{
   251  		ProtocolMsg:  onetMsg,
   252  		MessageProxy: io,
   253  	})
   254  	o.pendingMsgLock.Unlock()
   255  
   256  }
   257  
   258  // requestTree will ask for the tree the ProtocolMessage is related to.
   259  // it will put the message inside the pending list of ProtocolMessage waiting to
   260  // have their trees.
   261  // io is the wrapper to use to send the message, it can be nil.
   262  func (o *Overlay) requestTree(si *network.ServerIdentity, onetMsg *ProtocolMsg, io MessageProxy) error {
   263  	o.savePendingMsg(onetMsg, io)
   264  
   265  	var msg interface{}
   266  	om := &OverlayMsg{
   267  		RequestTree: &RequestTree{onetMsg.To.TreeID},
   268  	}
   269  	msg, err := io.Wrap(nil, om)
   270  	if err != nil {
   271  		return err
   272  	}
   273  
   274  	// no need to record sentLen because Overlay uses Server's CounterIO
   275  	_, err = o.server.Send(si, msg)
   276  	return err
   277  }
   278  
   279  // RegisterTree takes a tree and puts it in the map
   280  func (o *Overlay) RegisterTree(t *Tree) {
   281  	o.treeCache.Set(t)
   282  	o.checkPendingMessages(t)
   283  }
   284  
   285  // RegisterRoster puts an entityList in the map
   286  func (o *Overlay) RegisterRoster(r *Roster) {
   287  	o.rosterCache.Set(r)
   288  }
   289  
   290  // TreeNodeFromToken returns the treeNode corresponding to a token
   291  func (o *Overlay) TreeNodeFromToken(t *Token) (*TreeNode, error) {
   292  	if t == nil {
   293  		return nil, errors.New("didn't find tree-node: No token given")
   294  	}
   295  	// First, check the cache
   296  	if tn := o.treeNodeCache.GetFromToken(t); tn != nil {
   297  		return tn, nil
   298  	}
   299  	// If cache has not, then search the tree
   300  	tree := o.treeCache.Get(t.TreeID)
   301  	if tree == nil {
   302  		return nil, errors.New("didn't find tree")
   303  	}
   304  	tn := tree.Search(t.TreeNodeID)
   305  	if tn == nil {
   306  		return nil, errors.New("didn't find treenode")
   307  	}
   308  	// Since we found treeNode, cache it.
   309  	o.treeNodeCache.Set(tree, tn)
   310  	return tn, nil
   311  }
   312  
   313  // Rx implements the CounterIO interface, should be the same as the server
   314  func (o *Overlay) Rx() uint64 {
   315  	return o.server.Rx()
   316  }
   317  
   318  // Tx implements the CounterIO interface, should be the same as the server
   319  func (o *Overlay) Tx() uint64 {
   320  	return o.server.Tx()
   321  }
   322  
   323  func (o *Overlay) handleRequestTree(si *network.ServerIdentity, req *RequestTree, io MessageProxy) {
   324  	tid := req.TreeID
   325  	tree := o.treeCache.Get(tid)
   326  	var err error
   327  	var treeM *TreeMarshal
   328  	var msg interface{}
   329  	if tree != nil {
   330  		treeM = tree.MakeTreeMarshal()
   331  	} else {
   332  		// XXX Take care here for we must verify at the other side that
   333  		// the tree is Nil. Should we think of a way of sending back an
   334  		// "error" ?
   335  		treeM = (&Tree{}).MakeTreeMarshal()
   336  	}
   337  	msg, err = io.Wrap(nil, &OverlayMsg{
   338  		TreeMarshal: treeM,
   339  	})
   340  
   341  	if err != nil {
   342  		log.Error("couldn't wrap TreeMarshal:", err)
   343  		return
   344  	}
   345  
   346  	_, err = o.server.Send(si, msg)
   347  	if err != nil {
   348  		log.Error("Couldn't send tree:", err)
   349  	}
   350  }
   351  
   352  func (o *Overlay) handleSendTree(si *network.ServerIdentity, tm *TreeMarshal, io MessageProxy) {
   353  	if tm.TreeID.IsNil() {
   354  		log.Error("Received an empty Tree")
   355  		return
   356  	}
   357  	roster := o.rosterCache.Get(tm.RosterID)
   358  	// The roster does not exists, we should request that, too
   359  	if roster == nil {
   360  		msg, err := io.Wrap(nil, &OverlayMsg{
   361  			RequestRoster: &RequestRoster{tm.RosterID},
   362  		})
   363  		if err != nil {
   364  			log.Error("could not wrap RequestRoster:", err)
   365  		}
   366  		if _, err := o.server.Send(si, msg); err != nil {
   367  			log.Error("Requesting Roster in SendTree failed", err)
   368  		}
   369  		// put the tree marshal into pending queue so when we receive the
   370  		// entitylist we can create the real Tree.
   371  		o.addPendingTreeMarshal(tm)
   372  		return
   373  	}
   374  
   375  	tree, err := tm.MakeTree(roster)
   376  	if err != nil {
   377  		log.Error("Couldn't create tree:", err)
   378  		return
   379  	}
   380  	log.Lvl4("Received new tree")
   381  	o.RegisterTree(tree)
   382  }
   383  
   384  func (o *Overlay) handleRequestRoster(si *network.ServerIdentity, req *RequestRoster, io MessageProxy) {
   385  	id := req.RosterID
   386  	roster := o.rosterCache.Get(id)
   387  	var err error
   388  	var msg interface{}
   389  	if roster == nil {
   390  		// XXX Bad reaction to request...
   391  		log.Lvl2("Requested entityList that we don't have")
   392  		roster = &Roster{}
   393  	}
   394  
   395  	msg, err = io.Wrap(nil, &OverlayMsg{
   396  		Roster: roster,
   397  	})
   398  
   399  	if err != nil {
   400  		log.Error("error wraping up roster:", err)
   401  		return
   402  	}
   403  
   404  	_, err = o.server.Send(si, msg)
   405  	if err != nil {
   406  		log.Error("Couldn't send empty entity list from host:",
   407  			o.server.ServerIdentity.String(),
   408  			err)
   409  		return
   410  	}
   411  }
   412  
   413  func (o *Overlay) handleSendRoster(si *network.ServerIdentity, roster *Roster) {
   414  	if roster.ID.IsNil() {
   415  		log.Lvl2("Received an empty Roster")
   416  	} else {
   417  		o.RegisterRoster(roster)
   418  		// Check if some trees can be constructed from this entitylist
   419  		o.checkPendingTreeMarshal(roster)
   420  	}
   421  	log.Lvl4("Received new entityList")
   422  }
   423  
   424  // handleConfigMessage stores the config message so it can be dispatched
   425  // alongside with the protocol message later to the service.
   426  func (o *Overlay) handleConfigMessage(env *network.Envelope) {
   427  	config, ok := env.Msg.(*ConfigMsg)
   428  	if !ok {
   429  		// This should happen only if a bad packet gets through
   430  		log.Error(o.server.Address(), "Wrong config type, most likely invalid packet got through.")
   431  		return
   432  	}
   433  
   434  	o.pendingConfigsMut.Lock()
   435  	defer o.pendingConfigsMut.Unlock()
   436  	o.pendingConfigs[config.Dest] = &config.Config
   437  }
   438  
   439  // getConfig returns the generic config corresponding to this node if present,
   440  // and removes it from the list of pending configs.
   441  func (o *Overlay) getConfig(id TokenID) *GenericConfig {
   442  	o.pendingConfigsMut.Lock()
   443  	defer o.pendingConfigsMut.Unlock()
   444  	c := o.pendingConfigs[id]
   445  	delete(o.pendingConfigs, id)
   446  	return c
   447  }
   448  
   449  // SendToTreeNode sends a message to a treeNode
   450  // from is the sender token
   451  // to is the treenode of the destination
   452  // msg is the message to send
   453  // io is the messageproxy used to correctly create the wire format
   454  // c is the generic config that should be sent beforehand in order to get passed
   455  // in the `NewProtocol` method if a Service has created the protocol and set the
   456  // config with `SetConfig`. It can be nil.
   457  func (o *Overlay) SendToTreeNode(from *Token, to *TreeNode, msg network.Message, io MessageProxy, c *GenericConfig) (uint64, error) {
   458  	tokenTo := from.ChangeTreeNodeID(to.ID)
   459  	var totSentLen uint64
   460  
   461  	// first send the config if present
   462  	if c != nil {
   463  		sentLen, err := o.server.Send(to.ServerIdentity, &ConfigMsg{*c, tokenTo.ID()})
   464  		totSentLen += sentLen
   465  		if err != nil {
   466  			log.Error("sending config failed:", err)
   467  			return totSentLen, err
   468  		}
   469  	}
   470  	// then send the message
   471  	var final interface{}
   472  	info := &OverlayMsg{
   473  		TreeNodeInfo: &TreeNodeInfo{
   474  			From: from,
   475  			To:   tokenTo,
   476  		},
   477  	}
   478  	final, err := io.Wrap(msg, info)
   479  	if err != nil {
   480  		return totSentLen, err
   481  	}
   482  
   483  	sentLen, err := o.server.Send(to.ServerIdentity, final)
   484  	totSentLen += sentLen
   485  	return totSentLen, err
   486  }
   487  
   488  // nodeDone is called by node to signify that its work is finished and its
   489  // ressources can be released
   490  func (o *Overlay) nodeDone(tok *Token) {
   491  	o.instancesLock.Lock()
   492  	o.nodeDelete(tok)
   493  	o.instancesLock.Unlock()
   494  }
   495  
   496  // nodeDelete needs to be separated from nodeDone, as it is also called from
   497  // Close, but due to locking-issues here we don't lock.
   498  func (o *Overlay) nodeDelete(token *Token) {
   499  	tok := token.ID()
   500  	tni, ok := o.instances[tok]
   501  	if !ok {
   502  		log.Lvlf2("Node %s already gone", tok)
   503  		return
   504  	}
   505  	log.Lvl4("Closing node", tok)
   506  	err := tni.closeDispatch()
   507  	if err != nil {
   508  		log.Error("Error while closing node:", err)
   509  	}
   510  	delete(o.protocolInstances, tok)
   511  	delete(o.instances, tok)
   512  	// mark it done !
   513  	o.instancesInfo[tok] = true
   514  }
   515  
   516  func (o *Overlay) suite() network.Suite {
   517  	return o.server.Suite()
   518  }
   519  
   520  // Close calls all nodes, deletes them from the list and closes them
   521  func (o *Overlay) Close() {
   522  	o.instancesLock.Lock()
   523  	defer o.instancesLock.Unlock()
   524  	for _, tni := range o.instances {
   525  		log.Lvl4(o.server.Address(), "Closing TNI", tni.TokenID())
   526  		o.nodeDelete(tni.Token())
   527  	}
   528  }
   529  
   530  // CreateProtocol creates a ProtocolInstance, registers it to the Overlay.
   531  // Additionally, if sid is different than NilServiceID, sid is added to the token
   532  // so the protocol will be picked up by the correct service and handled by its
   533  // NewProtocol method. If the sid is NilServiceID, then the protocol is handled by onet alone.
   534  func (o *Overlay) CreateProtocol(name string, t *Tree, sid ServiceID) (ProtocolInstance, error) {
   535  	io := o.protoIO.getByName(name)
   536  	tni := o.NewTreeNodeInstanceFromService(t, t.Root, ProtocolNameToID(name), sid, io)
   537  	pi, err := o.server.protocolInstantiate(tni.token.ProtoID, tni)
   538  	if err != nil {
   539  		return nil, err
   540  	}
   541  	if err = o.RegisterProtocolInstance(pi); err != nil {
   542  		return nil, err
   543  	}
   544  	go func() {
   545  		err := pi.Dispatch()
   546  		if err != nil {
   547  			log.Errorf("%s.Dispatch() created in service %s returned error %s",
   548  				name, ServiceFactory.Name(sid), err)
   549  		}
   550  	}()
   551  	return pi, err
   552  }
   553  
   554  // StartProtocol will create and start a ProtocolInstance.
   555  func (o *Overlay) StartProtocol(name string, t *Tree, sid ServiceID) (ProtocolInstance, error) {
   556  	pi, err := o.CreateProtocol(name, t, sid)
   557  	if err != nil {
   558  		return nil, err
   559  	}
   560  	go func() {
   561  		err := pi.Start()
   562  		if err != nil {
   563  			log.Error("Error while starting:", err)
   564  		}
   565  	}()
   566  	return pi, err
   567  }
   568  
   569  // NewTreeNodeInstanceFromProtoName takes a protocol name and a tree and
   570  // instantiate a TreeNodeInstance for this protocol.
   571  func (o *Overlay) NewTreeNodeInstanceFromProtoName(t *Tree, name string) *TreeNodeInstance {
   572  	io := o.protoIO.getByName(name)
   573  	return o.NewTreeNodeInstanceFromProtocol(t, t.Root, ProtocolNameToID(name), io)
   574  }
   575  
   576  // NewTreeNodeInstanceFromProtocol takes a tree and a treenode (normally the
   577  // root) and and protocolID and returns a fresh TreeNodeInstance.
   578  func (o *Overlay) NewTreeNodeInstanceFromProtocol(t *Tree, tn *TreeNode, protoID ProtocolID, io MessageProxy) *TreeNodeInstance {
   579  	tok := &Token{
   580  		TreeNodeID: tn.ID,
   581  		TreeID:     t.ID,
   582  		RosterID:   t.Roster.ID,
   583  		ProtoID:    protoID,
   584  		RoundID:    RoundID(uuid.NewV4()),
   585  	}
   586  	tni := o.newTreeNodeInstanceFromToken(tn, tok, io)
   587  	o.RegisterTree(t)
   588  	o.RegisterRoster(t.Roster)
   589  	return tni
   590  }
   591  
   592  // NewTreeNodeInstanceFromService takes a tree, a TreeNode and a service ID and
   593  // returns a TNI.
   594  func (o *Overlay) NewTreeNodeInstanceFromService(t *Tree, tn *TreeNode, protoID ProtocolID, servID ServiceID, io MessageProxy) *TreeNodeInstance {
   595  	tok := &Token{
   596  		TreeNodeID: tn.ID,
   597  		TreeID:     t.ID,
   598  		RosterID:   t.Roster.ID,
   599  		ProtoID:    protoID,
   600  		ServiceID:  servID,
   601  		RoundID:    RoundID(uuid.NewV4()),
   602  	}
   603  	tni := o.newTreeNodeInstanceFromToken(tn, tok, io)
   604  	o.RegisterTree(t)
   605  	o.RegisterRoster(t.Roster)
   606  	return tni
   607  }
   608  
   609  // ServerIdentity Returns the entity of the Host
   610  func (o *Overlay) ServerIdentity() *network.ServerIdentity {
   611  	return o.server.ServerIdentity
   612  }
   613  
   614  // newTreeNodeInstanceFromToken is to be called by the Overlay when it receives
   615  // a message it does not have a treenodeinstance registered yet. The protocol is
   616  // already running so we should *not* generate a new RoundID.
   617  func (o *Overlay) newTreeNodeInstanceFromToken(tn *TreeNode, tok *Token, io MessageProxy) *TreeNodeInstance {
   618  	tni := newTreeNodeInstance(o, tok, tn, io)
   619  	o.instancesLock.Lock()
   620  	defer o.instancesLock.Unlock()
   621  	o.instances[tok.ID()] = tni
   622  	return tni
   623  }
   624  
   625  // ErrWrongTreeNodeInstance is returned when you already binded a TNI with a PI.
   626  var ErrWrongTreeNodeInstance = errors.New("This TreeNodeInstance doesn't exist")
   627  
   628  // ErrProtocolRegistered is when the protocolinstance is already registered to
   629  // the overlay
   630  var ErrProtocolRegistered = errors.New("a ProtocolInstance already has been registered using this TreeNodeInstance")
   631  
   632  // RegisterProtocolInstance takes a PI and stores it for dispatching the message
   633  // to it.
   634  func (o *Overlay) RegisterProtocolInstance(pi ProtocolInstance) error {
   635  	o.instancesLock.Lock()
   636  	defer o.instancesLock.Unlock()
   637  	var tni *TreeNodeInstance
   638  	var tok = pi.Token()
   639  	var ok bool
   640  	// if the TreeNodeInstance doesn't exist
   641  	if tni, ok = o.instances[tok.ID()]; !ok {
   642  		return ErrWrongTreeNodeInstance
   643  	}
   644  
   645  	if tni.isBound() {
   646  		return ErrProtocolRegistered
   647  	}
   648  
   649  	tni.bind(pi)
   650  	o.protocolInstances[tok.ID()] = pi
   651  	log.Lvlf4("%s registered ProtocolInstance %x", o.server.Address(), tok.ID())
   652  	return nil
   653  }
   654  
   655  // RegisterMessageProxy registers a message proxy only for this overlay
   656  func (o *Overlay) RegisterMessageProxy(m MessageProxy) {
   657  	o.protoIO.RegisterMessageProxy(m)
   658  }
   659  
   660  // pendingMsg is used to store messages destined for ProtocolInstances but when
   661  // the tree designated is not known to the Overlay. When the tree is sent to the
   662  // overlay, then the pendingMsg that are relying on this tree will get
   663  // processed.
   664  type pendingMsg struct {
   665  	*ProtocolMsg
   666  	MessageProxy
   667  }
   668  
   669  // defaultProtoIO implements the ProtocoIO interface but using the "regular/old"
   670  // wire format protocol,i.e. it wraps a message into a ProtocolMessage
   671  type defaultProtoIO struct {
   672  	suite network.Suite
   673  }
   674  
   675  // Wrap implements the MessageProxy interface for the Overlay.
   676  func (d *defaultProtoIO) Wrap(msg interface{}, info *OverlayMsg) (interface{}, error) {
   677  	if msg != nil {
   678  		buff, err := network.Marshal(msg)
   679  		if err != nil {
   680  			return nil, err
   681  		}
   682  		typ := network.MessageType(msg)
   683  		protoMsg := &ProtocolMsg{
   684  			From:     info.TreeNodeInfo.From,
   685  			To:       info.TreeNodeInfo.To,
   686  			MsgSlice: buff,
   687  			MsgType:  typ,
   688  		}
   689  		return protoMsg, nil
   690  	}
   691  	var returnMsg interface{}
   692  	switch true {
   693  	case info.RequestTree != nil:
   694  		returnMsg = info.RequestTree
   695  	case info.RequestRoster != nil:
   696  		returnMsg = info.RequestRoster
   697  	case info.TreeMarshal != nil:
   698  		returnMsg = info.TreeMarshal
   699  	case info.Roster != nil:
   700  		returnMsg = info.Roster
   701  	default:
   702  		panic("overlay: default wrapper has nothing to wrap")
   703  	}
   704  	return returnMsg, nil
   705  }
   706  
   707  // Unwrap implements the MessageProxy interface for the Overlay.
   708  func (d *defaultProtoIO) Unwrap(msg interface{}) (interface{}, *OverlayMsg, error) {
   709  	var returnMsg interface{}
   710  	var returnOverlay = new(OverlayMsg)
   711  	var err error
   712  
   713  	switch inner := msg.(type) {
   714  	case *ProtocolMsg:
   715  		onetMsg := inner
   716  		var err error
   717  		_, protoMsg, err := network.Unmarshal(onetMsg.MsgSlice, d.suite)
   718  		if err != nil {
   719  			return nil, nil, err
   720  		}
   721  		// Put the msg into ProtocolMsg
   722  		returnOverlay.TreeNodeInfo = &TreeNodeInfo{
   723  			To:   onetMsg.To,
   724  			From: onetMsg.From,
   725  		}
   726  		returnMsg = protoMsg
   727  	case *RequestTree:
   728  		returnOverlay.RequestTree = inner
   729  	case *RequestRoster:
   730  		returnOverlay.RequestRoster = inner
   731  	case *TreeMarshal:
   732  		returnOverlay.TreeMarshal = inner
   733  	case *Roster:
   734  		returnOverlay.Roster = inner
   735  	default:
   736  		err = errors.New("default protoIO: unwraping an unknown message type")
   737  	}
   738  	return returnMsg, returnOverlay, err
   739  }
   740  
   741  // Unwrap implements the MessageProxy interface for the Overlay.
   742  func (d *defaultProtoIO) PacketType() network.MessageTypeID {
   743  	return network.MessageTypeID([16]byte{})
   744  }
   745  
   746  // Name implements the MessageProxy interface. It returns the value "default".
   747  func (d *defaultProtoIO) Name() string {
   748  	return "default"
   749  }