Mercurial > pidgin.yaz
comparison src/network.c @ 12730:d5b8f4dc1622
[gaim-migrate @ 15074]
Update gaim_network_listen*() to have the socket type specified. This allows us to use the same functionality to listen on UDP sockets too. There are probably a couple things that should be updated to use this. I also updated SIMPLE to allow the connect port to be specified in the account options.
committer: Tailor Script <tailor@pidgin.im>
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Thu, 05 Jan 2006 05:04:07 +0000 |
parents | fb3b7466e3d2 |
children | 8e3b85fe4a55 |
comparison
equal
deleted
inserted
replaced
12729:d3232d64fafd | 12730:d5b8f4dc1622 |
---|---|
177 return gaim_network_get_local_system_ip(fd); | 177 return gaim_network_get_local_system_ip(fd); |
178 } | 178 } |
179 | 179 |
180 | 180 |
181 static int | 181 static int |
182 gaim_network_do_listen(unsigned short port) | 182 gaim_network_do_listen(unsigned short port, int socket_type) |
183 { | 183 { |
184 int listenfd = -1; | 184 int listenfd = -1; |
185 const int on = 1; | 185 const int on = 1; |
186 GaimUPnPControlInfo* controlInfo = NULL; | 186 GaimUPnPControlInfo* controlInfo = NULL; |
187 #if HAVE_GETADDRINFO | 187 #if HAVE_GETADDRINFO |
194 */ | 194 */ |
195 snprintf(serv, sizeof(serv), "%hu", port); | 195 snprintf(serv, sizeof(serv), "%hu", port); |
196 memset(&hints, 0, sizeof(struct addrinfo)); | 196 memset(&hints, 0, sizeof(struct addrinfo)); |
197 hints.ai_flags = AI_PASSIVE; | 197 hints.ai_flags = AI_PASSIVE; |
198 hints.ai_family = AF_UNSPEC; | 198 hints.ai_family = AF_UNSPEC; |
199 hints.ai_socktype = SOCK_STREAM; | 199 hints.ai_socktype = socket_type; |
200 errnum = getaddrinfo(NULL /* any IP */, serv, &hints, &res); | 200 errnum = getaddrinfo(NULL /* any IP */, serv, &hints, &res); |
201 if (errnum != 0) { | 201 if (errnum != 0) { |
202 #ifndef _WIN32 | 202 #ifndef _WIN32 |
203 gaim_debug_warning("network", "getaddrinfo: %s\n", gai_strerror(errnum)); | 203 gaim_debug_warning("network", "getaddrinfo: %s\n", gai_strerror(errnum)); |
204 if (errnum == EAI_SYSTEM) | 204 if (errnum == EAI_SYSTEM) |
220 continue; | 220 continue; |
221 if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) | 221 if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) |
222 gaim_debug_warning("network", "setsockopt: %s\n", strerror(errno)); | 222 gaim_debug_warning("network", "setsockopt: %s\n", strerror(errno)); |
223 if (bind(listenfd, next->ai_addr, next->ai_addrlen) == 0) | 223 if (bind(listenfd, next->ai_addr, next->ai_addrlen) == 0) |
224 break; /* success */ | 224 break; /* success */ |
225 /* XXX - It is unclear to me (datallah) whether we need to be | |
226 using a new socket each time */ | |
225 close(listenfd); | 227 close(listenfd); |
226 } | 228 } |
227 | 229 |
228 freeaddrinfo(res); | 230 freeaddrinfo(res); |
229 | 231 |
230 if (next == NULL) | 232 if (next == NULL) |
231 return -1; | 233 return -1; |
232 #else | 234 #else |
233 struct sockaddr_in sockin; | 235 struct sockaddr_in sockin; |
234 | 236 |
235 if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { | 237 if ((listenfd = socket(AF_INET, socket_type, 0)) < 0) { |
236 gaim_debug_warning("network", "socket: %s\n", strerror(errno)); | 238 gaim_debug_warning("network", "socket: %s\n", strerror(errno)); |
237 return -1; | 239 return -1; |
238 } | 240 } |
239 | 241 |
240 if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) | 242 if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) |
249 close(listenfd); | 251 close(listenfd); |
250 return -1; | 252 return -1; |
251 } | 253 } |
252 #endif | 254 #endif |
253 | 255 |
254 if (listen(listenfd, 4) != 0) { | 256 if (socket_type == SOCK_STREAM && listen(listenfd, 4) != 0) { |
255 gaim_debug_warning("network", "listen: %s\n", strerror(errno)); | 257 gaim_debug_warning("network", "listen: %s\n", strerror(errno)); |
256 close(listenfd); | 258 close(listenfd); |
257 return -1; | 259 return -1; |
258 } | 260 } |
259 fcntl(listenfd, F_SETFL, O_NONBLOCK); | 261 fcntl(listenfd, F_SETFL, O_NONBLOCK); |
260 | 262 |
261 if ((controlInfo = gaim_upnp_discover()) != NULL) { | 263 if ((controlInfo = gaim_upnp_discover()) != NULL) { |
264 char *type_desc = (socket_type == SOCK_STREAM) ? "TCP" : "UDP"; | |
262 if (!gaim_upnp_set_port_mapping(controlInfo, | 265 if (!gaim_upnp_set_port_mapping(controlInfo, |
263 gaim_network_get_port_from_fd(listenfd), | 266 gaim_network_get_port_from_fd(listenfd), |
264 "TCP")) { | 267 type_desc)) { |
265 gaim_upnp_remove_port_mapping(controlInfo, | 268 gaim_upnp_remove_port_mapping(controlInfo, |
266 gaim_network_get_port_from_fd(listenfd), "TCP"); | 269 gaim_network_get_port_from_fd(listenfd), |
270 type_desc); | |
267 gaim_upnp_set_port_mapping(controlInfo, | 271 gaim_upnp_set_port_mapping(controlInfo, |
268 gaim_network_get_port_from_fd(listenfd), "TCP"); | 272 gaim_network_get_port_from_fd(listenfd), |
273 type_desc); | |
269 | 274 |
270 } | 275 } |
271 g_free(controlInfo->serviceType); | 276 g_free(controlInfo->serviceType); |
272 g_free(controlInfo->controlURL); | 277 g_free(controlInfo->controlURL); |
273 g_free(controlInfo); | 278 g_free(controlInfo); |
276 gaim_debug_info("network", "Listening on port: %hu\n", gaim_network_get_port_from_fd(listenfd)); | 281 gaim_debug_info("network", "Listening on port: %hu\n", gaim_network_get_port_from_fd(listenfd)); |
277 return listenfd; | 282 return listenfd; |
278 } | 283 } |
279 | 284 |
280 int | 285 int |
281 gaim_network_listen(unsigned short port) | 286 gaim_network_listen(unsigned short port, int socket_type) |
282 { | 287 { |
283 g_return_val_if_fail(port != 0, -1); | 288 g_return_val_if_fail(port != 0, -1); |
284 | 289 |
285 return gaim_network_do_listen(port); | 290 return gaim_network_do_listen(port, socket_type); |
286 } | 291 } |
287 | 292 |
288 int | 293 int |
289 gaim_network_listen_range(unsigned short start, unsigned short end) | 294 gaim_network_listen_range(unsigned short start, unsigned short end, |
295 int socket_type) | |
290 { | 296 { |
291 int ret = -1; | 297 int ret = -1; |
292 | 298 |
293 if (gaim_prefs_get_bool("/core/network/ports_range_use")) { | 299 if (gaim_prefs_get_bool("/core/network/ports_range_use")) { |
294 start = gaim_prefs_get_int("/core/network/ports_range_start"); | 300 start = gaim_prefs_get_int("/core/network/ports_range_start"); |
297 if (end < start) | 303 if (end < start) |
298 end = start; | 304 end = start; |
299 } | 305 } |
300 | 306 |
301 for (; start <= end; start++) { | 307 for (; start <= end; start++) { |
302 ret = gaim_network_do_listen(start); | 308 ret = gaim_network_do_listen(start, socket_type); |
303 if (ret >= 0) | 309 if (ret >= 0) |
304 break; | 310 break; |
305 } | 311 } |
306 | 312 |
307 return ret; | 313 return ret; |