def recv(self, server): ''' Receive data on an emulation server socket and broadcast it to all connected session handlers. Returns the length of data recevied and forwarded. Return value of zero indicates the socket has closed and should be removed from the self.servers dict. ''' msghdr = server.sock.recv(coreapi.CoreMessage.hdrsiz) if len(msghdr) == 0: # server disconnected server.close() return 0 if len(msghdr) != coreapi.CoreMessage.hdrsiz: if self.verbose: self.session.info("warning: broker received not enough data " \ "len=%s" % len(msghdr)) return len(msghdr) msgtype, msgflags, msglen = coreapi.CoreMessage.unpackhdr(msghdr) msgdata = server.sock.recv(msglen) data = msghdr + msgdata count = None # snoop exec response for remote interactive TTYs if msgtype == coreapi.CORE_API_EXEC_MSG and \ msgflags & coreapi.CORE_API_TTY_FLAG: data = self.fixupremotetty(msghdr, msgdata, server.host) elif msgtype == coreapi.CORE_API_NODE_MSG: # snoop node delete response to decrement node counts if msgflags & coreapi.CORE_API_DEL_FLAG: msg = coreapi.CoreNodeMessage(msgflags, msghdr, msgdata) nodenum = msg.gettlv(coreapi.CORE_TLV_NODE_NUMBER) if nodenum is not None: count = self.delnodemap(server, nodenum) elif msgtype == coreapi.CORE_API_LINK_MSG: # this allows green link lines for remote WLANs msg = coreapi.CoreLinkMessage(msgflags, msghdr, msgdata) self.session.sdt.handledistributed(msg) elif msgtype == coreapi.CORE_API_EVENT_MSG: msg = coreapi.CoreEventMessage(msgflags, msghdr, msgdata) eventtype = msg.gettlv(coreapi.CORE_TLV_EVENT_TYPE) if eventtype == coreapi.CORE_EVENT_INSTANTIATION_COMPLETE: server.instantiation_complete = True if self.instantiation_complete(): self.session.checkruntime() self.session.broadcastraw(None, data) if count is not None and count < 1: return 0 else: return len(data)
def recv(self, server): """ Receive data on an emulation server socket and broadcast it to all connected session handlers. Returns the length of data recevied and forwarded. Return value of zero indicates the socket has closed and should be removed from the self.servers dict. :param CoreDistributedServer server: server to receive from :return: message length :rtype: int """ msghdr = server.sock.recv(coreapi.CoreMessage.header_len) if len(msghdr) == 0: # server disconnected logger.info("server disconnected, closing server") server.close() return 0 if len(msghdr) != coreapi.CoreMessage.header_len: logger.warn("warning: broker received not enough data len=%s", len(msghdr)) return len(msghdr) msgtype, msgflags, msglen = coreapi.CoreMessage.unpack_header(msghdr) msgdata = server.sock.recv(msglen) data = msghdr + msgdata count = None logger.debug("received message type: %s", MessageTypes(msgtype)) # snoop exec response for remote interactive TTYs if msgtype == MessageTypes.EXECUTE.value and msgflags & MessageFlags.TTY.value: data = self.fixupremotetty(msghdr, msgdata, server.host) logger.debug("created remote tty message: %s", data) elif msgtype == MessageTypes.NODE.value: # snoop node delete response to decrement node counts if msgflags & MessageFlags.DELETE.value: msg = coreapi.CoreNodeMessage(msgflags, msghdr, msgdata) nodenum = msg.get_tlv(NodeTlvs.NUMBER.value) if nodenum is not None: count = self.delnodemap(server, nodenum) elif msgtype == MessageTypes.LINK.value: # this allows green link lines for remote WLANs msg = coreapi.CoreLinkMessage(msgflags, msghdr, msgdata) self.session.sdt.handle_distributed(msg) elif msgtype == MessageTypes.EVENT.value: msg = coreapi.CoreEventMessage(msgflags, msghdr, msgdata) eventtype = msg.get_tlv(EventTlvs.TYPE.value) if eventtype == EventTypes.INSTANTIATION_COMPLETE.value: server.instantiation_complete = True if self.instantiation_complete(): self.session.check_runtime() else: logger.error("unknown message type received: %s", msgtype) try: for session_client in self.session_clients: session_client.sendall(data) except IOError: logger.exception("error sending message") if count is not None and count < 1: return 0 else: return len(data)