Example #1
0
void cXVDRServer::NewClientConnected(int fd)
{
  char buf[64];
  struct sockaddr_in sin;
  socklen_t len = sizeof(sin);

  if (getpeername(fd, (struct sockaddr *)&sin, &len))
  {
    ERRORLOG("getpeername() failed, dropping new incoming connection %d", m_IdCnt);
    close(fd);
    return;
  }

  cAllowedHosts AllowedHosts(m_AllowedHostsFile);
  if (!AllowedHosts.Acceptable(sin.sin_addr.s_addr))
  {
    ERRORLOG("Address not allowed to connect (%s)", *m_AllowedHostsFile);
    close(fd);
    return;
  }

  if (fcntl(fd, F_SETFL, fcntl (fd, F_GETFL) | O_NONBLOCK) == -1)
  {
    ERRORLOG("Error setting control socket to nonblocking mode");
    close(fd);
    return;
  }

  int val = 1;
  setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));

#ifndef __FreeBSD__
  val = 30;
  setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &val, sizeof(val));

  val = 15;
  setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &val, sizeof(val));

  val = 5;
  setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &val, sizeof(val));
#endif

  val = 1;
  setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));

  INFOLOG("Client with ID %d connected: %s", m_IdCnt, cxSocket::ip2txt(sin.sin_addr.s_addr, sin.sin_port, buf));
  cXVDRClient *connection = new cXVDRClient(fd, m_IdCnt, cxSocket::ip2txt(sin.sin_addr.s_addr, sin.sin_port, buf));
  m_clients.push_back(connection);
  m_IdCnt++;
}
void cXVDRServer::NewClientConnected(int fd)
{
  struct sockaddr_storage sin;
  socklen_t len = sizeof(sin);
  in_addr_t *ipv4_addr = NULL;

  if (getpeername(fd, (struct sockaddr *)&sin, &len))
  {
    ERRORLOG("getpeername() failed, dropping new incoming connection %d", m_IdCnt);
    close(fd);
    return;
  }

  if (!m_IPv4Fallback)
  {
    if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&sin)->sin6_addr) ||
        IN6_IS_ADDR_V4COMPAT(&((struct sockaddr_in6 *)&sin)->sin6_addr))
      ipv4_addr = &((struct sockaddr_in6 *)&sin)->sin6_addr.s6_addr32[3];
  }
  else
    ipv4_addr = &((struct sockaddr_in *)&sin)->sin_addr.s_addr;

  // Acceptable() method only supports in_addr_t argument so we're currently checking IPv4 hosts only
  if (ipv4_addr)
  {
    cAllowedHosts AllowedHosts(m_AllowedHostsFile);
    if (!AllowedHosts.Acceptable(*ipv4_addr))
    {
      ERRORLOG("Address not allowed to connect (%s)", *m_AllowedHostsFile);
      close(fd);
      return;
    }
  }

  if (fcntl(fd, F_SETFL, fcntl (fd, F_GETFL) | O_NONBLOCK) == -1)
  {
    ERRORLOG("Error setting control socket to nonblocking mode");
    close(fd);
    return;
  }

  int val = 1;
  setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));

#ifndef __FreeBSD__
  val = 30;
  setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &val, sizeof(val));

  val = 15;
  setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &val, sizeof(val));

  val = 5;
  setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &val, sizeof(val));
#endif

  val = 1;
  setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));

  if (!m_IPv4Fallback)
    INFOLOG("Client %s:%i with ID %d connected.", xvdr_inet_ntoa(((struct sockaddr_in6 *)&sin)->sin6_addr), ((struct sockaddr_in6 *)&sin)->sin6_port, m_IdCnt);
  else
    INFOLOG("Client %s:%i with ID %d connected.", inet_ntoa(((struct sockaddr_in *)&sin)->sin_addr), ((struct sockaddr_in *)&sin)->sin_port, m_IdCnt);
  cXVDRClient *connection = new cXVDRClient(fd, m_IdCnt);
  m_clients.push_back(connection);
  m_IdCnt++;
}