Socket& Socket::bind(int (*try_port)()) { if (try_port == 0) try_port = &rand; SBL_ASSERT(is_valid()); struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; int status = -1; for (int n = 0; n < 100 && status < 0; n++) { addr.sin_port = htons(try_port()); status = ::bind(id(), (struct sockaddr *) &addr, sizeof(addr)); } SBL_THROW_IF(status < 0, "unable to find a port to bind"); return *this; }
error_code relaylib_start (RIP_MANAGER_INFO* rmi, BOOL search_ports, u_short relay_port, u_short max_port, u_short *port_used, char *if_name, int max_connections, char *relay_ip, int have_metadata) { int ret; #ifdef WIN32 WSADATA wsd; #endif RELAYLIB_INFO* rli = &rmi->relaylib_info; /* GCS: These were globally initialized... */ rli->m_listensock = SOCKET_ERROR; rli->m_running = FALSE; rli->m_running_accept = FALSE; rli->m_running_send = FALSE; debug_printf ("relaylib_start()\n"); rmi->relay_list = 0; rmi->relay_list_len = 0; #ifdef WIN32 if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) { debug_printf ("relaylib_init(): SR_ERROR_CANT_BIND_ON_PORT\n"); return SR_ERROR_CANT_BIND_ON_PORT; } #endif if (relay_port < 1 || !port_used) { debug_printf ("relaylib_init(): SR_ERROR_INVALID_PARAM\n"); return SR_ERROR_INVALID_PARAM; } #ifndef WIN32 // catch a SIGPIPE if send fails signal(SIGPIPE, catch_pipe); #endif rli->m_sem_not_connected = threadlib_create_sem(); rmi->relay_list_sem = threadlib_create_sem(); threadlib_signal_sem (&rmi->relay_list_sem); // NOTE: we need to signal it here in case we try to destroy // relaylib before the thread starts! threadlib_signal_sem (&rli->m_sem_not_connected); //m_max_connections = max_connections; //m_have_metadata = have_metadata; *port_used = 0; if (!search_ports) max_port = relay_port; for(;relay_port <= max_port; relay_port++) { ret = try_port (rli, (u_short) relay_port, if_name, relay_ip); if (ret == SR_ERROR_CANT_BIND_ON_PORT) continue; // Keep searching. if (ret == SR_SUCCESS) { *port_used = relay_port; debug_printf ("Relay: Listening on port %d\n", relay_port); ret = SR_SUCCESS; if (!rli->m_running) { ret = relaylib_start_threads (rmi); } return ret; } else { return ret; } } return SR_ERROR_CANT_BIND_ON_PORT; }