Пример #1
0
UtlBoolean SipUdpServer::getStunAddress(UtlString* pIpAddress, int* pPort,
                                        const char* szLocalIp) 
{
    UtlBoolean bRet = false;
    OsStunDatagramSocket* pSocket = NULL;
    UtlVoidPtr* pSocketContainer = NULL;

    if (szLocalIp)
    {
        UtlString localIpKey(szLocalIp);
       
        pSocketContainer = (UtlVoidPtr*)this->mServerSocketMap.findValue(&localIpKey);
        if (pSocketContainer)
        {
            pSocket = (OsStunDatagramSocket*)pSocketContainer->getValue();
        }
    }
    else
    {
        // just use the default Socket in our collection
        UtlString defaultIpKey(mDefaultIp);
       
        pSocketContainer = (UtlVoidPtr*)mServerSocketMap.findValue(&defaultIpKey);
        if (pSocketContainer != NULL )
        {
            pSocket = (OsStunDatagramSocket*)pSocketContainer->getValue();
        }
    }
    
    if (pSocket)
    {
        bRet =  pSocket->getExternalIp(pIpAddress, pPort) ;
    }
    return bRet;
}
Пример #2
0
UtlBoolean SipUdpServer::getStunAddress(UtlString* pIpAddress, int* pPort,
                                        const char* szLocalIp) 
{
    UtlBoolean bRet = false;
    OsStunDatagramSocket* pSocket = NULL;

    if (szLocalIp)
    {
        UtlString localIpKey(szLocalIp);
       
        pSocket =
           dynamic_cast <OsStunDatagramSocket*> (mServerSocketMap.findValue(&localIpKey));
    }
    else
    {
        // just use the default Socket in our collection
        UtlString defaultIpKey(mDefaultIp);
       
        pSocket =
           dynamic_cast <OsStunDatagramSocket*> (mServerSocketMap.findValue(&defaultIpKey));
    }
    
    if (pSocket)
    {
        bRet =  pSocket->getExternalIp(pIpAddress, pPort);
    }
    return bRet;
}
Пример #3
0
void SipUdpServer::enableStun(const char* szStunServer,
                              const char* szLocalIp, 
                              int refreshPeriodInSecs, 
                              int stunOptions,
                              OsNotification* pNotification) 
{
    // Store settings
    mStunOptions = stunOptions ;
    mStunRefreshSecs = refreshPeriodInSecs ;   
    if (szStunServer)
    {
        mStunServer = szStunServer ;
    }
    else
    {
        mStunServer.remove(0) ;
    }
    
    UtlHashMapIterator iterator(mServerSocketMap);
    UtlString* pKey = NULL;

    char szIpToStun[256];
    memset((void*)szIpToStun, 0, sizeof(szIpToStun));
    
    if (szLocalIp)
    {
        strcpy(szIpToStun, szLocalIp);
    }
    bool bStunAll = false;
    if (0 == strcmp(szIpToStun, "") || 0 == strcmp(szIpToStun, "0.0.0.0"))
    {
        bStunAll = true;
        // if no ip specified, start on the first one
        pKey = (UtlString*) iterator();
        if (pKey)
        {
            strcpy(szIpToStun, pKey->data());
        }
    }
    
    while (0 != strcmp(szIpToStun, ""))
    {
        UtlVoidPtr* pSocketContainer;
        UtlString key(szIpToStun);
        
        pSocketContainer = (UtlVoidPtr*)this->mServerSocketMap.findValue(&key);
        OsStunDatagramSocket* pSocket = NULL;
        
        if (pSocketContainer)
        {
            pSocket = (OsStunDatagramSocket*)pSocketContainer->getValue();
        }                                                                  
        if (pSocket)
        {
            pSocket->enableStun(false) ;
            
            // Update server client
            if (pSocket && mStunServer.length()) 
            {
                pSocket->setStunServer(mStunServer) ;
                pSocket->setKeepAlivePeriod(refreshPeriodInSecs) ;
                pSocket->setNotifier(pNotification) ;
                pSocket->setStunOptions(mStunOptions) ;
                pSocket->enableStun(true) ;
            }  
        }
        if (bStunAll)
        {
            // get the next address to stun
            pKey = (UtlString*) iterator();
            if (pKey)
            {
                strcpy(szIpToStun, pKey->data());
            }
            else
            {
                strcpy(szIpToStun, "");
            }
        }
        else
        {
            break;
        }
    } // end while  
}
Пример #4
0
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;
}
Пример #5
0
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 */
      }
   }
}
Пример #6
0
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);
}