Пример #1
0
  def __init__ (self, sock):
    self._previous_stats = []

    self.ofnexus = _dummyOFNexus
    self.sock = sock
    self._sock_lock = threading.Lock()
    self._delayed_action = DelayedAction()
    self.buf = ''
    Connection.ID += 1
    self.ID = Connection.ID
    # TODO: dpid and features don't belong here; they should be eventually
    # be in topology.switch
    self.dpid = None
    self.features = None
    self.disconnected = False
    self.connect_time = None

    self.send(of.ofp_hello())
Пример #2
0
class Connection (EventMixin):
  """
  A Connection object represents a single TCP session with an
  openflow-enabled switch.
  If the switch reconnects, a new connection object is instantiated.
  """
  _eventMixin_events = set([
    ConnectionUp,
    ConnectionDown,
    PortStatus,
    FlowRemoved,
    PacketIn,
    ErrorIn,
    BarrierIn,
    RawStatsReply,
    SwitchDescReceived,
    FlowStatsReceived,
    AggregateFlowStatsReceived,
    TableStatsReceived,
    PortStatsReceived,
    QueueStatsReceived,
    FlowRemoved,
  ])
  
  # Globally unique identifier for the Connection instance
  ID = 0

  def msg (self, m):
    #print str(self), m
    log.debug(str(self) + " " + str(m))
  def err (self, m):
    #print str(self), m
    log.error(str(self) + " " + str(m))
  def info (self, m):
    pass
    #print str(self), m
    log.info(str(self) + " " + str(m))

  def __init__ (self, sock):
    self._previous_stats = []

    self.ofnexus = _dummyOFNexus
    self.sock = sock
    self._sock_lock = threading.Lock()
    self._delayed_action = DelayedAction()
    self.buf = ''
    Connection.ID += 1
    self.ID = Connection.ID
    # TODO: dpid and features don't belong here; they should be eventually
    # be in topology.switch
    self.dpid = None
    self.features = None
    self.disconnected = False
    self.connect_time = None

    self.send(of.ofp_hello())

    #TODO: set a time that makes sure we actually establish a connection by
    #      some timeout

  def fileno (self):
    return self.sock.fileno()

  def close (self):
    if not self.disconnected:
      self.info("closing connection")
    else:
      #self.msg("closing connection")
      pass
    try:
        with self._sock_lock:
            self.sock.shutdown(socket.SHUT_RDWR)
    except:
      pass
    try:
        with self._sock_lock:
            self.sock.close()
    except:
      pass

  def disconnect (self):
    """
    disconnect this Connection (usually not invoked manually).
    """
    if self.disconnected:
      self.err("already disconnected!")
    self.msg("disconnecting")
    self.disconnected = True
    try:
      self.ofnexus._disconnect(self.dpid)
    except:
      pass
    """
    try:
      if self.dpid != None:
        self.ofnexus.raiseEvent(ConnectionDown(self))
    except:
      self.err("ConnectionDown event caused exception")
    """
    if self.dpid != None:
      self.ofnexus.raiseEventNoErrors(ConnectionDown(self))

    try:
      #deferredSender.kill(self)
      pass
    except:
      pass
    try:
        with self._sock_lock:
            self.sock.shutdown(socket.SHUT_RDWR)
    except:
      pass
    try:
      pass
      #TODO disconnect notification
    except:
      pass

  def send (self, data):
    """
    Send raw data to the switch.

    Generally, data is a bytes object.  If not, we check if it has a pack()
    method and call it (hoping the result will be a bytes object).  This
    way, you can just pass one of the OpenFlow objects from the OpenFlow
    library to it and get the expected result, for example.
    """
    if self.disconnected: return
    data_bytes = data
    if type(data) is not bytes:
      if hasattr(data, 'pack'):
        data_bytes = data.pack()

    self._delayed_action.add_job(data, self._delayed_send, data_bytes)


  def _delayed_send(self, data):
    
    if deferredSender.sending:
      log.debug("deferred sender is sending!")
      deferredSender.send(self, data)
      return
    try:
      with self._sock_lock:
        l = self.sock.send(data)
      if l != len(data):
        self.msg("Didn't send complete buffer.")
        data = data[l:]
        deferredSender.send(self, data)
    except socket.error as (errno, strerror):
      if errno == EAGAIN:
        self.msg("Out of send buffer space.  " +
                 "Consider increasing SO_SNDBUF.")
        deferredSender.send(self, data)
      else:
        self.msg("Socket error: " + strerror)
        self.disconnect()