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)
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()
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()
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
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
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 }
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")
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)