changeset 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 d3232d64fafd
children f74a878b3c9d
files plugins/ChangeLog.API plugins/perl/common/Network.xs src/network.c src/network.h src/protocols/bonjour/jabber.c src/protocols/irc/dcc_send.c src/protocols/jabber/si.c src/protocols/oscar/oscar.c src/protocols/simple/simple.c
diffstat 9 files changed, 50 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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)
--- 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;
 	}
--- 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.
--- 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)
 	{
--- 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"),
--- 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;
 	}
--- 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;
 	}
--- 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);