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 }