Mercurial > pidgin
diff src/protocols/simple/simple.c @ 12909:8e3b85fe4a55
[gaim-migrate @ 15262]
Make UPnP truly asynchronous.
There are probably still a couple socket calls that should be made nonblocking, but I wanted to commit this before it became even bigger. This contains a number of probable leak fixes in the upnp stuff.
The UPnP stuff has been updated to use gaim_url_fetch_request() instead of the specific implementation.
To make this all work, I had to make gaim_network_listen() and gaim_network_listen_range() also asynchronous - seems to work just fine apart from the UPnP calls seeming to take longer than they should (I'm planning to look into this).
I also triggered a STUN and UPnP discovery on startup so that we hopefully have the information when we need it.
committer: Tailor Script <tailor@pidgin.im>
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Tue, 17 Jan 2006 05:48:51 +0000 |
parents | ab00cea25ef2 |
children | 256abf4dd912 |
line wrap: on
line diff
--- a/src/protocols/simple/simple.c Tue Jan 17 05:20:38 2006 +0000 +++ b/src/protocols/simple/simple.c Tue Jan 17 05:48:51 2006 +0000 @@ -1200,6 +1200,26 @@ return (gaim_utf8_strcasecmp(nick1, nick2) == 0); } +static void simple_udp_host_resolved_listen_cb(int listenfd, gpointer data) { + struct simple_account_data *sip = (struct simple_account_data*) data; + + if(listenfd == -1) { + gaim_connection_error(sip->gc, _("Could not create listen socket")); + return; + } + + sip->fd = listenfd; + + sip->listenport = gaim_network_get_port_from_fd(sip->fd); + sip->listenfd = sip->fd; + + sip->listenpa = gaim_input_add(sip->fd, GAIM_INPUT_READ, simple_udp_process, sip->gc); + + sip->resendtimeout = gaim_timeout_add(2500, (GSourceFunc) resend_timeout, sip); + sip->registertimeout = gaim_timeout_add((rand()%100)+10*1000, (GSourceFunc)subscribe_timeout, sip); + do_register(sip); +} + static void simple_udp_host_resolved(GSList *hosts, gpointer data, const char *error_message) { struct simple_account_data *sip = (struct simple_account_data*) data; int addr_size; @@ -1221,21 +1241,36 @@ } /* create socket for incoming connections */ - sip->fd = gaim_network_listen_range(5060, 5160, SOCK_DGRAM); + if(!gaim_network_listen_range(5060, 5160, SOCK_DGRAM, + simple_udp_host_resolved_listen_cb, sip)) { + gaim_connection_error(sip->gc, _("Could not create listen socket")); + return; + } +} - if(sip->fd == -1) { +static void +simple_tcp_connect_listen_cb(int listenfd, gpointer data) { + struct simple_account_data *sip = (struct simple_account_data*) data; + int error = 0; + + sip->listenfd = listenfd; + if(sip->listenfd == -1) { gaim_connection_error(sip->gc, _("Could not create listen socket")); return; } - sip->listenport = gaim_network_get_port_from_fd(sip->fd); - sip->listenfd = sip->fd; - - sip->listenpa = gaim_input_add(sip->fd, GAIM_INPUT_READ, simple_udp_process, sip->gc); - - sip->resendtimeout = gaim_timeout_add(2500, (GSourceFunc) resend_timeout, sip); - sip->registertimeout = gaim_timeout_add((rand()%100)+10*1000, (GSourceFunc)subscribe_timeout, sip); - do_register(sip); + gaim_debug_info("simple", "listenfd: %d\n", sip->listenfd); + sip->listenport = gaim_network_get_port_from_fd(sip->listenfd); + sip->listenpa = gaim_input_add(sip->listenfd, GAIM_INPUT_READ, + simple_newconn_cb, sip->gc); + gaim_debug_info("simple","connecting to %s port %d\n", + sip->realhostname, sip->realport); + /* open tcp connection to the server */ + error = gaim_proxy_connect(sip->account, sip->realhostname, + sip->realport, login_cb, sip->gc); + if(error) { + gaim_connection_error(sip->gc, _("Couldn't create socket")); + } } static void srvresolved(GaimSrvResponse *resp, int results, gpointer data) { @@ -1244,7 +1279,6 @@ gchar *hostname; int port = gaim_account_get_int(sip->account, "port", 0); - int error = 0; /* find the host to connect to */ if(results) { @@ -1266,21 +1300,11 @@ /* TCP case */ if(! sip->udp) { /* create socket for incoming connections */ - sip->listenfd = gaim_network_listen_range(5060, 5160, SOCK_STREAM); - if(sip->listenfd == -1) { + if(!gaim_network_listen_range(5060, 5160, SOCK_STREAM, + simple_tcp_connect_listen_cb, sip)) { gaim_connection_error(sip->gc, _("Could not create listen socket")); return; } - gaim_debug_info("simple", "listenfd: %d\n", sip->listenfd); - sip->listenport = gaim_network_get_port_from_fd(sip->listenfd); - sip->listenpa = gaim_input_add(sip->listenfd, GAIM_INPUT_READ, simple_newconn_cb, sip->gc); - gaim_debug_info("simple","connecting to %s port %d\n", hostname, port); - /* open tcp connection to the server */ - error = gaim_proxy_connect(sip->account, hostname, port, login_cb, sip->gc); - if(error) { - gaim_connection_error(sip->gc, _("Couldn't create socket")); - } - } else { /* UDP */ gaim_debug_info("simple", "using udp with server %s and port %d\n", hostname, port);