static void simple_readpipe(SIMPLE_THREAD_REC *rec, GIOChannel *pipe) { RESOLVED_IP_REC iprec; GIOChannel *handle; IPADDR *ip; g_return_if_fail(rec != NULL); g_source_remove(rec->tag); net_gethostbyname_return(pipe, &iprec); g_free_not_null(iprec.errorstr); g_io_channel_shutdown(rec->pipes[0], TRUE, NULL); g_io_channel_unref(rec->pipes[0]); g_io_channel_shutdown(rec->pipes[1], TRUE, NULL); g_io_channel_unref(rec->pipes[1]); ip = iprec.ip4.family != 0 ? &iprec.ip4 : &iprec.ip6; handle = iprec.error == -1 ? NULL : net_connect_ip(ip, rec->port, rec->my_ip); g_free_not_null(rec->my_ip); if (handle == NULL) { /* failed */ rec->func(NULL, rec->data); g_free(rec); return; } rec->tag = g_input_add(handle, G_INPUT_READ | G_INPUT_WRITE, (GInputFunction) simple_init, rec); }
static void server_connect_callback_readpipe(SERVER_REC *server) { RESOLVED_IP_REC iprec; IPADDR *ip; const char *errormsg; char *servername = NULL; g_source_remove(server->connect_tag); server->connect_tag = -1; net_gethostbyname_return(server->connect_pipe[0], &iprec); g_io_channel_close(server->connect_pipe[0]); g_io_channel_unref(server->connect_pipe[0]); g_io_channel_close(server->connect_pipe[1]); g_io_channel_unref(server->connect_pipe[1]); server->connect_pipe[0] = NULL; server->connect_pipe[1] = NULL; /* figure out if we should use IPv4 or v6 address */ if (iprec.error != 0) { /* error */ ip = NULL; } else if (server->connrec->family == AF_INET) { /* force IPv4 connection */ ip = iprec.ip4.family == 0 ? NULL : &iprec.ip4; servername = iprec.host4; } else if (server->connrec->family == AF_INET6) { /* force IPv6 connection */ ip = iprec.ip6.family == 0 ? NULL : &iprec.ip6; servername = iprec.host6; } else { /* pick the one that was found, or if both do it like /SET resolve_prefer_ipv6 says. */ if (iprec.ip4.family == 0 || (iprec.ip6.family != 0 && settings_get_bool("resolve_prefer_ipv6"))) { ip = &iprec.ip6; servername = iprec.host6; } else { ip = &iprec.ip4; servername = iprec.host4; } } if (ip != NULL) { /* host lookup ok */ if (servername) { g_free(server->connrec->address); server->connrec->address = g_strdup(servername); } server_real_connect(server, ip, NULL); errormsg = NULL; } else { if (iprec.error == 0 || net_hosterror_notfound(iprec.error)) { /* IP wasn't found for the host, don't try to reconnect back to this server */ server->dns_error = TRUE; } if (iprec.error == 0) { /* forced IPv4 or IPv6 address but it wasn't found */ errormsg = server->connrec->family == AF_INET ? "IPv4 address not found for host" : "IPv6 address not found for host"; } else { /* gethostbyname() failed */ errormsg = iprec.errorstr != NULL ? iprec.errorstr : "Host lookup failed"; } server->connection_lost = TRUE; server_connect_failed(server, errormsg); } g_free(iprec.errorstr); g_free(iprec.host4); g_free(iprec.host6); }