bool TCPAcceptor::StartAccept(BaseClientApplication *pApplication) { _pApplication = pApplication; _inboundFd = _outboundFd = (int) socket(PF_INET, SOCK_STREAM, 0); if (_inboundFd < 0) { int err = LASTSOCKETERROR; FATAL("Unable to create socket: %s(%d)", strerror(err), err); return false; } if (!setFdOptions(_inboundFd)) { FATAL("Unable to set socket options"); return false; } if (bind(_inboundFd, (sockaddr *) & _address, sizeof (sockaddr)) != 0) { int error = LASTSOCKETERROR; FATAL("Unable to bind on address: tcp://%s:%hu; Error was: %s (%d)", inet_ntoa(((sockaddr_in *) & _address)->sin_addr), ENTOHS(((sockaddr_in *) & _address)->sin_port), strerror(error), error); return false; } if (listen(_inboundFd, 100) != 0) { FATAL("Unable to put the socket in listening mode"); return false; } _enabled = true; return IOHandlerManager::EnableAcceptConnections(this); }
std::shared_ptr<Socket> Socket::accept() { int sockfd = ::accept(mFD, nullptr, nullptr); if (sockfd == -1) { const std::string msg = "Error in accept: " + getSystemErrorMessage(); LOGE(msg); throw IPCException(msg); } setFdOptions(sockfd); return std::make_shared<Socket>(sockfd); }
void CommonTestsSuite::test_setFdOptions() { InitNetworking(); int32_t fd = socket(AF_INET, SOCK_STREAM, 0); TS_ASSERT(fd > 0); TS_ASSERT(setFdNoSIGPIPE(fd)); TS_ASSERT(setFdNonBlock(fd)); TS_ASSERT(setFdNoNagle(fd)); TS_ASSERT(setFdKeepAlive(fd)); TS_ASSERT(setFdReuseAddress(fd)); CLOSE_SOCKET(fd); fd = -1; fd = socket(AF_INET, SOCK_STREAM, 0); TS_ASSERT(fd > 0); TS_ASSERT(setFdOptions(fd)); CLOSE_SOCKET(fd); }
int Socket::getSystemdSocketInternal(const std::string& path) { int n = ::sd_listen_fds(-1 /*Block further calls to sd_listen_fds*/); if (n < 0) { const std::string msg = "sd_listen_fds failed: " + getSystemErrorMessage(-n); LOGE(msg); throw IPCException(msg); } for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; ++fd) { if (0 < ::sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0)) { setFdOptions(fd); return fd; } } LOGW("No usable sockets were passed by systemd."); return -1; }
bool TCPAcceptor::Bind() { _inboundFd = _outboundFd = (int) socket(PF_INET, SOCK_STREAM, 0); //NOINHERIT if (_inboundFd < 0) { int err = errno; FATAL("Unable to create socket: (%d) %s", err, strerror(err)); return false; } if (!setFdOptions(_inboundFd, false)) { FATAL("Unable to set socket options"); return false; } if (bind(_inboundFd, (sockaddr *) & _address, sizeof (sockaddr)) != 0) { int err = errno; FATAL("Unable to bind on address: tcp://%s:%hu; Error was: (%d) %s", inet_ntoa(((sockaddr_in *) & _address)->sin_addr), ENTOHS(((sockaddr_in *) & _address)->sin_port), err, strerror(err)); return false; } if (_port == 0) { socklen_t tempSize = sizeof (sockaddr); if (getsockname(_inboundFd, (sockaddr *) & _address, &tempSize) != 0) { FATAL("Unable to extract the random port"); return false; } _parameters[CONF_PORT] = (uint16_t) ENTOHS(_address.sin_port); } if (listen(_inboundFd, 100) != 0) { FATAL("Unable to put the socket in listening mode"); return false; } _enabled = true; return true; }
bool TCPAcceptor::Accept() { sockaddr address; memset(&address, 0, sizeof (sockaddr)); socklen_t len = sizeof (sockaddr); int32_t fd; int32_t error; //1. Accept the connection fd = accept(_inboundFd, &address, &len); error = errno; if (fd < 0) { FATAL("Unable to accept client connection: %s (%d)", strerror(error), error); return false; } if (!_enabled) { CLOSE_SOCKET(fd); _droppedCount++; WARN("Acceptor is not enabled. Client dropped: %s:%"PRIu16" -> %s:%"PRIu16, inet_ntoa(((sockaddr_in *) & address)->sin_addr), ENTOHS(((sockaddr_in *) & address)->sin_port), STR(_ipAddress), _port); return true; } INFO("Client connected: %s:%"PRIu16" -> %s:%"PRIu16, inet_ntoa(((sockaddr_in *) & address)->sin_addr), ENTOHS(((sockaddr_in *) & address)->sin_port), STR(_ipAddress), _port); if (!setFdOptions(fd)) { FATAL("Unable to set socket options"); CLOSE_SOCKET(fd); return false; } //4. Create the chain BaseProtocol *pProtocol = ProtocolFactoryManager::CreateProtocolChain(_protocolChain, _parameters); if (pProtocol == NULL) { FATAL("Unable to create protocol chain"); CLOSE_SOCKET(fd); return false; } //5. Create the carrier and bind it TCPCarrier *pTCPCarrier = new TCPCarrier(fd); pTCPCarrier->SetProtocol(pProtocol->GetFarEndpoint()); pProtocol->GetFarEndpoint()->SetIOHandler(pTCPCarrier); //6. Register the protocol stack with an application if (_pApplication != NULL) { pProtocol = pProtocol->GetNearEndpoint(); pProtocol->SetApplication(_pApplication); } if (pProtocol->GetNearEndpoint()->GetOutputBuffer() != NULL) pProtocol->GetNearEndpoint()->EnqueueForOutbound(); _acceptedCount++; //7. Done return true; }
UDPCarrier* UDPCarrier::Create(string bindIp, uint16_t bindPort, uint16_t ttl, uint16_t tos) { //1. Create the socket int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { int err = errno; FATAL("Unable to create socket: (%d) %s", err, strerror(err)); return NULL; } //2. fd options if (!setFdOptions(sock, true)) { FATAL("Unable to set fd options"); CLOSE_SOCKET(sock); return NULL; } if (tos <= 255) { if (!setFdTOS(sock, (uint8_t) tos)) { FATAL("Unable to set tos"); CLOSE_SOCKET(sock); return NULL; } } //3. bind if necessary sockaddr_in bindAddress; memset(&bindAddress, 0, sizeof (bindAddress)); if (bindIp != "") { bindAddress.sin_family = PF_INET; bindAddress.sin_addr.s_addr = inet_addr(STR(bindIp)); bindAddress.sin_port = EHTONS(bindPort); //----MARKED-SHORT---- if (bindAddress.sin_addr.s_addr == INADDR_NONE) { FATAL("Unable to bind on address %s:%hu", STR(bindIp), bindPort); CLOSE_SOCKET(sock); return NULL; } uint32_t testVal = EHTONL(bindAddress.sin_addr.s_addr); if ((testVal > 0xe0000000) && (testVal < 0xefffffff)) { INFO("Subscribe to multicast %s:%"PRIu16, STR(bindIp), bindPort); int activateBroadcast = 1; if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &activateBroadcast, sizeof (activateBroadcast)) != 0) { int err = errno; FATAL("Unable to activate SO_BROADCAST on the socket: (%d) %s", err, strerror(err)); return NULL; } if (ttl <= 255) { if (!setFdMulticastTTL(sock, (uint8_t) ttl)) { FATAL("Unable to set ttl"); CLOSE_SOCKET(sock); return NULL; } } } else { if (ttl <= 255) { if (!setFdTTL(sock, (uint8_t) ttl)) { FATAL("Unable to set ttl"); CLOSE_SOCKET(sock); return NULL; } } } if (bind(sock, (sockaddr *) & bindAddress, sizeof (sockaddr)) != 0) { int err = errno; FATAL("Unable to bind on address: udp://%s:%"PRIu16"; Error was: (%d) %s", STR(bindIp), bindPort, err, strerror(err)); CLOSE_SOCKET(sock); return NULL; } if ((testVal > 0xe0000000) && (testVal < 0xefffffff)) { struct ip_mreq group; group.imr_multiaddr.s_addr = inet_addr(STR(bindIp)); group.imr_interface.s_addr = INADDR_ANY; if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &group, sizeof (group)) < 0) { FATAL("Adding multicast group error"); CLOSE_SOCKET(sock); return NULL; } } } //4. Create the carrier UDPCarrier *pResult = new UDPCarrier(sock); pResult->_nearAddress = bindAddress; return pResult; }
UDPCarrier* UDPCarrier::Create(string bindIp, uint16_t bindPort, uint16_t ttl, uint16_t tos, string ssmIp) { //1. Create the socket int sock = socket(AF_INET, SOCK_DGRAM, 0); if ((sock < 0) || (!setFdCloseOnExec(sock))) { int err = LASTSOCKETERROR; FATAL("Unable to create socket: %d", err); return NULL; } //2. fd options if (!setFdOptions(sock, true)) { FATAL("Unable to set fd options"); CLOSE_SOCKET(sock); return NULL; } if (tos <= 255) { if (!setFdTOS(sock, (uint8_t) tos)) { FATAL("Unable to set tos"); CLOSE_SOCKET(sock); return NULL; } } //3. bind if necessary sockaddr_in bindAddress; memset(&bindAddress, 0, sizeof (bindAddress)); if (bindIp != "") { bindAddress.sin_family = PF_INET; bindAddress.sin_addr.s_addr = inet_addr(STR(bindIp)); bindAddress.sin_port = EHTONS(bindPort); //----MARKED-SHORT---- if (bindAddress.sin_addr.s_addr == INADDR_NONE) { FATAL("Unable to bind on address %s:%hu", STR(bindIp), bindPort); CLOSE_SOCKET(sock); return NULL; } uint32_t testVal = EHTONL(bindAddress.sin_addr.s_addr); if ((testVal > 0xe0000000) && (testVal < 0xefffffff)) { INFO("Subscribe to multicast %s:%"PRIu16, STR(bindIp), bindPort); BOOL activateBroadcast = FALSE; if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *) &activateBroadcast, sizeof (activateBroadcast)) != 0) { int err = LASTSOCKETERROR; FATAL("Unable to activate SO_BROADCAST on the socket: %d", err); return NULL; } if (ttl <= 255) { if (!setFdMulticastTTL(sock, (uint8_t) ttl)) { FATAL("Unable to set ttl"); CLOSE_SOCKET(sock); return NULL; } } } else { if (ttl <= 255) { if (!setFdTTL(sock, (uint8_t) ttl)) { FATAL("Unable to set ttl"); CLOSE_SOCKET(sock); return NULL; } } } if (bind(sock, (sockaddr *) & bindAddress, sizeof (sockaddr)) != 0) { int err = LASTSOCKETERROR; FATAL("Unable to bind on address: udp://%s:%"PRIu16"; Error was: %d", STR(bindIp), bindPort, err); CLOSE_SOCKET(sock); return NULL; } if ((testVal > 0xe0000000) && (testVal < 0xefffffff)) { if (!setFdJoinMulticast(sock, bindIp, bindPort, ssmIp)) { FATAL("Adding multicast failed"); CLOSE_SOCKET(sock); return NULL; } } } //4. Create the carrier UDPCarrier *pResult = new UDPCarrier(sock); pResult->_nearAddress = bindAddress; return pResult; }