/* 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); }
/* 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; }
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); }
/* 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; }
/* 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; }