comparison src/proxy.c @ 10707:7672a83c04da

[gaim-migrate @ 12296] Fix the 64 bit DNS thing for real in HEAD, and also lots of formatting changes. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 20 Mar 2005 17:23:30 +0000
parents b221bc891e7a
children cc9922ce3a52
comparison
equal deleted inserted replaced
10706:b221bc891e7a 10707:7672a83c04da
223 } queued_dns_request_t; 223 } queued_dns_request_t;
224 224
225 static void req_free(pending_dns_request_t *req) 225 static void req_free(pending_dns_request_t *req)
226 { 226 {
227 g_return_if_fail(req != NULL); 227 g_return_if_fail(req != NULL);
228 if(req->host) 228
229 g_free(req->host);
230 close(req->fd_in); 229 close(req->fd_in);
231 close(req->fd_out); 230 close(req->fd_out);
231
232 g_free(req->host);
232 g_free(req); 233 g_free(req);
234
233 number_of_dns_children--; 235 number_of_dns_children--;
234 } 236 }
235 237
236 static int send_dns_request_to_child(pending_dns_request_t *req, dns_params_t *dns_params) 238 static int send_dns_request_to_child(pending_dns_request_t *req, dns_params_t *dns_params)
237 { 239 {
238 char ch; 240 char ch;
239 int rc; 241 int rc;
240 242
241 /* Are you alive? */ 243 /* Are you alive? */
242 if(kill(req->dns_pid, 0) != 0) { 244 if (kill(req->dns_pid, 0) != 0) {
243 gaim_debug_warning("dns", 245 gaim_debug_warning("dns",
244 "DNS child %d no longer exists\n", req->dns_pid); 246 "DNS child %d no longer exists\n", req->dns_pid);
245 return -1; 247 return -1;
246 } 248 }
247 249
248 /* Let's contact this lost child! */ 250 /* Let's contact this lost child! */
249 rc = write(req->fd_in, dns_params, sizeof(*dns_params)); 251 rc = write(req->fd_in, dns_params, sizeof(*dns_params));
250 if(rc<0) { 252 if (rc < 0) {
251 gaim_debug_error("dns", 253 gaim_debug_error("dns",
252 "Unable to write to DNS child %d: %d\n", 254 "Unable to write to DNS child %d: %d\n",
253 req->dns_pid, strerror(errno)); 255 req->dns_pid, strerror(errno));
254 close(req->fd_in); 256 close(req->fd_in);
255 return -1; 257 return -1;
256 } 258 }
257 259
258 g_return_val_if_fail(rc == sizeof(*dns_params), -1); 260 g_return_val_if_fail(rc == sizeof(*dns_params), -1);
259 261
260 /* Did you hear me? (This avoids some race conditions) */ 262 /* Did you hear me? (This avoids some race conditions) */
261 rc = read(req->fd_out, &ch, 1); 263 rc = read(req->fd_out, &ch, sizeof(ch));
262 if(rc != 1 || ch!='Y') { 264 if (rc != 1 || ch != 'Y')
265 {
263 gaim_debug_warning("dns", 266 gaim_debug_warning("dns",
264 "DNS child %d not responding. Killing it!\n", 267 "DNS child %d not responding. Killing it!\n",
265 req->dns_pid); 268 req->dns_pid);
266 kill(req->dns_pid, SIGKILL); 269 kill(req->dns_pid, SIGKILL);
267 return -1; 270 return -1;
268 } 271 }
269 272
270 gaim_debug_info("dns", 273 gaim_debug_info("dns",
271 "Successfully sent DNS request to child %d\n", req->dns_pid); 274 "Successfully sent DNS request to child %d\n", req->dns_pid);
275
272 return 0; 276 return 0;
273 } 277 }
274 278
275 static void host_resolved(gpointer data, gint source, GaimInputCondition cond); 279 static void host_resolved(gpointer data, gint source, GaimInputCondition cond);
276 280
277 static void release_dns_child(pending_dns_request_t *req) 281 static void release_dns_child(pending_dns_request_t *req)
278 { 282 {
279 g_free(req->host); 283 g_free(req->host);
280 req->host=NULL; 284 req->host = NULL;
281 285
282 if(queued_requests && !g_queue_is_empty(queued_requests)) { 286 if (queued_requests && !g_queue_is_empty(queued_requests)) {
283 queued_dns_request_t *r = g_queue_pop_head(queued_requests); 287 queued_dns_request_t *r = g_queue_pop_head(queued_requests);
284 req->host = g_strdup(r->params.hostname); 288 req->host = g_strdup(r->params.hostname);
285 req->port = r->params.port; 289 req->port = r->params.port;
286 req->callback = r->callback; 290 req->callback = r->callback;
287 req->data = r->data; 291 req->data = r->data;
288 292
289 gaim_debug_info("dns", 293 gaim_debug_info("dns",
290 "Processing queued DNS query for '%s' with child %d\n", 294 "Processing queued DNS query for '%s' with child %d\n",
291 req->host, req->dns_pid); 295 req->host, req->dns_pid);
292 296
293 if(send_dns_request_to_child(req, &(r->params)) != 0) { 297 if (send_dns_request_to_child(req, &(r->params)) != 0) {
294 req_free(req); 298 req_free(req);
295 req = NULL; 299 req = NULL;
296 300
297 gaim_debug_warning("dns", 301 gaim_debug_warning("dns",
298 "Intent of process queued query of '%s' failed, " 302 "Intent of process queued query of '%s' failed, "
320 size_t addrlen; 324 size_t addrlen;
321 325
322 gaim_debug_info("dns", "Host '%s' resolved\n", req->host); 326 gaim_debug_info("dns", "Host '%s' resolved\n", req->host);
323 gaim_input_remove(req->inpa); 327 gaim_input_remove(req->inpa);
324 328
325 rc=read(req->fd_out, &err, sizeof(err)); 329 rc = read(req->fd_out, &err, sizeof(err));
326 if((rc==4) && (err!=0)) { 330 if ((rc == 4) && (err != 0))
331 {
327 char message[1024]; 332 char message[1024];
328 #if HAVE_GETADDRINFO 333 #if HAVE_GETADDRINFO
329 g_snprintf(message, sizeof(message), "DNS error: %s (pid=%d)", 334 g_snprintf(message, sizeof(message), "DNS error: %s (pid=%d)",
330 gai_strerror(err), req->dns_pid); 335 gai_strerror(err), req->dns_pid);
331 #else 336 #else
335 gaim_debug_error("dns", "%s\n", message); 340 gaim_debug_error("dns", "%s\n", message);
336 req->callback(NULL, req->data, message); 341 req->callback(NULL, req->data, message);
337 release_dns_child(req); 342 release_dns_child(req);
338 return; 343 return;
339 } 344 }
340 if(rc>0) { 345 if (rc > 0)
341 while(rc > 0) { 346 {
342 rc=read(req->fd_out, &addrlen, sizeof(addrlen)); 347 while (rc > 0) {
343 if(rc>0 && addrlen > 0) { 348 rc = read(req->fd_out, &addrlen, sizeof(addrlen));
344 addr=g_malloc(addrlen); 349 if (rc > 0 && addrlen > 0) {
345 rc=read(req->fd_out, addr, addrlen); 350 addr = g_malloc(addrlen);
351 rc = read(req->fd_out, addr, addrlen);
346 hosts = g_slist_append(hosts, GINT_TO_POINTER(addrlen)); 352 hosts = g_slist_append(hosts, GINT_TO_POINTER(addrlen));
347 hosts = g_slist_append(hosts, addr); 353 hosts = g_slist_append(hosts, addr);
348 } else { 354 } else {
349 break; 355 break;
350 } 356 }
351 } 357 }
352 } else if(rc==-1) { 358 } else if (rc == -1) {
353 char message[1024]; 359 char message[1024];
354 g_snprintf(message, sizeof(message), "Error reading from DNS child: %s",strerror(errno)); 360 g_snprintf(message, sizeof(message), "Error reading from DNS child: %s",strerror(errno));
355 gaim_debug_error("dns", "%s\n", message); 361 gaim_debug_error("dns", "%s\n", message);
356 req->callback(NULL, req->data, message); 362 req->callback(NULL, req->data, message);
357 req_free(req); 363 req_free(req);
358 return; 364 return;
359 } else if(rc==0) { 365 } else if (rc == 0) {
360 char message[1024]; 366 char message[1024];
361 g_snprintf(message, sizeof(message), "EOF reading from DNS child"); 367 g_snprintf(message, sizeof(message), "EOF reading from DNS child");
362 close(req->fd_out); 368 close(req->fd_out);
363 gaim_debug_error("dns", "%s\n", message); 369 gaim_debug_error("dns", "%s\n", message);
364 req->callback(NULL, req->data, message); 370 req->callback(NULL, req->data, message);
417 } 423 }
418 424
419 static void 425 static void
420 gaim_dns_childthread(int child_out, int child_in, dns_params_t *dns_params, gboolean show_debug) 426 gaim_dns_childthread(int child_out, int child_in, dns_params_t *dns_params, gboolean show_debug)
421 { 427 {
422 const size_t zero = 0; 428 const int zero = 0;
423 int rc; 429 int rc;
424 #if HAVE_GETADDRINFO 430 #if HAVE_GETADDRINFO
425 struct addrinfo hints, *res, *tmp; 431 struct addrinfo hints, *res, *tmp;
426 char servname[20]; 432 char servname[20];
427 #else 433 #else
438 signal(SIGTRAP, trap_gdb_bug); 444 signal(SIGTRAP, trap_gdb_bug);
439 #endif 445 #endif
440 446
441 while (1) { 447 while (1) {
442 if (dns_params->hostname[0] == '\0') { 448 if (dns_params->hostname[0] == '\0') {
443 const char Y = 'Y'; 449 const char ch = 'Y';
444 fd_set fds; 450 fd_set fds;
445 struct timeval tv = { .tv_sec = 40 , .tv_usec = 0 }; 451 struct timeval tv = { .tv_sec = 40 , .tv_usec = 0 };
446 FD_ZERO(&fds); 452 FD_ZERO(&fds);
447 FD_SET(child_in, &fds); 453 FD_SET(child_in, &fds);
448 rc = select(child_in + 1, &fds, NULL, NULL, &tv); 454 rc = select(child_in + 1, &fds, NULL, NULL, &tv);
454 rc = read(child_in, dns_params, sizeof(dns_params_t)); 460 rc = read(child_in, dns_params, sizeof(dns_params_t));
455 if (rc < 0) { 461 if (rc < 0) {
456 perror("read()"); 462 perror("read()");
457 break; 463 break;
458 } 464 }
459 if (rc==0) { 465 if (rc == 0) {
460 if (show_debug) 466 if (show_debug)
461 fprintf(stderr,"dns[%d]: Oops, father has gone, wait for me, wait...!\n", getpid()); 467 fprintf(stderr,"dns[%d]: Oops, father has gone, wait for me, wait...!\n", getpid());
462 _exit(0); 468 _exit(0);
463 } 469 }
464 if (dns_params->hostname[0] == '\0') { 470 if (dns_params->hostname[0] == '\0') {
465 fprintf(stderr, "dns[%d]: hostname = \"\" (port = %d)!!!\n", getpid(), dns_params->port); 471 fprintf(stderr, "dns[%d]: hostname = \"\" (port = %d)!!!\n", getpid(), dns_params->port);
466 _exit(1); 472 _exit(1);
467 } 473 }
468 write(child_out, &Y, 1); 474 write(child_out, &ch, sizeof(ch));
469 } 475 }
470 476
471 #if HAVE_GETADDRINFO 477 #if HAVE_GETADDRINFO
472 g_snprintf(servname, sizeof(servname), "%d", dns_params->port); 478 g_snprintf(servname, sizeof(servname), "%d", dns_params->port);
473 memset(&hints,0,sizeof(hints)); 479 memset(&hints, 0, sizeof(hints));
474 480
475 /* This is only used to convert a service 481 /* This is only used to convert a service
476 * name to a port number. As we know we are 482 * name to a port number. As we know we are
477 * passing a number already, we know this 483 * passing a number already, we know this
478 * value will not be really used by the C 484 * value will not be really used by the C
479 * library. 485 * library.
480 */ 486 */
481 hints.ai_socktype = SOCK_STREAM; 487 hints.ai_socktype = SOCK_STREAM;
482 rc = getaddrinfo(dns_params->hostname, servname, &hints, &res); 488 rc = getaddrinfo(dns_params->hostname, servname, &hints, &res);
483 if (rc) { 489 if (rc != 0) {
484 write(child_out, &rc, sizeof(int)); 490 write(child_out, &rc, sizeof(rc));
485 close(child_out); 491 close(child_out);
486 if (show_debug) 492 if (show_debug)
487 fprintf(stderr,"dns[%d] Error: getaddrinfo returned %d\n", 493 fprintf(stderr,"dns[%d] Error: getaddrinfo returned %d\n",
488 getpid(), rc); 494 getpid(), rc);
489 dns_params->hostname[0] = '\0'; 495 dns_params->hostname[0] = '\0';
490 continue; 496 continue;
491 } 497 }
492 write(child_out, &zero, sizeof(zero)); 498 write(child_out, &zero, sizeof(zero));
493 tmp = res; 499 tmp = res;
494 while(res) { 500 while (res) {
495 size_t ai_addrlen = res->ai_addrlen; 501 size_t ai_addrlen = res->ai_addrlen;
496 write(child_out, &ai_addrlen, sizeof(ai_addrlen)); 502 write(child_out, &ai_addrlen, sizeof(ai_addrlen));
497 write(child_out, res->ai_addr, res->ai_addrlen); 503 write(child_out, res->ai_addr, res->ai_addrlen);
498 res = res->ai_next; 504 res = res->ai_next;
499 } 505 }