| 417 g_strfreev(ft_proxy_list); |
417 g_strfreev(ft_proxy_list); |
| 418 } |
418 } |
| 419 |
419 |
| 420 } |
420 } |
| 421 |
421 |
| 422 /* should probably share this code with google.c, or maybe from 2.7.0 |
|
| 423 introduce an abstracted hostname -> IP function in dns.c */ |
|
| 424 static void |
422 static void |
| 425 jabber_disco_stun_lookup_cb(GSList *hosts, gpointer data, |
423 jabber_disco_stun_srv_resolve_cb(GObject *sender, GAsyncResult *result, gpointer data) { |
| 426 const char *error_message) |
424 GError *error = NULL; |
| 427 { |
425 GList *services = NULL; |
| 428 JabberStream *js = (JabberStream *) data; |
426 JabberStream *js = (JabberStream *) data; |
| 429 |
427 gint results = 0; |
| 430 if (error_message) { |
428 |
| 431 purple_debug_error("jabber", "STUN lookup failed: %s\n", |
429 services = g_resolver_lookup_service_finish(g_resolver_get_default(), result, &error); |
| 432 error_message); |
430 |
| 433 g_slist_free(hosts); |
431 if(error != NULL) { |
| 434 js->stun_query = NULL; |
432 purple_debug_info("jabber", "Failed to look up a STUN record : %s\n", error->message); |
| |
433 |
| |
434 g_error_free(error); |
| |
435 |
| 435 return; |
436 return; |
| 436 } |
437 } |
| 437 |
438 |
| 438 if (hosts && g_slist_next(hosts)) { |
439 results = g_list_length(services); |
| 439 common_sockaddr_t addr; |
|
| 440 char dst[INET6_ADDRSTRLEN]; |
|
| 441 int port; |
|
| 442 |
|
| 443 memcpy(&addr, g_slist_next(hosts)->data, sizeof(addr)); |
|
| 444 |
|
| 445 if (addr.sa.sa_family == AF_INET6) { |
|
| 446 inet_ntop(addr.sa.sa_family, &addr.in6.sin6_addr, |
|
| 447 dst, sizeof(dst)); |
|
| 448 port = ntohs(addr.in6.sin6_port); |
|
| 449 } else { |
|
| 450 inet_ntop(addr.sa.sa_family, &addr.in.sin_addr, |
|
| 451 dst, sizeof(dst)); |
|
| 452 port = ntohs(addr.in.sin_port); |
|
| 453 } |
|
| 454 |
|
| 455 if (js->stun_ip) |
|
| 456 g_free(js->stun_ip); |
|
| 457 js->stun_ip = g_strdup(dst); |
|
| 458 js->stun_port = port; |
|
| 459 |
|
| 460 purple_debug_info("jabber", "set STUN IP/port address: " |
|
| 461 "%s:%d\n", dst, port); |
|
| 462 |
|
| 463 /* unmark ongoing query */ |
|
| 464 js->stun_query = NULL; |
|
| 465 } |
|
| 466 |
|
| 467 while (hosts != NULL) { |
|
| 468 hosts = g_slist_delete_link(hosts, hosts); |
|
| 469 /* Free the address */ |
|
| 470 g_free(hosts->data); |
|
| 471 hosts = g_slist_delete_link(hosts, hosts); |
|
| 472 } |
|
| 473 } |
|
| 474 |
|
| 475 |
|
| 476 static void |
|
| 477 jabber_disco_stun_srv_resolve_cb(PurpleSrvResponse *resp, int results, gpointer data) |
|
| 478 { |
|
| 479 JabberStream *js = (JabberStream *) data; |
|
| 480 |
440 |
| 481 purple_debug_info("jabber", "got %d SRV responses for STUN.\n", results); |
441 purple_debug_info("jabber", "got %d SRV responses for STUN.\n", results); |
| 482 js->srv_query_data = NULL; |
|
| 483 |
442 |
| 484 if (results > 0) { |
443 if (results > 0) { |
| 485 PurpleAccount *account; |
444 GSrvTarget *target = (GSrvTarget *)services->data; |
| 486 purple_debug_info("jabber", "looking up IP for %s:%d\n", |
445 const gchar *hostname = g_srv_target_get_hostname(target); |
| 487 resp[0].hostname, resp[0].port); |
446 |
| 488 account = purple_connection_get_account(js->gc); |
447 js->stun_ip = g_strdup(hostname); |
| 489 js->stun_query = |
448 js->stun_port = g_srv_target_get_port(target); |
| 490 purple_dnsquery_a(account, resp[0].hostname, resp[0].port, |
449 |
| 491 jabber_disco_stun_lookup_cb, js); |
450 purple_debug_info("jabber", "set stun address to %s:%d\n", |
| 492 } |
451 hostname, js->stun_port); |
| |
452 } |
| |
453 |
| |
454 g_resolver_free_targets(services); |
| 493 } |
455 } |
| 494 |
456 |
| 495 |
457 |
| 496 static void |
458 static void |
| 497 jabber_disco_server_info_result_cb(JabberStream *js, const char *from, |
459 jabber_disco_server_info_result_cb(JabberStream *js, const char *from, |
| 551 purple_strequal(purple_network_get_stun_ip(), "")) { |
513 purple_strequal(purple_network_get_stun_ip(), "")) { |
| 552 jabber_google_send_jingle_info(js); |
514 jabber_google_send_jingle_info(js); |
| 553 } |
515 } |
| 554 } else if (purple_network_get_stun_ip() == NULL || |
516 } else if (purple_network_get_stun_ip() == NULL || |
| 555 purple_strequal(purple_network_get_stun_ip(), "")) { |
517 purple_strequal(purple_network_get_stun_ip(), "")) { |
| 556 js->srv_query_data = |
518 |
| 557 purple_srv_resolve( |
519 g_resolver_lookup_service_async(g_resolver_get_default(), |
| 558 purple_connection_get_account(js->gc), "stun", "udp", |
520 "stun", |
| 559 js->user->domain, |
521 "udp", |
| 560 jabber_disco_stun_srv_resolve_cb, js); |
522 js->user->domain, |
| |
523 NULL, |
| |
524 jabber_disco_stun_srv_resolve_cb, |
| |
525 js); |
| 561 /* TODO: add TURN support later... */ |
526 /* TODO: add TURN support later... */ |
| 562 } |
527 } |
| 563 } |
528 } |
| 564 |
529 |
| 565 for (child = purple_xmlnode_get_child(query, "feature"); child; |
530 for (child = purple_xmlnode_get_child(query, "feature"); child; |