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;