示例#1
0
int SendTo(int sock, const uint8_t *buffer, int len, const address &from, const address &to) {
#ifdef IPV6_PKTINFO
	if (from.family() == AF_INET6) {
		uint8_t ctlbuf[CMSG_SPACE(sizeof(in6_pktinfo))];

		cmsghdr *chdr = (cmsghdr *)ctlbuf;
		chdr->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));
		chdr->cmsg_level = IPPROTO_IPV6;
		chdr->cmsg_type = IPV6_PKTINFO;

		in6_pktinfo *info = (in6_pktinfo *)CMSG_DATA(chdr);
		info->ipi6_addr = from.v6()->sin6_addr;
		info->ipi6_ifindex = 0;

		msghdr msg;
		iovec iov;

		msg.msg_name = (char *)to.saddr();
		msg.msg_namelen = to.addrlen();
		msg.msg_iov = &iov;
		msg.msg_iovlen = 1;
		msg.msg_control = (char *)ctlbuf;
		msg.msg_controllen = sizeof(ctlbuf);
		msg.msg_flags = 0;

		iov.iov_base = (char *)buffer;
		iov.iov_len = len;

		return sendmsg(sock, &msg, 0);
	}
#endif
	return sendto(sock, buffer, len, 0, to.saddr(), to.addrlen());
}
示例#2
0
static bool set_address(sockaddr_storage &t, const address &addr) {
	if (addr.family() == AF_INET)
		memcpy(&t, addr.v4(), addr.addrlen());
	else if (addr.family() == AF_INET6)
		memcpy(&t, addr.v6(), addr.addrlen());
	else
		return false;
	return true;
}
示例#3
0
bool address::is_equal(const address &a) const {
	if (stor.ss_family != a.stor.ss_family)
		return false;
	if (stor.ss_family == AF_INET6)
		return memcmp(&v6()->sin6_addr, &a.v6()->sin6_addr, sizeof(in6_addr)) == 0;
	else if (stor.ss_family == AF_INET)
		return v4()->sin_addr.s_addr == a.v4()->sin_addr.s_addr;
	return false;
}
示例#4
0
bool address::copy_address(const address &source) {
	if (family() != source.family())
		return false;

	if (stor.ss_family == AF_INET6)
		v6()->sin6_addr = source.v6()->sin6_addr;
	else
		v4()->sin_addr = source.v4()->sin_addr;

	return true;
}
示例#5
0
int _McastListenOldAPI(int sock, const address &grpaddr) {
	if (grpaddr.family() == AF_INET6) {
		ipv6_mreq mreq;
		mreq.ipv6mr_interface = mcastInterface;
		mreq.ipv6mr_multiaddr = grpaddr.v6()->sin6_addr;

		return setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq));
	} else {
		ip_mreq mreq;
		memset(&mreq, 0, sizeof(mreq));
		// Specifying the interface doesn't work, there's ip_mreqn in linux..
		// but what about other OSs? -hugo
		mreq.imr_multiaddr = grpaddr.v4()->sin_addr;

		return setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
	}
}
示例#6
0
int RecvMsg(int sock, address &from, address &to, uint8_t *buffer, int buflen, int &ttl, uint64_t &ts) {
	int len;
	struct msghdr msg;
	struct iovec iov;
	uint8_t ctlbuf[64];

	from.set_family(beaconUnicastAddr.family());

	msg.msg_name = (char *)from.saddr();
	msg.msg_namelen = from.addrlen();
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = (char *)ctlbuf;
	msg.msg_controllen = sizeof(ctlbuf);
	msg.msg_flags = 0;

	iov.iov_base = (char *)buffer;
	iov.iov_len = buflen;

	len = recvmsg(sock, &msg, 0);
	if (len < 0)
		return len;

	ts = 0;
	ttl = 127;

	to = beaconUnicastAddr;

	if (msg.msg_controllen > 0) {
		for (cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) {
			if (hdr->cmsg_level == IPPROTO_IPV6 && hdr->cmsg_type == IPV6_HOPLIMIT) {
				ttl = *(int *)CMSG_DATA(hdr);
#ifdef IPV6_PKTINFO
			} else if (hdr->cmsg_level == IPPROTO_IPV6 && hdr->cmsg_type == IPV6_PKTINFO) {
				if (hdr->cmsg_len == CMSG_LEN(sizeof(in6_pktinfo))) {
					in6_pktinfo *pktinfo = (in6_pktinfo *)CMSG_DATA(hdr);
					to.set_family(AF_INET6);
					to.v6()->sin6_addr = pktinfo->ipi6_addr;
				}
#endif
#ifdef IP_RECVTTL
			} else if (hdr->cmsg_level == IPPROTO_IP && hdr->cmsg_type == IP_RECVTTL) {
				ttl = *(uint8_t *)CMSG_DATA(hdr);
#endif
			} else if (hdr->cmsg_level == IPPROTO_IP && hdr->cmsg_type == IP_TTL) {
				ttl = *(int *)CMSG_DATA(hdr);
#ifdef SO_TIMESTAMP
			} else if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SO_TIMESTAMP) {
				timeval *tv = (timeval *)CMSG_DATA(hdr);
				ts = tv->tv_sec;
				ts *= 1000;
				ts += tv->tv_usec / 1000;
#endif
			}
		}
	}

	if (!ts) {
		ts = get_time_of_day();
	}

	return len;
}