def _NodeUp(self, connection, nodeName): """This callback is called from the in/out connection object when a new connection has been established.""" erl_common.Debug(M, "NODEUP: nodeName=%s connection=%s" % \ (nodeName, connection)) self._connections[nodeName] = connection for (id, cb) in self._nodeUpCb: cb("nodeup", nodeName)
def _NoResponse(self): """This callback is called by the Ticker class instance when nothing has been received from the other end for too long. """ erl_common.Debug(M, "InConnection: Connection broken") self._state = self._STATE_DISCONNECTED self._tickTimers.Stop() self._connectionBrokenCb(self, self.GetPeerNodeName())
def _NodeDown(self, connection, nodeName): """This callback is called from the in/out connection object when a connection has been broken.""" erl_common.Debug(M, "NODENOWN: nodeName=%s connection=%s" % \ (nodeName, connection)) if nodeName in self._connections: del self._connections[nodeName] for (id, cb) in self._nodeDownCb: cb("nodedown", nodeName)
def Msg(self, sourceNodeName, msg): """This routine is intended to be called only from mbox's node. SOURCE-NODE-NAME = string MSG = <term> Returns: void Throws: nothing An incoming message """ if type(msg) == tuple and \ len(msg) == 2 and \ erl_term.IsErlAtom(msg[0]) and \ msg[0].atomText == "rex" and \ len(self._pendingRPCs) > 0: self._RPCAnswer(sourceNodeName, msg[1]) else: erl_common.Debug("REX: Unexpected msg: %s" % repr(msg))
def _In(self): """Callback routine, which is called when data is available on the connection.""" connection = self.GetConnection() newData = connection.recv(100000) if len(newData) == 0: self.Close() if self._state != self._STATE_CONNECTED: self._state = self._STATE_DISCONNECTED else: erl_common.Debug(M, "InConnection: Connection broken") self._state = self._STATE_DISCONNECTED if self._tickTimers != None: self._tickTimers.Stop() self._connectionBrokenCb(self, self.GetPeerNodeName()) return self._recvdata = self._recvdata + newData remainingUnhandledData = self._HandleData(self._recvdata) self._recvdata = remainingUnhandledData
def _SendPacket(self, packet): msg = self.PackInt4(len(packet)) + packet erl_common.Debug(M, "Sending msg") self._tickTimers.RestartTick() self.Send(msg)
def _SendHandshakeMsg(self, packet): msg = self.PackInt2(len(packet)) + packet erl_common.Debug(M, "Sending handshake") self.Send(msg)
def _HandlePacket(self, data): if self._state == self._STATE_HANDSHAKE_RECV_NAME: # First check that the correct message came in if data[0] != "n": erl_common.DebugHex(M, "handshake:recv_name", data) self.Close() self._state = self._STATE_DISCONNECTED self._peerDistrVersion = self.ReadInt2(data[1:3]) self._peerFlags = self.ReadInt4(data[3:7]) self._peerName = data[7:] # FIXME: check for connections _to_ this node: # check whether nodeName > ownNodeName (or check < ?) self._SendStatusOk() self._SendChallenge() self._state = self._STATE_HANDSHAKE_RECV_CHALLENGE_REPLY elif self._state == self._STATE_HANDSHAKE_RECV_CHALLENGE_REPLY: # First check that the correct message came in if data[0] != "r": erl_common.DebugHex(M, "handshake:recv_chreply", data) self.Close() self._state = self._STATE_DISCONNECTED peersChallenge = self.ReadInt4(data[1:5]) peersDigest = data[5:] ownCookie = self._opts.GetCookie() if CheckDigest(peersDigest, self._challengeToPeer, ownCookie): self._SendChallengeAck(peersChallenge) self._packetLenSize = 4 self._state = self._STATE_CONNECTED t = self._opts.GetNetTickTime() self._tickTimers = Ticker(t, self._Tick, self._NoResponse) self._newConnectionUpCb(self, self.GetPeerNodeName()) else: erl_common.Debug( M, "Connection attempt from disallowed node %s" % self._peerName) self.Close() self._state = self._STATE_DISCONNECTED elif self._state == self._STATE_CONNECTED: self._tickTimers.GotResonse() if len(data) == 0: # A tick return msgType = data[0] if msgType == "p": terms = erl_term.BinariesToTerms(data[1:]) if len(terms) == 2: controlMsg = terms[0] msg = terms[1] peerName = self.GetPeerNodeName() self._passThroughMsgCb(self, peerName, controlMsg, msg) elif len(terms) == 1: controlMsg = terms[0] peerName = self.GetPeerNodeName() self._passThroughMsgCb(self, peerName, controlMsg) else: debugTxt = "PassThrough-msg: terms=%s" % ` terms ` erl_common.DebugHex(M, debugTxt, data) else: erl_common.DebugHex(M, "msgType=%c" % msgType, data) else: erl_common.DebugHex(M, "state=%d" % self._state, data)
def _HandlePacket(self, data): if self._state == self._STATE_HANDSHAKE_RECV_STATUS: # First check that the correct message came in if data[0] != "s": erl_common.DebugHex(M, "handshake:recv_status: got", data) self.Close() self._state = self._STATE_DISCONNECTED self._connectFailedCb() status = data[1:] if status == "ok" or status == "ok_simultaneous": self._state = self._STATE_HANDSHAKE_RECV_CHALLENGE elif status == "nok" or status == "not_allowed": self.Close() self._state = self._STATE_DISCONNECTED self._connectFailedCb() elif status == "alive": self._SendStatusAliveTrue() self._state = self._STATE_HANDSHAKE_RECV_CHALLENGE else: erl_common.DebugHex(M, "handshake:recv_status", data) elif self._state == self._STATE_HANDSHAKE_RECV_CHALLENGE: # First check that the correct message came in if data[0] != "n": erl_common.DebugHex(M, "handshake:recv_cha", data) self.Close() self._state = self._STATE_DISCONNECTED self._connectFailedCb() self._peerVersion = self.ReadInt2(data[1:3]) self._peerFlags = self.ReadInt4(data[3:7]) challenge = self.ReadInt4(data[7:11]) self._peerName = data[11:] self._SendChallengeReply(challenge) self._state = self._STATE_HANDSHAKE_RECV_CHALLENGE_ACK elif self._state == self._STATE_HANDSHAKE_RECV_CHALLENGE_ACK: # First check that the correct message came in if data[0] != "a": erl_common.DebugHex(M, "handshake:recv_cha_ack", data) self.Close() self._state = self._STATE_DISCONNECTED self._connectFailedCb() digest = data[1:] ownCookie = self._opts.GetCookie() if CheckDigest(digest, self._challengeToPeer, ownCookie): self._packetLenSize = 4 self._state = self._STATE_CONNECTED t = self._opts.GetNetTickTime() self._tickTimers = Ticker(t, self._Tick, self._NoResponse) self._connectOkCb() else: erl_common.Debug( M, "Connection attempt to disallowed node %s" % self._peerName) self.Close() self._state = self._STATE_DISCONNECTED self._connectFailedCb() elif self._state == self._STATE_CONNECTED: self._tickTimers.GotResonse() if len(data) == 0: # A tick return msgType = data[0] if msgType == "p": terms = erl_term.BinariesToTerms(data[1:]) if len(terms) == 2: controlMsg = terms[0] msg = terms[1] self._passThroughMsgCb(self, self.GetPeerNodeName(), controlMsg, msg) elif len(terms) == 1: controlMsg = terms[0] self._passThroughMsgCb(self, self.GetPeerNodeName(), controlMsg, msg) else: debugTxt = "PassThrough-msg: terms=%s" % ` terms ` erl_common.DebugHex(M, debugTxt, data) else: erl_common.DebugHex(M, "msgType=%c" % msgType, data) else: erl_common.DebugHex(M, "state=%d" % self._state, data)
def _PassThroughMsg(self, connection, remoteNodeName, ctrlMsg, msg=None): """This callback is called when a connection recevies a message of type passthrough. Currently all messages are of type passthrough.""" erl_common.Debug(M, "ctrlMsg=%s" % repr(ctrlMsg)) ctrlMsgOp = ctrlMsg[0] if ctrlMsgOp == self.CTRLMSGOP_LINK: fromPid = ctrlMsg[1] toPid = self._InternPid(ctrlMsg[2]) pass elif ctrlMsgOp == self.CTRLMSGOP_SEND: cookie = ctrlMsg[1] toPid = self._InternPid(ctrlMsg[2]) msg = msg erl_common.Debug(M, "SEND: msg=%s" % repr(msg)) if toPid in self._pids: mbox = self._pids[toPid] mbox.Msg(remoteNodeName, msg) else: erl_common.Debug(M, "Got SEND with no dest pid: %s" % toPid) erl_common.Debug(M, "Pids:\n%s" % repr(self._pids)) elif ctrlMsgOp == self.CTRLMSGOP_EXIT: fromPid = ctrlMsg[1] toPid = self._InternPid(ctrlMsg[2]) reason = ctrlMsg[3] pass elif ctrlMsgOp == self.CTRLMSGOP_UNLINK: fromPid = ctrlMsg[1] toPid = self._InternPid(ctrlMsg[2]) pass elif ctrlMsgOp == self.CTRLMSGOP_NODE_LINK: pass elif ctrlMsgOp == self.CTRLMSGOP_REG_SEND: fromPid = ctrlMsg[1] cookie = ctrlMsg[2] toNameAtom = ctrlMsg[3] toName = toNameAtom.atomText msg = msg if toName in self._registeredNames: mboxPid = self._registeredNames[toName] mbox = self._pids[mboxPid] mbox.Msg(remoteNodeName, msg) else: erl_common.Debug( M, "Got REG_SEND with no dest mbox: \"%s\": %s" % (toName, msg)) elif ctrlMsgOp == self.CTRLMSGOP_GROUP_LEADER: fromPid = ctrlMsg[1] toPid = self._InternPid(ctrlMsg[2]) pass elif ctrlMsgOp == self.CTRLMSGOP_EXIT2: fromPid = ctrlMsg[1] toPid = self._InternPid(ctrlMsg[2]) reason = ctrlMsg[3] pass elif ctrlMsgOp == self.CTRLMSGOP_SEND_TT: cookie = ctrlMsg[1] toPid = self._InternPid(ctrlMsg[2]) traceToken = ctrlMsg[3] msg = msg pass elif ctrlMsgOp == self.CTRLMSGOP_EXIT_TT: fromPid = ctrlMsg[1] toPid = self._InternPid(ctrlMsg[2]) traceToken = ctrlMsg[3] reason = ctrlMsg[4] pass elif ctrlMsgOp == self.CTRLMSGOP_REG_SEND_TT: fromPid = ctrlMsg[1] cookie = ctrlMsg[2] toName = ctrlMsg[3] traceToken = ctrlMsg[4] msg = msg pass elif ctrlMsgOp == self.CTRLMSGOP_EXIT2_TT: fromPid = ctrlMsg[1] toPid = self._InternPid(ctrlMsg[2]) traceToken = ctrlMsg[3] reason = ctrlMsg[4] pass elif ctrlMsgOp == self.CTRLMSGOP_MONITOR_P: fromPid = ctrlMsg[1] toPid = self._InternPid(ctrlMsg[2]) ref = ctrlMsg[3] pass elif ctrlMsgOp == self.CTRLMSGOP_DEMONITOR_P: fromPid = ctrlMsg[1] toPid = self._InternPid(ctrlMsg[2]) ref = ctrlMsg[3] pass elif ctrlMsgOp == self.CTRLMSGOP_MONITOR_P_EXIT: fromPid = ctrlMsg[1] toPid = self._InternPid(ctrlMsg[2]) ref = ctrlMsg[3] pass else: erl_common.Debug(M, "Unknown controlmsg: %s" % repr(ctrlMsg))
def _NewConnection(self, s, remoteAddr): erl_common.Debug(M, "new connection from %s" % repr(remoteAddr)) inConn = ErlNodeInConnection(s, self._nodeName, self._opts, self._nodeUpCb, self._nodeDownCb, self._passThroughMsgCb)