github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/lnp2p/msgproc.go (about) 1 package lnp2p 2 3 import ( 4 "fmt" 5 "github.com/mit-dci/lit/logging" 6 "sync" 7 ) 8 9 // ParseFuncType is the type of a Message parser function. 10 type ParseFuncType func([]byte) (Message, error) 11 12 // HandleFuncType is the type of a Message handler function, handling for a particular peer. 13 type HandleFuncType func(*Peer, Message) error 14 15 type messagehandler struct { 16 parseFunc ParseFuncType 17 handleFunc HandleFuncType 18 } 19 20 // MessageProcessor is can be given messages and figures out how to parse them and which function to call. 21 type MessageProcessor struct { 22 handlers [256]*messagehandler 23 24 // This is for keeping track of if we're making changes to the message 25 // processor. Locking and unlocking is slow and shouldn't be necessary when 26 // handling messages, but we don't want to be handling messages while making 27 // changes to the handlerset. 28 // TODO Evaluate if this mutex is even necessary? 29 active bool 30 actmtx *sync.Mutex 31 } 32 33 // NewMessageProcessor processes messages coming in from over the network. 34 func NewMessageProcessor() MessageProcessor { 35 return MessageProcessor{ 36 handlers: [256]*messagehandler{}, 37 active: false, 38 actmtx: &sync.Mutex{}, 39 } 40 } 41 42 // DefineMessage defines processing routines for a particular message type. 43 func (mp *MessageProcessor) DefineMessage(mtype uint8, pfunc ParseFuncType, hfunc HandleFuncType) { 44 mp.actmtx.Lock() 45 act := mp.active 46 mp.active = false 47 48 // Actually set the handler. 49 mp.handlers[mtype] = &messagehandler{ 50 parseFunc: pfunc, 51 handleFunc: hfunc, 52 } 53 54 logging.Debugf("msgproc: Setup message type %x\n", mtype) 55 56 mp.active = act 57 mp.actmtx.Unlock() 58 } 59 60 // Activate sets the MessageProcessor to be "active" 61 func (mp *MessageProcessor) Activate() { 62 mp.active = true 63 } 64 65 // IsActive returns the activiation state for the MessageProcessor. 66 func (mp *MessageProcessor) IsActive() bool { 67 return mp.active 68 } 69 70 // HandleMessage runs through the normal handling procedure for the message, returning any errors. 71 func (mp *MessageProcessor) HandleMessage(peer *Peer, buf []byte) error { 72 if !mp.active { 73 return fmt.Errorf("message processor not active, retry later") 74 } 75 76 var err error 77 78 // First see if we have handlers defined for this message type. 79 mtype := buf[0] 80 h := mp.handlers[mtype] 81 if h == nil { 82 return fmt.Errorf("no handler found for messasge of type %x", mtype) 83 } 84 85 // Parse the message. 86 parsed, err := h.parseFunc(buf[1:]) 87 if err != nil { 88 logging.Warnf("msgproc: Malformed message of type %x from peer %s\n", mtype, peer.GetPrettyName()) 89 return err 90 } 91 92 // If ok, then actually handle the message. 93 err = h.handleFunc(peer, parsed) 94 if err != nil { 95 return err 96 } 97 98 return nil 99 }