Exemple #1
0
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);
}
Exemple #2
0
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);
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}