Mon, 12 Dec 2005 18:59:29 +0000
[gaim-migrate @ 14778]
SF Patch #1372898 from charkins
"This patch updates the unseen conversation api in
gtkconv to ensure consistancy and avoid code
duplication. The ...first_unseen() function is renamed
and expanded to return a list of conversations that
match the specified criteria. A max_count parameter is
used to allow this to short circuit early (using 1
gives old behavior). An additional flag was added to
allow this function to only consider hidden
conversations (used by the buddy list). The blist is
currently inconsistant in which conversations it loops
over for showing the menu tray icon, creating the
tooltip and the unseen menu. This patch fixes that.
The ...find_unseen_list() now handles contact-aware
conversations correctly as well (based on sadrul's
patches in #1362579 which are obsoleted by this patch).
I also included the fix from #1362579 which increments
unseen_count only when state>=UNSEEN_TEXT."
committer: Richard Laager <rlaager@pidgin.im>
| 8231 | 1 | /** |
| 2 | * @file network.c Network Implementation | |
| 3 | * @ingroup core | |
| 4 | * | |
| 5 | * gaim | |
| 6 | * | |
| 7 | * Gaim is the legal property of its developers, whose names are too numerous | |
| 8 | * to list here. Please refer to the COPYRIGHT file distributed with this | |
| 9 | * source distribution. | |
| 10 | * | |
| 11 | * This program is free software; you can redistribute it and/or modify | |
| 12 | * it under the terms of the GNU General Public License as published by | |
| 13 | * the Free Software Foundation; either version 2 of the License, or | |
| 14 | * (at your option) any later version. | |
| 15 | * | |
| 16 | * This program is distributed in the hope that it will be useful, | |
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 19 | * GNU General Public License for more details. | |
| 20 | * | |
| 21 | * You should have received a copy of the GNU General Public License | |
| 22 | * along with this program; if not, write to the Free Software | |
| 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 24 | */ | |
| 25 | ||
|
8245
c1397ca0a619
[gaim-migrate @ 8968]
Herman Bloggs <herman@bluedigits.com>
parents:
8240
diff
changeset
|
26 | #include "internal.h" |
| 8231 | 27 | |
| 28 | #include "debug.h" | |
| 29 | #include "account.h" | |
| 30 | #include "network.h" | |
| 31 | #include "prefs.h" | |
|
11411
b74834586187
[gaim-migrate @ 13648]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11391
diff
changeset
|
32 | #include "stun.h" |
|
11195
d84d542a04ac
[gaim-migrate @ 13319]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11033
diff
changeset
|
33 | #include "upnp.h" |
| 8231 | 34 | |
|
11391
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
35 | |
|
8838
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
36 | const unsigned char * |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
37 | gaim_network_ip_atoi(const char *ip) |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
38 | { |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
39 | static unsigned char ret[4]; |
| 8981 | 40 | gchar *delimiter = "."; |
|
8838
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
41 | gchar **split; |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
42 | int i; |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
43 | |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
44 | g_return_val_if_fail(ip != NULL, NULL); |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
45 | |
| 8981 | 46 | split = g_strsplit(ip, delimiter, 4); |
|
8838
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
47 | for (i = 0; split[i] != NULL; i++) |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
48 | ret[i] = atoi(split[i]); |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
49 | g_strfreev(split); |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
50 | |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
51 | /* i should always be 4 */ |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
52 | if (i != 4) |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
53 | return NULL; |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
54 | |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
55 | return ret; |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
56 | } |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
57 | |
| 8231 | 58 | void |
|
8834
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
59 | gaim_network_set_public_ip(const char *ip) |
| 8231 | 60 | { |
| 61 | g_return_if_fail(ip != NULL); | |
| 62 | ||
|
8838
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
63 | /* XXX - Ensure the IP address is valid */ |
|
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
64 | |
| 8231 | 65 | gaim_prefs_set_string("/core/network/public_ip", ip); |
| 66 | } | |
| 67 | ||
| 68 | const char * | |
|
8834
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
69 | gaim_network_get_public_ip(void) |
| 8231 | 70 | { |
| 71 | const char *ip; | |
|
11411
b74834586187
[gaim-migrate @ 13648]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11391
diff
changeset
|
72 | struct stun_nattype *stun; |
|
11391
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
73 | |
| 8231 | 74 | ip = gaim_prefs_get_string("/core/network/public_ip"); |
| 75 | ||
|
11411
b74834586187
[gaim-migrate @ 13648]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11391
diff
changeset
|
76 | if (ip == NULL || *ip == '\0') { |
|
b74834586187
[gaim-migrate @ 13648]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11391
diff
changeset
|
77 | /* Check if STUN discovery was already done */ |
|
b74834586187
[gaim-migrate @ 13648]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11391
diff
changeset
|
78 | stun = gaim_stun_discover(NULL); |
|
b74834586187
[gaim-migrate @ 13648]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11391
diff
changeset
|
79 | if(stun && stun->status>1) |
|
b74834586187
[gaim-migrate @ 13648]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11391
diff
changeset
|
80 | return stun->publicip; |
| 8231 | 81 | return NULL; |
|
11411
b74834586187
[gaim-migrate @ 13648]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11391
diff
changeset
|
82 | } |
| 8231 | 83 | |
| 84 | return ip; | |
| 85 | } | |
| 86 | ||
| 87 | static const char * | |
| 88 | gaim_network_get_local_ip_from_fd(int fd) | |
| 89 | { | |
| 90 | struct sockaddr_in addr; | |
| 91 | socklen_t len; | |
| 92 | static char ip[16]; | |
| 93 | const char *tmp; | |
| 94 | ||
|
8840
414e20c7c010
[gaim-migrate @ 9607]
Mark Doliner <markdoliner@pidgin.im>
parents:
8838
diff
changeset
|
95 | g_return_val_if_fail(fd >= 0, NULL); |
| 8231 | 96 | |
| 97 | len = sizeof(addr); | |
| 98 | if (getsockname(fd, (struct sockaddr *) &addr, &len) == -1) { | |
| 99 | gaim_debug_warning("network", "getsockname: %s\n", strerror(errno)); | |
| 100 | return NULL; | |
| 101 | } | |
| 102 | ||
| 103 | tmp = inet_ntoa(addr.sin_addr); | |
| 104 | strncpy(ip, tmp, sizeof(ip)); | |
|
8838
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
105 | |
| 8231 | 106 | return ip; |
| 107 | } | |
| 108 | ||
| 109 | const char * | |
| 110 | gaim_network_get_local_system_ip(int fd) | |
| 111 | { | |
| 112 | struct hostent *host; | |
| 113 | char localhost[129]; | |
| 114 | long unsigned add; | |
| 115 | static char ip[46]; | |
| 116 | const char *tmp = NULL; | |
| 117 | ||
|
8840
414e20c7c010
[gaim-migrate @ 9607]
Mark Doliner <markdoliner@pidgin.im>
parents:
8838
diff
changeset
|
118 | if (fd >= 0) |
| 8231 | 119 | tmp = gaim_network_get_local_ip_from_fd(fd); |
| 120 | ||
| 121 | if (tmp) | |
| 122 | return tmp; | |
| 123 | ||
| 124 | if (gethostname(localhost, 128) < 0) | |
| 125 | return NULL; | |
| 126 | ||
| 127 | if ((host = gethostbyname(localhost)) == NULL) | |
| 128 | return NULL; | |
| 129 | ||
| 130 | memcpy(&add, host->h_addr_list[0], 4); | |
| 131 | add = htonl(add); | |
| 132 | ||
| 133 | g_snprintf(ip, 16, "%lu.%lu.%lu.%lu", | |
| 134 | ((add >> 24) & 255), | |
| 135 | ((add >> 16) & 255), | |
| 136 | ((add >> 8) & 255), | |
| 137 | add & 255); | |
| 138 | ||
| 139 | return ip; | |
| 140 | } | |
| 141 | ||
| 142 | const char * | |
|
8838
c23227da7b4a
[gaim-migrate @ 9604]
Mark Doliner <markdoliner@pidgin.im>
parents:
8834
diff
changeset
|
143 | gaim_network_get_my_ip(int fd) |
| 8231 | 144 | { |
|
11215
4ae2f96b0342
[gaim-migrate @ 13347]
Richard Laager <rlaager@pidgin.im>
parents:
11213
diff
changeset
|
145 | const char *ip = NULL; |
|
11391
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
146 | GaimUPnPControlInfo* controlInfo = NULL; |
|
11424
b0f8535daa74
[gaim-migrate @ 13661]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11411
diff
changeset
|
147 | struct stun_nattype *stun; |
|
8834
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
148 | |
|
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
149 | /* Check if the user specified an IP manually */ |
|
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
150 | if (!gaim_prefs_get_bool("/core/network/auto_ip")) { |
|
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
151 | ip = gaim_network_get_public_ip(); |
|
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
152 | if (ip != NULL) |
|
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
153 | return ip; |
|
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
154 | } |
|
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
155 | |
|
11424
b0f8535daa74
[gaim-migrate @ 13661]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11411
diff
changeset
|
156 | if (ip == NULL || *ip == '\0') { |
|
b0f8535daa74
[gaim-migrate @ 13661]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11411
diff
changeset
|
157 | /* Check if STUN discovery was already done */ |
|
b0f8535daa74
[gaim-migrate @ 13661]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11411
diff
changeset
|
158 | stun = gaim_stun_discover(NULL); |
|
b0f8535daa74
[gaim-migrate @ 13661]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11411
diff
changeset
|
159 | if(stun && stun->status>1) |
|
b0f8535daa74
[gaim-migrate @ 13661]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11411
diff
changeset
|
160 | return stun->publicip; |
|
b0f8535daa74
[gaim-migrate @ 13661]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11411
diff
changeset
|
161 | } |
|
b0f8535daa74
[gaim-migrate @ 13661]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11411
diff
changeset
|
162 | |
|
b0f8535daa74
[gaim-migrate @ 13661]
Thomas Butter <tbutter@users.sourceforge.net>
parents:
11411
diff
changeset
|
163 | |
|
11195
d84d542a04ac
[gaim-migrate @ 13319]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11033
diff
changeset
|
164 | /* attempt to get the ip from a NAT device */ |
|
11391
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
165 | if ((controlInfo = gaim_upnp_discover()) != NULL) { |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
166 | ip = gaim_upnp_get_public_ip(controlInfo); |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
167 | g_free(controlInfo->controlURL); |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
168 | g_free(controlInfo->serviceType); |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
169 | g_free(controlInfo); |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
170 | if (ip != NULL) { |
|
11195
d84d542a04ac
[gaim-migrate @ 13319]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11033
diff
changeset
|
171 | return ip; |
|
11391
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
172 | } |
|
11195
d84d542a04ac
[gaim-migrate @ 13319]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11033
diff
changeset
|
173 | } |
|
d84d542a04ac
[gaim-migrate @ 13319]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11033
diff
changeset
|
174 | |
|
8834
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
175 | /* Just fetch the IP of the local system */ |
|
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
176 | return gaim_network_get_local_system_ip(fd); |
| 8231 | 177 | } |
| 178 | ||
|
11391
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
179 | |
|
8834
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
180 | static int |
|
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
181 | gaim_network_do_listen(unsigned short port) |
| 8231 | 182 | { |
|
9452
0e3cdb898d3e
[gaim-migrate @ 10276]
Mark Doliner <markdoliner@pidgin.im>
parents:
9449
diff
changeset
|
183 | int listenfd = -1; |
| 8231 | 184 | const int on = 1; |
|
11391
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
185 | GaimUPnPControlInfo* controlInfo = NULL; |
|
9449
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
186 | #if HAVE_GETADDRINFO |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
187 | int errnum; |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
188 | struct addrinfo hints, *res, *next; |
| 9456 | 189 | char serv[6]; |
| 8231 | 190 | |
|
9449
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
191 | /* |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
192 | * Get a list of addresses on this machine. |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
193 | */ |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
194 | snprintf(serv, sizeof(serv), "%hu", port); |
| 8231 | 195 | memset(&hints, 0, sizeof(struct addrinfo)); |
| 196 | hints.ai_flags = AI_PASSIVE; | |
| 197 | hints.ai_family = AF_UNSPEC; | |
| 198 | hints.ai_socktype = SOCK_STREAM; | |
|
9449
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
199 | errnum = getaddrinfo(NULL /* any IP */, serv, &hints, &res); |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
200 | if (errnum != 0) { |
|
11221
be3982550ac0
[gaim-migrate @ 13353]
Daniel Atallah <datallah@pidgin.im>
parents:
11215
diff
changeset
|
201 | #ifndef _WIN32 |
|
9449
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
202 | gaim_debug_warning("network", "getaddrinfo: %s\n", gai_strerror(errnum)); |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
203 | if (errnum == EAI_SYSTEM) |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
204 | gaim_debug_warning("network", "getaddrinfo: system error: %s\n", strerror(errno)); |
|
11221
be3982550ac0
[gaim-migrate @ 13353]
Daniel Atallah <datallah@pidgin.im>
parents:
11215
diff
changeset
|
205 | #else |
|
be3982550ac0
[gaim-migrate @ 13353]
Daniel Atallah <datallah@pidgin.im>
parents:
11215
diff
changeset
|
206 | gaim_debug_warning("network", "getaddrinfo: Error Code = %d\n", errnum); |
|
be3982550ac0
[gaim-migrate @ 13353]
Daniel Atallah <datallah@pidgin.im>
parents:
11215
diff
changeset
|
207 | #endif |
| 8231 | 208 | return -1; |
| 209 | } | |
|
9449
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
210 | |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
211 | /* |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
212 | * Go through the list of addresses and attempt to listen on |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
213 | * one of them. |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
214 | * XXX - Try IPv6 addresses first? |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
215 | */ |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
216 | for (next = res; next != NULL; next = next->ai_next) { |
| 9455 | 217 | listenfd = socket(next->ai_family, next->ai_socktype, next->ai_protocol); |
| 8231 | 218 | if (listenfd < 0) |
| 219 | continue; | |
|
9449
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
220 | if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
221 | gaim_debug_warning("network", "setsockopt: %s\n", strerror(errno)); |
| 9455 | 222 | if (bind(listenfd, next->ai_addr, next->ai_addrlen) == 0) |
| 8231 | 223 | break; /* success */ |
| 224 | close(listenfd); | |
|
9449
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
225 | } |
| 8231 | 226 | |
|
9449
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
227 | freeaddrinfo(res); |
| 8231 | 228 | |
|
9449
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
229 | if (next == NULL) |
|
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
230 | return -1; |
| 8231 | 231 | #else |
| 232 | struct sockaddr_in sockin; | |
| 233 | ||
| 234 | if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { | |
| 235 | gaim_debug_warning("network", "socket: %s\n", strerror(errno)); | |
| 236 | return -1; | |
| 237 | } | |
| 238 | ||
|
9449
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
239 | if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) |
| 8231 | 240 | gaim_debug_warning("network", "setsockopt: %s\n", strerror(errno)); |
| 241 | ||
| 242 | memset(&sockin, 0, sizeof(struct sockaddr_in)); | |
|
9449
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
243 | sockin.sin_family = PF_INET; |
|
8251
091ca9b900c1
[gaim-migrate @ 8974]
Mark Doliner <markdoliner@pidgin.im>
parents:
8250
diff
changeset
|
244 | sockin.sin_port = htons(port); |
| 8231 | 245 | |
| 246 | if (bind(listenfd, (struct sockaddr *)&sockin, sizeof(struct sockaddr_in)) != 0) { | |
| 247 | gaim_debug_warning("network", "bind: %s\n", strerror(errno)); | |
| 248 | close(listenfd); | |
| 249 | return -1; | |
| 250 | } | |
| 251 | #endif | |
| 252 | ||
| 253 | if (listen(listenfd, 4) != 0) { | |
| 254 | gaim_debug_warning("network", "listen: %s\n", strerror(errno)); | |
| 255 | close(listenfd); | |
| 256 | return -1; | |
| 257 | } | |
| 258 | fcntl(listenfd, F_SETFL, O_NONBLOCK); | |
| 259 | ||
|
11391
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
260 | if((controlInfo = gaim_upnp_discover()) != NULL) { |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
261 | if(!gaim_upnp_set_port_mapping(controlInfo, |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
262 | gaim_network_get_port_from_fd(listenfd), |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
263 | "TCP")) { |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
264 | gaim_upnp_remove_port_mapping(controlInfo, |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
265 | gaim_network_get_port_from_fd(listenfd), "TCP"); |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
266 | gaim_upnp_set_port_mapping(controlInfo, |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
267 | gaim_network_get_port_from_fd(listenfd), "TCP"); |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
268 | |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
269 | } |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
270 | g_free(controlInfo->serviceType); |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
271 | g_free(controlInfo->controlURL); |
|
d172e72988cc
[gaim-migrate @ 13620]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11336
diff
changeset
|
272 | g_free(controlInfo); |
|
11195
d84d542a04ac
[gaim-migrate @ 13319]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11033
diff
changeset
|
273 | } |
|
d84d542a04ac
[gaim-migrate @ 13319]
Adam Warrington <awarring@users.sourceforge.net>
parents:
11033
diff
changeset
|
274 | |
| 8231 | 275 | gaim_debug_info("network", "Listening on port: %hu\n", gaim_network_get_port_from_fd(listenfd)); |
| 276 | return listenfd; | |
| 277 | } | |
| 278 | ||
|
8834
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
279 | int |
|
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
280 | gaim_network_listen(unsigned short port) |
|
8246
c83c0421149a
[gaim-migrate @ 8969]
Mark Doliner <markdoliner@pidgin.im>
parents:
8245
diff
changeset
|
281 | { |
|
8250
e855dcce1fa0
[gaim-migrate @ 8973]
Mark Doliner <markdoliner@pidgin.im>
parents:
8248
diff
changeset
|
282 | g_return_val_if_fail(port != 0, -1); |
|
e855dcce1fa0
[gaim-migrate @ 8973]
Mark Doliner <markdoliner@pidgin.im>
parents:
8248
diff
changeset
|
283 | |
|
8246
c83c0421149a
[gaim-migrate @ 8969]
Mark Doliner <markdoliner@pidgin.im>
parents:
8245
diff
changeset
|
284 | return gaim_network_do_listen(port); |
|
c83c0421149a
[gaim-migrate @ 8969]
Mark Doliner <markdoliner@pidgin.im>
parents:
8245
diff
changeset
|
285 | } |
|
c83c0421149a
[gaim-migrate @ 8969]
Mark Doliner <markdoliner@pidgin.im>
parents:
8245
diff
changeset
|
286 | |
|
8834
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
287 | int |
|
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
288 | gaim_network_listen_range(unsigned short start, unsigned short end) |
| 8231 | 289 | { |
|
8240
2e5f97ed575d
[gaim-migrate @ 8963]
Mark Doliner <markdoliner@pidgin.im>
parents:
8239
diff
changeset
|
290 | int ret = -1; |
| 8231 | 291 | |
|
8250
e855dcce1fa0
[gaim-migrate @ 8973]
Mark Doliner <markdoliner@pidgin.im>
parents:
8248
diff
changeset
|
292 | if (gaim_prefs_get_bool("/core/network/ports_range_use")) { |
|
8239
d19f1c66720c
[gaim-migrate @ 8962]
Mark Doliner <markdoliner@pidgin.im>
parents:
8231
diff
changeset
|
293 | start = gaim_prefs_get_int("/core/network/ports_range_start"); |
|
d19f1c66720c
[gaim-migrate @ 8962]
Mark Doliner <markdoliner@pidgin.im>
parents:
8231
diff
changeset
|
294 | end = gaim_prefs_get_int("/core/network/ports_range_end"); |
|
8250
e855dcce1fa0
[gaim-migrate @ 8973]
Mark Doliner <markdoliner@pidgin.im>
parents:
8248
diff
changeset
|
295 | } else { |
|
e855dcce1fa0
[gaim-migrate @ 8973]
Mark Doliner <markdoliner@pidgin.im>
parents:
8248
diff
changeset
|
296 | if (end < start) |
|
e855dcce1fa0
[gaim-migrate @ 8973]
Mark Doliner <markdoliner@pidgin.im>
parents:
8248
diff
changeset
|
297 | end = start; |
|
8239
d19f1c66720c
[gaim-migrate @ 8962]
Mark Doliner <markdoliner@pidgin.im>
parents:
8231
diff
changeset
|
298 | } |
| 8231 | 299 | |
| 300 | for (; start <= end; start++) { | |
| 301 | ret = gaim_network_do_listen(start); | |
| 302 | if (ret >= 0) | |
| 303 | break; | |
| 304 | } | |
| 305 | ||
| 306 | return ret; | |
| 307 | } | |
| 308 | ||
|
8834
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
309 | unsigned short |
|
0a798e3d2b84
[gaim-migrate @ 9598]
Mark Doliner <markdoliner@pidgin.im>
parents:
8251
diff
changeset
|
310 | gaim_network_get_port_from_fd(int fd) |
| 8231 | 311 | { |
| 312 | struct sockaddr_in addr; | |
| 313 | socklen_t len; | |
| 314 | ||
|
9449
8c5a1697bca6
[gaim-migrate @ 10273]
Mark Doliner <markdoliner@pidgin.im>
parents:
8981
diff
changeset
|
315 | g_return_val_if_fail(fd >= 0, 0); |
| 8231 | 316 | |
| 317 | len = sizeof(addr); | |
| 318 | if (getsockname(fd, (struct sockaddr *) &addr, &len) == -1) { | |
| 319 | gaim_debug_warning("network", "getsockname: %s\n", strerror(errno)); | |
| 320 | return 0; | |
| 321 | } | |
| 322 | ||
| 323 | return ntohs(addr.sin_port); | |
| 324 | } | |
| 325 | ||
| 326 | void | |
| 327 | gaim_network_init(void) | |
| 328 | { | |
| 329 | gaim_prefs_add_none ("/core/network"); | |
| 330 | gaim_prefs_add_bool ("/core/network/auto_ip", TRUE); | |
| 331 | gaim_prefs_add_string("/core/network/public_ip", ""); | |
| 332 | gaim_prefs_add_bool ("/core/network/ports_range_use", FALSE); | |
| 333 | gaim_prefs_add_int ("/core/network/ports_range_start", 1024); | |
| 334 | gaim_prefs_add_int ("/core/network/ports_range_end", 2048); | |
| 335 | } |