예제 #1
0
파일: network.c 프로젝트: svn2github/irssi
/* 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);
}
예제 #2
0
파일: network.c 프로젝트: svn2github/irssi
/* 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;
}
예제 #3
0
파일: ncic_inet.c 프로젝트: devinsmith/ncic
int nb_connect(	struct sockaddr_storage *ss,
				struct sockaddr_storage *laddr,
				in_port_t port,
				int *dsock)
{
	int sock;
	int ret = 0;

	sock = socket(ss->ss_family, SOCK_STREAM, 0);
	if (sock < 0) {
		debug("socket: %s", strerror(errno));
		return (-1);
	}

	if (laddr != NULL) {
		if (bind(sock, (struct sockaddr *) laddr, sin_len(laddr)) != 0) {
			debug("bind: %s", strerror(errno));
			goto err_out;
		}
	}

	/* Set nonblocking socket */
	if (sock_setflags(sock, O_NONBLOCK) == -1)
		goto err_out;

	sin_set_port(ss, htons(port));

	if (connect(sock, (struct sockaddr *) ss, sin_len(ss)) != 0) {
		if (errno != EINPROGRESS) {
			debug("connect: %s", strerror(errno));
			goto err_out;
		}

		ret = -EINPROGRESS;
	} else {
		/* Turn off non-blocking. */
		if (sock_setflags(sock, 0) == -1)
			goto err_out;
	}

	if (ret == 0)
		debug("immediate connect");

	*dsock = sock;
	return (ret);

err_out:
	close(sock);
	return (-1);
}
예제 #4
0
파일: network.c 프로젝트: svn2github/irssi
/* 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;
}
예제 #5
0
파일: network.c 프로젝트: svn2github/irssi
/* 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;
}