示例#1
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 */
      }
   }
}
示例#2
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;
}
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);
}