def on_close(self):
     logger.info("%s  has disconnected", self.s.getpeername())
     self.input_list.remove(self.s)
     if self.s in self.tunnels:
         self.input_list.remove(self.tun2ofchannel[self.s])
         out = self.tun2ofchannel[self.s]
         out.close()
         self.s.close()
         del self.tun2ofchannel[self.s]
         del self.ofchannel2tun[out]
         self.tunnels.remove(self.s)
         self.tunnelIndex = {
             k: v
             for k, v in self.tunnelIndex.items() if v != self.s
         }
         self.ofchannelIndex = {
             k: v
             for k, v in self.ofchannelIndex.items() if v != out
         }
     else:
         self.input_list.remove(self.ofchannel2tun[self.s])
         out = self.ofchannel2tun[self.s]
         out.close()
         self.s.close()
         del self.ofchannel2tun[self.s]
         del self.tun2ofchannel[out]
         self.ofchannels.remove(self.s)
         self.tunnelIndex = {
             k: v
             for k, v in self.tunnelIndex.items() if v != out
         }
         self.ofchannelIndex = {
             k: v
             for k, v in self.ofchannelIndex.items() if v != self.s
         }
 def update_ovs2sp(self, mapInfo):
     logger.info("update_ovs2sp %s" % mapInfo)
     mapInfo = mapInfo.split(' ')
     switch_addr = mapInfo[0]
     sproxy_addr = mapInfo[1]
     sproxy_port = mapInfo[2]
     if switch_addr not in self.switch_addr2sproxy_addr.keys():
         self.switch_addr2sproxy_addr[
             switch_addr] = sproxy_addr + ' ' + sproxy_port
    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)
예제 #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 on_accept(self):
     ofchannel_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     ofchannel_sock.connect((self.forward_addr, self.forward_port))
     self.ofchannels.add(ofchannel_sock)
     clientsock, clientaddr = self.server.accept()
     logger.info("accept from %s" % str(clientaddr))
     tunnel_sock = clientsock
     self.tunnels.add(tunnel_sock)
     self.tunnelLock[tunnel_sock] = threading.Lock()
     self.ofchannel2tun[ofchannel_sock] = tunnel_sock
     self.tun2ofchannel[tunnel_sock] = ofchannel_sock
     self.input_list.append(ofchannel_sock)
     self.input_list.append(tunnel_sock)
 def process_operationmsg(self, data):
     spmsg = spcomunication_pb2.spmsg()
     spmsg.ParseFromString(data)
     logger.info("process " + str(spmsg))
     ackentry = operation_entry(spmsg.type, spmsg.switch_addr,
                                spmsg.operation_id)
     ack_fromQueue.add(ackentry)
     for containerItem in self.pending_container:
         containerItem.receive_ack()
         if containerItem.state:
             # fully satisfied
             self.__exec(containerItem)
             del containerItem  # TODO check it
예제 #8
0
 async def _on_pass_msg(self, msg):
     logger = self._connection.logger
     self._writer.write(msg.body)
     try:
         of_msg = unpack(msg.body)
     except UnpackException:
         logger.warn("can not unpack OpenFlow Message, %s", str(msg.body))
     else:
         if of_msg.header.message_type == Type.OFPT_FEATURES_REPLY:
             dpid = of_msg.datapath_id.value
             logger.info("get OFPT_FEATURES_REPLY, dpid=%s" % dpid)
             self._connection.register_info(dpid, self._info)
     await self._writer.drain()
 def on_accept(self):
     ofsock, clientaddr = self.server.accept()
     tunnel_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     try:
         tunnel_sock.connect((self.forward_addr, self.forward_port))
         logger.info("establish successfully %s" % str(clientaddr))
     except:
         logger.error("can not estabilsh tunnel")
     self.ofchannel2tun[ofsock] = tunnel_sock
     self.tun2ofchannel[tunnel_sock] = ofsock
     self.tunnels.add(tunnel_sock)
     self.ofchannels.add(ofsock)
     self.input_list.append(ofsock)
     self.input_list.append(tunnel_sock)
 def run(self):
     logger.info("update scheduler start")
     while True:
         e = self.__msg_queue.get()
         logger.info("msg = %s", str(e))
         if isinstance(e, Topology):
             self.__update_topology(e)
         elif isinstance(e, tuple):
             priority, match, path = e
             flow = make_flow_key(priority, match)
             self.__flow_status.setdefault(flow, _FlowStatus(key=flow))
             stat = self.__flow_status[flow]
             dep = DependencyGraph().construct(priority, match, stat.path,
                                               path)
             self.__execute(dep)
             stat.path = path
             stat.priority = priority
             stat.match = match
         elif isinstance(e, list):
             new_flow_status = {}
             for priority, match, path in e:
                 assert path is not None
                 flow = make_flow_key(priority, match)
                 status = _FlowStatus(key=flow,
                                      priority=priority,
                                      match=match,
                                      path=path)
                 new_flow_status[flow] = status
             new = set(new_flow_status.keys())
             old = set(self.__flow_status.keys())
             for install in new - old:
                 s = new_flow_status[install]
                 dep = DependencyGraph().construct(s.priority, s.match,
                                                   None, s.path)
                 self.__execute(dep)
             for modify in new & old:
                 s1 = self.__flow_status[modify]
                 s2 = new_flow_status[modify]
                 dep = DependencyGraph().construct(s2.priority, s2.match,
                                                   s1.path, s2.path)
                 self.__execute(dep)
             for remove in old - new:
                 s = self.__flow_status[remove]
                 dep = DependencyGraph().construct(s.priority, s.match,
                                                   s.path, None)
                 self.__execute(dep)
             self.__flow_status = new_flow_status
예제 #11
0
 def on_close(self):
     try:
         logger.warn("%s has disconnected", self.s.getpeername())
     except:
         return
     # remove objects from input_list
     self.input_list.remove(self.s)
     if self.s in self.tunnels:
         self.input_list.remove(self.tun2ofchannel[self.s])
         out = self.tun2ofchannel[self.s]
         out.close()
         self.s.close()
         del self.tun2ofchannel[self.s]
         if self.s in self.tun2idx.keys():
             del self.tun2idx[self.s]
         del self.ofchannel2tun[out]
         self.tunnels.remove(self.s)
         self.tunnelIndex = {
             k: v
             for k, v in self.tunnelIndex.items() if v != self.s
         }
         self.ofchannelIndex = {
             k: v
             for k, v in self.ofchannelIndex.items() if v != out
         }
     else:
         self.input_list.remove(self.ofchannel2tun[self.s])
         out = self.ofchannel2tun[self.s]
         out.close()
         self.s.close()
         del self.ofchannel2tun[self.s]
         del self.tun2ofchannel[out]
         if out in self.tun2idx.keys():
             del self.tun2idx[out]
         try:
             self.tunnels.remove(self.s)
         except:
             logger.info("has been removed")
         self.tunnelIndex = {
             k: v
             for k, v in self.tunnelIndex.items() if v != out
         }
         self.ofchannelIndex = {
             k: v
             for k, v in self.ofchannelIndex.items() if v != self.s
         }
예제 #12
0
 def send_container(self, container):
     logger.info("send_container protobuf object:\n%s" % str(container))
     dpid = container.switch
     sock = self.tunnelIndex[dpid]
     self.__send_container_by_sock(sock, container)
 def __exec(self, container):
     logger.info("exec %s" % str(container))
     self.pending_container.remove(container)
     sock = self.ofchannelIndex[container.switch_addr]
     sock.sendall(container.entry)
     self.Push(container)
 def run(self):
     self.__server.main_loop()
     logger.info("ProxyThread exited")
예제 #15
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)