Esempio n. 1
0
static Boolean unsetGroupsockBySocket(Groupsock const* groupsock) {
  do {
    if (groupsock == NULL) break;

    int sock = groupsock->socketNum();
    // Make sure "sock" is in bounds:
    if (sock < 0) break;

    HashTable*& sockets = getSocketTable(groupsock->env());

    Groupsock* gs = (Groupsock*)sockets->Lookup((char*)(long)sock);
    if (gs == NULL || gs != groupsock) break;
    sockets->Remove((char*)(long)sock);

    if (sockets->IsEmpty()) {
      // We can also delete the table (to reclaim space):
      delete sockets; sockets = NULL;
      reclaimGroupsockPriv(gs->env());
    }

    return True;
  } while (0);

  return False;
}
Esempio n. 2
0
NoReuse::~NoReuse() {
  groupsockPriv(fEnv)->reuseFlag = 1;
  reclaimGroupsockPriv(fEnv);
}
Esempio n. 3
0
int setupDatagramSocket(UsageEnvironment& env, Port port) {
  if (!initializeWinsockIfNecessary()) {
    socketErr(env, "Failed to initialize 'winsock': ");
    return -1;
  }

  int newSocket = createSocket(SOCK_DGRAM);
  if (newSocket < 0) {
    socketErr(env, "unable to create datagram socket: ");
    return newSocket;
  }

  int reuseFlag = groupsockPriv(env)->reuseFlag;
  reclaimGroupsockPriv(env);
  if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR,
		 (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
    socketErr(env, "setsockopt(SO_REUSEADDR) error: ");
    closeSocket(newSocket);
    return -1;
  }

#if defined(__WIN32__) || defined(_WIN32)
  // Windoze doesn't properly handle SO_REUSEPORT or IP_MULTICAST_LOOP
#else
#ifdef SO_REUSEPORT
  if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT,
		 (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
    socketErr(env, "setsockopt(SO_REUSEPORT) error: ");
    closeSocket(newSocket);
    return -1;
  }
#endif

#ifdef IP_MULTICAST_LOOP
  const u_int8_t loop = 1;
  if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
		 (const char*)&loop, sizeof loop) < 0) {
    socketErr(env, "setsockopt(IP_MULTICAST_LOOP) error: ");
    closeSocket(newSocket);
    return -1;
  }
#endif
#endif

  // Note: Windoze requires binding, even if the port number is 0
  netAddressBits addr = INADDR_ANY;
#if defined(__WIN32__) || defined(_WIN32)
#else
  if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) {
#endif
    if (port.num() == 0) addr = ReceivingInterfaceAddr;
    MAKE_SOCKADDR_IN(name, addr, port.num());
    if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
      char tmpBuffer[100];
      sprintf(tmpBuffer, "bind() error (port number: %d): ",
	      ntohs(port.num()));
      socketErr(env, tmpBuffer);
      closeSocket(newSocket);
      return -1;
    }
#if defined(__WIN32__) || defined(_WIN32)
#else
  }
#endif

  // Set the sending interface for multicasts, if it's not the default:
  if (SendingInterfaceAddr != INADDR_ANY) {
    struct in_addr addr;
    addr.s_addr = SendingInterfaceAddr;

    if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_IF,
		   (const char*)&addr, sizeof addr) < 0) {
      socketErr(env, "error setting outgoing multicast interface: ");
      closeSocket(newSocket);
      return -1;
    }
  }

  return newSocket;
}
Esempio n. 4
0
int setupStreamSocket(UsageEnvironment& env,
                      Port port, Boolean makeNonBlocking) {
  if (!initializeWinsockIfNecessary()) {
    socketErr(env, "Failed to initialize 'winsock': ");
    return -1;
  }

  int newSocket = createSocket(SOCK_STREAM);
  if (newSocket < 0) {
    socketErr(env, "unable to create stream socket: ");
    return newSocket;
  }

  int reuseFlag = groupsockPriv(env)->reuseFlag;
  reclaimGroupsockPriv(env);
  if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR,
		 (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
    socketErr(env, "setsockopt(SO_REUSEADDR) error: ");
    closeSocket(newSocket);
    return -1;
  }

  // SO_REUSEPORT doesn't really make sense for TCP sockets, so we
  // normally don't set them.  However, if you really want to do this
  // #define REUSE_FOR_TCP
#ifdef REUSE_FOR_TCP
#if defined(__WIN32__) || defined(_WIN32)
  // Windoze doesn't properly handle SO_REUSEPORT
#else
#ifdef SO_REUSEPORT
  if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT,
		 (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
    socketErr(env, "setsockopt(SO_REUSEPORT) error: ");
    closeSocket(newSocket);
    return -1;
  }
#endif
#endif
#endif

  // Note: Windoze requires binding, even if the port number is 0
#if defined(__WIN32__) || defined(_WIN32)
#else
  if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) {
#endif
    MAKE_SOCKADDR_IN(name, ReceivingInterfaceAddr, port.num());
    if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
      char tmpBuffer[100];
      sprintf(tmpBuffer, "bind() error (port number: %d): ",
	      ntohs(port.num()));
      socketErr(env, tmpBuffer);
      closeSocket(newSocket);
      return -1;
    }
#if defined(__WIN32__) || defined(_WIN32)
#else
  }
#endif

  if (makeNonBlocking) {
    if (!makeSocketNonBlocking(newSocket)) {
      socketErr(env, "failed to make non-blocking: ");
      closeSocket(newSocket);
      return -1;
    }
  }

  return newSocket;
}