Esempio n. 1
0
int domain_name_lookup_reverse(const char *addr, char *name)
{
	struct in_addr iaddr;
	int err;

	struct sockaddr_in saddr; //replace with sockaddr_in6 for ipv6
	char host[DOMAIN_NAME_MAX];

	debug(D_DNS, "looking up addr %s", addr);

	if(!string_to_ip_address(addr, (unsigned char *) &iaddr)) {
		debug(D_DNS, "%s is not a valid addr", addr);
		return 0;
	}
	saddr.sin_addr = iaddr;
	saddr.sin_family = AF_INET;

	if ((err = getnameinfo((struct sockaddr *) &saddr, sizeof(saddr), host, sizeof(host), NULL, 0, 0)) != 0){
		debug(D_DNS, "couldn't look up %s: %s", addr, gai_strerror(err));
		return 0;
	}
	strcpy(name, host);
	debug(D_DNS, "%s is %s", addr, name);
	
	return 1;
}
Esempio n. 2
0
struct link *link_serve_address(const char *addr, int port)
{
	struct link *link = 0;
	struct sockaddr_in address;
	int success;
	int value;

	link = link_create();
	if(!link)
		goto failure;

	link->fd = socket(AF_INET, SOCK_STREAM, 0);
	if(link->fd < 0)
		goto failure;

	value = 1;
	setsockopt(link->fd, SOL_SOCKET, SO_REUSEADDR, (void *) &value, sizeof(value));

	link_window_configure(link);

	if(addr != 0 || port != LINK_PORT_ANY) {

		memset(&address, 0, sizeof(address));
#if defined(CCTOOLS_OPSYS_DARWIN)
		address.sin_len = sizeof(address);
#endif
		address.sin_family = AF_INET;
		address.sin_port = htons(port);

		if(addr) {
			string_to_ip_address(addr, (unsigned char *) &address.sin_addr.s_addr);
		} else {
			address.sin_addr.s_addr = htonl(INADDR_ANY);
		}

		success = bind(link->fd, (struct sockaddr *) &address, sizeof(address));
		if(success < 0)
			goto failure;
	}

	success = listen(link->fd, 5);
	if(success < 0)
		goto failure;

	if(!link_nonblocking(link, 1))
		goto failure;

	debug(D_TCP, "listening on port %d", port);
	return link;

      failure:
	if(link)
		link_close(link);
	return 0;
}
Esempio n. 3
0
int datagram_send(struct datagram *d, const char *data, int length, const char *addr, int port)
{
	int result;
	struct sockaddr_in iaddr;
	SOCKLEN_T iaddr_length;

	iaddr_length = sizeof(iaddr);

	iaddr.sin_family = AF_INET;
	iaddr.sin_port = htons(port);
	if(!string_to_ip_address(addr, (unsigned char *) &iaddr.sin_addr))
		return -1;

	result = sendto(d->fd, data, length, 0, (const struct sockaddr *) &iaddr, iaddr_length);
	if(result < 0)
		return result;

	return result;
}
Esempio n. 4
0
struct datagram *datagram_create_address(const char *addr, int port)
{
	struct datagram *d = 0;
	struct sockaddr_in address;
	int success;
	int on = 1;

	d = malloc(sizeof(*d));
	if(!d)
		goto failure;

	d->fd = socket(PF_INET, SOCK_DGRAM, 0);
	if(d->fd < 0)
		goto failure;

	setsockopt(d->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

	memset(&address, 0, sizeof(address));
	address.sin_family = AF_INET;
#if defined(CCTOOLS_OPSYS_DARWIN)
	address.sin_len = sizeof(address);
#endif
	if(addr) {
		string_to_ip_address(addr, (unsigned char *) &address.sin_addr.s_addr);
	} else {
		address.sin_addr.s_addr = htonl(INADDR_ANY);
	}
	address.sin_port =  DATAGRAM_PORT_ANY ? htons(0) : htons(port);

	success = bind(d->fd, (struct sockaddr *) &address, sizeof(address));
	if(success < 0)
		goto failure;

	return d;
failure:
	datagram_delete(d);
	return 0;
}
Esempio n. 5
0
struct link *link_connect(const char *addr, int port, time_t stoptime)
{
	struct sockaddr_in address;
	struct link *link = 0;
	int result;
	int save_errno;

	link = link_create();
	if(!link)
		goto failure;

	link_squelch();

	memset(&address, 0, sizeof(address));
#if defined(CCTOOLS_OPSYS_DARWIN)
	address.sin_len = sizeof(address);
#endif
	address.sin_family = AF_INET;
	address.sin_port = htons(port);

	if(!string_to_ip_address(addr, (unsigned char *) &address.sin_addr))
		goto failure;

	link->fd = socket(AF_INET, SOCK_STREAM, 0);
	if(link->fd < 0)
		goto failure;

	link_window_configure(link);

	/* sadly, cygwin does not do non-blocking connect correctly */
#ifdef CCTOOLS_OPSYS_CYGWIN
	if(!link_nonblocking(link, 0))
		goto failure;
#else
	if(!link_nonblocking(link, 1))
		goto failure;
#endif

	debug(D_TCP, "connecting to %s:%d", addr, port);

	do {
		result = connect(link->fd, (struct sockaddr *) &address, sizeof(address));

		/* On some platforms, errno is not set correctly. */
		/* If the remote address can be found, then we are really connected. */
		/* Also, on bsd-derived systems, failure to connect is indicated by a second connect returning EINVAL. */

		if(result < 0 && !errno_is_temporary(errno)) {
			if(errno == EINVAL)
				errno = ECONNREFUSED;
			break;
		}

		if(link_address_remote(link, link->raddr, &link->rport)) {

			debug(D_TCP, "made connection to %s:%d", link->raddr, link->rport);

#ifdef CCTOOLS_OPSYS_CYGWIN
			link_nonblocking(link, 1);
#endif
			return link;
		}
	} while(link_sleep(link, stoptime, 0, 1));

	debug(D_TCP, "connection to %s:%d failed (%s)", addr, port, strerror(errno));

      failure:
	save_errno = errno;
	if(link)
		link_close(link);
	errno = save_errno;
	return 0;
}
Esempio n. 6
0
File: link.c Progetto: mcast/cctools
struct link *link_connect(const char *addr, int port, time_t stoptime)
{
	struct sockaddr_in address;
	struct link *link = 0;
	int result;
	int save_errno;

	link = link_create();
	if(!link)
		goto failure;

	link_squelch();

	memset(&address, 0, sizeof(address));
#if defined(CCTOOLS_OPSYS_DARWIN)
	address.sin_len = sizeof(address);
#endif
	address.sin_family = AF_INET;
	address.sin_port = htons(port);

	if(!string_to_ip_address(addr, (unsigned char *) &address.sin_addr))
		goto failure;

	link->fd = socket(AF_INET, SOCK_STREAM, 0);
	if(link->fd < 0)
		goto failure;

	link_window_configure(link);

	/* sadly, cygwin does not do non-blocking connect correctly */
#ifdef CCTOOLS_OPSYS_CYGWIN
	if(!link_nonblocking(link, 0))
		goto failure;
#else
	if(!link_nonblocking(link, 1))
		goto failure;
#endif

	debug(D_TCP, "connecting to %s:%d", addr, port);

	while(1) {
		// First attempt a non-blocking connect
		result = connect(link->fd, (struct sockaddr *) &address, sizeof(address));

		// On many platforms, non-blocking connect sets errno in unexpected ways:

		// On OSX, result=-1 and errno==EISCONN indicates a successful connection.
		if(result<0 && errno==EISCONN) result=0;

		// On BSD-derived systems, failure to connect is indicated by errno = EINVAL.
		// Set it to something more explanatory.
		if(result<0 && errno==EINVAL) errno=ECONNREFUSED;

		// Otherwise, a non-temporary errno should cause us to bail out.
		if(result<0 && !errno_is_temporary(errno)) break;

		// If the remote address is valid, we are connected no matter what.
		if(link_address_remote(link, link->raddr, &link->rport)) {
			debug(D_TCP, "made connection to %s:%d", link->raddr, link->rport);
#ifdef CCTOOLS_OPSYS_CYGWIN
			link_nonblocking(link, 1);
#endif
			return link;
		}

		// if the time has expired, bail out
		if( time(0) >= stoptime ) {
			errno = ETIMEDOUT;
			break;
		}

		// wait for some activity on the socket.
		link_sleep(link, stoptime, 0, 1);

		// No matter how the sleep ends, we want to go back to the top
		// and call connect again to get a proper errno.
	}


	debug(D_TCP, "connection to %s:%d failed (%s)", addr, port, strerror(errno));

failure:
	save_errno = errno;
	if(link)
		link_close(link);
	errno = save_errno;
	return 0;
}
Esempio n. 7
0
File: link.c Progetto: mcast/cctools
struct link *link_serve_address(const char *addr, int port)
{
	struct link *link = 0;
	struct sockaddr_in address;
	int success;
	int value;

	link = link_create();
	if(!link)
		goto failure;

	link->fd = socket(AF_INET, SOCK_STREAM, 0);
	if(link->fd < 0)
		goto failure;

	value = fcntl(link->fd, F_GETFD);
	if (value == -1)
		goto failure;
	value |= FD_CLOEXEC;
	if (fcntl(link->fd, F_SETFD, value) == -1)
		goto failure;

	value = 1;
	setsockopt(link->fd, SOL_SOCKET, SO_REUSEADDR, (void *) &value, sizeof(value));

	link_window_configure(link);

	memset(&address, 0, sizeof(address));
#if defined(CCTOOLS_OPSYS_DARWIN)
	address.sin_len = sizeof(address);
#endif
	address.sin_family = AF_INET;

	if(addr) {
		string_to_ip_address(addr, (unsigned char *) &address.sin_addr.s_addr);
	} else {
		address.sin_addr.s_addr = htonl(INADDR_ANY);
	}

	int low = TCP_LOW_PORT_DEFAULT;
	int high = TCP_HIGH_PORT_DEFAULT;
	if(port < 1) {
		const char *lowstr = getenv("TCP_LOW_PORT");
		if (lowstr)
			low = atoi(lowstr);
		const char *highstr = getenv("TCP_HIGH_PORT");
		if (highstr)
			high = atoi(highstr);
	} else {
		low = high = port;
	}

	if(high < low)
		fatal("high port %d is less than low port %d in range", high, low);

	for (port = low; port <= high; port++) {
		address.sin_port = htons(port);
		success = bind(link->fd, (struct sockaddr *) &address, sizeof(address));
		if(success == -1) {
			if(errno == EADDRINUSE) {
				//If a port is specified, fail!
				if (low == high) {
					goto failure;
				} else {
					continue;
				}
			} else {
				goto failure;
			}
		}
		break;
	}

	success = listen(link->fd, 5);
	if(success < 0)
		goto failure;

	if(!link_nonblocking(link, 1))
		goto failure;

	debug(D_TCP, "listening on port %d", port);
	return link;

      failure:
	if(link)
		link_close(link);
	return 0;
}