void SipUdpServer::printStatus() { SipClient* pServer = NULL; UtlHashMapIterator iterator(mServers); UtlVoidPtr* pServerContainer = NULL; UtlString* pKey = NULL; while (pKey = (UtlString*)iterator()) { pServerContainer = (UtlVoidPtr*) iterator.value(); if (pServerContainer) { pServer = (SipClient*)pServerContainer->getValue(); } if (pServer) { UtlString clientNames; long clientTouchedTime = pServer->getLastTouchedTime(); UtlBoolean clientOk = pServer->isOk(); pServer->getClientNames(clientNames); osPrintf("UDP server %p last used: %ld ok: %d names: \n%s \n", this, clientTouchedTime, clientOk, clientNames.data()); SipProtocolServerBase::printStatus(); } } }
void SipProtocolServerBase::printStatus() { int numClients = mClientList.getCount(); int iteratorHandle = mClientList.getIteratorHandle(); OsTime time; OsDateTime::getCurTimeSinceBoot(time); long currentTime = time.seconds(); //long currentTime = OsDateTime::getSecsSinceEpoch(); SipClient* client; UtlString clientNames; long clientTouchedTime; UtlBoolean clientOk; osPrintf("%s %d clients in list at: %ld\n", mProtocolString.data(), numClients, currentTime); while ((client = (SipClient*)mClientList.next(iteratorHandle))) { // Remove this or any other bad client clientTouchedTime = client->getLastTouchedTime(); clientOk = client->isOk(); client->getClientNames(clientNames); osPrintf("%s client %p last used: %ld ok: %d names:\n%s\n", mProtocolString.data(), this, clientTouchedTime, clientOk, clientNames.data()); } mClientList.releaseIteratorHandle(iteratorHandle); }
UtlBoolean SipProtocolServerBase::send(SipMessage* message, const char* hostAddress, int hostPort) { UtlBoolean sendOk = FALSE; UtlString localIp(message->getLocalIp()); if (localIp.length() < 1) { localIp = mDefaultIp; } SipClient* client = createClient(hostAddress, hostPort, localIp); if(client) { int isBusy = client->isInUseForWrite(); UtlString clientNames; client->getClientNames(clientNames); OsSysLog::add(FAC_SIP, PRI_DEBUG, "Sip%sServerBase::send %p isInUseForWrite %d, client info\n %s", mProtocolString.data(), client, isBusy, clientNames.data()); sendOk = client->sendTo(*message, hostAddress, hostPort); if(!sendOk) { OsTask* pCallingTask = OsTask::getCurrentTask(); OsTaskId_t callingTaskId = -1; OsTaskId_t clientTaskId = -1; if ( pCallingTask ) { pCallingTask->id(callingTaskId); } client->id(clientTaskId); if (clientTaskId != callingTaskId) { // Do not need to clientLock.acquireWrite(); // as deleteClient uses the locking list lock // which is all that is needed as the client is // already marked as busy when we called // createClient above. deleteClient(client); client = NULL; } } } if(client) { releaseClient(client); } return(sendOk); }
void SipProtocolServerBase::deleteClient(SipClient* sipClient) { // Find the client in the list of clients and shut it down int iteratorHandle = mClientList.getIteratorHandle(); SipClient* client = NULL; #ifdef TEST_PRINT OsSysLog::add(FAC_SIP, PRI_DEBUG, "Sip%sServer::deleteClient(%p)", mProtocolString.data(), sipClient); #endif while ((client = (SipClient*)mClientList.next(iteratorHandle))) { // Remove this bad client // This used to be a little over zealous and delete any // SipClient that was not ok. It was not checking if // the SipClient was busy or not so bad things could // happen. This is now on the conservative side and // deleting only the thing it is supposed to. if(client == sipClient) { #ifdef TEST_PRINT UtlString clientNames; client->getClientNames(clientNames); OsSysLog::add(FAC_SIP, PRI_DEBUG, "Removing %s client %p names:\n%s", mProtocolString.data(), this, clientNames.data()); #endif mClientList.remove(iteratorHandle); break; } } mClientList.releaseIteratorHandle(iteratorHandle); // Delete the client outside the lock on the list as // it can create a deadlock. If the client is doing // an operation that requires the locking list, the // client gets blocked from shutting down. We then // block here trying to delete the client forever. if(client) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "Sip%sServer::deleteClient(%p) done", mProtocolString.data(), sipClient); delete client; client = NULL; } #ifdef TEST_PRINT OsSysLog::add(FAC_SIP, PRI_DEBUG, "Sip%sServer::deleteClient(%p) done", mProtocolString.data(), sipClient); #endif }
void SipUdpServer::printStatus() { UtlHashMapIterator iterator(mServers); UtlString* pKey = NULL; while ((pKey = dynamic_cast <UtlString*> (iterator()))) { SipClient* pServer = dynamic_cast <SipClient*> (iterator.value()); UtlString clientNames; long clientTouchedTime = pServer->getLastTouchedTime(); UtlBoolean clientOk = pServer->isOk(); pServer->getClientNames(clientNames); osPrintf("UDP server %p last used: %ld ok: %d names: \n%s \n", this, clientTouchedTime, clientOk, clientNames.data()); SipProtocolServerBase::printStatus(); } }
void SipProtocolServerBase::removeOldClients(long oldTime) { mClientLock.acquireWrite(); // Find the old clients in the list and shut them down int iteratorHandle = mClientList.getIteratorHandle(); SipClient* client; int numClients = mClientList.getCount(); int numDelete = 0; int numBusy = 0; SipClient** deleteClientArray = NULL; UtlString clientNames; while ((client = (SipClient*)mClientList.next(iteratorHandle))) { if(client->isInUseForWrite()) numBusy++; // Remove any client with a bad socket // With TCP clients let them stay around if they are still // good as the may stay open for the session // The clients opened from this side for sending requests // get closed by the server (i.e. other side). The clients // opened as servers for requests from the remote side are // explicitly closed on this side when the final response is // sent. if( ! client->isInUseForWrite() // can't remove it if writing to it... && ( ! client->isOk() // socket is bad || client->getLastTouchedTime() < oldTime // idle for long enough ) ) { client->getClientNames(clientNames); #ifdef TEST_PRINT osPrintf("Removing %s client names:\n%s\r\n", mProtocolString.data(), clientNames.data()); #endif OsSysLog::add(FAC_SIP, PRI_DEBUG, "Sip%sServer::Removing old client %p:\n%s\r", mProtocolString.data(), client, clientNames.data()); mClientList.remove(iteratorHandle); // Delete the clients after releasing the lock if(!deleteClientArray) deleteClientArray = new SipClient*[numClients]; deleteClientArray[numDelete] = client; numDelete++; client = NULL; } else { # ifdef TEST_PRINT UtlString names; client->getClientNames(names); OsSysLog::add(FAC_SIP, PRI_DEBUG, "Sip%sServer::removeOldClients leaving client:\n%s", mProtocolString.data(), names.data()); # endif } } mClientList.releaseIteratorHandle(iteratorHandle); mClientLock.releaseWrite(); if ( numDelete || numBusy ) // get rid of lots of 'doing nothing when nothing to do' messages in the log { OsSysLog::add(FAC_SIP, PRI_DEBUG, "Sip%sServer::removeOldClients deleting %d of %d SipClients (%d busy)", mProtocolString.data(), numDelete, numClients, numBusy); } // These have been removed from the list so delete them // after releasing the locks for(int clientIndex = 0; clientIndex < numDelete; clientIndex++) { delete deleteClientArray[clientIndex]; } if(deleteClientArray) { delete[] deleteClientArray; deleteClientArray = NULL; } }