/* 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; }
struct addrinfo CreateAddrinfo( sockaddr_u* sock) { struct addrinfo a; a.ai_family = sock->sa.sa_family; a.ai_addrlen = SIZEOF_SOCKADDR(a.ai_family); a.ai_addr = &sock->sa; return a; }
struct addrinfo CreateAddrinfo(sockaddr_u* sock) { struct addrinfo a; memset(&a, '\0', sizeof(struct addrinfo)); a.ai_family = sock->sa.sa_family; a.ai_addrlen = SIZEOF_SOCKADDR(a.ai_family); a.ai_addr = &sock->sa; return a; }
bool WSocket::ipToStringW(const SOCKADDR_STORAGE *sockAddr, LPWSTR buffer) { DWORD size = MAX_PATH; if(CWA(ws2_32, WSAAddressToStringW)((LPSOCKADDR)sockAddr, SIZEOF_SOCKADDR(sockAddr->ss_family), NULL, buffer, &size) != 0) { Str::_CopyW(buffer, L"0:0", 3); return false; } return true; }
SOCKET WSocket::tcpConnect(const SOCKADDR_STORAGE *sockAddr) { SOCKET s = CWA(ws2_32, socket)(sockAddr->ss_family, SOCK_STREAM, IPPROTO_TCP); if(s != INVALID_SOCKET) { if(CWA(ws2_32, connect)(s, (sockaddr *)sockAddr, SIZEOF_SOCKADDR(sockAddr->ss_family)) != 0) { CWA(ws2_32, closesocket)(s); s = INVALID_SOCKET; } } return s; }
SOCKET WSocket::udpListen(const SOCKADDR_STORAGE *sockAddr) { SOCKET s = CWA(ws2_32, socket)(sockAddr->ss_family, SOCK_DGRAM, IPPROTO_UDP); if(s != INVALID_SOCKET) { if(CWA(ws2_32, bind)(s, (sockaddr *)sockAddr, SIZEOF_SOCKADDR(sockAddr->ss_family)) != 0) { CWA(ws2_32, closesocket)(s); s = INVALID_SOCKET; } } return s; }
SOCKET WSocket::tcpListen(const SOCKADDR_STORAGE *sockAddr, int backlog) { SOCKET s = CWA(ws2_32, socket)(sockAddr->ss_family, SOCK_STREAM, IPPROTO_TCP); if(s != INVALID_SOCKET) { if(CWA(ws2_32, bind)(s, (sockaddr *)sockAddr, SIZEOF_SOCKADDR(sockAddr->ss_family)) != 0 || CWA(ws2_32, listen)(s, backlog) != 0) { CWA(ws2_32, closesocket)(s); s = INVALID_SOCKET; } } return s; }
int silc_net_udp_send(SilcStream stream, const char *remote_ip_addr, int remote_port, const unsigned char *data, SilcUInt32 data_len) { SilcSocketStream sock = stream; SilcSockaddr remote; int ret; SILC_LOG_DEBUG(("Sending data to UDP socket %d", sock->sock)); /* Set sockaddr */ if (!silc_net_set_sockaddr(&remote, remote_ip_addr, remote_port)) return -2; /* Send */ ret = sendto(sock->sock, data, data_len, 0, &remote.sa, SIZEOF_SOCKADDR(remote)); if (ret < 0) { if (errno == EAGAIN || errno == EINTR) { SILC_LOG_DEBUG(("Could not send immediately, will do it later")); silc_schedule_set_listen_fd(sock->schedule, sock->sock, SILC_TASK_READ | SILC_TASK_WRITE, FALSE); return -1; } SILC_LOG_DEBUG(("Cannot send to UDP socket: %s", strerror(errno))); silc_schedule_unset_listen_fd(sock->schedule, sock->sock); sock->sock_error = errno; return -2; } SILC_LOG_DEBUG(("Sent data %d bytes", ret)); if (silc_schedule_get_fd_events(sock->schedule, sock->sock) & SILC_TASK_WRITE) silc_schedule_set_listen_fd(sock->schedule, sock->sock, SILC_TASK_READ, FALSE); return ret; }
/* * getnetnum - given a host name, return its net number * and (optional) full name */ static int getnetnum( const char *hname, sockaddr_u *num, char *fullhost, int af ) { int sockaddr_len; struct addrinfo hints, *ai = NULL; sockaddr_len = SIZEOF_SOCKADDR(af); memset((char *)&hints, 0, sizeof(struct addrinfo)); hints.ai_flags = AI_CANONNAME; #ifdef AI_ADDRCONFIG hints.ai_flags |= AI_ADDRCONFIG; #endif /* decodenetnum only works with addresses */ if (decodenetnum(hname, num)) { if (fullhost != 0) { getnameinfo(&num->sa, sockaddr_len, fullhost, sizeof(fullhost), NULL, 0, NI_NUMERICHOST); } return 1; } else if (getaddrinfo(hname, "ntp", &hints, &ai) == 0) { memmove((char *)num, ai->ai_addr, ai->ai_addrlen); if (fullhost != 0) (void) strcpy(fullhost, ai->ai_canonname); return 1; } else { (void) fprintf(stderr, "***Can't find host %s\n", hname); return 0; } /*NOTREACHED*/ }
SilcStream silc_net_udp_connect(const char *local_ip_addr, int local_port, const char *remote_ip_addr, int remote_port, SilcSchedule schedule) { SilcStream stream; SilcSockaddr server; int sock = -1, rval; const char *ipany = "0.0.0.0"; SILC_LOG_DEBUG(("Creating UDP stream")); if (!schedule) goto err; /* Bind to local addresses */ SILC_LOG_DEBUG(("Binding to local address %s", local_ip_addr ? local_ip_addr : ipany)); /* Set sockaddr for server */ if (!silc_net_set_sockaddr(&server, local_ip_addr ? local_ip_addr : ipany, local_port)) goto err; /* Create the socket */ sock = socket(server.sin.sin_family, SOCK_DGRAM, 0); if (sock < 0) { SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno))); goto err; } /* Set the socket options */ rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1); if (rval < 0) { SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno))); goto err; } #ifdef SO_REUSEPORT rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEPORT, 1); if (rval < 0) { SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno))); goto err; } #endif /* SO_REUSEPORT */ /* Bind the listener socket */ rval = bind(sock, &server.sa, SIZEOF_SOCKADDR(server)); if (rval < 0) { SILC_LOG_DEBUG(("Cannot bind socket: %s", strerror(errno))); goto err; } /* Set to connected state if remote address is provided. */ if (remote_ip_addr && remote_port) { if (!silc_net_set_sockaddr(&server, remote_ip_addr, remote_port)) goto err; rval = connect(sock, &server.sa, SIZEOF_SOCKADDR(server)); if (rval < 0) { SILC_LOG_DEBUG(("Cannot connect UDP stream: %s", strerror(errno))); goto err; } } /* Set send and receive buffer size */ #ifdef SO_SNDBUF rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_SNDBUF, 765535); if (rval < 0) { rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_SNDBUF, 65535); if (rval < 0) { SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno))); goto err; } } #endif /* SO_SNDBUF */ #ifdef SO_RCVBUF rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_RCVBUF, 765535); if (rval < 0) { rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_RCVBUF, 65535); if (rval < 0) { SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno))); goto err; } } #endif /* SO_RCVBUF */ /* Encapsulate into socket stream */ stream = silc_socket_udp_stream_create(sock, local_ip_addr ? silc_net_is_ip6(local_ip_addr) : FALSE, remote_ip_addr ? TRUE : FALSE, schedule); if (!stream) goto err; SILC_LOG_DEBUG(("UDP stream created, fd=%d", sock)); return stream; err: if (sock != -1) close(sock); return NULL; }
SilcNetListener silc_net_tcp_create_listener(const char **local_ip_addr, SilcUInt32 local_ip_count, int port, SilcBool lookup, SilcBool require_fqdn, SilcSchedule schedule, SilcNetCallback callback, void *context) { SilcNetListener listener = NULL; SilcSockaddr server; int i, sock, rval; const char *ipany = "0.0.0.0"; SILC_LOG_DEBUG(("Creating TCP listener")); if (port < 0 || !schedule || !callback) goto err; listener = silc_calloc(1, sizeof(*listener)); if (!listener) return NULL; listener->schedule = schedule; listener->callback = callback; listener->context = context; listener->require_fqdn = require_fqdn; listener->lookup = lookup; if (local_ip_count > 0) { listener->socks = silc_calloc(local_ip_count, sizeof(*listener->socks)); if (!listener->socks) return NULL; } else { listener->socks = silc_calloc(1, sizeof(*listener->socks)); if (!listener->socks) return NULL; local_ip_count = 1; } /* Bind to local addresses */ for (i = 0; i < local_ip_count; i++) { SILC_LOG_DEBUG(("Binding to local address %s:%d", local_ip_addr ? local_ip_addr[i] : ipany, port)); /* Set sockaddr for server */ if (!silc_net_set_sockaddr(&server, local_ip_addr ? local_ip_addr[i] : ipany, port)) goto err; /* Create the socket */ sock = socket(server.sin.sin_family, SOCK_STREAM, 0); if (sock < 0) { SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno))); goto err; } /* Set the socket options */ rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1); if (rval < 0) { SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno))); close(sock); goto err; } /* Bind the listener socket */ rval = bind(sock, &server.sa, SIZEOF_SOCKADDR(server)); if (rval < 0) { SILC_LOG_ERROR(("Cannot bind socket: %s", strerror(errno))); close(sock); goto err; } /* Specify that we are listenning */ rval = listen(sock, 64); if (rval < 0) { SILC_LOG_ERROR(("Cannot set socket listenning: %s", strerror(errno))); close(sock); goto err; } /* Set the server socket to non-blocking mode */ silc_net_set_socket_nonblock(sock); /* Schedule for incoming connections */ silc_schedule_task_add_fd(schedule, sock, silc_net_accept, listener); SILC_LOG_DEBUG(("TCP listener created, fd=%d", sock)); listener->socks[i] = sock; listener->socks_count++; } return listener; err: if (listener) silc_net_close_listener(listener); return NULL; }