示例#1
0
OsConnectionSocket* OsServerSocket::accept()
{
   OsConnectionSocket* connectSock = NULL;

   /* Block while waiting for a client to connect. */
   struct sockaddr_in clientSocketAddr;
   int clientAddrLength = sizeof clientSocketAddr;
   int clientSocket = ::accept(socketDescriptor,
                     (struct sockaddr*) &clientSocketAddr,
                     SOCKET_LEN_TYPE &clientAddrLength);
   if (clientSocket < 0)
   {
      int error = OsSocketGetERRNO();
      OsSysLog::add(FAC_KERNEL, PRI_ERR, "OsServerSocket: accept call failed with error: %d=0x%x",
         error, error);
      socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
      return NULL;
   }
   
#ifdef WIN32
   const int one = 1 ;
   setsockopt(clientSocket, SOL_SOCKET, SO_DONTROUTE, (char *)&one, sizeof(one)) ;
#endif

   connectSock = createConnectionSocket(mLocalIp, clientSocket);

   return(connectSock);
}
示例#2
0
OsConnectionSocket* OsServerSocket::accept()
{
   OsConnectionSocket* connectSock = NULL;

   /* Block while waiting for a client to connect. */
   struct sockaddr_in clientSocketAddr;
   SocketLenType clientAddrLength = sizeof (clientSocketAddr);
   // Remember the value of socketDescriptor, which may be changed by other
   // methods (particularly in a race with ::close()).
   int s = socketDescriptor;
   int clientSocket = ::accept(s,
                               (struct sockaddr*) &clientSocketAddr,
                               &clientAddrLength);
   if (clientSocket < 0)
   {
      int error = OsSocketGetERRNO();
      Os::Logger::instance().log(FAC_KERNEL, PRI_ERR, "OsServerSocket: accept(%d) error: %d=%s",
                    s, error, strerror(error));
      // Flag the socket as invalid.
      socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
      // Close the socket, since we are losing record that we have it open.
      ::close(s);
   }
   else
   {
      connectSock = new OsConnectionSocket(mLocalIp,clientSocket);
   }

   return(connectSock);
}
示例#3
0
// Common code for both constructors
// Returns 0 on success
int OsDatagramSocket::ctorCommonCode()
{
    socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;    

    // Verify socket layer is initialized.
    if (!socketInit())
    {
        return -1;
    }

    // Obtain time for throttling logging of write errors
    time(&mLastWriteErrorTime);

    // Initialize state settings
    mToSockaddrValid = FALSE;
    mpToSockaddr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
    assert(NULL != mpToSockaddr);
    memset(mpToSockaddr, 0, sizeof(struct sockaddr_in));

    // Create the socket
    socketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (socketDescriptor == OS_INVALID_SOCKET_DESCRIPTOR)
    {
        int error = OsSocketGetERRNO();
        close();
        return error;
    }

    return 0;
}
示例#4
0
int OsMulticastSocket::read(char* buffer, int bufferLength)
{
        int error;
        struct sockaddr_in serverSockAddr;
        int fromStructLength = sizeof(serverSockAddr);
        //int bytesRead = recv(socketDescriptor, buffer, bufferLength, 0);
        int bytesRead = recvfrom(socketDescriptor, buffer, bufferLength,
                0,
                (struct sockaddr*) &serverSockAddr,
#ifdef __pingtel_on_posix__
                        (socklen_t *)
#endif
                        &fromStructLength);

        if(bytesRead == -1)
        {
                error = OsSocketGetERRNO();
                // WIN32: 10038 WSAENOTSOCK not a valid socket descriptor
                if(error)
                {
                        close();
                        perror("OsSocket::read call to recv failed\n");
                }
        }

        return(bytesRead);
}
示例#5
0
int OsDatagramSocket::write(const char* buffer, int bufferLength,
      const char* ipAddress, int port)
{
    int bytesSent = 0;

    struct sockaddr_in toSockAddress;
    toSockAddress.sin_family = AF_INET;
    toSockAddress.sin_port = htons(port);

    if(ipAddress == NULL || !strcmp(ipAddress, "0.0.0.0") ||
        strlen(ipAddress) == 0 ||
        (toSockAddress.sin_addr.s_addr = inet_addr(ipAddress)) ==
            OS_INVALID_INET_ADDRESS)
    {
        osPrintf("OsDatagramSocket::write invalid IP address: \"%s\"\n",
            ipAddress);
    }
    else
    {
        // Why isn't this abstracted into OsSocket, as is done in ::write(2)?
        bytesSent = sendto(socketDescriptor,
#ifdef _VXWORKS
            (char*)
#endif
            buffer, bufferLength,
            0,
            (struct sockaddr*) &toSockAddress, sizeof(struct sockaddr_in));

        if(bytesSent != bufferLength)
        {
           OsSysLog::add(FAC_SIP, PRI_ERR,
                         "OsDatagramSocket::write(4) bytesSent = %d, "
                         "bufferLength = %d, errno = %d",
                         bytesSent, bufferLength, errno);
            time_t rightNow;

            (void) time(&rightNow);

            mNumRecentWriteErrors++;

            if (MIN_REPORT_SECONDS <= (rightNow - mLastWriteErrorTime)) {

                mNumTotalWriteErrors += mNumRecentWriteErrors;
                if (0 == mNumTotalWriteErrors) {
                    mLastWriteErrorTime = rightNow;
                }
                osPrintf("OsDataGramSocket::write:\n"
                    "     In last %ld seconds: %d errors; total %d errors;"
                    " last errno=%d\n",
                    (rightNow - mLastWriteErrorTime), mNumRecentWriteErrors,
                    mNumTotalWriteErrors, OsSocketGetERRNO());

                mLastWriteErrorTime = rightNow;
                mNumRecentWriteErrors = 0;
            }
        }
    }
    return(bytesSent);
}
示例#6
0
OsConnectionSocket* OsServerSocket::accept(long waitMilliseconds)
{
    OsConnectionSocket* pRC = NULL ;
    int error=0;
    struct pollfd pset[1];

    // Wait for some data to be available
    pset[0].fd      = socketDescriptor;
    pset[0].events  = POLLIN;
    pset[0].revents = 0;
    int pollResult  = poll(pset, 1, waitMilliseconds); // returns # of events
    if (1 == pollResult)
    {
        if (pset[0].revents & POLLERR)
        {
            // Socket is perhaps dead?
            error = OsSocketGetERRNO();
        }
        else if (pset[0].revents & POLLIN)
        {
            // Data is available; invoke accept
            error = 0;
            pRC = accept();
            if (pRC == NULL)
                error = OsSocketGetERRNO() ;
        }
    }
    else if (0 == pollResult)
    {
        // Timed out waiting for connection
        error = ETIMEDOUT;
    }
    else
    {
        // Some other error -- socket dead?
        error = OsSocketGetERRNO();
    }

    if (pRC == NULL)
    {
        Os::Logger::instance().log(FAC_KERNEL, PRI_DEBUG, "OsServerSocket: accept(%d, %ld ms) error: %d=%s",
                        socketDescriptor, waitMilliseconds, error, strerror(error));
    }

    return pRC ;
}
示例#7
0
int OsDatagramSocket::bind(int localHostPortNum, const char* localHost)
{
    int error = 0;

    localHostPort = localHostPortNum;    
    if (localHost)
    {
        localHostName = localHost ;
    }

    struct sockaddr_in localAddr;
    memset(&localAddr, 0, sizeof(localAddr));
    localAddr.sin_family = AF_INET;
    localAddr.sin_port = htons(localHostPort == PORT_DEFAULT ? 0 : localHostPort);

#ifdef WIN32
    localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    mLocalIp = localHost;
#else
    // Should use host address (if specified in localHost) but for now use any
    if (!localHost)
    {
        localAddr.sin_addr.s_addr=OsSocket::getDefaultBindAddress(); // $$$
        mLocalIp = inet_ntoa(localAddr.sin_addr);
    }
    else
    {
        struct in_addr  ipAddr;
        ipAddr.s_addr = inet_addr (localHost);
        localAddr.sin_addr.s_addr= ipAddr.s_addr;
        mLocalIp = localHost;
    }
#endif

    
    error = ::bind( socketDescriptor, (struct sockaddr*) &localAddr,
                    sizeof(localAddr));

    if(error == OS_INVALID_SOCKET_DESCRIPTOR)
    {
        error = OsSocketGetERRNO();
        close();
        OsSysLog::add(FAC_KERNEL, PRI_ERR, "OsDatagramSocket::bind to %s:%d failed w/errno %d\n",
                 mLocalIp.data(), localHostPortNum, error);
    }
    else
    {
        sockaddr_in addr ;
        int addrSize = sizeof(struct sockaddr_in);
        error = getsockname(socketDescriptor, (struct sockaddr*) &addr, SOCKET_LEN_TYPE& addrSize);
        localHostPort = htons(addr.sin_port);
    }

    return error;
}
示例#8
0
OsConnectionSocket* OsTLSServerSocket::accept()
{
   OsConnectionSocket* newSocket = NULL;
   
   if (socketDescriptor == OS_INVALID_SOCKET_DESCRIPTOR)
   {
      OsSysLog::add(FAC_KERNEL, PRI_ERR
                    , "OsTLSServerSocket: accept exiting because socketDescriptor is %d"
                    ,socketDescriptor);
   }
   else
   {
        /* Block while waiting for a client to connect. */
        struct sockaddr_in clientSocketAddr;
        int clientAddrLength = sizeof clientSocketAddr;
      
        PRNetAddr   addr;
        PRFileDesc *tcpSocket;

        PRFileDesc* listenSocket = PR_ImportTCPSocket(socketDescriptor);

        /* Accept a connection to the socket. */
        tcpSocket = PR_Accept(listenSocket, &addr, PR_INTERVAL_NO_TIMEOUT);
      

      if (!tcpSocket)
      {
         int error = OsSocketGetERRNO();
         OsSysLog::add(FAC_KERNEL, PRI_ERR, 
                       "OsTLSServerSocket: accept call failed with error: %d=%x",
                       error, error);
         socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
      }
      else
      {

         // need to create a new OsTLSConnectionSocket
        int socketDescriptor = PR_FileDesc2NativeHandle(tcpSocket);
        newSocket = new OsTLSServerConnectionSocket(socketDescriptor, mCertNickname, mCertPassword, mDbLocation );
        if (newSocket)
        {
        }
      }
   }
   
   return(newSocket);
}
示例#9
0
int OsDatagramSocket::writeTo(const char* buffer, int bufferLength)
{
    int bytesSent = 0;

    if (getToSockaddr()) 
    {
        bytesSent = sendto(socketDescriptor,
#ifdef _VXWORKS
            (char*)
#endif
            buffer, bufferLength,
            0,
            (struct sockaddr*) mpToSockaddr, sizeof(struct sockaddr_in));

#ifdef TEST_PRINT
        UtlString address(inet_ntoa(mpToSockaddr->sin_addr));
        OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "OsDatagramSocket::writeTo bytes: %d to address: %s port: %d",
            bytesSent, address.data(), (int) ntohs(mpToSockaddr->sin_port));
#endif

        if(bytesSent != bufferLength)
        {
            time_t rightNow;

            (void) time(&rightNow);

            mNumRecentWriteErrors++;

            if (MIN_REPORT_SECONDS <= (rightNow - mLastWriteErrorTime)) {

                mNumTotalWriteErrors += mNumRecentWriteErrors;
                if (0 == mNumTotalWriteErrors) {
                    mLastWriteErrorTime = rightNow;
                }
                osPrintf("OsDataGramSocket::write:\n"
                    "     In last %ld seconds: %d errors; total %d errors;"
                    " last errno=%d\n",
                    (rightNow - mLastWriteErrorTime), mNumRecentWriteErrors,
                    mNumTotalWriteErrors, OsSocketGetERRNO());

                mLastWriteErrorTime = rightNow;
                mNumRecentWriteErrors = 0;
            }
        }
    }
    return(bytesSent);
}
示例#10
0
int OsSocket::read(char* buffer, int bufferLength)
{

#ifdef FORCE_SOCKET_ERRORS

   static int numForFailure = 30;
   static int count = 0;
   count++;

   if (count > numForFailure)
   {
      count = 0;
      numForFailure = 10;
#ifdef _WIN32
      closesocket(socketDescriptor);
#else
      ::close(socketDescriptor);
      Os::Logger::instance().log(FAC_KERNEL, PRI_DEBUG, "OsSocket::read[2] close socket %d",
                    socketDescriptor);
#endif
      return 0;
   }
#endif //FORCE_SOCKET_ERRORS

   int flags = 0;

#if defined(__linux__) || defined(sun) || defined(__FreeBSD__)
   // We do not want send to throw signals if there is a
   // problem with the socket as this results in the process
   // getting aborted. We just want it to return an error.
   // (Under OS X, we use SO_NOSIGPIPE because this is not
   // supported... this is done in the constructors for
   // stream socket types as it is a one-time-only thing.)
   flags = MSG_NOSIGNAL;
#endif

   int error;
   ssize_t bytesRead = recv(socketDescriptor, buffer, bufferLength, flags);
   if (bytesRead < 0)
   {
      error = OsSocketGetERRNO();
      // WIN32: 10038 WSAENOTSOCK not a valid socket descriptor
      Os::Logger::instance().log(FAC_KERNEL, PRI_DEBUG, "OsSocket::read error %d", error);
   }

   return bytesRead;
}
示例#11
0
int OsDatagramSocket::writeTo(const char* buffer, int bufferLength)
{
    int bytesSent = 0;

    if (getToSockaddr()) {
        bytesSent = sendto(socketDescriptor,
#ifdef _VXWORKS
            (char*)
#endif
            buffer, bufferLength,
            0,
            (struct sockaddr*) mpToSockaddr, sizeof(struct sockaddr_in));

        if(bytesSent != bufferLength)
        {
            time_t rightNow;

            (void) time(&rightNow);

            mNumRecentWriteErrors++;

            if (MIN_REPORT_SECONDS <= (rightNow - mLastWriteErrorTime)) {

                mNumTotalWriteErrors += mNumRecentWriteErrors;
                if (0 == mNumTotalWriteErrors) {
                    mLastWriteErrorTime = rightNow;
                }
                osPrintf("OsDataGramSocket::write:\n"
                    "     In last %ld seconds: %d errors; total %d errors;"
                    " last errno=%d\n",
                    (rightNow - mLastWriteErrorTime), mNumRecentWriteErrors,
                    mNumTotalWriteErrors, OsSocketGetERRNO());

                mLastWriteErrorTime = rightNow;
                mNumRecentWriteErrors = 0;
            }
        }
    }
    return(bytesSent);
}
示例#12
0
// Constructor
OsDatagramSocket::OsDatagramSocket(int remoteHostPortNum,
       const char* remoteHost, int localHostPortNum, const char* localHost) :
   mNumTotalWriteErrors(0),
   mNumRecentWriteErrors(0)
{
    OsSysLog::add(FAC_SIP, PRI_DEBUG, "OsDatagramSocket::_ attempt %s:%d"
                  ,remoteHost, remoteHostPortNum);

    int                error = 0;
    UtlBoolean         isIp = FALSE;
    struct sockaddr_in localAddr;
    struct hostent*    server = NULL;

    // Verify socket layer is initialized.
    if(!socketInit())
    {
        goto EXIT;
    }

    // Obtain time for throttling logging of write errors
    time(&mLastWriteErrorTime);

    // Initialize state settings
    mToSockaddrValid = FALSE;
    mpToSockaddr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
    assert(NULL != mpToSockaddr);
    memset(mpToSockaddr, 0, sizeof(struct sockaddr_in));
    socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;    
    localHostPort = localHostPortNum;    
    if(localHost)
    {
        localHostName = localHost ;
    }

    // Create the socket
    socketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(socketDescriptor == OS_INVALID_SOCKET_DESCRIPTOR)
    {
        error = OsSocketGetERRNO();
        close();

        OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                "OsDatagramSocket::OsDatagramSocket( %s:%d %s:%d) failed w/ errno %d)",
                        remoteHost, remoteHostPortNum, localHost, 
                        localHostPortNum, error);

        goto EXIT;
    }

    // Bind to the socket
    localAddr.sin_family = AF_INET;
    localAddr.sin_port =
       htons(localHostPort == PORT_DEFAULT ? 0 : localHostPort);

    // Should use host address (if specified in localHost) but for now use any
    if (!localHost)
    {
        localAddr.sin_addr.s_addr=OsSocket::getDefaultBindAddress(); // $$$
        mLocalIp = inet_ntoa(localAddr.sin_addr);
    }
    else
    {
        struct in_addr  ipAddr;
        ipAddr.s_addr = inet_addr (localHost);
        localAddr.sin_addr.s_addr= ipAddr.s_addr;
        mLocalIp = localHost;
    }

    
#   if defined(_WIN32)
    error = bind( socketDescriptor, (const struct sockaddr*) &localAddr,
            sizeof(localAddr));
#   elif defined(__pingtel_on_posix__)

    error = bind( socketDescriptor, (struct sockaddr*) &localAddr,
            sizeof(localAddr));
#   endif
    if(error == OS_INVALID_SOCKET_DESCRIPTOR)
    {
        close();
        goto EXIT;
    }
    else
    {
        sockaddr_in addr ;
        int addrSize = sizeof(struct sockaddr_in);
        error = getsockname(socketDescriptor, (struct sockaddr*) &addr, SOCKET_LEN_TYPE& addrSize);
        localHostPort = htons(addr.sin_port);
    }

    // Kick off connection
    mSimulatedConnect = FALSE;
    doConnect(remoteHostPortNum, remoteHost, mSimulatedConnect) ;

EXIT:
    return;
}
示例#13
0
void OsDatagramSocket::doConnect(int remoteHostPortNum, const char* remoteHost,
                                 UtlBoolean simulateConnect)
{
    struct hostent* server;    

    mToSockaddrValid = FALSE;
    memset(mpToSockaddr, 0, sizeof(struct sockaddr_in));
    remoteHostPort = remoteHostPortNum;

    // Store host name
    if(remoteHost)
    {
        remoteHostName = remoteHost ;
        getHostIpByName(remoteHostName, &mRemoteIpAddress);
    }
    else
    {
        remoteHostName.remove(0) ;
    }

    // Connect to a remote host if given
    if(portIsValid(remoteHostPort) && remoteHost && !simulateConnect)
    {
        server = gethostbyname(remoteHost);
        if (server)
        {
            struct in_addr* serverAddr = (in_addr*) (server->h_addr);
            struct sockaddr_in serverSockAddr;
            serverSockAddr.sin_family = server->h_addrtype;
            serverSockAddr.sin_port = htons(remoteHostPort);
            serverSockAddr.sin_addr.s_addr = (serverAddr->s_addr);

            // Set the default destination address for the socket
            if(connect(socketDescriptor, (const struct sockaddr*) 
                    &serverSockAddr, sizeof(serverSockAddr)))
            {
                int error = OsSocketGetERRNO();
                close();
                OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                        "OsDatagramSocket::doConnect( %s:%d ) failed w/ errno %d)",
                        remoteHost, remoteHostPortNum, error);
            }
            else
            {
                mIsConnected = TRUE;
            }
        }
        else
        {
            close();
            OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                    "OsDatagramSocket::doConnect( %s:%d ) failed host lookup)",
                    remoteHost, remoteHostPortNum);           

            goto EXIT;
        }
    }
    else if(portIsValid(remoteHostPort) && remoteHost && simulateConnect)
    {
        mIsConnected = TRUE;
        mSimulatedConnect = TRUE;
    }
EXIT:
   ;
}
示例#14
0
OsConnectionSocket* OsSSLServerSocket::accept()
{
   OsConnectionSocket* newSocket = NULL;
   
   if (socketDescriptor == OS_INVALID_SOCKET_DESCRIPTOR)
   {
      OsSysLog::add(FAC_KERNEL, PRI_ERR
                    , "OsSSLServerSocket: accept exiting because socketDescriptor is %d"
                    ,socketDescriptor);
   }
   else
   {
      /* Block while waiting for a client to connect. */
      struct sockaddr_in clientSocketAddr;
      int clientAddrLength = sizeof clientSocketAddr;
      int clientSocket = ::accept(socketDescriptor,
                                  (struct sockaddr*) &clientSocketAddr,
                                  SOCKET_LEN_TYPE &clientAddrLength);

      if (clientSocket < 0)
      {
         int error = OsSocketGetERRNO();
         if (0 != error)
         {
            OsSysLog::add(FAC_KERNEL, PRI_ERR, 
                          "OsSSLServerSocket: accept call failed with error: %d=%x",
                          error, error);
            socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
         }
      }
      else
      {
         OsSysLog::add(FAC_KERNEL, PRI_DEBUG, 
                       "OsSSLServerSocket::accept socket accepted: %d",
                       clientSocket);

         // TODO: allow this to be a non-shared context...
         SSL* pSSL = OsSharedSSL::get()->getServerConnection();
         if (pSSL)
         {
            SSL_set_fd (pSSL, clientSocket);

            newSocket = new OsSSLConnectionSocket(pSSL,clientSocket);
            if (newSocket)
            {
               int result = SSL_accept(pSSL);
               if (1 == result)
               {
                  OsSSL::logConnectParams(FAC_KERNEL, PRI_DEBUG
                                          ,"OsSSLServerSocket::accept"
                                          ,pSSL);
               }
               else
               {
                  OsSSL::logError(FAC_KERNEL, PRI_ERR,
                                  (  result == 0
                                   ? "OsSSLServerSocket SSL_accept - incompatible client?"
                                   : "OsSSLServerSocket SSL_accept SSL handshake error"
                                   ),
                                  SSL_get_error(pSSL, result));
                  socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;

                  // SSL failed, so clear this out.
                  delete newSocket;
                  newSocket = NULL;
               }
            }
            else
            {
               OsSysLog::add(FAC_KERNEL, PRI_ERR,
                             "OsSSLServerSocket::accept - new OsSSLConnectionSocket failed"
                             );
               socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
            }            
         }
         else
         {
            OsSysLog::add(FAC_KERNEL, PRI_ERR
                          , "OsSSLConnectionSocket::accept - Error creating new SSL connection.");
            socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
         }
      }
   }
   
   return(newSocket);
}
示例#15
0
// Constructor
OsServerSocket::OsServerSocket(int connectionQueueSize,
    int serverPort,
    const char* szBindAddr,
    const bool bPerformBind)
{
   const int one = 1;
   int error = 0;
   socketDescriptor = 0;
   struct sockaddr_in localAddr;
   int addrSize;

   // Windows specific startup
   if(!OsSocket::socketInit())
   {
      goto EXIT;
   }

   localHostPort = serverPort;

   OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                 "OsServerSocket::_ queue=%d port=%d bindaddr=%s",
                 connectionQueueSize, serverPort, szBindAddr
                 );

   // Create the socket
   socketDescriptor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
   if(socketDescriptor == OS_INVALID_SOCKET_DESCRIPTOR)
   {
      error = OsSocketGetERRNO();
      OsSysLog::add(FAC_KERNEL, PRI_ERR,
                    "OsServerSocket: socket call failed with error: %d=0x%x",
         error, error);
      socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
      goto EXIT;
   }

#ifndef WIN32
   if(setsockopt(socketDescriptor, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)))
      OsSysLog::add(FAC_KERNEL, PRI_ERR, "OsServerSocket: setsockopt(SO_REUSEADDR) failed!");
#endif
/*
    Don't know why we don't want to route...we do support subnets, do we not?
    setsockopt(socketDescriptor, SOL_SOCKET, SO_DONTROUTE, (char *)&one, sizeof(one)) ;
*/

#  if defined(__APPLE__)
   // Under OS X, we use SO_NOSIGPIPE here because MSG_NOSIGNAL
   // is not supported for the write() call.
   if(setsockopt(socketDescriptor, SOL_SOCKET, SO_NOSIGPIPE, (char *)&one, sizeof(one)))
   {
      error = OsSocketGetERRNO();
      close();
      OsSysLog::add(FAC_SIP, PRI_ERR,
                    "setsockopt call failed with error: 0x%x in OsServerSocket::OsServerSocket",
                    error);
      goto EXIT;
   }
#       endif


   memset(&localAddr, 0, sizeof(localAddr));
   localAddr.sin_family = AF_INET;

   // Bind to a specific server port if given, or let the system pick
   // any available port number if PORT_DEFAULT.
   localAddr.sin_port = htons((PORT_DEFAULT == serverPort) ? 0 : serverPort);

   // Allow IP in on any of this host's addresses or NICs.
   if (szBindAddr)
   {
      localAddr.sin_addr.s_addr = inet_addr (szBindAddr);
      mLocalIp = szBindAddr;
   }
   else
   {
      localAddr.sin_addr.s_addr=OsSocket::getDefaultBindAddress();
      mLocalIp = inet_ntoa(localAddr.sin_addr);
   }

   if (bPerformBind)
   {
        error = bind(socketDescriptor,
                        (OsSS_CONST struct sockaddr*) &localAddr,
                        sizeof(localAddr));
        if (error == OS_INVALID_SOCKET_DESCRIPTOR)
        {
            error = OsSocketGetERRNO();
            OsSysLog::add(FAC_KERNEL, PRI_ERR,
                    "OsServerSocket:  bind to port %d failed with error: %d = 0x%x",
                            ((PORT_DEFAULT == serverPort) ? 0 : serverPort), error, error);
            socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
            goto EXIT;
        }
   }
   addrSize = sizeof(struct sockaddr_in);
   error = getsockname(socketDescriptor,
                           (struct sockaddr*) &localAddr, SOCKET_LEN_TYPE &addrSize);
   if (error) {
      error = OsSocketGetERRNO();
      OsSysLog::add(FAC_KERNEL, PRI_ERR, "OsServerSocket: getsockname call failed with error: %d=0x%x",
         error, error);
   } else {
      localHostPort = htons(localAddr.sin_port);
   }

    // Setup the queue for connection requests
    if (bPerformBind)
    {
        error = listen(socketDescriptor,  connectionQueueSize);
        if (error)
        {
            error = OsSocketGetERRNO();
            OsSysLog::add(FAC_KERNEL, PRI_ERR, "OsServerSocket: listen call failed with error: %d=0x%x",
                error, error);
            socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
        }
    }

EXIT:
   ;

}
示例#16
0
void OsDatagramSocket::doConnect(int remoteHostPortNum, const char* remoteHost,
                                 UtlBoolean simulateConnect)
{
    struct hostent* server = NULL;

    mToSockaddrValid = FALSE;
    memset(mpToSockaddr, 0, sizeof(struct sockaddr_in));
    remoteHostPort = remoteHostPortNum;

    // Store host name
    if(remoteHost)
    {
        remoteHostName = remoteHost ;
        getHostIpByName(remoteHostName, &mRemoteIpAddress);
    }
    else
    {
        remoteHostName.remove(0) ;
    }

    // Connect to a remote host if given
    if(portIsValid(remoteHostPort) && remoteHost && !simulateConnect)
    {
#if defined(_WIN32) || defined(__pingtel_on_posix__)
        unsigned long ipAddr;

        ipAddr = inet_addr(remoteHost);

        if (ipAddr != INADDR_NONE) 
        {
           server = gethostbyaddr((char * )&ipAddr,sizeof(ipAddr),AF_INET);
        }

        if ( server == NULL ) 
        { 
           server = gethostbyname(remoteHost);
        }

#elif defined(_VXWORKS)
        char hostentBuf[512];
        server = resolvGetHostByName((char*) remoteHost,
                                      hostentBuf, sizeof(hostentBuf));
#else
#  error Unsupported target platform.
#endif //_VXWORKS

        if (server)
        {
            struct in_addr* serverAddr = (in_addr*) (server->h_addr);
            struct sockaddr_in serverSockAddr;
            serverSockAddr.sin_family = server->h_addrtype;
            serverSockAddr.sin_port = htons(remoteHostPort);
            serverSockAddr.sin_addr.s_addr = (serverAddr->s_addr);

            // Set the default destination address for the socket
#if defined(_WIN32) || defined(__pingtel_on_posix__)
            if(connect(socketDescriptor, (const struct sockaddr*) 
                    &serverSockAddr, sizeof(serverSockAddr)))
#elif defined(_VXWORKS)
            if(connect(socketDescriptor, (struct sockaddr*) &serverSockAddr,
                       sizeof(serverSockAddr)))
#else
#  error Unsupported target platform.
#endif



            {
                int error = OsSocketGetERRNO();
                close();
                OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                        "OsDatagramSocket::doConnect( %s:%d ) failed w/ errno %d)",
                        remoteHost, remoteHostPortNum, error);
            }
            else
            {
                mIsConnected = TRUE;
            }
        }
        else
        {
            close();
            OsSysLog::add(FAC_KERNEL, PRI_DEBUG,
                    "OsDatagramSocket::doConnect( %s:%d ) failed host lookup)",
                    remoteHost, remoteHostPortNum);           

            goto EXIT;
        }
    }
    else if(portIsValid(remoteHostPort) && remoteHost && simulateConnect)
    {
        mIsConnected = TRUE;
        mSimulatedConnect = TRUE;
    }
EXIT:
   ;
}
示例#17
0
// Constructor
OsDatagramSocket::OsDatagramSocket(int remoteHostPortNum,
                                   const char* remoteHost,
                                   int localHostPortNum,
                                   const char* localHost) :
   mNumTotalWriteErrors(0),
   mNumRecentWriteErrors(0),
   mSimulatedConnect(FALSE)     // Simulated connection is off until
                                // activated in doConnect.
{
    Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "OsDatagramSocket::_ attempt %s:%d"
                  ,remoteHost != NULL ? remoteHost : "[null]", remoteHostPortNum);

    int                error = 0;
#ifdef IP_MTU_DISCOVER
    int                pmtuDiscover;
#endif
    struct sockaddr_in localAddr;

    // Verify socket layer is initialized.
    if(!socketInit())
    {
        goto EXIT;
    }

    // Obtain time for throttling logging of write errors
    time(&mLastWriteErrorTime);

    // Initialize state settings
    mToSockaddrValid = FALSE;
    mpToSockaddr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
    assert(NULL != mpToSockaddr);
    memset(mpToSockaddr, 0, sizeof(struct sockaddr_in));
    socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
    localHostPort = localHostPortNum;
    if(localHost)
    {
        localHostName = localHost ;
    }

    // Create the socket
    socketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(socketDescriptor == OS_INVALID_SOCKET_DESCRIPTOR)
    {
        error = OsSocketGetERRNO();
        close();

        Os::Logger::instance().log(FAC_KERNEL, PRI_WARNING,
                      "OsDatagramSocket::_ socket(%d, %d, %d) failed w/ errno %d '%s')",
                      AF_INET, SOCK_DGRAM, IPPROTO_UDP,
                      error, strerror(error));

        goto EXIT;
    }

    // Set Socket Options: IP_MTU_DISCOVER to DONT: Do not set dontfrag bit in
    // IP header
#ifdef IP_MTU_DISCOVER
    pmtuDiscover = IP_PMTUDISC_DONT ;
    error = setsockopt(socketDescriptor, IPPROTO_IP, IP_MTU_DISCOVER, &pmtuDiscover, sizeof(pmtuDiscover)) ;
    if (error != 0)
    {
        static bool bReported = false ;
        // Failure to set the socket option isn't a show-stopper, but should
        // be noted (and not spammed).
        if (!bReported)
        {
            bReported = true ;
            Os::Logger::instance().log(FAC_KERNEL, PRI_WARNING,
                    "OsDatagramSocket::_ socket %d failed to set IP_MTU_DISCOVER (rc=%d, errno=%d)",
                    socketDescriptor, error,  OsSocketGetERRNO());
        }
    }
#endif

    // Bind to the socket
    memset(&localAddr, 0, sizeof(localAddr));
    localAddr.sin_family = AF_INET;
    localAddr.sin_port =
       htons(localHostPort == PORT_DEFAULT ? 0 : localHostPort);

    // Should use host address (if specified in localHost) but for now use any
    if (!localHost)
    {
        localAddr.sin_addr.s_addr=OsSocket::getDefaultBindAddress(); // $$$
        mLocalIp = inet_ntoa(localAddr.sin_addr);
    }
    else
    {
        struct in_addr  ipAddr;
        ipAddr.s_addr = inet_addr (localHost);
        localAddr.sin_addr.s_addr= ipAddr.s_addr;
        mLocalIp = localHost;
    }


#   if defined(_WIN32)
    error = bind( socketDescriptor, (const struct sockaddr*) &localAddr,
            sizeof(localAddr));
#   elif defined(__pingtel_on_posix__)

    error = bind( socketDescriptor, (struct sockaddr*) &localAddr,
            sizeof(localAddr));
#   endif
    if(error == OS_INVALID_SOCKET_DESCRIPTOR)
    {
        error = OsSocketGetERRNO();
        close();

        // Extract the address and port we were trying to bind() to.
        const char *addr = inet_ntoa(localAddr.sin_addr);
        int port = ntohs(localAddr.sin_port);
        Os::Logger::instance().log(FAC_KERNEL, PRI_WARNING,
                      "OsDatagramSocket::_ %d (%s:%d %s:%d) bind(%d, %s:%d) failed w/ errno %d '%s')",
                      socketDescriptor,
                      remoteHost, remoteHostPortNum, localHost, localHostPortNum,
                      socketDescriptor, addr, port,
                      error, strerror(error));

        goto EXIT;
    }
    else
    {
        sockaddr_in addr ;
        int addrSize = sizeof(struct sockaddr_in);
        error = getsockname(socketDescriptor, (struct sockaddr*) &addr, SOCKET_LEN_TYPE& addrSize);
        localHostPort = htons(addr.sin_port);
    }

    Os::Logger::instance().log(FAC_KERNEL, PRI_DEBUG,
                  "OsDatagramSocket::_ %d (%s:%d %s:%d) socket and bind succeeded",
                  socketDescriptor,
                  remoteHost, remoteHostPortNum, localHost, localHostPortNum);

    // Kick off connection
    mSimulatedConnect = FALSE;
    doConnect(remoteHostPortNum, remoteHost, mSimulatedConnect) ;

EXIT:
    return;
}
示例#18
0
// Constructor
OsMulticastSocket::OsMulticastSocket(int multicastPortNum, const char* multicastHost,
                        int localHostPortNum, const char* localHost)
{
        int error = 0;
        struct sockaddr_in localAddr;
        struct hostent* server = NULL;
        int iTmp = TRUE;

        socketDescriptor = OS_INVALID_SOCKET_DESCRIPTOR;
        localHostPort = localHostPortNum;
        if(localHost)
        {
                localHostName.append(localHost);
        }
        remoteHostPort = multicastPortNum;
        if(multicastHost)
        {
                remoteHostName.append(multicastHost);
        }


        if(!socketInit())
        {
                goto EXIT;
        }

#       ifdef _VXWORKS
        char hostentBuf[512];
#       endif


        // Create the socket
        socketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if(socketDescriptor == OS_INVALID_SOCKET_DESCRIPTOR)
        {
                error = OsSocketGetERRNO();
                close();
                perror("call to socket failed in OsMulticastSocket::OsMulticastSocket\n");
                osPrintf("socket call failed with error in OsMulticastSocket::OsMulticastSocket: 0x%x\n", error);
                goto EXIT;
        }

         /* avoid EADDRINUSE error on bind() */
        iTmp = TRUE;
        if(setsockopt(socketDescriptor, SOL_SOCKET, SO_REUSEADDR, (char *)&iTmp,
     sizeof(iTmp)))
        {
                error = OsSocketGetERRNO();
                close();
                perror("call to setsockopt failed\n");
                osPrintf("setsockopt SO_REUSEADDR call failed with error: %d\n", error);
                goto EXIT;
        }


        localAddr.sin_family = AF_INET;
        localAddr.sin_port = htons(multicastPortNum);
        if(localHost == NULL)
        {
                localAddr.sin_addr.s_addr=OsSocket::getDefaultBindAddress();
//              localAddr.sin_addr.s_addr=htonl(INADDR_ANY); // Allow IP in on
                // any of this hosts addresses or NICs.
        }
        else
        {
                // Should use host address specified, for now use any
                localAddr.sin_addr.s_addr=OsSocket::getDefaultBindAddress();
//              localAddr.sin_addr.s_addr=htonl(INADDR_ANY); // Allow IP in on
                // any of this hosts addresses or NICs.
        }

#       if defined(_WIN32)
        error = bind( socketDescriptor, (const struct sockaddr*) &localAddr,
                        sizeof(localAddr));
#       elif defined(_VXWORKS) || defined(__pingtel_on_posix__)

        error = bind( socketDescriptor, (struct sockaddr*) &localAddr,
                        sizeof(localAddr));
#       else
#       error Unsupported target platform.
#       endif

        if(error == OS_INVALID_SOCKET_DESCRIPTOR)
        {
                // error = OsSocketGetERRNO();
                close();
                // perror("bind to socket failed\n");
                goto EXIT;
        }


        // Setup multicast options
#       if defined(_WIN32) || defined(__pingtel_on_posix__)
        server = gethostbyname(multicastHost);

#       elif defined(_VXWORKS)
        server = resolvGetHostByName((char*) multicastHost,
                                hostentBuf, sizeof(hostentBuf));
#       else
#       error Unsupported target platform.
#       endif //_VXWORKS

        if(server == NULL)
        {
                error = OsSocketGetERRNO();
                close();
                perror("call to gethostbyname failed\n");
                osPrintf("gethostbyname(%s) call failed with error: %d\n",multicastHost,
                                error);
                goto EXIT;
        }
        struct ip_mreq mreq;
        mreq.imr_multiaddr = *((in_addr*) (server->h_addr));

        mreq.imr_interface.s_addr = OsSocket::getDefaultBindAddress();
//      mreq.imr_interface.s_addr = htonl(INADDR_ANY);

   if(setsockopt(socketDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mreq, sizeof(mreq)))
        {
                error = OsSocketGetERRNO();
                close();
                perror("call to setsockopt failed\n");
                osPrintf("setsockopt call failed with error: %d\n", error);
                goto EXIT;
        }

   joinMulticast(multicastPortNum, multicastHost);

EXIT:
   ;
}
示例#19
0
int OsSocket::read(char* buffer, int bufferLength,
                   struct in_addr* fromAddress, int* fromPort)
{

#ifdef FORCE_SOCKET_ERRORS

   static int numForFailure = 30;
   static int count = 0;
   count++;

   if (count > numForFailure)
   {
      count = 0;
      numForFailure = 10;
#ifdef _WIN32
      closesocket(socketDescriptor);
#else
      ::close(socketDescriptor);
      Os::Logger::instance().log(FAC_KERNEL, PRI_DEBUG, "OsSocket::read[4in_addr] close socket %d",
                    socketDescriptor);
#endif
      return 0;
   }

#endif //FORCE_SOCKET_ERRORS

   int error;
   struct sockaddr_in fromSockAddress;
   size_t fromLength = sizeof(fromSockAddress);

   if (NULL != fromPort) *fromPort = PORT_NONE;
   if (NULL != fromAddress) fromAddress->s_addr = 0;

   int flags = 0;

#if defined(__linux__) || defined(sun) || defined(__FreeBSD__)
   // We do not want send to throw signals if there is a
   // problem with the socket as this results in the process
   // getting aborted. We just want it to return an error.
   // (Under OS X, we use SO_NOSIGPIPE because this is not
   // supported... this is done in the constructors for
   // stream socket types as it is a one-time-only thing.)
   flags = MSG_NOSIGNAL;
#endif

   ssize_t bytesRead = recvfrom(socketDescriptor, buffer, bufferLength,
                            flags,
                            (struct sockaddr*) &fromSockAddress,
#ifdef __pingtel_on_posix__
                            (socklen_t *)
#endif
                            &fromLength);
   if(bytesRead == -1)
   {
      error = OsSocketGetERRNO();
      // 10038 WSAENOTSOCK not a valid socket descriptor
      switch(error)
      {
         // These should be ignored
         case EAGAIN:
         case EINTR:
            break ;

         // Others should not.
         default:
            Os::Logger::instance().log(FAC_KERNEL, PRI_WARNING,
                          "OsSocket::read %d (%s:%d %s:%d) recvfrom returned %d '%s'",
                          socketDescriptor,
                          remoteHostName.data(), remoteHostPort,
                          localHostName.data(), localHostPort,
                          error, strerror(error)
               );
            close();
      }

   }
   else
   {
      if (NULL != fromPort)
      {
         *fromPort = ntohs(fromSockAddress.sin_port);
      }
      if (NULL != fromAddress)
      {
         *fromAddress = fromSockAddress.sin_addr;
      }
   }

   return (bytesRead);
}