Example #1
0
    /**
     * Start a client and server and send 2 messages over TCP thru them
     * 
     * NOTE: This can/will fail if /etc/hosts defines localhost as ::1 (as 
     *       opposed to 127.0.0.1).
     */
    void testWriteAndAcceptMsg()
    {
    	// Create/Verify Sockets
        OsServerSocket* server = new OsServerSocket(50, 8021);
        KNOWN_BUG("This can fail if there is a port conflict on the test system", "XECS-1924");
        CPPUNIT_ASSERT_MESSAGE("server socket failure", 
                               server->isOk());
        
        OsSocket* client = new OsConnectionSocket(8021, "localhost");        
        CPPUNIT_ASSERT_MESSAGE("client socket failure", 
                               client->isOk());
                
        OsSocket* serverClient = server->accept(1000);
        CPPUNIT_ASSERT_MESSAGE("socket server failed to accept connection", 
                               serverClient != NULL);

        // Begin read/write test
        const char* msg = "hello\n";
        int len = strlen(msg) + 1; // +1 for NULL
        int bytesWritten = client->write(msg, len);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("write correct number of bytes", 
                bytesWritten, len);

        char recvBuf[1024];
        int bytesRead = serverClient->read(recvBuf, sizeof(recvBuf) - 1);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("read correct number of bytes", 
                len, bytesRead);
        ASSERT_STR_EQUAL_MESSAGE("message same as was sent", msg, recvBuf);

        const char *resp = "bye";
        len = strlen(resp) + 1; // +1 for NULL
        bytesWritten = serverClient->write(resp, len);

        CPPUNIT_ASSERT_EQUAL_MESSAGE("write correct number of bytes on 2nd msg", 
            len, bytesWritten);

        bytesRead = client->read(recvBuf, sizeof(recvBuf) - 1);
        CPPUNIT_ASSERT_EQUAL_MESSAGE("read correct number of bytes on 2nd msg", 
            len, bytesRead);

        CPPUNIT_ASSERT_EQUAL_MESSAGE("write correct number of bytes on 2nd msg", 
            len, bytesWritten);

        ASSERT_STR_EQUAL_MESSAGE("2nd message same as was sent", 
                resp, recvBuf);

        serverClient->close();
        client->close();
        server->close();

        delete client;
        delete server;
    }
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);
}