Exemplo n.º 1
0
/* Connect to socket with ip address */
GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
{
	union sockaddr_union so;
	int handle, ret, opt = 1;

	if (my_ip != NULL && ip->family != my_ip->family) {
		g_warning("net_connect_ip(): ip->family != my_ip->family");
                my_ip = NULL;
	}

	/* create the socket */
	memset(&so, 0, sizeof(so));
        so.sin.sin_family = ip->family;
	handle = socket(ip->family, SOCK_STREAM, 0);

	if (handle == -1)
		return NULL;

	/* set socket options */
#ifndef WIN32
	fcntl(handle, F_SETFL, O_NONBLOCK);
#endif
	setsockopt(handle, SOL_SOCKET, SO_REUSEADDR,
		   (char *) &opt, sizeof(opt));
	setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE,
		   (char *) &opt, sizeof(opt));

	/* set our own address */
	if (my_ip != NULL) {
		sin_set_ip(&so, my_ip);
		if (bind(handle, &so.sa, SIZEOF_SOCKADDR(so)) == -1) {
			/* failed, set it back to INADDR_ANY */
			sin_set_ip(&so, NULL);
			bind(handle, &so.sa, SIZEOF_SOCKADDR(so));
		}
	}

	/* connect */
	sin_set_ip(&so, ip);
	sin_set_port(&so, port);
	ret = connect(handle, &so.sa, SIZEOF_SOCKADDR(so));

#ifndef WIN32
	if (ret < 0 && errno != EINPROGRESS)
#else
	if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
#endif
	{
		int old_errno = errno;
		close(handle);
		errno = old_errno;
		return NULL;
	}

	return g_io_channel_new(handle);
}
Exemplo n.º 2
0
Arquivo: network.c Projeto: GPF/irssi
/* Get name for host, *name should be g_free()'d unless it's NULL.
   Return values are the same as with net_gethostbyname() */
int net_gethostbyaddr(IPADDR *ip, char **name)
{
#ifdef HAVE_IPV6
	union sockaddr_union so;
	int host_error;
	char hostname[NI_MAXHOST];
#else
	struct hostent *hp;
#endif

	g_return_val_if_fail(ip != NULL, -1);
	g_return_val_if_fail(name != NULL, -1);

	*name = NULL;
#ifdef HAVE_IPV6
	memset(&so, 0, sizeof(so));
	sin_set_ip(&so, ip);

	/* save error to host_error for later use */
        host_error = getnameinfo((struct sockaddr *) &so, sizeof(so),
                                 hostname, sizeof(hostname), NULL, 0, 0);
        if (host_error != 0)
                return host_error;

	*name = g_strdup(hostname);
#else
	if (ip->family != AF_INET) return -1;
	hp = gethostbyaddr((const char *) &ip->ip, 4, AF_INET);
	if (hp == NULL) return -1;

	*name = g_strdup(hp->h_name);
#endif

	return 0;
}
Exemplo n.º 3
0
/* Listen for connections on a socket. if `my_ip' is NULL, listen in any
   address. */
GIOChannel *net_listen(IPADDR *my_ip, int *port)
{
	union sockaddr_union so;
	int ret, handle, opt = 1;
	socklen_t len;

	g_return_val_if_fail(port != NULL, NULL);

	memset(&so, 0, sizeof(so));
	sin_set_port(&so, *port);
	sin_set_ip(&so, my_ip);

	/* create the socket */
	handle = socket(so.sin.sin_family, SOCK_STREAM, 0);
#ifdef HAVE_IPV6
	if (handle == -1 && (errno == EINVAL || errno == EAFNOSUPPORT)) {
		/* IPv6 is not supported by OS */
		so.sin.sin_family = AF_INET;
		so.sin.sin_addr.s_addr = INADDR_ANY;

		handle = socket(AF_INET, SOCK_STREAM, 0);
	}
#endif
	if (handle == -1)
		return NULL;

	/* set socket options */
#ifndef WIN32
	fcntl(handle, F_SETFL, O_NONBLOCK);
#endif
	setsockopt(handle, SOL_SOCKET, SO_REUSEADDR,
		   (char *) &opt, sizeof(opt));
	setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE,
		   (char *) &opt, sizeof(opt));

	/* specify the address/port we want to listen in */
	ret = bind(handle, &so.sa, SIZEOF_SOCKADDR(so));
	if (ret >= 0) {
		/* get the actual port we started listen */
		len = SIZEOF_SOCKADDR(so);
		ret = getsockname(handle, &so.sa, &len);
		if (ret >= 0) {
			*port = sin_get_port(&so);

			/* start listening */
			if (listen(handle, 1) >= 0)
                                return g_io_channel_new(handle);
		}

	}

        /* error */
	close(handle);
	return NULL;
}
Exemplo n.º 4
0
/* Connect to socket with ip address */
int net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
{
	union sockaddr_union so;
	int handle, ret, opt = 1;

	/* create the socket */
	memset(&so, 0, sizeof(so));
        so.sin.sin_family = ip->family;
	handle = socket(ip->family, SOCK_STREAM, 0);

	if (handle == -1)
		return -1;

	/* set socket options */
	fcntl(handle, F_SETFL, O_NONBLOCK);
	setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt));
	setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt));

	/* set our own address, ignore if bind() fails */
	if (my_ip != NULL) {
		sin_set_ip(&so, my_ip);
		bind(handle, &so.sa, sizeof(so));
	}

	/* connect */
	sin_set_ip(&so, ip);
	sin_set_port(&so, port);
	ret = connect(handle, &so.sa, sizeof(so));

	if (ret < 0 && errno != EINPROGRESS) {
		close(handle);
		return -1;
	}

	return handle;
}
Exemplo n.º 5
0
/* Listen for connections on a socket. if `my_ip' is NULL, listen in any
   address. */
int net_listen(IPADDR *my_ip, int *port)
{
	union sockaddr_union so;
	int ret, handle, opt = 1;
	socklen_t len = sizeof(so);

	g_return_val_if_fail(port != NULL, -1);

	memset(&so, 0, sizeof(so));
	sin_set_port(&so, *port);
	sin_set_ip(&so, my_ip);

	/* create the socket */
	handle = socket(so.sin.sin_family, SOCK_STREAM, 0);
	if (handle == -1)
		return -1;

	/* set socket options */
	fcntl(handle, F_SETFL, O_NONBLOCK);
	setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt));
	setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt));

	/* specify the address/port we want to listen in */
	ret = bind(handle, &so.sa, sizeof(so));
	if (ret < 0) {
		close(handle);
		return -1;
	}

	/* get the actual port we started listen */
	ret = getsockname(handle, &so.sa, &len);
	if (ret < 0) {
		close(handle);
		return -1;
	}

	*port = sin_get_port(&so);

	/* start listening */
	if (listen(handle, 1) < 0) {
		close(handle);
		return -1;
	}

	return handle;
}