Mercurial > pidgin
annotate src/network.c @ 13119:fcde3faa1f57
[gaim-migrate @ 15481]
This adds support for displaying log timestamps in their original timezone. If your OS's definition of struct tm sucks, then the log timestamps will show up in your local timezone, but converted, so the time is accurate. Yay! Anyway, this all works, as I've renamed lots of my log files locally, but currently, there's no code to save new logs in this name format. That's held up on a portability issue and backwards compatibility issue.
committer: Tailor Script <tailor@pidgin.im>
| author | Richard Laager <rlaager@wiktel.com> |
|---|---|
| date | Sat, 04 Feb 2006 20:55:52 +0000 |
| parents | a85c8c11bfab |
| children | d0ae6489a0fb |
| rev | line source |
|---|---|
| 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
91c6629b1ee8
[gaim-migrate @ 8968]
Herman Bloggs <hermanator12002@yahoo.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 | 32 #include "stun.h" |
| 11195 | 33 #include "upnp.h" |
| 8231 | 34 |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
35 typedef struct { |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
36 int listenfd; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
37 int socket_type; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
38 gboolean retry; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
39 gboolean adding; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
40 GaimNetworkListenCallback cb; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
41 gpointer cb_data; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
42 } ListenUPnPData; |
| 11391 | 43 |
| 8838 | 44 const unsigned char * |
| 45 gaim_network_ip_atoi(const char *ip) | |
| 46 { | |
| 47 static unsigned char ret[4]; | |
| 8981 | 48 gchar *delimiter = "."; |
| 8838 | 49 gchar **split; |
| 50 int i; | |
| 51 | |
| 52 g_return_val_if_fail(ip != NULL, NULL); | |
| 53 | |
| 8981 | 54 split = g_strsplit(ip, delimiter, 4); |
| 8838 | 55 for (i = 0; split[i] != NULL; i++) |
| 56 ret[i] = atoi(split[i]); | |
| 57 g_strfreev(split); | |
| 58 | |
| 59 /* i should always be 4 */ | |
| 60 if (i != 4) | |
| 61 return NULL; | |
| 62 | |
| 63 return ret; | |
| 64 } | |
| 65 | |
| 8231 | 66 void |
| 8834 | 67 gaim_network_set_public_ip(const char *ip) |
| 8231 | 68 { |
| 69 g_return_if_fail(ip != NULL); | |
| 70 | |
| 8838 | 71 /* XXX - Ensure the IP address is valid */ |
| 72 | |
| 8231 | 73 gaim_prefs_set_string("/core/network/public_ip", ip); |
| 74 } | |
| 75 | |
| 76 const char * | |
| 8834 | 77 gaim_network_get_public_ip(void) |
| 8231 | 78 { |
| 79 const char *ip; | |
|
12686
5f65a0cca87c
[gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents:
11424
diff
changeset
|
80 GaimStunNatDiscovery *stun; |
| 11391 | 81 |
| 8231 | 82 ip = gaim_prefs_get_string("/core/network/public_ip"); |
| 83 | |
| 11411 | 84 if (ip == NULL || *ip == '\0') { |
| 85 /* Check if STUN discovery was already done */ | |
| 86 stun = gaim_stun_discover(NULL); | |
|
12686
5f65a0cca87c
[gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents:
11424
diff
changeset
|
87 if (stun != NULL && stun->status == GAIM_STUN_STATUS_DISCOVERED) |
| 11411 | 88 return stun->publicip; |
| 8231 | 89 return NULL; |
| 11411 | 90 } |
| 8231 | 91 |
| 92 return ip; | |
| 93 } | |
| 94 | |
| 95 static const char * | |
| 96 gaim_network_get_local_ip_from_fd(int fd) | |
| 97 { | |
| 98 struct sockaddr_in addr; | |
| 99 socklen_t len; | |
| 100 static char ip[16]; | |
| 101 const char *tmp; | |
| 102 | |
| 8840 | 103 g_return_val_if_fail(fd >= 0, NULL); |
| 8231 | 104 |
| 105 len = sizeof(addr); | |
| 106 if (getsockname(fd, (struct sockaddr *) &addr, &len) == -1) { | |
| 107 gaim_debug_warning("network", "getsockname: %s\n", strerror(errno)); | |
| 108 return NULL; | |
| 109 } | |
| 110 | |
| 111 tmp = inet_ntoa(addr.sin_addr); | |
| 112 strncpy(ip, tmp, sizeof(ip)); | |
| 8838 | 113 |
| 8231 | 114 return ip; |
| 115 } | |
| 116 | |
| 117 const char * | |
| 118 gaim_network_get_local_system_ip(int fd) | |
| 119 { | |
| 120 struct hostent *host; | |
| 121 char localhost[129]; | |
| 122 long unsigned add; | |
| 123 static char ip[46]; | |
| 124 const char *tmp = NULL; | |
| 125 | |
| 8840 | 126 if (fd >= 0) |
| 8231 | 127 tmp = gaim_network_get_local_ip_from_fd(fd); |
| 128 | |
| 129 if (tmp) | |
| 130 return tmp; | |
| 131 | |
| 132 if (gethostname(localhost, 128) < 0) | |
| 133 return NULL; | |
| 134 | |
| 135 if ((host = gethostbyname(localhost)) == NULL) | |
| 136 return NULL; | |
| 137 | |
| 138 memcpy(&add, host->h_addr_list[0], 4); | |
| 139 add = htonl(add); | |
| 140 | |
| 141 g_snprintf(ip, 16, "%lu.%lu.%lu.%lu", | |
| 142 ((add >> 24) & 255), | |
| 143 ((add >> 16) & 255), | |
| 144 ((add >> 8) & 255), | |
| 145 add & 255); | |
| 146 | |
| 147 return ip; | |
| 148 } | |
| 149 | |
| 150 const char * | |
| 8838 | 151 gaim_network_get_my_ip(int fd) |
| 8231 | 152 { |
|
12686
5f65a0cca87c
[gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents:
11424
diff
changeset
|
153 const char *ip = NULL; |
|
5f65a0cca87c
[gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents:
11424
diff
changeset
|
154 GaimStunNatDiscovery *stun; |
| 8834 | 155 |
| 156 /* Check if the user specified an IP manually */ | |
| 157 if (!gaim_prefs_get_bool("/core/network/auto_ip")) { | |
| 158 ip = gaim_network_get_public_ip(); | |
| 159 if (ip != NULL) | |
| 160 return ip; | |
| 161 } | |
| 162 | |
| 11424 | 163 if (ip == NULL || *ip == '\0') { |
| 164 /* Check if STUN discovery was already done */ | |
| 165 stun = gaim_stun_discover(NULL); | |
|
12686
5f65a0cca87c
[gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents:
11424
diff
changeset
|
166 if (stun != NULL && stun->status == GAIM_STUN_STATUS_DISCOVERED) |
| 11424 | 167 return stun->publicip; |
| 168 | |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
169 /* attempt to get the ip from a NAT device */ |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
170 ip = gaim_upnp_get_public_ip(); |
|
12686
5f65a0cca87c
[gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents:
11424
diff
changeset
|
171 |
|
5f65a0cca87c
[gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents:
11424
diff
changeset
|
172 if (ip != NULL) |
|
5f65a0cca87c
[gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents:
11424
diff
changeset
|
173 return ip; |
|
5f65a0cca87c
[gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents:
11424
diff
changeset
|
174 } |
| 11195 | 175 |
| 8834 | 176 /* Just fetch the IP of the local system */ |
| 177 return gaim_network_get_local_system_ip(fd); | |
| 8231 | 178 } |
| 179 | |
| 11391 | 180 |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
181 static void |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
182 gaim_network_set_upnp_port_mapping_cb(gboolean success, gpointer data) |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
183 { |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
184 ListenUPnPData *ldata = data; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
185 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
186 if (!success) { |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
187 gaim_debug_warning("network", "Couldn't create UPnP mapping for...\n"); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
188 if (ldata->retry) { |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
189 ldata->retry = FALSE; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
190 ldata->adding = FALSE; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
191 gaim_upnp_remove_port_mapping( |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
192 gaim_network_get_port_from_fd(ldata->listenfd), |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
193 (ldata->socket_type == SOCK_STREAM) ? "TCP" : "UDP", |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
194 gaim_network_set_upnp_port_mapping_cb, ldata); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
195 return; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
196 } |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
197 } else if (!ldata->adding) { |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
198 /* We've tried successfully to remove the port mapping. |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
199 * Try to add it again */ |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
200 ldata->adding = TRUE; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
201 gaim_upnp_set_port_mapping( |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
202 gaim_network_get_port_from_fd(ldata->listenfd), |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
203 (ldata->socket_type == SOCK_STREAM) ? "TCP" : "UDP", |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
204 gaim_network_set_upnp_port_mapping_cb, ldata); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
205 return; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
206 } |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
207 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
208 if (ldata->cb) |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
209 ldata->cb(ldata->listenfd, ldata->cb_data); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
210 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
211 g_free(ldata); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
212 } |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
213 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
214 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
215 static gboolean |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
216 gaim_network_do_listen(unsigned short port, int socket_type, GaimNetworkListenCallback cb, gpointer cb_data) |
| 8231 | 217 { |
| 9452 | 218 int listenfd = -1; |
| 8231 | 219 const int on = 1; |
|
12917
a85c8c11bfab
[gaim-migrate @ 15270]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12909
diff
changeset
|
220 ListenUPnPData *ld; |
| 9449 | 221 #if HAVE_GETADDRINFO |
| 222 int errnum; | |
| 223 struct addrinfo hints, *res, *next; | |
| 9456 | 224 char serv[6]; |
| 8231 | 225 |
| 9449 | 226 /* |
| 227 * Get a list of addresses on this machine. | |
| 228 */ | |
| 229 snprintf(serv, sizeof(serv), "%hu", port); | |
| 8231 | 230 memset(&hints, 0, sizeof(struct addrinfo)); |
| 231 hints.ai_flags = AI_PASSIVE; | |
| 232 hints.ai_family = AF_UNSPEC; | |
|
12730
d5b8f4dc1622
[gaim-migrate @ 15074]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12728
diff
changeset
|
233 hints.ai_socktype = socket_type; |
| 9449 | 234 errnum = getaddrinfo(NULL /* any IP */, serv, &hints, &res); |
| 235 if (errnum != 0) { | |
|
11221
5ed33bb06a84
[gaim-migrate @ 13353]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11215
diff
changeset
|
236 #ifndef _WIN32 |
| 9449 | 237 gaim_debug_warning("network", "getaddrinfo: %s\n", gai_strerror(errnum)); |
| 238 if (errnum == EAI_SYSTEM) | |
| 239 gaim_debug_warning("network", "getaddrinfo: system error: %s\n", strerror(errno)); | |
|
11221
5ed33bb06a84
[gaim-migrate @ 13353]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11215
diff
changeset
|
240 #else |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
241 gaim_debug_warning("network", "getaddrinfo: Error Code = %d\n", errnum); |
|
11221
5ed33bb06a84
[gaim-migrate @ 13353]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11215
diff
changeset
|
242 #endif |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
243 return FALSE; |
| 8231 | 244 } |
| 9449 | 245 |
| 246 /* | |
| 247 * Go through the list of addresses and attempt to listen on | |
| 248 * one of them. | |
| 249 * XXX - Try IPv6 addresses first? | |
| 250 */ | |
| 251 for (next = res; next != NULL; next = next->ai_next) { | |
| 9455 | 252 listenfd = socket(next->ai_family, next->ai_socktype, next->ai_protocol); |
| 8231 | 253 if (listenfd < 0) |
| 254 continue; | |
| 9449 | 255 if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) |
| 256 gaim_debug_warning("network", "setsockopt: %s\n", strerror(errno)); | |
| 9455 | 257 if (bind(listenfd, next->ai_addr, next->ai_addrlen) == 0) |
| 8231 | 258 break; /* success */ |
|
12730
d5b8f4dc1622
[gaim-migrate @ 15074]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12728
diff
changeset
|
259 /* XXX - It is unclear to me (datallah) whether we need to be |
|
d5b8f4dc1622
[gaim-migrate @ 15074]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12728
diff
changeset
|
260 using a new socket each time */ |
| 8231 | 261 close(listenfd); |
| 9449 | 262 } |
| 8231 | 263 |
| 9449 | 264 freeaddrinfo(res); |
| 8231 | 265 |
| 9449 | 266 if (next == NULL) |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
267 return FALSE; |
| 8231 | 268 #else |
| 269 struct sockaddr_in sockin; | |
| 270 | |
|
12730
d5b8f4dc1622
[gaim-migrate @ 15074]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12728
diff
changeset
|
271 if ((listenfd = socket(AF_INET, socket_type, 0)) < 0) { |
| 8231 | 272 gaim_debug_warning("network", "socket: %s\n", strerror(errno)); |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
273 return FALSE; |
| 8231 | 274 } |
| 275 | |
| 9449 | 276 if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) |
| 8231 | 277 gaim_debug_warning("network", "setsockopt: %s\n", strerror(errno)); |
| 278 | |
| 279 memset(&sockin, 0, sizeof(struct sockaddr_in)); | |
| 9449 | 280 sockin.sin_family = PF_INET; |
| 8251 | 281 sockin.sin_port = htons(port); |
| 8231 | 282 |
| 283 if (bind(listenfd, (struct sockaddr *)&sockin, sizeof(struct sockaddr_in)) != 0) { | |
| 284 gaim_debug_warning("network", "bind: %s\n", strerror(errno)); | |
| 285 close(listenfd); | |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
286 return FALSE; |
| 8231 | 287 } |
| 288 #endif | |
| 289 | |
|
12730
d5b8f4dc1622
[gaim-migrate @ 15074]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12728
diff
changeset
|
290 if (socket_type == SOCK_STREAM && listen(listenfd, 4) != 0) { |
| 8231 | 291 gaim_debug_warning("network", "listen: %s\n", strerror(errno)); |
| 292 close(listenfd); | |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
293 return FALSE; |
| 8231 | 294 } |
| 295 fcntl(listenfd, F_SETFL, O_NONBLOCK); | |
| 296 | |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
297 gaim_debug_info("network", "Listening on port: %hu\n", gaim_network_get_port_from_fd(listenfd)); |
| 11391 | 298 |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
299 ld = g_new0(ListenUPnPData, 1); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
300 ld->listenfd = listenfd; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
301 ld->adding = TRUE; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
302 ld->retry = TRUE; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
303 ld->cb = cb; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
304 ld->cb_data = cb_data; |
| 11195 | 305 |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
306 gaim_upnp_set_port_mapping( |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
307 gaim_network_get_port_from_fd(listenfd), |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
308 (socket_type == SOCK_STREAM) ? "TCP" : "UDP", |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
309 gaim_network_set_upnp_port_mapping_cb, ld); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
310 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
311 return TRUE; |
| 8231 | 312 } |
| 313 | |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
314 gboolean |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
315 gaim_network_listen(unsigned short port, int socket_type, |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
316 GaimNetworkListenCallback cb, gpointer cb_data) |
| 8246 | 317 { |
| 8250 | 318 g_return_val_if_fail(port != 0, -1); |
| 319 | |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
320 return gaim_network_do_listen(port, socket_type, cb, cb_data); |
| 8246 | 321 } |
| 322 | |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
323 gboolean |
|
12730
d5b8f4dc1622
[gaim-migrate @ 15074]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12728
diff
changeset
|
324 gaim_network_listen_range(unsigned short start, unsigned short end, |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
325 int socket_type, GaimNetworkListenCallback cb, gpointer cb_data) |
| 8231 | 326 { |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
327 gboolean ret = FALSE; |
| 8231 | 328 |
| 8250 | 329 if (gaim_prefs_get_bool("/core/network/ports_range_use")) { |
| 8239 | 330 start = gaim_prefs_get_int("/core/network/ports_range_start"); |
| 331 end = gaim_prefs_get_int("/core/network/ports_range_end"); | |
| 8250 | 332 } else { |
| 333 if (end < start) | |
| 334 end = start; | |
| 8239 | 335 } |
| 8231 | 336 |
| 337 for (; start <= end; start++) { | |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
338 ret = gaim_network_do_listen(start, socket_type, cb, cb_data); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
339 if (ret) |
| 8231 | 340 break; |
| 341 } | |
| 342 | |
| 343 return ret; | |
| 344 } | |
| 345 | |
| 8834 | 346 unsigned short |
| 347 gaim_network_get_port_from_fd(int fd) | |
| 8231 | 348 { |
| 349 struct sockaddr_in addr; | |
| 350 socklen_t len; | |
| 351 | |
| 9449 | 352 g_return_val_if_fail(fd >= 0, 0); |
| 8231 | 353 |
| 354 len = sizeof(addr); | |
| 355 if (getsockname(fd, (struct sockaddr *) &addr, &len) == -1) { | |
| 356 gaim_debug_warning("network", "getsockname: %s\n", strerror(errno)); | |
| 357 return 0; | |
| 358 } | |
| 359 | |
| 360 return ntohs(addr.sin_port); | |
| 361 } | |
| 362 | |
| 363 void | |
| 364 gaim_network_init(void) | |
| 365 { | |
| 366 gaim_prefs_add_none ("/core/network"); | |
| 367 gaim_prefs_add_bool ("/core/network/auto_ip", TRUE); | |
| 368 gaim_prefs_add_string("/core/network/public_ip", ""); | |
| 369 gaim_prefs_add_bool ("/core/network/ports_range_use", FALSE); | |
| 370 gaim_prefs_add_int ("/core/network/ports_range_start", 1024); | |
| 371 gaim_prefs_add_int ("/core/network/ports_range_end", 2048); | |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
372 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
373 gaim_upnp_discover(NULL, NULL); |
| 8231 | 374 } |
