annotate src/dnsquery.c @ 14182:ccb670ba3b4f

[gaim-migrate @ 16834] Only doing 2 DNS requests at a time seems a little restrictive. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Fri, 18 Aug 2006 07:22:55 +0000
parents fc92a5a7dd95
children c3c792958635
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
14181
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
1 /**
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
2 * @file dnsquery.c DNS query API
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
3 * @ingroup core
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
4 *
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
5 * gaim
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
6 *
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
7 * Gaim is the legal property of its developers, whose names are too numerous
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
8 * to list here. Please refer to the COPYRIGHT file distributed with this
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
9 * source distribution.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
10 *
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
11 * This program is free software; you can redistribute it and/or modify
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
12 * it under the terms of the GNU General Public License as published by
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
13 * the Free Software Foundation; either version 2 of the License, or
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
14 * (at your option) any later version.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
15 *
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
16 * This program is distributed in the hope that it will be useful,
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
19 * GNU General Public License for more details.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
20 *
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
21 * You should have received a copy of the GNU General Public License
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
22 * along with this program; if not, write to the Free Software
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
24 *
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
25 */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
26
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
27 #include "internal.h"
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
28 #include "debug.h"
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
29 #include "notify.h"
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
30 #include "prefs.h"
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
31 #include "dnsquery.h"
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
32 #include "util.h"
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
33
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
34 /**************************************************************************
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
35 * DNS query API
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
36 **************************************************************************/
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
37
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
38 #if defined(__unix__) || defined(__APPLE__)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
39
14182
ccb670ba3b4f [gaim-migrate @ 16834]
Mark Doliner <mark@kingant.net>
parents: 14181
diff changeset
40 #define MAX_DNS_CHILDREN 4
ccb670ba3b4f [gaim-migrate @ 16834]
Mark Doliner <mark@kingant.net>
parents: 14181
diff changeset
41
14181
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
42 /*
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
43 * This structure represents both a pending DNS request and
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
44 * a free child process.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
45 */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
46 typedef struct {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
47 char *host;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
48 int port;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
49 GaimProxyDnsConnectFunction callback;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
50 gpointer data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
51 guint inpa;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
52 int fd_in, fd_out;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
53 pid_t dns_pid;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
54 } pending_dns_request_t;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
55
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
56 static GSList *free_dns_children = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
57 static GQueue *queued_requests = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
58
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
59 static int number_of_dns_children = 0;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
60
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
61 typedef struct {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
62 char hostname[512];
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
63 int port;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
64 } dns_params_t;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
65
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
66 typedef struct {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
67 dns_params_t params;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
68 GaimProxyDnsConnectFunction callback;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
69 gpointer data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
70 } queued_dns_request_t;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
71
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
72 /*
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
73 * Begin the DNS resolver child process functions.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
74 */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
75 #ifdef HAVE_SIGNAL_H
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
76 static void
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
77 trap_gdb_bug()
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
78 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
79 const char *message =
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
80 "Gaim's DNS child got a SIGTRAP signal.\n"
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
81 "This can be caused by trying to run gaim inside gdb.\n"
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
82 "There is a known gdb bug which prevents this. Supposedly gaim\n"
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
83 "should have detected you were using gdb and used an ugly hack,\n"
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
84 "check cope_with_gdb_brokenness() in dnsquery.c.\n\n"
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
85 "For more info about this bug, see http://sources.redhat.com/ml/gdb/2001-07/msg00349.html\n";
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
86 fputs("\n* * *\n",stderr);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
87 fputs(message,stderr);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
88 fputs("* * *\n\n",stderr);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
89 execlp("xmessage","xmessage","-center", message, NULL);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
90 _exit(1);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
91 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
92 #endif
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
93
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
94 static void
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
95 cope_with_gdb_brokenness()
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
96 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
97 #ifdef __linux__
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
98 static gboolean already_done = FALSE;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
99 char s[256], e[512];
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
100 int n;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
101 pid_t ppid;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
102
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
103 if(already_done)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
104 return;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
105 already_done = TRUE;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
106 ppid = getppid();
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
107 snprintf(s, sizeof(s), "/proc/%d/exe", ppid);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
108 n = readlink(s, e, sizeof(e));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
109 if(n < 0)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
110 return;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
111
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
112 e[MIN(n,sizeof(e)-1)] = '\0';
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
113
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
114 if(strstr(e,"gdb")) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
115 gaim_debug_info("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
116 "Debugger detected, performing useless query...\n");
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
117 gethostbyname("x.x.x.x.x");
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
118 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
119 #endif
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
120 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
121
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
122 static void
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
123 gaim_dns_resolverthread(int child_out, int child_in, gboolean show_debug)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
124 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
125 dns_params_t dns_params;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
126 const size_t zero = 0;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
127 int rc;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
128 #ifdef HAVE_GETADDRINFO
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
129 struct addrinfo hints, *res, *tmp;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
130 char servname[20];
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
131 #else
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
132 struct sockaddr_in sin;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
133 const size_t addrlen = sizeof(sin);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
134 #endif
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
135
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
136 #ifdef HAVE_SIGNAL_H
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
137 signal(SIGHUP, SIG_DFL);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
138 signal(SIGINT, SIG_DFL);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
139 signal(SIGQUIT, SIG_DFL);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
140 signal(SIGCHLD, SIG_DFL);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
141 signal(SIGTERM, SIG_DFL);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
142 signal(SIGTRAP, trap_gdb_bug);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
143 #endif
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
144
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
145 /*
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
146 * We resolve 1 host name for each iteration of this
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
147 * while loop.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
148 *
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
149 * The top half of this reads in the hostname and port
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
150 * number from the socket with our parent. The bottom
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
151 * half of this resolves the IP (blocking) and sends
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
152 * the result back to our parent, when finished.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
153 */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
154 while (1) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
155 const char ch = 'Y';
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
156 fd_set fds;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
157 struct timeval tv = { .tv_sec = 40 , .tv_usec = 0 };
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
158 FD_ZERO(&fds);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
159 FD_SET(child_in, &fds);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
160 rc = select(child_in + 1, &fds, NULL, NULL, &tv);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
161 if (!rc) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
162 if (show_debug)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
163 printf("dns[%d]: nobody needs me... =(\n", getpid());
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
164 break;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
165 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
166 rc = read(child_in, &dns_params, sizeof(dns_params_t));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
167 if (rc < 0) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
168 perror("read()");
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
169 break;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
170 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
171 if (rc == 0) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
172 if (show_debug)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
173 printf("dns[%d]: Oops, father has gone, wait for me, wait...!\n", getpid());
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
174 _exit(0);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
175 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
176 if (dns_params.hostname[0] == '\0') {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
177 printf("dns[%d]: hostname = \"\" (port = %d)!!!\n", getpid(), dns_params.port);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
178 _exit(1);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
179 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
180 /* Tell our parent that we read the data successfully */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
181 write(child_out, &ch, sizeof(ch));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
182
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
183 /* We have the hostname and port, now resolve the IP */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
184
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
185 #ifdef HAVE_GETADDRINFO
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
186 g_snprintf(servname, sizeof(servname), "%d", dns_params.port);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
187 memset(&hints, 0, sizeof(hints));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
188
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
189 /* This is only used to convert a service
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
190 * name to a port number. As we know we are
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
191 * passing a number already, we know this
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
192 * value will not be really used by the C
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
193 * library.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
194 */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
195 hints.ai_socktype = SOCK_STREAM;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
196 rc = getaddrinfo(dns_params.hostname, servname, &hints, &res);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
197 write(child_out, &rc, sizeof(rc));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
198 if (rc != 0) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
199 close(child_out);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
200 if (show_debug)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
201 printf("dns[%d] Error: getaddrinfo returned %d\n",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
202 getpid(), rc);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
203 dns_params.hostname[0] = '\0';
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
204 continue;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
205 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
206 tmp = res;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
207 while (res) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
208 size_t ai_addrlen = res->ai_addrlen;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
209 write(child_out, &ai_addrlen, sizeof(ai_addrlen));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
210 write(child_out, res->ai_addr, res->ai_addrlen);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
211 res = res->ai_next;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
212 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
213 freeaddrinfo(tmp);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
214 write(child_out, &zero, sizeof(zero));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
215 #else
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
216 if (!inet_aton(dns_params.hostname, &sin.sin_addr)) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
217 struct hostent *hp;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
218 if (!(hp = gethostbyname(dns_params.hostname))) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
219 write(child_out, &h_errno, sizeof(int));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
220 close(child_out);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
221 if (show_debug)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
222 printf("DNS Error: %d\n", h_errno);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
223 _exit(0);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
224 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
225 memset(&sin, 0, sizeof(struct sockaddr_in));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
226 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
227 sin.sin_family = hp->h_addrtype;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
228 } else
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
229 sin.sin_family = AF_INET;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
230
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
231 sin.sin_port = htons(dns_params.port);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
232 write(child_out, &addrlen, sizeof(addrlen));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
233 write(child_out, &sin, addrlen);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
234 write(child_out, &zero, sizeof(zero));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
235 #endif
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
236 dns_params.hostname[0] = '\0';
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
237 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
238
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
239 close(child_out);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
240 close(child_in);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
241
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
242 _exit(0);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
243 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
244
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
245 static pending_dns_request_t *
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
246 gaim_dns_new_resolverthread(gboolean show_debug)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
247 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
248 pending_dns_request_t *req;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
249 int child_out[2], child_in[2];
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
250
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
251 /* Create pipes for communicating with the child process */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
252 if (pipe(child_out) || pipe(child_in)) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
253 gaim_debug_error("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
254 "Could not create pipes: %s\n", strerror(errno));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
255 return NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
256 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
257
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
258 req = g_new(pending_dns_request_t, 1);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
259
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
260 cope_with_gdb_brokenness();
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
261
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
262 /* Fork! */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
263 req->dns_pid = fork();
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
264
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
265 /* If we are the child process... */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
266 if (req->dns_pid == 0) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
267 /* We should not access the parent's side of the pipes, so close them */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
268 close(child_out[0]);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
269 close(child_in[1]);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
270
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
271 gaim_dns_resolverthread(child_out[1], child_in[0], show_debug);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
272 /* The thread calls _exit() rather than returning, so we never get here */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
273 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
274
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
275 /* We should not access the child's side of the pipes, so close them */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
276 close(child_out[1]);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
277 close(child_in[0]);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
278 if (req->dns_pid == -1) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
279 gaim_debug_error("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
280 "Could not create child process for DNS: %s\n",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
281 strerror(errno));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
282 g_free(req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
283 return NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
284 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
285
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
286 req->fd_out = child_out[0];
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
287 req->fd_in = child_in[1];
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
288 number_of_dns_children++;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
289 gaim_debug_info("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
290 "Created new DNS child %d, there are now %d children.\n",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
291 req->dns_pid, number_of_dns_children);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
292
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
293 return req;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
294 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
295 /*
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
296 * End the DNS resolver child process functions.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
297 */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
298
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
299 /*
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
300 * Begin the functions for dealing with the DNS child processes.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
301 */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
302 static void
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
303 req_free(pending_dns_request_t *req)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
304 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
305 g_return_if_fail(req != NULL);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
306
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
307 close(req->fd_in);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
308 close(req->fd_out);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
309
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
310 g_free(req->host);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
311 g_free(req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
312
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
313 number_of_dns_children--;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
314 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
315
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
316 static int
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
317 send_dns_request_to_child(pending_dns_request_t *req, dns_params_t *dns_params)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
318 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
319 char ch;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
320 int rc;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
321 pid_t pid;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
322
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
323 /* This waitpid might return the child's PID if it has recently
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
324 * exited, or it might return an error if it exited "long
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
325 * enough" ago that it has already been reaped; in either
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
326 * instance, we can't use it. */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
327 if ((pid = waitpid (req->dns_pid, NULL, WNOHANG)) > 0) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
328 gaim_debug_warning("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
329 "DNS child %d no longer exists\n", req->dns_pid);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
330 return -1;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
331 } else if (pid < 0) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
332 gaim_debug_warning("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
333 "Wait for DNS child %d failed: %s\n",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
334 req->dns_pid, strerror(errno));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
335 return -1;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
336 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
337
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
338 /* Let's contact this lost child! */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
339 rc = write(req->fd_in, dns_params, sizeof(*dns_params));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
340 if (rc < 0) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
341 gaim_debug_error("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
342 "Unable to write to DNS child %d: %d\n",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
343 req->dns_pid, strerror(errno));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
344 close(req->fd_in);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
345 return -1;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
346 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
347
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
348 g_return_val_if_fail(rc == sizeof(*dns_params), -1);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
349
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
350 /* Did you hear me? (This avoids some race conditions) */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
351 rc = read(req->fd_out, &ch, sizeof(ch));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
352 if (rc != 1 || ch != 'Y')
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
353 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
354 gaim_debug_warning("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
355 "DNS child %d not responding. Killing it!\n",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
356 req->dns_pid);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
357 kill(req->dns_pid, SIGKILL);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
358 return -1;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
359 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
360
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
361 gaim_debug_info("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
362 "Successfully sent DNS request to child %d\n", req->dns_pid);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
363
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
364 return 0;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
365 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
366
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
367 static void
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
368 host_resolved(gpointer data, gint source, GaimInputCondition cond);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
369
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
370 static void
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
371 release_dns_child(pending_dns_request_t *req)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
372 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
373 g_free(req->host);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
374 req->host = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
375
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
376 if (queued_requests && !g_queue_is_empty(queued_requests)) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
377 queued_dns_request_t *r = g_queue_pop_head(queued_requests);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
378 req->host = g_strdup(r->params.hostname);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
379 req->port = r->params.port;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
380 req->callback = r->callback;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
381 req->data = r->data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
382
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
383 gaim_debug_info("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
384 "Processing queued DNS query for '%s' with child %d\n",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
385 req->host, req->dns_pid);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
386
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
387 if (send_dns_request_to_child(req, &(r->params)) != 0) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
388 req_free(req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
389 req = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
390
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
391 gaim_debug_warning("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
392 "Intent of process queued query of '%s' failed, "
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
393 "requeueing...\n", r->params.hostname);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
394 g_queue_push_head(queued_requests, r);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
395 } else {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
396 req->inpa = gaim_input_add(req->fd_out, GAIM_INPUT_READ, host_resolved, req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
397 g_free(r);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
398 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
399
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
400 } else {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
401 req->host = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
402 req->callback = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
403 req->data = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
404 free_dns_children = g_slist_append(free_dns_children, req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
405 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
406 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
407
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
408 static void
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
409 host_resolved(gpointer data, gint source, GaimInputCondition cond)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
410 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
411 pending_dns_request_t *req = (pending_dns_request_t*)data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
412 int rc, err;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
413 GSList *hosts = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
414 struct sockaddr *addr = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
415 size_t addrlen;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
416
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
417 gaim_debug_info("dns", "Got response for '%s'\n", req->host);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
418 gaim_input_remove(req->inpa);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
419
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
420 rc = read(req->fd_out, &err, sizeof(err));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
421 if ((rc == 4) && (err != 0))
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
422 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
423 char message[1024];
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
424 #ifdef HAVE_GETADDRINFO
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
425 g_snprintf(message, sizeof(message), "DNS error: %s (pid=%d)",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
426 gai_strerror(err), req->dns_pid);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
427 #else
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
428 g_snprintf(message, sizeof(message), "DNS error: %d (pid=%d)",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
429 err, req->dns_pid);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
430 #endif
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
431 gaim_debug_error("dns", "%s\n", message);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
432 req->callback(NULL, req->data, message);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
433 release_dns_child(req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
434 return;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
435 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
436 if (rc > 0)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
437 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
438 while (rc > 0) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
439 rc = read(req->fd_out, &addrlen, sizeof(addrlen));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
440 if (rc > 0 && addrlen > 0) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
441 addr = g_malloc(addrlen);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
442 rc = read(req->fd_out, addr, addrlen);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
443 hosts = g_slist_append(hosts, GINT_TO_POINTER(addrlen));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
444 hosts = g_slist_append(hosts, addr);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
445 } else {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
446 break;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
447 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
448 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
449 } else if (rc == -1) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
450 char message[1024];
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
451 g_snprintf(message, sizeof(message), "Error reading from DNS child: %s",strerror(errno));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
452 gaim_debug_error("dns", "%s\n", message);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
453 req->callback(NULL, req->data, message);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
454 req_free(req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
455 return;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
456 } else if (rc == 0) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
457 char message[1024];
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
458 g_snprintf(message, sizeof(message), "EOF reading from DNS child");
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
459 close(req->fd_out);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
460 gaim_debug_error("dns", "%s\n", message);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
461 req->callback(NULL, req->data, message);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
462 req_free(req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
463 return;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
464 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
465
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
466 /* wait4(req->dns_pid, NULL, WNOHANG, NULL); */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
467
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
468 req->callback(hosts, req->data, NULL);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
469
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
470 release_dns_child(req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
471 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
472 /*
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
473 * End the functions for dealing with the DNS child processes.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
474 */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
475
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
476 int
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
477 gaim_gethostbyname_async(const char *hostname, int port, GaimProxyDnsConnectFunction callback, gpointer data)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
478 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
479 pending_dns_request_t *req = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
480 dns_params_t dns_params;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
481 gchar *host_temp;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
482 gboolean show_debug;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
483
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
484 show_debug = gaim_debug_is_enabled();
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
485
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
486 host_temp = g_strstrip(g_strdup(hostname));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
487 strncpy(dns_params.hostname, host_temp, sizeof(dns_params.hostname) - 1);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
488 g_free(host_temp);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
489 dns_params.hostname[sizeof(dns_params.hostname) - 1] = '\0';
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
490 dns_params.port = port;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
491
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
492 /*
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
493 * If we have any children, attempt to have them perform the DNS
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
494 * query. If we're able to send the query to a child, then req
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
495 * will be set to the pending_dns_request_t. Otherwise, req will
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
496 * be NULL and we'll need to create a new DNS request child.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
497 */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
498 while (free_dns_children != NULL) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
499 req = free_dns_children->data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
500 free_dns_children = g_slist_remove(free_dns_children, req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
501
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
502 if (send_dns_request_to_child(req, &dns_params) == 0)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
503 /* We found an acceptable child, yay */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
504 break;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
505
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
506 req_free(req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
507 req = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
508 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
509
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
510 /* We need to create a new DNS request child */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
511 if (req == NULL) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
512 if (number_of_dns_children >= MAX_DNS_CHILDREN) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
513 queued_dns_request_t *r = g_new(queued_dns_request_t, 1);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
514 memcpy(&(r->params), &dns_params, sizeof(dns_params));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
515 r->callback = callback;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
516 r->data = data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
517 if (!queued_requests)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
518 queued_requests = g_queue_new();
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
519 g_queue_push_tail(queued_requests, r);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
520
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
521 gaim_debug_info("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
522 "DNS query for '%s' queued\n", dns_params.hostname);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
523
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
524 return 0;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
525 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
526
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
527 req = gaim_dns_new_resolverthread(show_debug);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
528 if (req == NULL)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
529 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
530 gaim_debug_error("proxy", "oh dear, this is going to explode, I give up\n");
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
531 return -1;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
532 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
533 send_dns_request_to_child(req, &dns_params);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
534 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
535
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
536 req->host = g_strdup(hostname);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
537 req->port = port;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
538 req->callback = callback;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
539 req->data = data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
540 req->inpa = gaim_input_add(req->fd_out, GAIM_INPUT_READ, host_resolved, req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
541
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
542 return 0;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
543 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
544
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
545 #elif defined _WIN32 /* end __unix__ || __APPLE__ */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
546
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
547 typedef struct _dns_tdata {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
548 char *hostname;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
549 int port;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
550 GaimProxyDnsConnectFunction callback;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
551 gpointer data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
552 GSList *hosts;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
553 char *errmsg;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
554 } dns_tdata;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
555
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
556 static gboolean dns_main_thread_cb(gpointer data) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
557 dns_tdata *td = (dns_tdata*)data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
558 if (td->errmsg != NULL) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
559 gaim_debug_info("dns", "%s\n", td->errmsg);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
560 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
561 td->callback(td->hosts, td->data, td->errmsg);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
562 g_free(td->hostname);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
563 g_free(td->errmsg);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
564 g_free(td);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
565 return FALSE;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
566 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
567
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
568 static gpointer dns_thread(gpointer data) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
569
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
570 #ifdef HAVE_GETADDRINFO
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
571 int rc;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
572 struct addrinfo hints, *res, *tmp;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
573 char servname[20];
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
574 #else
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
575 struct sockaddr_in sin;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
576 struct hostent *hp;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
577 #endif
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
578 dns_tdata *td = (dns_tdata*)data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
579
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
580 #ifdef HAVE_GETADDRINFO
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
581 g_snprintf(servname, sizeof(servname), "%d", td->port);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
582 memset(&hints,0,sizeof(hints));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
583
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
584 /* This is only used to convert a service
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
585 * name to a port number. As we know we are
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
586 * passing a number already, we know this
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
587 * value will not be really used by the C
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
588 * library.
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
589 */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
590 hints.ai_socktype = SOCK_STREAM;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
591 if ((rc = getaddrinfo(td->hostname, servname, &hints, &res)) == 0) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
592 tmp = res;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
593 while(res) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
594 td->hosts = g_slist_append(td->hosts,
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
595 GSIZE_TO_POINTER(res->ai_addrlen));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
596 td->hosts = g_slist_append(td->hosts,
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
597 g_memdup(res->ai_addr, res->ai_addrlen));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
598 res = res->ai_next;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
599 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
600 freeaddrinfo(tmp);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
601 } else {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
602 td->errmsg = g_strdup_printf("DNS getaddrinfo(\"%s\", \"%s\") error: %d", td->hostname, servname, rc);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
603 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
604 #else
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
605 if ((hp = gethostbyname(td->hostname))) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
606 memset(&sin, 0, sizeof(struct sockaddr_in));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
607 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
608 sin.sin_family = hp->h_addrtype;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
609 sin.sin_port = htons(td->port);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
610
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
611 td->hosts = g_slist_append(td->hosts,
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
612 GSIZE_TO_POINTER(sizeof(sin)));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
613 td->hosts = g_slist_append(td->hosts,
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
614 g_memdup(&sin, sizeof(sin)));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
615 } else {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
616 td->errmsg = g_strdup_printf("DNS gethostbyname(\"%s\") error: %d", td->hostname, h_errno);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
617 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
618 #endif
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
619 /* back to main thread */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
620 g_idle_add(dns_main_thread_cb, td);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
621 return 0;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
622 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
623
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
624 int
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
625 gaim_gethostbyname_async(const char *hostname, int port,
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
626 GaimProxyDnsConnectFunction callback, gpointer data)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
627 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
628 dns_tdata *td;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
629 struct sockaddr_in sin;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
630 GError* err = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
631
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
632 if(inet_aton(hostname, &sin.sin_addr)) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
633 GSList *hosts = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
634 sin.sin_family = AF_INET;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
635 sin.sin_port = htons(port);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
636 hosts = g_slist_append(hosts, GINT_TO_POINTER(sizeof(sin)));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
637 hosts = g_slist_append(hosts, g_memdup(&sin, sizeof(sin)));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
638 callback(hosts, data, NULL);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
639 return 0;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
640 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
641
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
642 gaim_debug_info("dns", "DNS Lookup for: %s\n", hostname);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
643 td = g_new0(dns_tdata, 1);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
644 td->hostname = g_strdup(hostname);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
645 td->port = port;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
646 td->callback = callback;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
647 td->data = data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
648
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
649 if(!g_thread_create(dns_thread, td, FALSE, &err)) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
650 gaim_debug_error("dns", "DNS thread create failure: %s\n", err?err->message:"");
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
651 g_error_free(err);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
652 g_free(td->hostname);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
653 g_free(td);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
654 return -1;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
655 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
656 return 0;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
657 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
658
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
659 #else /* not __unix__ or __APPLE__ or _WIN32 */
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
660
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
661 typedef struct {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
662 gpointer data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
663 size_t addrlen;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
664 struct sockaddr *addr;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
665 GaimProxyDnsConnectFunction callback;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
666 } pending_dns_request_t;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
667
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
668 static gboolean host_resolved(gpointer data)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
669 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
670 pending_dns_request_t *req = (pending_dns_request_t*)data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
671 GSList *hosts = NULL;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
672 hosts = g_slist_append(hosts, GINT_TO_POINTER(req->addrlen));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
673 hosts = g_slist_append(hosts, req->addr);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
674 req->callback(hosts, req->data, NULL);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
675 g_free(req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
676 return FALSE;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
677 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
678
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
679 int
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
680 gaim_gethostbyname_async(const char *hostname, int port,
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
681 GaimProxyDnsConnectFunction callback, gpointer data)
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
682 {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
683 struct sockaddr_in sin;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
684 pending_dns_request_t *req;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
685
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
686 if (!inet_aton(hostname, &sin.sin_addr)) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
687 struct hostent *hp;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
688 if(!(hp = gethostbyname(hostname))) {
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
689 gaim_debug_error("dns",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
690 "gaim_gethostbyname(\"%s\", %d) failed: %d\n",
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
691 hostname, port, h_errno);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
692 return -1;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
693 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
694 memset(&sin, 0, sizeof(struct sockaddr_in));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
695 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
696 sin.sin_family = hp->h_addrtype;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
697 } else
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
698 sin.sin_family = AF_INET;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
699 sin.sin_port = htons(port);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
700
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
701 req = g_new(pending_dns_request_t, 1);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
702 req->addr = (struct sockaddr*) g_memdup(&sin, sizeof(sin));
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
703 req->addrlen = sizeof(sin);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
704 req->data = data;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
705 req->callback = callback;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
706 gaim_timeout_add(10, host_resolved, req);
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
707 return 0;
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
708 }
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
709
fc92a5a7dd95 [gaim-migrate @ 16833]
Mark Doliner <mark@kingant.net>
parents:
diff changeset
710 #endif /* not __unix__ or __APPLE__ or _WIN32 */