void SipUdpServer::createServerSocket(const char* szBindAddr, int& port, const UtlBoolean& bUseNextAvailablePort, int udpReadBufferSize) { // Create the socket. OsStunDatagramSocket* pSocket = new OsStunDatagramSocket(0, NULL, port, szBindAddr, FALSE); // If the socket is busy or unbindable and the user requested using the // next available port, try the next SIP_MAX_PORT_RANGE ports. if (bUseNextAvailablePort) { for (int i=1; !pSocket->isOk() && i<=SIP_MAX_PORT_RANGE; i++) { delete pSocket; pSocket = new OsStunDatagramSocket(0, NULL, port+i, szBindAddr, FALSE); } } // If we opened the socket. if (pSocket->isOk()) { // Inform the SipUserAgent of the contact address. if (mSipUserAgent) { port = pSocket->getLocalHostPort(); CONTACT_ADDRESS contact; strcpy(contact.cIpAddress, szBindAddr); contact.iPort = port; contact.eContactType = LOCAL; char szAdapterName[16]; memset((void*)szAdapterName, 0, sizeof(szAdapterName)); // null out the string getContactAdapterName(szAdapterName, contact.cIpAddress); strcpy(contact.cInterface, szAdapterName); mSipUserAgent->addContactAddress(contact); } // Add address and port to the maps. UtlString* address = new UtlString(szBindAddr); mServerSocketMap.insertKeyAndValue(address, pSocket); port = pSocket->getLocalHostPort(); mServerPortMap.insertKeyAndValue(address, new UtlInt(port)); // Get the UDP buffer size from the kernel. int sockbufsize = 0; // The type of 'size' depends on the platform. #if defined(__pingtel_on_posix__) socklen_t #else int #endif size = sizeof (sockbufsize); getsockopt(pSocket->getSocketDescriptor(), SOL_SOCKET, SO_RCVBUF, (char*) &sockbufsize, &size); #ifdef LOG_SIZE OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipUdpServer[%s]::SipUdpServer UDP buffer size: %d size: %d", getName().data(), sockbufsize, size); #endif /* LOG_SIZE */ // If the user specified a UDP buffer size, attempt to set it. if (udpReadBufferSize > 0) { setsockopt(pSocket->getSocketDescriptor(), SOL_SOCKET, SO_RCVBUF, (char*) &udpReadBufferSize, sizeof (udpReadBufferSize)); getsockopt(pSocket->getSocketDescriptor(), SOL_SOCKET, SO_RCVBUF, (char*) &sockbufsize, &size); #ifdef LOG_SIZE OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipUdpServer[%s]::SipUdpServer reset UDP buffer size: %d size: %d", getName().data(), sockbufsize, size); #endif /* LOG_SIZE */ } } }
OsStatus SipUdpServer::createServerSocket(const char* szBoundIp, int& port, const UtlBoolean& bUseNextAvailablePort, int udpReadBufferSize) { OsStatus rc = OS_FAILED; OsStunDatagramSocket* pSocket = new OsStunDatagramSocket(0, NULL, port, szBoundIp, FALSE); if (pSocket) { // If the socket is busy or unbindable and the user requested using the // next available port, try the next SIP_MAX_PORT_RANGE ports. if (bUseNextAvailablePort & portIsValid(port) && pSocket && !pSocket->isOk()) { for (int i=1; i<=SIP_MAX_PORT_RANGE; i++) { delete pSocket ; pSocket = new OsStunDatagramSocket(0, NULL, port+i, szBoundIp, FALSE); if (pSocket->isOk()) { break ; } } } } if (pSocket) { port = pSocket->getLocalHostPort(); CONTACT_ADDRESS contact; strcpy(contact.cIpAddress, szBoundIp); contact.iPort = port; contact.eContactType = LOCAL; char szAdapterName[16]; memset((void*)szAdapterName, 0, sizeof(szAdapterName)); // null out the string getContactAdapterName(szAdapterName, contact.cIpAddress); strcpy(contact.cInterface, szAdapterName); mSipUserAgent->addContactAddress(contact); // add address and port to the maps mServerSocketMap.insertKeyAndValue(new UtlString(szBoundIp), new UtlVoidPtr((void*)pSocket)); port = pSocket->getLocalHostPort() ; mServerPortMap.insertKeyAndValue(new UtlString(szBoundIp), new UtlInt(port)); int sockbufsize = 0; int size = sizeof(int); getsockopt(pSocket->getSocketDescriptor(), SOL_SOCKET, SO_RCVBUF, (char*)&sockbufsize, #if defined(__pingtel_on_posix__) (socklen_t*) // caste #endif &size); #ifdef LOG_SIZE OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipUdpServer::SipUdpServer UDP buffer size: %d size: %d\n", sockbufsize, size); #endif /* LOG_SIZE */ if(udpReadBufferSize > 0) { setsockopt(pSocket->getSocketDescriptor(), SOL_SOCKET, SO_RCVBUF, (char*)&udpReadBufferSize, sizeof(int)); getsockopt(pSocket->getSocketDescriptor(), SOL_SOCKET, SO_RCVBUF, (char*)&sockbufsize, #if defined(__pingtel_on_posix__) (socklen_t*) // caste #endif &size); #ifdef LOG_SIZE OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipUdpServer::SipUdpServer reset UDP buffer size: %d size: %d\n", sockbufsize, size); #endif /* LOG_SIZE */ } } return rc; }
OsStatus CpPhoneMediaInterface::createConnection(int& connectionId, void* videoWindowHandle) { int localPort ; OsStatus returnCode; { connectionId = mpFlowGraph->createConnection(); mpFactoryImpl->getNextRtpPort(localPort); int iNextRtpPort = localPort ; CpPhoneMediaConnection* mediaConnection = new CpPhoneMediaConnection(); OsSysLog::add(FAC_CP, PRI_DEBUG, "CpPhoneMediaInterface::createConnection creating a new connection %p", mediaConnection); *mediaConnection = connectionId; mMediaConnections.append(mediaConnection); // Create the sockets // Eventually this should use a specified address as this // host may be multi-homed OsStunDatagramSocket* rtpSocket = new OsStunDatagramSocket(0, NULL, localPort, mLocalAddress.data(), mStunServer.length() != 0, mStunServer, mStunRefreshPeriodSecs); OsStunDatagramSocket* rtcpSocket = new OsStunDatagramSocket(0, NULL, localPort == 0 ? 0 : localPort + 1, mLocalAddress.data(), mStunServer.length() != 0, mStunServer, mStunRefreshPeriodSecs); // Validate local port is not auto-selecting. if (localPort != 0) { // If either of the sockets are bad (e.g. already in use) or // if either have stuff on them to read (e.g. someone is // sending junk to the ports, look for another port pair while(!rtpSocket->isOk() || !rtcpSocket->isOk() || rtcpSocket->isReadyToRead() || rtpSocket->isReadyToRead(60)) { localPort +=2; // This should use mLastRtpPort instead of some // hardcoded MAX, but I do not think mLastRtpPort // is set correctly in all of the products. if(localPort > iNextRtpPort + MAX_RTP_PORTS) { OsSysLog::add(FAC_CP, PRI_ERR, "No available ports for RTP and RTCP in range %d - %d", iNextRtpPort, iNextRtpPort + MAX_RTP_PORTS); break; // time to give up } delete rtpSocket; delete rtcpSocket; rtpSocket = new OsStunDatagramSocket(0, NULL, localPort, mLocalAddress.data(), mStunServer.length() != 0, mStunServer, mStunRefreshPeriodSecs); rtcpSocket = new OsStunDatagramSocket(0, NULL, localPort + 1, mLocalAddress.data(), mStunServer.length() != 0, mStunServer, mStunRefreshPeriodSecs); } } // Set a maximum on the buffers for the sockets so // that the network stack does not get swamped by early media // from the other side; { int sRtp, sRtcp, oRtp, oRtcp, optlen; sRtp = rtpSocket->getSocketDescriptor(); sRtcp = rtcpSocket->getSocketDescriptor(); optlen = sizeof(int); oRtp = 2000; setsockopt(sRtp, SOL_SOCKET, SO_RCVBUF, (char *) (&oRtp), optlen); oRtcp = 500; setsockopt(sRtcp, SOL_SOCKET, SO_RCVBUF, (char *) (&oRtcp), optlen); // Set the type of service (DiffServ code point) to low delay int tos = mExpeditedIpTos; setsockopt (sRtp, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)); setsockopt (sRtcp, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)); } // Store settings mediaConnection->mpRtpSocket = rtpSocket; mediaConnection->mpRtcpSocket = rtcpSocket; mediaConnection->mRtpReceivePort = rtpSocket->getLocalHostPort() ; mediaConnection->mRtcpReceivePort = rtcpSocket->getLocalHostPort() ; mediaConnection->mpCodecFactory = new SdpCodecFactory(mSupportedCodecs); mediaConnection->mpCodecFactory->bindPayloadTypes(); OsSysLog::add(FAC_CP, PRI_DEBUG, "CpPhoneMediaInterface::createConnection creating a new RTP socket: %p descriptor: %d", mediaConnection->mpRtpSocket, mediaConnection->mpRtpSocket->getSocketDescriptor()); OsSysLog::add(FAC_CP, PRI_DEBUG, "CpPhoneMediaInterface::createConnection creating a new RTCP socket: %p descriptor: %d", mediaConnection->mpRtcpSocket, mediaConnection->mpRtcpSocket->getSocketDescriptor()); OsSysLog::add(FAC_CP, PRI_DEBUG, "CpPhoneMediaInterface::createConnection creating a new SdpCodecFactory %p", mediaConnection->mpCodecFactory); returnCode = OS_SUCCESS; } return(returnCode); }