# HG changeset patch # User Daniel Atallah # Date 1136437447 0 # Node ID d5b8f4dc1622d90607cb43ae2ae94467e6960d24 # Parent d3232d64fafdc90842e418ed7f85f0b0aa09e4e8 [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 diff -r d3232d64fafd -r d5b8f4dc1622 plugins/ChangeLog.API --- a/plugins/ChangeLog.API Thu Jan 05 04:32:25 2006 +0000 +++ b/plugins/ChangeLog.API Thu Jan 05 05:04:07 2006 +0000 @@ -85,6 +85,8 @@ * GaimPluginProtocolInfo: Added whiteboard_prpl_ops * GaimPluginProtocolInfo: Added media_prpl_ops * gaim_pounce_new(): Added option argument for pounce options + * gaim_network_listen() and gaim_network_listen_range(): Added + socket_type parameter to allow creation of UDP listening. Removed: * gaim_gtk_sound_{get,set}_mute() (replaced by the /gaim/gtk/sound/mute diff -r d3232d64fafd -r d5b8f4dc1622 plugins/perl/common/Network.xs --- a/plugins/perl/common/Network.xs Thu Jan 05 04:32:25 2006 +0000 +++ b/plugins/perl/common/Network.xs Thu Jan 05 05:04:07 2006 +0000 @@ -28,13 +28,15 @@ const char *ip int -gaim_network_listen(port) +gaim_network_listen(port, socket_type) unsigned short port + int socket_type int -gaim_network_listen_range(start, end) +gaim_network_listen_range(start, end, socket_type) unsigned short start unsigned short end + int socket_type void gaim_network_set_public_ip(ip) diff -r d3232d64fafd -r d5b8f4dc1622 src/network.c --- a/src/network.c Thu Jan 05 04:32:25 2006 +0000 +++ b/src/network.c Thu Jan 05 05:04:07 2006 +0000 @@ -179,7 +179,7 @@ static int -gaim_network_do_listen(unsigned short port) +gaim_network_do_listen(unsigned short port, int socket_type) { int listenfd = -1; const int on = 1; @@ -196,7 +196,7 @@ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; + hints.ai_socktype = socket_type; errnum = getaddrinfo(NULL /* any IP */, serv, &hints, &res); if (errnum != 0) { #ifndef _WIN32 @@ -222,6 +222,8 @@ gaim_debug_warning("network", "setsockopt: %s\n", strerror(errno)); if (bind(listenfd, next->ai_addr, next->ai_addrlen) == 0) break; /* success */ + /* XXX - It is unclear to me (datallah) whether we need to be + using a new socket each time */ close(listenfd); } @@ -232,7 +234,7 @@ #else struct sockaddr_in sockin; - if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + if ((listenfd = socket(AF_INET, socket_type, 0)) < 0) { gaim_debug_warning("network", "socket: %s\n", strerror(errno)); return -1; } @@ -251,7 +253,7 @@ } #endif - if (listen(listenfd, 4) != 0) { + if (socket_type == SOCK_STREAM && listen(listenfd, 4) != 0) { gaim_debug_warning("network", "listen: %s\n", strerror(errno)); close(listenfd); return -1; @@ -259,13 +261,16 @@ fcntl(listenfd, F_SETFL, O_NONBLOCK); if ((controlInfo = gaim_upnp_discover()) != NULL) { + char *type_desc = (socket_type == SOCK_STREAM) ? "TCP" : "UDP"; if (!gaim_upnp_set_port_mapping(controlInfo, gaim_network_get_port_from_fd(listenfd), - "TCP")) { + type_desc)) { gaim_upnp_remove_port_mapping(controlInfo, - gaim_network_get_port_from_fd(listenfd), "TCP"); + gaim_network_get_port_from_fd(listenfd), + type_desc); gaim_upnp_set_port_mapping(controlInfo, - gaim_network_get_port_from_fd(listenfd), "TCP"); + gaim_network_get_port_from_fd(listenfd), + type_desc); } g_free(controlInfo->serviceType); @@ -278,15 +283,16 @@ } int -gaim_network_listen(unsigned short port) +gaim_network_listen(unsigned short port, int socket_type) { g_return_val_if_fail(port != 0, -1); - return gaim_network_do_listen(port); + return gaim_network_do_listen(port, socket_type); } int -gaim_network_listen_range(unsigned short start, unsigned short end) +gaim_network_listen_range(unsigned short start, unsigned short end, + int socket_type) { int ret = -1; @@ -299,7 +305,7 @@ } for (; start <= end; start++) { - ret = gaim_network_do_listen(start); + ret = gaim_network_do_listen(start, socket_type); if (ret >= 0) break; } diff -r d3232d64fafd -r d5b8f4dc1622 src/network.h --- a/src/network.h Thu Jan 05 04:32:25 2006 +0000 +++ b/src/network.h Thu Jan 05 05:04:07 2006 +0000 @@ -115,11 +115,13 @@ * returned. * * @param port The port number to bind to. Must be greater than 0. + * @param socket_type The type of socket to open for listening. + * This will be either SOCK_STREAM for TCP or SOCK_DGRAM for UDP. * * @return The file descriptor of the listening socket, or -1 if * no socket could be established. */ -int gaim_network_listen(unsigned short port); +int gaim_network_listen(unsigned short port, int socket_type); /** * Opens a listening port selected from a range of ports. The range of @@ -140,11 +142,14 @@ * @param end The highest possible port in the range of ports to listen on, * or 0 to pick a random port. Users are allowed to override this * arg in prefs. + * @param socket_type The type of socket to open for listening. + * This will be either SOCK_STREAM for TCP or SOCK_DGRAM for UDP. * * @return The file descriptor of the listening socket, or -1 if * no socket could be established. */ -int gaim_network_listen_range(unsigned short start, unsigned short end); +int gaim_network_listen_range(unsigned short start, unsigned short end, + int socket_type); /** * Gets a port number from a file descriptor. diff -r d3232d64fafd -r d5b8f4dc1622 src/protocols/bonjour/jabber.c --- a/src/protocols/bonjour/jabber.c Thu Jan 05 04:32:25 2006 +0000 +++ b/src/protocols/bonjour/jabber.c Thu Jan 05 05:04:07 2006 +0000 @@ -474,7 +474,8 @@ } #if 0 - data->socket = gaim_network_listen(data->port); + /* TODO: Why isn't this being used? */ + data->socket = gaim_network_listen(data->port, SOCK_STREAM); if (data->socket == -1) { diff -r d3232d64fafd -r d5b8f4dc1622 src/protocols/irc/dcc_send.c --- a/src/protocols/irc/dcc_send.c Thu Jan 05 04:32:25 2006 +0000 +++ b/src/protocols/irc/dcc_send.c Thu Jan 05 05:04:07 2006 +0000 @@ -266,7 +266,7 @@ xfer->filename = g_path_get_basename(xfer->local_filename); /* Create a listening socket */ - sock = gaim_network_listen_range(0, 0); + sock = gaim_network_listen_range(0, 0, SOCK_STREAM); if (sock < 0) { gaim_notify_error(gc, NULL, _("File Transfer Failed"), diff -r d3232d64fafd -r d5b8f4dc1622 src/protocols/jabber/si.c --- a/src/protocols/jabber/si.c Thu Jan 05 04:32:25 2006 +0000 +++ b/src/protocols/jabber/si.c Thu Jan 05 05:04:07 2006 +0000 @@ -436,7 +436,7 @@ xmlnode_set_attrib(streamhost, "jid", jid); g_free(jid); - if((fd = gaim_network_listen_range(0, 0)) < 0) { + if((fd = gaim_network_listen_range(0, 0, SOCK_STREAM)) < 0) { /* XXX: couldn't open a port, we're fscked */ return; } diff -r d3232d64fafd -r d5b8f4dc1622 src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Thu Jan 05 04:32:25 2006 +0000 +++ b/src/protocols/oscar/oscar.c Thu Jan 05 05:04:07 2006 +0000 @@ -1540,7 +1540,7 @@ dim->gc = gc; g_snprintf(dim->name, sizeof dim->name, "%s", who); - listenfd = gaim_network_listen_range(5190, 5199); + listenfd = gaim_network_listen_range(5190, 5199, SOCK_STREAM); ip = gaim_network_get_my_ip(od->conn ? od->conn->fd : -1); if (listenfd >= 0) dim->conn = aim_odc_initiate(od->sess, who, listenfd, gaim_network_ip_atoi(ip), gaim_network_get_port_from_fd(listenfd), cookie); @@ -2560,7 +2560,7 @@ gaim_debug_info("oscar", "AAA - in oscar_xfer_init_send\n"); /* Create a listening socket and an associated libfaim conn */ - if ((listenfd = gaim_network_listen_range(5190, 5199)) < 0) { + if ((listenfd = gaim_network_listen_range(5190, 5199, SOCK_STREAM)) < 0) { gaim_xfer_cancel_local(xfer); return; } diff -r d3232d64fafd -r d5b8f4dc1622 src/protocols/simple/simple.c --- a/src/protocols/simple/simple.c Thu Jan 05 04:32:25 2006 +0000 +++ b/src/protocols/simple/simple.c Thu Jan 05 05:04:07 2006 +0000 @@ -1198,15 +1198,16 @@ struct simple_account_data *sip = (struct simple_account_data*) data; gchar *hostname; - int port = 5060; + int port = gaim_account_get_int(sip->account, "port", 0); int error = 0; - struct sockaddr_in addr; struct hostent *h; /* find the host to connect to */ if(results) { hostname = g_strdup(resp->hostname); + /* TODO: Should this work more like Jabber where the SRV value will be ignored + * if there is one manually specified? */ port = resp->port; g_free(resp); } else { @@ -1222,7 +1223,7 @@ /* TCP case */ if(! sip->udp) { /* create socket for incoming connections */ - sip->listenfd = gaim_network_listen_range(5060, 5160); + sip->listenfd = gaim_network_listen_range(5060, 5160, SOCK_STREAM); if(sip->listenfd == -1) { gaim_connection_error(sip->gc, _("Could not create listen socket")); return; @@ -1246,15 +1247,14 @@ return; } - sip->fd = socket(AF_INET, SOCK_DGRAM, 0); + /* create socket for incoming connections */ + sip->fd = gaim_network_listen_range(5060, 5160, SOCK_DGRAM); - addr.sin_family = AF_INET; - addr.sin_port = htons(5060); - addr.sin_addr.s_addr = INADDR_ANY; - while((bind(sip->fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) <0) && ntohs(addr.sin_port)<5160) { - addr.sin_port = htons(ntohs(addr.sin_port)+1); + if(sip->fd == -1) { + gaim_connection_error(sip->gc, _("Could not create listen socket")); + return; } - sip->listenport = ntohs(addr.sin_port); + sip->listenfd = sip->fd; sip->listenpa = gaim_input_add(sip->fd, GAIM_INPUT_READ, simple_udp_process, sip->gc); @@ -1461,6 +1461,10 @@ option = gaim_account_option_bool_new(_("Publish status (note: everyone may watch you)"), "dopublish", TRUE); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + option = gaim_account_option_int_new(_("Connect port"), "port", 5060); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + + option = gaim_account_option_bool_new(_("Use UDP"), "udp", FALSE); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); option = gaim_account_option_bool_new(_("Use proxy"), "useproxy", FALSE);