Пример #1
0
    def addlinkendpoints(self, message, servers1, servers2):
        """
        For a link message that is not handled locally, inform the remote
        servers of the IP addresses used as tunnel endpoints by adding
        opaque data to the link message.

        :param core.api.coreapi.CoreMessage message: message to link end points
        :param servers1:
        :param servers2:
        :return: core link message
        :rtype: coreapi.CoreLinkMessage
        """
        ip1 = ""
        for server in servers1:
            if server.host is not None:
                ip1 = server.host
                break
        ip2 = ""
        for server in servers2:
            if server.host is not None:
                ip2 = server.host
                break
        tlvdata = message.raw_message[coreapi.CoreMessage.header_len:]
        tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.OPAQUE.value, "%s:%s" % (ip1, ip2))
        newraw = coreapi.CoreLinkMessage.pack(message.flags, tlvdata)
        msghdr = newraw[:coreapi.CoreMessage.header_len]
        return coreapi.CoreLinkMessage(message.flags, msghdr, tlvdata)
    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)
Пример #3
0
    def sendobjs(self):
        ''' Session has already started, and the SDT3D GUI later connects.
            Send all node and link objects for display. Otherwise, nodes and
            links will only be drawn when they have been updated (e.g. moved).
        '''
        nets = []
        with self.session._objslock:
            for obj in self.session.objs():
                if isinstance(obj, PyCoreNet):
                    nets.append(obj)
                if not isinstance(obj, PyCoreObj):
                    continue
                (x, y, z) = obj.getposition()
                if x is None or y is None:
                    continue
                self.updatenode(obj.objid, coreapi.CORE_API_ADD_FLAG, x, y, z,
                                obj.name, obj.type, obj.icon)
            for nodenum in sorted(self.remotes.keys()):
                r = self.remotes[nodenum]
                (x, y, z) = r.pos
                self.updatenode(nodenum, coreapi.CORE_API_ADD_FLAG, x, y, z,
                                r.name, r.type, r.icon)

            for net in nets:
                # use tolinkmsgs() to handle various types of links
                msgs = net.tolinkmsgs(flags=coreapi.CORE_API_ADD_FLAG)
                for msg in msgs:
                    msghdr = msg[:coreapi.CoreMessage.hdrsiz]
                    flags = coreapi.CoreMessage.unpackhdr(msghdr)[1]
                    m = coreapi.CoreLinkMessage(
                        flags, msghdr, msg[coreapi.CoreMessage.hdrsiz:])
                    n1num = m.gettlv(coreapi.CORE_TLV_LINK_N1NUMBER)
                    n2num = m.gettlv(coreapi.CORE_TLV_LINK_N2NUMBER)
                    link_msg_type = m.gettlv(coreapi.CORE_TLV_LINK_TYPE)
                    if isinstance(net, nodes.WlanNode) or \
                       isinstance(net, nodes.EmaneNode):
                        if (n1num == net.objid):
                            continue
                    wl = (link_msg_type == coreapi.CORE_LINK_WIRELESS)
                    self.updatelink(n1num, n2num, coreapi.CORE_API_ADD_FLAG,
                                    wl)
            for n1num in sorted(self.remotes.keys()):
                r = self.remotes[n1num]
                for (n2num, wl) in r.links:
                    self.updatelink(n1num, n2num, coreapi.CORE_API_ADD_FLAG,
                                    wl)
Пример #4
0
 def addlinkendpoints(self, msg, serverset1, serverset2):
     ''' For a link message that is not handled locally, inform the remote
         servers of the IP addresses used as tunnel endpoints by adding
         opaque data to the link message.
     '''
     ip1 = ""
     for server in serverset1:
         (host, port, sock) = self.getserver(server)
         if host is not None:
             ip1 = host
     ip2 = ""
     for server in serverset2:
         (host, port, sock) = self.getserver(server)
         if host is not None:
             ip2 = host
     tlvdata = msg.rawmsg[coreapi.CoreMessage.hdrsiz:] 
     tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_OPAQUE,
                                 "%s:%s" % (ip1, ip2))
     newraw = coreapi.CoreLinkMessage.pack(msg.flags, tlvdata)
     msghdr = newraw[:coreapi.CoreMessage.hdrsiz] 
     return coreapi.CoreLinkMessage(msg.flags, msghdr, tlvdata)
 def addlinkendpoints(self, msg, servers1, servers2):
     ''' For a link message that is not handled locally, inform the remote
         servers of the IP addresses used as tunnel endpoints by adding
         opaque data to the link message.
     '''
     ip1 = ''
     for server in servers1:
         if server.host is not None:
             ip1 = server.host
             break
     ip2 = ''
     for server in servers2:
         if server.host is not None:
             ip2 = server.host
             break
     tlvdata = msg.rawmsg[coreapi.CoreMessage.hdrsiz:]
     tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_OPAQUE,
                                         "%s:%s" % (ip1, ip2))
     newraw = coreapi.CoreLinkMessage.pack(msg.flags, tlvdata)
     msghdr = newraw[:coreapi.CoreMessage.hdrsiz]
     return coreapi.CoreLinkMessage(msg.flags, msghdr, tlvdata)
Пример #6
0
    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)