def main_loop(self):
        global pendingBackAck
        self.input_list.append(self.server)
        self.input_list.append(self.broadclient)
        self.input_list.append(self.operation_server)
        while True:
            time.sleep(self.delay)
            ss = select.select
            inputready, outputready, exceptready = ss(self.input_list, [], [])
            senderdata = {}
            for item in pendingBackAck:
                if item.sender in senderdata.keys():
                    senderdata[item.sender] += item.data
                else:
                    senderdata[item.sender] = item.data
            for sender in senderdata.keys():
                sender.send(senderdata[sender])
            del pendingBackAck[:]

            for self.s in inputready:
                if self.s == self.server:
                    self.on_accept()
                else:
                    self.data = self.s.recv(self.buffer_size)
                    if self.s in self.tunnels:
                        if len(self.data) == 0:
                            self.on_close()
                            break

                        else:
                            if self.s not in self.tun2buffer.keys():
                                self.tun2buffer[self.s] = bytes()
                            self.tun2buffer[self.s] += self.data
                            while True:
                                if len(self.tun2buffer[self.s]) < headerSize:
                                    break
                                else:
                                    headPack = struct.unpack(
                                        '!3I',
                                        self.tun2buffer[self.s][:headerSize])
                                    bodySize = headPack[1]
                                    if len(self.tun2buffer[
                                            self.s]) < headerSize + bodySize:
                                        logger.debug(
                                            "not a complicated packet")
                                        break
                                    else:
                                        self.data = self.tun2buffer[
                                            self.s][headerSize:headerSize +
                                                    bodySize]
                                        self.tun2buffer[
                                            self.s] = self.tun2buffer[
                                                self.s][headerSize + bodySize:]
                                        self.on_recv()
                    else:
                        if len(self.data) == 0:
                            self.on_close()
                            break
                        else:
                            self.on_recv()
예제 #2
0
    def pop_out_tunnel(self, data):
        '''
        tunnel->of
        '''
        nccontainer = ncctunnel_pb2.nccontainer()
        nccontainer.ParseFromString(data)
        data = nccontainer.entry
        if nccontainer.instruction == "Centralized":  # TODO
            self.echo += 1
            ack_fromQueue.append(
                operation_entry(1, nccontainer.switch, nccontainer.op_id))
            # self.checkPending()
        else:
            try:
                of_msg = unpack(data)
            except:
                logger.debug("Non OpenFlow Message" + str(len(data)))
            else:
                if of_msg.header.message_type == Type.OFPT_FEATURES_REPLY:
                    switch_addr = of_msg.datapath_id.value
                    self.tunnelIndex[switch_addr] = self.s
                    self.tun2idx[self.s] = switch_addr
                    self.ofchannelIndex[switch_addr] = self.tun2ofchannel[
                        self.s]

            if self.s in self.tun2idx.keys():
                # logger.debug("datapath created id : %s" % self.tun2idx[self.s])
                pass
            try:
                self.tun2ofchannel[self.s].send(data)
            except:
                pass
예제 #3
0
 def on_recv(self):
     data = self.data
     # here we can parse and/or modify the data before send forward
     # logger.debug("Recived %d bytes from %s to %s" % (len(data), self.s.getpeername(), self.s.getsockname()))
     if self.s in self.ofchannels:
         logger.debug("Push in tunnel")
         self.push_in_tunnel(data)
     else:
         logger.debug("Pop out tunnel")
         self.pop_out_tunnel(data)
예제 #4
0
 def main_loop(self):
     logger.info("start server at %s" % str(self.server.getsockname()))
     self.input_list.append(self.server)
     while True:
         time.sleep(self.delay)
         ss = select.select
         inputready, outputready, exceptready = ss(self.input_list, [], [])
         for self.s in inputready:
             if self.s == self.server:
                 self.on_accept()
             else:
                 try:
                     self.data = self.s.recv(self.buffer_size)
                 except:
                     pass
                 else:
                     if self.s in self.tunnels:
                         if len(self.data) == 0:
                             self.on_close()
                             break
                         else:
                             if self.s not in self.tun2buffer.keys():
                                 self.tun2buffer[self.s] = bytes()
                             self.tun2buffer[self.s] += self.data
                             while True:
                                 if len(self.tun2buffer[
                                         self.s]) < headerSize:
                                     # logger.debug("shorter than headerSize")
                                     break
                                 else:
                                     headPack = struct.unpack(
                                         '!3I', self.tun2buffer[self.s]
                                         [:headerSize])
                                     bodySize = headPack[1]
                                     if len(self.tun2buffer[self.s]
                                            ) < headerSize + bodySize:
                                         logger.debug(
                                             "not a complicated packet")
                                         break
                                     else:
                                         self.data = self.tun2buffer[
                                             self.s][headerSize:headerSize +
                                                     bodySize]
                                         self.tun2buffer[
                                             self.s] = self.tun2buffer[
                                                 self.s][headerSize +
                                                         bodySize:]
                                         self.on_recv()
                     else:
                         if len(self.data) == 0:
                             self.on_close()
                             break
                         else:
                             self.on_recv()
예제 #5
0
 async def _on_of_msg(self, of_msg, msg_data):
     logger = self._connection.logger
     logger.debug("OpenFlow Message Type: %s" % of_msg.header.message_type)
     if of_msg.header.message_type == Type.OFPT_FEATURES_REQUEST:
         logger.info("accept Type.OFPT_FEATURES_REQUEST")
     elif of_msg.header.message_type == Type.OFPT_ERROR:
         logger.info(of_msg.error_type)
     msg = TunnelMsg.construct(TunnelMsg.TYPE_PASS, msg_data)
     tunnel = self._writer
     tunnel.write(msg.pack())
     await tunnel.drain()
예제 #6
0
 def __send_container_by_sock(self, tun_sock, nccontainer):
     size = nccontainer.ByteSize()
     nccontainer = nccontainer.SerializeToString()
     ver = 1
     cmd = 101
     header = [ver, size, cmd]
     headPack = struct.pack("!3I", *header)
     try:
         lock = self.tunnelLock[tun_sock]
         lock.acquire()
         tun_sock.sendall(headPack + nccontainer)
         lock.release()
     except:
         logger.debug("pipe is deleted")
예제 #7
0
 def encapsulate(self, data):
     """
     encapsulate of_message with container_operation
     """
     # TODO: encapsulate of_message with container_op
     nccontainer = ncctunnel_pb2.nccontainer()
     try:
         of_msg = unpack(data)
     except UnpackException:
         # logger.debug("Non OpenFlow Message")
         pass
     else:
         logger.debug("OpenFlow Message Type: %s" %
                      of_msg.header.message_type)
         if of_msg.header.message_type == Type.OFPT_FLOW_MOD:
             id = str(random.random())
             nccontainer.op_id = id
     nccontainer.entry = data
     return nccontainer
    def broadcast_ovs2sp(self, switch_addr):
        logger.debug(
            "broadcast_ovs2sp %s %s" %
            (self.server.getsockname()[0], self.server.getsockname()[1]))
        mapInfo = switch_addr + ' ' + self.host + ' ' + str(
            self.operation_port)
        self.update_ovs2sp(mapInfo)
        network = '<broadcast>'

        # self.broadserver.sendto(mapInfo.encode('utf-8'), (network,self.broadcast_port))

        def period_broadcast(data, addr):
            while True:
                self.broadserver.sendto(data, addr)
                logger.debug("period broadcast")
                time.sleep(4)

        threading.Thread(target=period_broadcast,
                         args=(mapInfo.encode('utf-8'),
                               (network, self.broadcast_port))).start()
    def pop_out_tunnel(self, tunneldata):
        """
        tunnel -> of
        """
        global pendingBackAck

        nccontainer = ncctunnel_pb2.nccontainer()
        nccontainer.ParseFromString(tunneldata)
        data = nccontainer.entry
        if nccontainer.instruction == "TEST":
            self.block = True
            logger.debug(str(datetime.now()))
            newcontainer = container(nccontainer.op_id,
                                     nccontainer.instruction,
                                     nccontainer.switch, nccontainer.entry,
                                     nccontainer.ack_from, nccontainer.ack_to)
            logger.info("new container " + str(newcontainer))
            self.pending_container.append(newcontainer)
            if newcontainer.state:
                self.__exec(newcontainer)

        # elif nccontainer.instruction == "Centralized":
        #     size = nccontainer.ByteSize()
        #     nccontainer = nccontainer.SerializeToString()
        #     ver = 1
        #     cmd = 101
        #     header = [ver,size, cmd]
        #     headPack = struct.pack("!3I", *header)
        #
        #     pendingBackAck.append(backAck(self.s,headPack+nccontainer))
        #     # self.s.send(headPack+nccontainer)
        else:
            if self.s in self.senderdata.keys():
                self.senderdata[self.s] += data
            else:
                self.senderdata[self.s] = data

            lenth = int.from_bytes(self.senderdata[self.s][2:4],
                                   byteorder='big')

            if lenth > len(self.senderdata[self.s]):
                logger.debug("not complicated packet")
                return
            else:
                data = self.senderdata[self.s][:lenth]
                self.senderdata[self.s] = self.senderdata[self.s][
                    lenth:]  # NOTE buffer

            try:
                of_msg = unpack(data)
            except UnpackException:
                logger.debug("Non OpenFlow Message")
                self.tun2ofchannel[self.s].send(data)
            else:
                self.tun2ofchannel[self.s].send(data)
 def on_recv(self):
     data = self.data
     if self.s in self.ofchannels:
         logger.debug("Push in tunnel")
         self.push_in_tunnel(data)
     elif self.s == self.broadclient:
         logger.debug("on_recv update_ovs2sp")
         self.update_ovs2sp(data.decode('utf-8'))
     elif self.s == self.operation_server:
         self.process_operationmsg(data)
     else:
         logger.debug("Pop out tunnel")
         self.pop_out_tunnel(data)
 def period_broadcast(data, addr):
     while True:
         self.broadserver.sendto(data, addr)
         logger.debug("period broadcast")
         time.sleep(4)
 def bind_tun_ofchannel(self, of_msg):
     switch_addr = of_msg.datapath_id.value
     self.ofchannelIndex[switch_addr] = self.s
     logger.debug("bind_tun_ofchannel %s" % switch_addr)
     self.tunnelIndex[switch_addr] = self.ofchannel2tun[self.s]
     self.tun2IDX[self.ofchannel2tun[self.s]] = switch_addr
    def push_in_tunnel(self, data):
        """
        of -> tunnel
        """
        global pendingBackAck

        if self.s in self.ofchaneldata.keys():
            self.ofchaneldata[self.s] += data
        else:
            self.ofchaneldata[self.s] = data
        lenth = int.from_bytes(self.ofchaneldata[self.s][2:4], byteorder='big')
        if lenth > len(self.ofchaneldata[self.s]):
            logger.debug("not complicated packet")
            return
        else:
            data = self.ofchaneldata[self.s][:lenth]
            self.ofchaneldata[self.s] = self.ofchaneldata[self.s][lenth:]
        try:
            of_msg = unpack(data)
            logger.debug("OpenFlow Message Type: %s" %
                         of_msg.header.message_type)
            if of_msg.header.message_type == Type.OFPT_FEATURES_REPLY:
                logger.debug("accept Type.OFPT_FEATURES_REPLY")
                self.bind_tun_ofchannel(of_msg)
                self.broadcast_ovs2sp(of_msg.datapath_id.value)
            elif of_msg.header.message_type == Type.OFPT_PORT_STATUS:
                # self.receievePortStatus(data)
                logger.debug(" ingore port status ")
            elif of_msg.header.message_type == Type.OFPT_ERROR:
                logger.debug(of_msg.error_type)
        except:
            logger.debug("Non OpenFlow Message")

        nccontainer = self.encapsulate(data)
        self.ofchaneldata[self.s] = bytes()
        size = nccontainer.ByteSize()
        nccontainer = nccontainer.SerializeToString()
        ver = 1
        cmd = 101
        header = [ver, size, cmd]
        headPack = struct.pack("!3I", *header)

        data = headPack + nccontainer

        if len(pendingBackAck):
            senderdata = {}
            for item in pendingBackAck:
                if item.sender in senderdata.keys():
                    senderdata[item.sender] += item.data
                else:
                    senderdata[item.sender] = item.data
            for sender in senderdata.keys():
                if sender == self.ofchannel2tun[self.s]:
                    data += senderdata[sender]
                    pendingBackAck = [
                        item for item in pendingBackAck
                        if item.sender != self.s
                    ]
                    break
        self.ofchannel2tun[self.s].send(data)
예제 #14
0
 async def _on_info_msg(self, msg):
     logger = self._connection.logger
     logger.debug('get info msg')
     self._info = msg.body.decode()
     logger.info(self._info)