Ejemplo n.º 1
0
void AdvancedTCPConnector::Disconnect(const IPV4SocketAddress &endpoint,
                                      bool pause) {
  IPPortPair key(endpoint.Host(), endpoint.Port());
  ConnectionMap::iterator iter = m_connections.find(key);
  if (iter == m_connections.end())
    return;

  if (iter->second->state != CONNECTED)
    return;

  iter->second->failed_attempts = 0;

  if (pause) {
    iter->second->state = PAUSED;
  } else {
    // schedule a retry as if this endpoint failed once
    iter->second->state = DISCONNECTED;
    iter->second->retry_timeout = m_ss->RegisterSingleTimeout(
        iter->second->policy->BackOffTime(1),
        ola::NewSingleCallback(
          this,
          &AdvancedTCPConnector::RetryTimeout,
          iter->first));
  }
}
Ejemplo n.º 2
0
void MockUDPSocket::AddExpectedData(IOQueue *ioqueue,
                                    const IPV4SocketAddress &dest) {
    unsigned int size;
    uint8_t *data = IOQueueToBuffer(ioqueue, &size);
    expected_call call = {data, size, dest.Host(), dest.Port(), true};
    m_expected_calls.push(call);
}
Ejemplo n.º 3
0
/*
 * Called when there is data on this socket
 */
void PathportNode::SocketReady(UDPSocket *socket) {
  pathport_packet_s packet;
  ssize_t packet_size = sizeof(packet);
  IPV4SocketAddress source;

  if (!socket->RecvFrom(reinterpret_cast<uint8_t*>(&packet),
                        &packet_size, &source))
    return;

  // skip packets sent by us
  if (source.Host() == m_interface.ip_address)
    return;

  if (packet_size < static_cast<ssize_t>(sizeof(packet.header))) {
    OLA_WARN << "Small pathport packet received, discarding";
    return;
  }
  packet_size -= static_cast<ssize_t>(sizeof(packet.header));

  // Validate header
  if (!ValidateHeader(packet.header)) {
    OLA_WARN << "Invalid pathport packet";
    return;
  }

  uint32_t destination = NetworkToHost(packet.header.destination);
  if (destination != m_device_id &&
      destination != PATHPORT_ID_BROADCAST &&
      destination != PATHPORT_STATUS_GROUP &&
      destination != PATHPORT_CONFIG_GROUP &&
      destination != PATHPORT_DATA_GROUP) {
    ola::network::IPV4Address addr(destination);
    OLA_WARN << "pathport destination not set to us: " << addr;
    return;
  }

  // TODO(simon): Handle multiple pdus here
  pathport_packet_pdu *pdu = &packet.d.pdu;

  if (packet_size < static_cast<ssize_t>(sizeof(pathport_pdu_header))) {
    OLA_WARN << "Pathport packet too small to fit a pdu header";
    return;
  }
  packet_size -= sizeof(pathport_pdu_header);

  switch (NetworkToHost(pdu->head.type)) {
    case PATHPORT_DATA:
      HandleDmxData(pdu->d.data, packet_size);
      break;
    case PATHPORT_ARP_REQUEST:
      SendArpReply();
      break;
    case PATHPORT_ARP_REPLY:
      OLA_DEBUG << "Got pathport arp reply";
      break;
    default:
      OLA_INFO << "Unhandled pathport packet with id: " <<
        NetworkToHost(pdu->head.type);
  }
}
Ejemplo n.º 4
0
/**
 * Inject the data in an IOQueue into the socket. This acts as if the data was
 * received on the UDP socket.
 * @param ioqueue the data to inject
 * @param source the socket address where this fake data came from
 */
void MockUDPSocket::InjectData(IOQueue *ioqueue,
                               const IPV4SocketAddress &source) {
    unsigned int data_size;
    // This incurs a copy, but this is just testing code so it doesn't matter.
    uint8_t *data = IOQueueToBuffer(ioqueue, &data_size);
    expected_call call = {data, data_size, source.Host(), source.Port(), true};
    m_received_data.push(call);
    PerformRead();
}
Ejemplo n.º 5
0
void AdvancedTCPConnector::RemoveEndpoint(const IPV4SocketAddress &endpoint) {
  IPPortPair key(endpoint.Host(), endpoint.Port());
  ConnectionMap::iterator iter = m_connections.find(key);
  if (iter == m_connections.end())
    return;

  AbortConnection(iter->second);
  delete iter->second;
  m_connections.erase(iter);
}
Ejemplo n.º 6
0
void AdvancedTCPConnector::Resume(const IPV4SocketAddress &endpoint) {
  IPPortPair key(endpoint.Host(), endpoint.Port());
  ConnectionMap::iterator iter = m_connections.find(key);
  if (iter == m_connections.end())
    return;

  if (iter->second->state == PAUSED) {
    iter->second->state = DISCONNECTED;
    AttemptConnection(iter->first, iter->second);
  }
}
Ejemplo n.º 7
0
bool AdvancedTCPConnector::GetEndpointState(
    const IPV4SocketAddress &endpoint,
    ConnectionState *connected,
    unsigned int *failed_attempts) const {
  IPPortPair key(endpoint.Host(), endpoint.Port());
  ConnectionMap::const_iterator iter = m_connections.find(key);
  if (iter == m_connections.end())
    return false;

  *connected = iter->second->state;
  *failed_attempts = iter->second->failed_attempts;
  return true;
}
Ejemplo n.º 8
0
/*
 * Receive some data and check it.
 */
void SocketTest::UDPReceiveAndTerminate(UDPSocket *socket) {
  IPV4Address expected_address;
  OLA_ASSERT_TRUE(IPV4Address::FromString("127.0.0.1", &expected_address));

  IPV4SocketAddress source;

  uint8_t buffer[sizeof(test_cstring) + 10];
  ssize_t data_read = sizeof(buffer);
  socket->RecvFrom(buffer, &data_read, &source);
  OLA_ASSERT_EQ(static_cast<ssize_t>(sizeof(test_cstring)), data_read);
  OLA_ASSERT_EQ(expected_address, source.Host());
  m_ss->Terminate();
}
Ejemplo n.º 9
0
/**
 * Add a remote host. This will trigger the connection process to start.
 * If the ip:port already exists this won't do anything.
 * When the connection is successfull the on_connect callback will be run, and
 * ownership of the TCPSocket object is transferred.
 * @param endpoint the IPV4SocketAddress to connect to.
 * @param backoff_policy the BackOffPolicy to use for this connection.
 * @param paused true if we don't want to immediately connect to this peer.
 */
void AdvancedTCPConnector::AddEndpoint(const IPV4SocketAddress &endpoint,
                                       BackOffPolicy *backoff_policy,
                                       bool paused) {
  IPPortPair key(endpoint.Host(), endpoint.Port());
  ConnectionMap::iterator iter = m_connections.find(key);
  if (iter != m_connections.end())
    return;

  // new ip:port
  ConnectionInfo *state = new ConnectionInfo;
  state->state = paused ? PAUSED : DISCONNECTED;
  state->failed_attempts = 0;
  state->retry_timeout = ola::thread::INVALID_TIMEOUT;
  state->connection_id = 0;
  state->policy = backoff_policy;

  m_connections[key] = state;

  if (!paused)
    AttemptConnection(key, state);
}
Ejemplo n.º 10
0
 bool CheckIfMaster() {
   vector<Master>::iterator iter = m_masters.begin();
   uint8_t priority = 0;
   Master *preferred_master = NULL;
   for (; iter != m_masters.end(); ++iter) {
     if (iter->priority > priority &&
         iter->address.Host() != IPV4Address::WildCard()) {
       preferred_master = &(*iter);
       priority = iter->priority;
     }
   }
   return (preferred_master &&
           preferred_master->address.Port() == m_listen_address.Port() &&
           STLContains(m_local_ips, preferred_master->address.Host()));
 }
Ejemplo n.º 11
0
TCPConnector::TCPConnectionID TCPConnector::Connect(
    const IPV4SocketAddress &endpoint,
    const ola::TimeInterval &timeout,
    TCPConnectCallback *callback) {
  struct sockaddr server_address;
  if (!endpoint.ToSockAddr(&server_address, sizeof(server_address))) {
    callback->Run(-1, 0);
    return 0;
  }

  int sd = socket(endpoint.Family(), SOCK_STREAM, 0);
  if (sd < 0) {
    int error = errno;
    OLA_WARN << "socket() failed, " << strerror(error);
    callback->Run(-1, error);
    return 0;
  }

#ifdef _WIN32
  ola::io::DescriptorHandle descriptor;
  descriptor.m_handle.m_fd = sd;
  descriptor.m_type = ola::io::SOCKET_DESCRIPTOR;
#else
  ola::io::DescriptorHandle descriptor = sd;
#endif
  ola::io::ConnectedDescriptor::SetNonBlocking(descriptor);

  int r = connect(sd, &server_address, sizeof(server_address));

  if (r) {
#ifdef _WIN32
    if (WSAGetLastError() != WSAEWOULDBLOCK) {
#else
    if (errno != EINPROGRESS) {
#endif
      int error = errno;
      OLA_WARN << "connect() to " << endpoint << " returned, "
               << strerror(error);
      close(sd);
      callback->Run(-1, error);
      return 0;
    }
  } else {
    // connect returned immediately
    callback->Run(sd, 0);
    return 0;
  }

  PendingTCPConnection *connection = new PendingTCPConnection(
    this,
    endpoint.Host(),
    sd,
    callback);

  m_connections.insert(connection);

  connection->timeout_id = m_ss->RegisterSingleTimeout(
    timeout,
    ola::NewSingleCallback(this, &TCPConnector::TimeoutEvent, connection));

  m_ss->AddWriteDescriptor(connection);
  return connection;
}

bool TCPConnector::Cancel(TCPConnectionID id) {
  PendingTCPConnection *connection =
    const_cast<PendingTCPConnection*>(
        reinterpret_cast<const PendingTCPConnection*>(id));
  ConnectionSet::iterator iter = m_connections.find(connection);
  if (iter == m_connections.end())
    return false;

  if (connection->timeout_id != ola::thread::INVALID_TIMEOUT) {
    m_ss->RemoveTimeout(connection->timeout_id);
    connection->timeout_id = ola::thread::INVALID_TIMEOUT;
  }

  Timeout(iter);
  m_connections.erase(iter);
  return true;
}
Ejemplo n.º 12
0
/**
 * Ownership of the data is not transferred.
 */
void MockUDPSocket::InjectData(const uint8_t *data,
                               unsigned int size,
                               const IPV4SocketAddress &source) {
    InjectData(data, size, source.Host(), source.Port());
}