# HG changeset patch # User Daniel Atallah # Date 1235254227 0 # Node ID f38799160cfa3aee8c1527d93c4ff5966d86a539 # Parent 7d58d7a3c5c3fd8197928cded7ba9140d6939eee Better support running many Bonjour clients on the same machine by allowing a listening port to be specified and falling back to a system-assigned port if it can't be used. Fixes #8462. diff -r 7d58d7a3c5c3 -r f38799160cfa libpurple/protocols/bonjour/bonjour.c --- a/libpurple/protocols/bonjour/bonjour.c Thu Feb 19 22:52:49 2009 +0000 +++ b/libpurple/protocols/bonjour/bonjour.c Sat Feb 21 22:10:27 2009 +0000 @@ -102,7 +102,7 @@ /* Start waiting for jabber connections (iChat style) */ bd->jabber_data = g_new0(BonjourJabber, 1); - bd->jabber_data->port = BONJOUR_DEFAULT_PORT_INT; + bd->jabber_data->port = purple_account_get_int(account, "port", BONJOUR_DEFAULT_PORT); bd->jabber_data->account = account; if (bonjour_jabber_start(bd->jabber_data) == -1) { @@ -706,6 +706,9 @@ prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); /* Creating the options for the protocol */ + option = purple_account_option_int_new(_("Local Port"), "port", BONJOUR_DEFAULT_PORT); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + option = purple_account_option_string_new(_("First name"), "first", default_firstname); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); diff -r 7d58d7a3c5c3 -r f38799160cfa libpurple/protocols/bonjour/bonjour.h --- a/libpurple/protocols/bonjour/bonjour.h Thu Feb 19 22:52:49 2009 +0000 +++ b/libpurple/protocols/bonjour/bonjour.h Sat Feb 21 22:10:27 2009 +0000 @@ -38,7 +38,7 @@ #define BONJOUR_STATUS_ID_AVAILABLE "available" #define BONJOUR_STATUS_ID_AWAY "away" -#define BONJOUR_DEFAULT_PORT_INT 5298 +#define BONJOUR_DEFAULT_PORT 5298 typedef struct _BonjourData { diff -r 7d58d7a3c5c3 -r f38799160cfa libpurple/protocols/bonjour/jabber.c --- a/libpurple/protocols/bonjour/jabber.c Thu Feb 19 22:52:49 2009 +0000 +++ b/libpurple/protocols/bonjour/jabber.c Sat Feb 21 22:10:27 2009 +0000 @@ -672,14 +672,11 @@ bonjour_jabber_start(BonjourJabber *jdata) { struct sockaddr_in my_addr; - int i; - gboolean bind_successful; /* Open a listening socket for incoming conversations */ - if ((jdata->socket = socket(PF_INET, SOCK_STREAM, 0)) < 0) - { + if ((jdata->socket = socket(PF_INET, SOCK_STREAM, 0)) < 0) { purple_debug_error("bonjour", "Cannot open socket: %s\n", g_strerror(errno)); - purple_connection_error_reason (jdata->account->gc, + purple_connection_error_reason(jdata->account->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Cannot open socket")); return -1; @@ -688,36 +685,25 @@ memset(&my_addr, 0, sizeof(struct sockaddr_in)); my_addr.sin_family = AF_INET; - /* Attempt to find a free port */ - bind_successful = FALSE; - for (i = 0; i < 10; i++) - { - my_addr.sin_port = htons(jdata->port); - if (bind(jdata->socket, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == 0) - { - bind_successful = TRUE; - break; + /* Try to use the specified port - if it isn't available, use a random port */ + my_addr.sin_port = htons(jdata->port); + if (bind(jdata->socket, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) != 0) { + purple_debug_info("bonjour", "Unable to bind to specified port %u (%s).\n", jdata->port, g_strerror(errno)); + my_addr.sin_port = 0; + if (bind(jdata->socket, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) != 0) { + purple_debug_error("bonjour", "Unable to bind to system assigned port (%s).\n", g_strerror(errno)); + purple_connection_error_reason(jdata->account->gc, + PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Could not bind socket to port")); + return -1; } - - purple_debug_info("bonjour", "Unable to bind to port %u.(%s)\n", jdata->port, g_strerror(errno)); - jdata->port++; - } - - /* On no! We tried 10 ports and could not bind to ANY of them */ - if (!bind_successful) - { - purple_debug_error("bonjour", "Cannot bind socket: %s\n", g_strerror(errno)); - purple_connection_error_reason (jdata->account->gc, - PURPLE_CONNECTION_ERROR_NETWORK_ERROR, - _("Could not bind socket to port")); - return -1; + jdata->port = purple_network_get_port_from_fd(jdata->socket); } /* Attempt to listen on the bound socket */ - if (listen(jdata->socket, 10) != 0) - { + if (listen(jdata->socket, 10) != 0) { purple_debug_error("bonjour", "Cannot listen on socket: %s\n", g_strerror(errno)); - purple_connection_error_reason (jdata->account->gc, + purple_connection_error_reason(jdata->account->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Could not listen on socket")); return -1;