void ares__close_sockets(struct server_state *server) { struct send_request *sendreq; /* Free all pending output buffers. */ while (server->qhead) { /* Advance server->qhead; pull out query as we go. */ sendreq = server->qhead; server->qhead = sendreq->next; free(sendreq); } server->qtail = NULL; /* Reset any existing input buffer. */ if (server->tcp_buffer) free(server->tcp_buffer); server->tcp_buffer = NULL; server->tcp_lenbuf_pos = 0; /* Close the TCP and UDP sockets. */ if (server->tcp_socket != -1) { ares__kill_socket(server->tcp_socket); server->tcp_socket = -1; } if (server->udp_socket != -1) { ares__kill_socket(server->udp_socket); server->udp_socket = -1; } }
static int connect_udp_ipv4(int s, ares_channel channel, struct server_state *server) { struct sockaddr_in sin; /* Connect to the server. */ memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr = server->addr; sin.sin_port = channel->udp_port; if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1) { //fprintf(stderr,"kennard:ares:open_udp:ipv4: connect error %d: %s\n", errno, strerror(errno)); ares__kill_socket(s); return -1; } return 0; }
static int open_udp_socket(ares_channel channel, struct server_state *server) { u_int8_t family; int s; #ifdef USE_IPV6 family = server->family; assert(family == AF_INET || family == AF_INET6); #else family = AF_INET; #endif /* Acquire a socket. */ s = (int)socket(family, SOCK_DGRAM, 0); if (s == -1) { //fprintf(stderr,"kennard:ares:open_udp: no socket %d: %s\n", errno, strerror(errno)); return -1; } if (make_socket_non_blocking(s)) { //fprintf(stderr,"kennard:ares:open_udp: nonblocking failed %d: %s\n", errno, strerror(errno)); ares__kill_socket(s); return -1; } #ifdef USE_IPV6 // added by Rohan 7-Sept-2004 // should really replace sockaddr_in6 with sockaddr_storage /* Connect to the server. */ if (server->family == AF_INET6) { struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_addr = server->addr6; sin6.sin6_port = channel->udp_port; sin6.sin6_flowinfo = 0; sin6.sin6_scope_id = 0; // do i need to explicitly set the length? if (connect(s, (const struct sockaddr *) &sin6, sizeof(sin6)) == -1) { ares__kill_socket(s); return -1; } } else // IPv4 DNS server { if ( connect_udp_ipv4(s, channel, server)==-1 ) return -1; } #else if ( connect_udp_ipv4(s, channel, server)==-1 ) return -1; #endif if(channel->socket_function) { channel->socket_function(s, 0, __FILE__, __LINE__); } server->udp_socket = s; return 0; }
static int open_tcp_socket(ares_channel channel, struct server_state *server) { int s; struct sockaddr_in sin; #ifdef USE_IPV6 struct sockaddr_in6 sin6; #endif /* Acquire a socket. */ #ifdef USE_IPV6 assert(server->family == AF_INET || server->family == AF_INET6); s = (int)socket(server->family, SOCK_STREAM, 0); #else s = (int)socket(AF_INET, SOCK_STREAM, 0); #endif if (s == -1) return -1; if (make_socket_non_blocking(s)) { ares__kill_socket(s); return -1; } #ifdef WIN32 #define PORTABLE_INPROGRESS_ERR WSAEWOULDBLOCK #else #define PORTABLE_INPROGRESS_ERR EINPROGRESS #endif /* Connect to the server. */ #ifdef USE_IPV6 if (server->family == AF_INET6) { memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_addr = server->addr6; sin6.sin6_port = channel->tcp_port; sin6.sin6_flowinfo = 0; sin6.sin6_scope_id = 0; // do i need to explicitly set the length? if (connect(s, (const struct sockaddr *) &sin6 , sizeof(sin6)) == -1 && getErrno() != PORTABLE_INPROGRESS_ERR) { ares__kill_socket(s); return -1; } } else // IPv4 DNS server { memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr = server->addr; sin.sin_port = channel->tcp_port; if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1 && getErrno() != PORTABLE_INPROGRESS_ERR) { ares__kill_socket(s); return -1; } } #else memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr = server->addr; sin.sin_port = channel->tcp_port; if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1 && getErrno() != PORTABLE_INPROGRESS_ERR) { ares__kill_socket(s); return -1; } #endif server->tcp_socket = s; return 0; }