int iax_init(int preferredportno) { int portno = preferredportno; struct sockaddr_in sin; unsigned int sinlen; int flags; if(iax_recvfrom == (recvfrom_t) recvfrom) { if (netfd > -1) { /* Sokay, just don't do anything */ DEBU(G "Already initialized."); return 0; } netfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (netfd < 0) { DEBU(G "Unable to allocate UDP socket\n"); IAXERROR "Unable to allocate UDP socket\n"); return -1; } if (preferredportno == 0) preferredportno = IAX_DEFAULT_PORTNO; if (preferredportno < 0) preferredportno = 0; sin.sin_family = AF_INET; sin.sin_addr.s_addr = 0; sin.sin_port = htons((short)preferredportno); if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0) { #if defined(WIN32) || defined(_WIN32_WCE) if (WSAGetLastError() == WSAEADDRINUSE) #else if (errno == EADDRINUSE) #endif { /*the port is already in use, so bind to a free port chosen by the IP stack*/ DEBU(G "Unable to bind to preferred port - port is in use. Trying to bind to a free one"); sin.sin_port = htons((short)0); if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0) { IAXERROR "Unable to bind UDP socket\n"); return -1; } } else { IAXERROR "Unable to bind UDP socket\n"); return -1; } } sinlen = sizeof(sin); if (getsockname(netfd, (struct sockaddr *) &sin, &sinlen) < 0) { close(netfd); netfd = -1; DEBU(G "Unable to figure out what I'm bound to."); IAXERROR "Unable to determine bound port number."); return -1; } #if defined(WIN32) || defined(_WIN32_WCE) flags = 1; if (ioctlsocket(netfd,FIONBIO,(unsigned long *) &flags)) { closesocket(netfd); netfd = -1; DEBU(G "Unable to set non-blocking mode."); IAXERROR "Unable to set non-blocking mode."); return -1; } #else if ((flags = fcntl(netfd, F_GETFL)) < 0) { close(netfd); netfd = -1; DEBU(G "Unable to retrieve socket flags."); IAXERROR "Unable to retrieve socket flags."); return -1; } if (fcntl(netfd, F_SETFL, flags | O_NONBLOCK) < 0) { close(netfd); netfd = -1; DEBU(G "Unable to set non-blocking mode."); IAXERROR "Unable to set non-blocking mode."); return -1; } #endif portno = ntohs(sin.sin_port); } srand(time(NULL)); callnums = rand() % 32767 + 1; transfer_id = rand() % 32767 + 1; DEBU(G "Started on port %d\n", portno); return portno; }