int init_listen(int port,int af) { int sock = -1; struct addrinfo hints; struct addrinfo *base_res = NULL; struct addrinfo *res_ptr = NULL; char portstr[32]; int ret; if( port <= 0 ){ return(-1); } sprintf(portstr,"%d",port); memset(&hints,'\0',sizeof(hints)); hints.ai_family = af; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; ret = getaddrinfo(NULL,portstr,&hints,&base_res); if( ret != 0 ){ fprintf(stderr,"ERROR: getaddrinfo: %s\n",gai_strerror(ret)); return(-1); } for( res_ptr = base_res; res_ptr != NULL; res_ptr = res_ptr->ai_next ){ sock = socket(res_ptr->ai_family,res_ptr->ai_socktype,res_ptr->ai_protocol); if( sock < 0 ){ continue; } set_reuseaddr(sock); set_sndbuf(sock,65535); set_rcvbuf(sock,65535); if( bind(sock,res_ptr->ai_addr,res_ptr->ai_addrlen) < 0 ){ fprintf(stderr,"WARN: bind: %s\n",strerror(errno)); close(sock); sock = -1; continue; } if( listen(sock,BACKLOG_NUMBER) < 0 ){ fprintf(stderr,"WARN: listen: %s\n",strerror(errno)); close(sock); sock = -1; continue; } break; } freeaddrinfo(base_res); base_res = NULL; return(sock); }
int connect2(const char *host,int port,int af) { int sock = -1; struct addrinfo hints; struct addrinfo *base_res = NULL; struct addrinfo *res_ptr = NULL; char portstr[32]; int ret; if( NULL == host || port <= 0 ){ return(-1); } sprintf(portstr,"%d",port); memset(&hints,'\0',sizeof(hints)); hints.ai_family = af; hints.ai_socktype = SOCK_STREAM; ret = getaddrinfo(host,portstr,&hints,&base_res); if( ret != 0 ){ fprintf(stderr,"ERROR: getaddrinfo: %s\n",gai_strerror(ret)); return(-1); } for( res_ptr = base_res; res_ptr != NULL; res_ptr = res_ptr->ai_next ){ sock = socket(res_ptr->ai_family,res_ptr->ai_socktype,res_ptr->ai_protocol); if( sock < 0 ){ continue; } set_sndbuf(sock,65535); set_rcvbuf(sock,65535); if( connect(sock,res_ptr->ai_addr,res_ptr->ai_addrlen) < 0 ){ close(sock); sock = -1; continue; } break; } freeaddrinfo(base_res); base_res = NULL; return(sock); }
/* set up the socket to receive multicast data * */ int setup_mcast_listener( struct sockaddr_in* sa, const struct ip_mreq* mreq, int* mcastfd, int sockbuflen ) { int sockfd, rc; int ON = 1; int buflen = sockbuflen; size_t rcvbuf_len = 0; assert( sa && mreq && mcastfd && (sockbuflen >= 0) ); TRACE( (void)tmfprintf( g_flog, "Setting up multicast listener\n") ); rc = ERR_INTERNAL; do { sockfd = socket( AF_INET, SOCK_DGRAM, 0 ); if( -1 == sockfd ) { mperror(g_flog, errno, "%s: socket", __func__); break; } if (buflen != 0) { rc = get_rcvbuf( sockfd, &rcvbuf_len ); if (0 != rc) break; if ((size_t)buflen > rcvbuf_len) { rc = set_rcvbuf( sockfd, buflen ); if (0 != rc) break; } } else { TRACE( (void)tmfprintf( g_flog, "Must not adjust buffer size " "for mcast socket [%d]\n", sockfd ) ); } rc = setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &ON, sizeof(ON) ); if( 0 != rc ) { mperror(g_flog, errno, "%s: setsockopt SO_REUSEADDR", __func__); break; } #ifdef SO_REUSEPORT /* On some systems (such as FreeBSD) SO_REUSEADDR just isn't enough to subscribe to N same channels for different clients. */ rc = setsockopt( sockfd, SOL_SOCKET, SO_REUSEPORT, &ON, sizeof(ON) ); if( 0 != rc ) { mperror(g_flog, errno, "%s: setsockopt SO_REUSEPORT", __func__); break; } #endif /* SO_REUSEPORT */ rc = bind( sockfd, (struct sockaddr*)sa, sizeof(*sa) ); if( 0 != rc ) { mperror(g_flog, errno, "%s: bind", __func__); break; } rc = set_multicast( sockfd, mreq, IP_ADD_MEMBERSHIP ); if( 0 != rc ) break; } while(0); if( 0 == rc ) { *mcastfd = sockfd; TRACE( (void)tmfprintf( g_flog, "Mcast listener socket=[%d] set up\n", sockfd) ); } else { (void)close(sockfd); } return rc; }
int make_socket ( os_socket * sock, unsigned short port, c_bool stream, c_bool reuse, const os_sockaddr_storage * mcip, const char * address ) { int rc = -2; *sock = os_sockNew ((config.useIpv6 ? AF_INET6 : AF_INET), stream ? SOCK_STREAM : SOCK_DGRAM); if (! Q_VALID_SOCKET (*sock)) { print_sockerror ("socket"); return rc; } if (port && reuse && ((rc = set_reuse_options (*sock)) < 0)) { goto fail; } if ( (rc = set_rcvbuf (*sock) < 0) || (rc = set_sndbuf (*sock) < 0) || ((rc = maybe_set_dont_route (*sock)) < 0) || ((rc = bind_socket (*sock, port, address)) < 0) ) { goto fail; } if (! stream) { if ((rc = set_mc_options_transmit (*sock)) < 0) { goto fail; } } if (stream) { #ifdef SO_NOSIGPIPE set_socket_nosigpipe (*sock); #endif #ifdef TCP_NODELAY if (config.tcp_nodelay) { set_socket_nodelay (*sock); } #endif } if (mcip && ((rc = join_mcgroups (*sock, mcip)) < 0)) { goto fail; } return 0; fail: os_sockFree (*sock); *sock = Q_INVALID_SOCKET; return rc; }