Mercurial > pidgin
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 } |
