예제 #1
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;
}
예제 #2
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;
}