Beispiel #1
0
extern int
SH_CmpSockAddr(SockBase base, struct sockaddr *sa1, struct sockaddr *sa2) {
	sa_family_t fam = sa1->sa_family;
	if (fam != sa2->sa_family) return (fam - sa2->sa_family);
	int len1 = SockAddrLen(sa1);
	int len2 = SockAddrLen(sa2);
	if (len1 <= 0 || len2 <= 0) {
		return Gleep(base->debug, "SH_CmpSockAddr");
	}
	int delta = len1-len2;
	if (delta != 0) return delta;
	return memcmp(sa1, sa2, len1);
}
Beispiel #2
0
static int
InnerConnect(SockBase base, struct sockaddr *sap) {
	int fd = socket(sap->sa_family,
					SOCK_STREAM,
					IPPROTO_TCP);
	if (fd >= 0) {
		// we've got a socket, so try for a connection
		int timeout = base->robustTimeout;
		uint64_t start = GetCurrentTime();
		for (;;) {
			int connRes = connect(fd, sap, SockAddrLen(sap));
			if (connRes >= 0) {
				// success!
				return fd;
			}
			MilliSleep(RobustMillis);
			uint64_t now = GetCurrentTime();
			double dt = DeltaTime(start, now);
			int e = errno;
			if (dt > timeout || (e != EAGAIN && e != EINTR)) {
				// failed, so give back the socket and report the failure
				close(fd);
				return connRes;
			}
		}
	}
	return fd;
}
Beispiel #3
0
extern int
SH_CopySockAddr(SockBase base, struct sockaddr *dst, struct sockaddr *src) {
	int len = SockAddrLen(src);
	if (len <= 0) {
		return Gleep(base->debug, "SH_CopySockAddr");
	}
	memcpy(dst, src, len);
	return 0;
}
Beispiel #4
0
/**
 * Try to extract an AF_INET address from a sockaddr. If successful, sa points
 * to the next sockaddr and true is returned.
 */
bool ExtractIPV4AddressFromSockAddr(const uint8_t **data,
                                    IPV4Address *ip) {
  const struct sockaddr *sa = reinterpret_cast<const struct sockaddr*>(*data);
  if (sa->sa_family != AF_INET) {
    return false;
  }

  *ip = IPV4Address(
      reinterpret_cast<const struct sockaddr_in*>(*data)->sin_addr.s_addr);
  *data += SockAddrLen(*sa);
  return true;
}
Beispiel #5
0
/**
 * Performs a robust connect, restarting when interrupted.
 * Requires a valid socket (se->fd >= 0).
 */
extern int
SH_RobustConnect(SockEntry se, struct sockaddr *sap) {
	int timeout = se->base->robustTimeout;
	uint64_t start = GetCurrentTime();
	for (;;) {
		int connRes = connect(se->fd, sap, SockAddrLen(sap));
		if (connRes >= 0) {
			se->lastUsed = GetCurrentTime();
			return connRes;
		}
		int e = errno;
		if (e != EAGAIN && e != EINTR) break;
		MilliSleep(RobustMillis);
		uint64_t now = GetCurrentTime();
		double dt = DeltaTime(start, now);
		if (dt > timeout) break;
	}
	se->errCount++;
	return -1;
}