Mercurial > pidgin
changeset 25497:f38799160cfa
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.
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Sat, 21 Feb 2009 22:10:27 +0000 |
parents | 7d58d7a3c5c3 |
children | 6eff00e729ac |
files | libpurple/protocols/bonjour/bonjour.c libpurple/protocols/bonjour/bonjour.h libpurple/protocols/bonjour/jabber.c |
diffstat | 3 files changed, 21 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- 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);
--- 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 {
--- 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;