libpurple/network.c

branch
vv
changeset 26256
d2673c935184
parent 25326
c4f4b222dbac
child 26261
ffabb135a4b6
equal deleted inserted replaced
26255:3b0da2f49570 26256:d2673c935184
46 #include "nat-pmp.h" 46 #include "nat-pmp.h"
47 #include "network.h" 47 #include "network.h"
48 #include "prefs.h" 48 #include "prefs.h"
49 #include "stun.h" 49 #include "stun.h"
50 #include "upnp.h" 50 #include "upnp.h"
51 #include "dnsquery.h"
51 52
52 /* 53 /*
53 * Calling sizeof(struct ifreq) isn't always correct on 54 * Calling sizeof(struct ifreq) isn't always correct on
54 * Mac OS X (and maybe others). 55 * Mac OS X (and maybe others).
55 */ 56 */
89 }; 90 };
90 91
91 #ifdef HAVE_NETWORKMANAGER 92 #ifdef HAVE_NETWORKMANAGER
92 static NMState nm_get_network_state(void); 93 static NMState nm_get_network_state(void);
93 #endif 94 #endif
95
96 /* Cached IP address for STUN server */
97 static gchar *stun_ip = NULL;
94 98
95 const unsigned char * 99 const unsigned char *
96 purple_network_ip_atoi(const char *ip) 100 purple_network_ip_atoi(const char *ip)
97 { 101 {
98 static unsigned char ret[4]; 102 static unsigned char ret[4];
683 switch(state) 687 switch(state)
684 { 688 {
685 case NM_STATE_CONNECTED: 689 case NM_STATE_CONNECTED:
686 /* Call res_init in case DNS servers have changed */ 690 /* Call res_init in case DNS servers have changed */
687 res_init(); 691 res_init();
692 /* update STUN IP in case we it changed (theoretically we could
693 have gone from IPv4 to IPv6, f.ex. or we were previously
694 offline */
695 purple_network_set_stun_server(
696 purple_prefs_get_string("/purple/network/stun_server"));
697
688 if (ui_ops != NULL && ui_ops->network_connected != NULL) 698 if (ui_ops != NULL && ui_ops->network_connected != NULL)
689 ui_ops->network_connected(); 699 ui_ops->network_connected();
690 break; 700 break;
691 case NM_STATE_ASLEEP: 701 case NM_STATE_ASLEEP:
692 case NM_STATE_CONNECTING: 702 case NM_STATE_CONNECTING:
744 } 754 }
745 } 755 }
746 756
747 #endif 757 #endif
748 758
759 static void
760 purple_network_stun_lookup_cb(GSList *hosts, gpointer data,
761 const char *error_message)
762 {
763 if (error_message) {
764 purple_debug_error("network", "lookup of STUN server IP failed: %s\n",
765 error_message);
766 g_slist_free(hosts);
767 return;
768 }
769
770 if (hosts && g_slist_next(hosts)) {
771 size_t addr_len = (size_t) hosts->data;
772 struct sockaddr *addr = g_slist_next(hosts)->data;
773 char dst[INET6_ADDRSTRLEN];
774
775 if (addr->sa_family == AF_INET6) {
776 inet_ntop(addr->sa_family, &((struct sockaddr_in6 *) addr)->sin6_addr,
777 dst, sizeof(dst));
778 } else {
779 inet_ntop(addr->sa_family, &((struct sockaddr_in *) addr)->sin_addr,
780 dst, sizeof(dst));
781 }
782
783 stun_ip = g_strdup(dst);
784 purple_debug_info("network", "set STUN IP: %s\n", stun_ip);
785 }
786
787 g_slist_free(hosts);
788 }
789
790 void
791 purple_network_set_stun_server(const gchar *stun_server)
792 {
793 if (stun_server && stun_server[0] != '\0') {
794 if (purple_network_is_available()) {
795 purple_debug_info("network", "running DNS query for STUN server\n");
796 purple_dnsquery_a(stun_server, 3478, purple_network_stun_lookup_cb,
797 NULL);
798 } else {
799 purple_debug_info("network",
800 "network is unavailable, don't try to update STUN IP");
801 }
802 } else if (stun_ip) {
803 g_free(stun_ip);
804 stun_ip = NULL;
805 }
806 }
807
808 const gchar *
809 purple_network_get_stun_ip(void)
810 {
811 return stun_ip;
812 }
813
749 void * 814 void *
750 purple_network_get_handle(void) 815 purple_network_get_handle(void)
751 { 816 {
752 static int handle; 817 static int handle;
753 818
775 purple_debug_error("network", "Couldn't create Network Monitor thread: %s\n", err ? err->message : ""); 840 purple_debug_error("network", "Couldn't create Network Monitor thread: %s\n", err ? err->message : "");
776 } 841 }
777 #endif 842 #endif
778 843
779 purple_prefs_add_none ("/purple/network"); 844 purple_prefs_add_none ("/purple/network");
845 purple_prefs_add_string("/purple/network/stun_server", "");
780 purple_prefs_add_bool ("/purple/network/auto_ip", TRUE); 846 purple_prefs_add_bool ("/purple/network/auto_ip", TRUE);
781 purple_prefs_add_string("/purple/network/public_ip", ""); 847 purple_prefs_add_string("/purple/network/public_ip", "");
782 purple_prefs_add_bool ("/purple/network/map_ports", TRUE); 848 purple_prefs_add_bool ("/purple/network/map_ports", TRUE);
783 purple_prefs_add_bool ("/purple/network/ports_range_use", FALSE); 849 purple_prefs_add_bool ("/purple/network/ports_range_use", FALSE);
784 purple_prefs_add_int ("/purple/network/ports_range_start", 1024); 850 purple_prefs_add_int ("/purple/network/ports_range_start", 1024);
813 purple_signal_register(purple_network_get_handle(), "network-configuration-changed", 879 purple_signal_register(purple_network_get_handle(), "network-configuration-changed",
814 purple_marshal_VOID, NULL, 0); 880 purple_marshal_VOID, NULL, 0);
815 881
816 purple_pmp_init(); 882 purple_pmp_init();
817 purple_upnp_init(); 883 purple_upnp_init();
884
885 purple_network_set_stun_server(
886 purple_prefs_get_string("/purple/network/stun_server"));
818 } 887 }
819 888
820 void 889 void
821 purple_network_uninit(void) 890 purple_network_uninit(void)
822 { 891 {
852 g_static_mutex_unlock(&mutex); 921 g_static_mutex_unlock(&mutex);
853 922
854 #endif 923 #endif
855 purple_signal_unregister(purple_network_get_handle(), 924 purple_signal_unregister(purple_network_get_handle(),
856 "network-configuration-changed"); 925 "network-configuration-changed");
857 } 926
927 if (stun_ip)
928 g_free(stun_ip);
929 }

mercurial