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); }
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); }
// 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; }
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); }
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); }
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 ; }
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; }
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); }
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); }
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; }
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); }
// 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; }
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: ; }
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); }
// 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: ; }
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: ; }
// 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; }
// 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: ; }
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); }