UtlBoolean SipProtocolServerBase::startListener() { # ifdef TEST_PRINT osPrintf("SIP Server binding to port %d\n", serverPort); # endif UtlHashMapIterator iter(mServerSocketMap); UtlVoidPtr* pSocketContainer = NULL; UtlString* pKey; while ((pKey =(UtlString*)iter())) { OsSocket* pSocket = NULL; SipClient* pServer = NULL; UtlVoidPtr* pServerContainer = NULL; UtlString localIp = *pKey; pSocketContainer = (UtlVoidPtr*)iter.value(); if (pSocketContainer) { pSocket = (OsSocket*)pSocketContainer->getValue(); } pServerContainer = (UtlVoidPtr*)mServers.findValue(&localIp); if (!pServerContainer) { pServer = new SipClient(pSocket); // This used to be done at the end of this else statement // however there is a race and the userAgent must be set before // starting this client. I think the race occurs if there is // immediately an incoming message on the socket. if(mSipUserAgent) { if (pServer) { pServer->setUserAgent(mSipUserAgent); } } this->mServers.insertKeyAndValue(new UtlString(localIp), new UtlVoidPtr((void*)pServer)); pServer->start(); } else { pServer = (SipClient*) pServerContainer->getValue(); if(mSipUserAgent) { if (pServer) { pServer->setUserAgent(mSipUserAgent); } } } } return(TRUE); }
void SipProtocolServerBase::startClients() { int iteratorHandle = mClientList.getIteratorHandle(); SipClient* client = NULL; while ((client = (SipClient*)mClientList.next(iteratorHandle))) { client->start(); } mClientList.releaseIteratorHandle(iteratorHandle); }
SipClient* SipProtocolServerBase::createClient(const char* hostAddress, int hostPort, const char* localIp) { UtlString remoteHostAddr; UtlBoolean clientStarted = FALSE; mClientLock.acquireWrite(); SipClient* client = getClient(hostAddress, hostPort, localIp); if(! client) { # if TEST_CLIENT_CREATION OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipProtocolServerBase::createClient( %s, %d )", hostAddress, hostPort); # endif if(!portIsValid(hostPort)) { hostPort = mDefaultPort; # if TEST_CLIENT_CREATION OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipProtocolServerBase::createClient port defaulting to %d", hostPort); # endif } OsTime time; OsDateTime::getCurTimeSinceBoot(time); long beforeSecs = time.seconds(); OsSocket* clientSocket = buildClientSocket(hostPort, hostAddress, localIp); OsDateTime::getCurTimeSinceBoot(time); long afterSecs = time.seconds(); if(afterSecs - beforeSecs > 1) { OsSysLog::add(FAC_SIP, PRI_WARNING, "SIP %s socket create for %s:%d took %d seconds", mProtocolString.data(), hostAddress, hostPort, (int)(afterSecs - beforeSecs)); } UtlBoolean isOk = clientSocket->isOk(); int writeWait = 3000; // mSec UtlBoolean isReadyToWrite = clientSocket->isReadyToWrite(writeWait); if(!isReadyToWrite) { OsSysLog::add(FAC_SIP, PRI_WARNING, "SIP %s socket %s:%d not ready for writing after %d seconds", mProtocolString.data(), hostAddress, hostPort, (int) (writeWait/1000)); } if(isOk && isReadyToWrite) { #ifdef TEST osPrintf("Socket OK, creating client\n"); #endif client = new SipClient(clientSocket) ; if (client && mSipUserAgent->getUseRport() && clientSocket->getIpProtocol() == OsSocket::UDP) { client->setSharedSocket(TRUE) ; } #ifdef TEST osPrintf("Created client\n"); #endif if(mSipUserAgent) { client->setUserAgent(mSipUserAgent); } if (clientSocket->getIpProtocol() != OsSocket::UDP) { //osPrintf("starting client\n"); clientStarted = client->start(); if(!clientStarted) { osPrintf("SIP %s client failed to start\n", mProtocolString.data()); } } OsSysLog::add(FAC_SIP, PRI_DEBUG, "Sip%sServer::createClient client: %p %s -> %s:%d", mProtocolString.data(), client, localIp, hostAddress, hostPort); mClientList.push(client); } // The socket failed to be connected else { if(clientSocket) { if (!mSipUserAgent->getUseRport() || (clientSocket->getIpProtocol() == OsSocket::TCP)) { delete clientSocket; } clientSocket = NULL; } OsSysLog::add(FAC_SIP, PRI_WARNING, "Sip%sServer::createClient client %p Failed to create socket %s -> %s:%d", mProtocolString.data(), this, localIp, hostAddress, hostPort); } } int isBusy = FALSE; if(client) { isBusy = client->isInUseForWrite(); if(!isBusy) client->markInUseForWrite(); } mClientLock.releaseWrite(); if(client && isBusy) { if(!waitForClientToWrite(client)) client = NULL; } return(client); }