Mercurial > pidgin.yaz
diff src/protocols/oscar/oscar.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 | ff267281e882 |
children | a05fbd9dcc31 |
line wrap: on
line diff
--- a/src/protocols/oscar/oscar.c Tue Jan 17 05:20:38 2006 +0000 +++ b/src/protocols/oscar/oscar.c Tue Jan 17 05:48:51 2006 +0000 @@ -1507,6 +1507,51 @@ g_free(data); } +struct dir_im_listen { + struct oscar_direct_im *dim; + const guchar *cookie; +}; + +static void +oscar_direct_im_listen_cb(int listenfd, gpointer data) { + struct dir_im_listen *dim_l = data; + const char *ip; + OscarData *od; + struct oscar_direct_im *dim = dim_l->dim; + + od = (OscarData *)dim->gc->proto_data; + + /* XXX: shouldn't this be your public IP or something? */ + ip = gaim_network_get_my_ip(od->conn ? od->conn->fd : -1); + + if (listenfd >= 0) + dim->conn = aim_odc_initiate(od->sess, dim->name, listenfd, + gaim_network_ip_atoi(ip), + gaim_network_get_port_from_fd(listenfd), dim_l->cookie); + + if (dim->conn != NULL) { + char *tmp; + GaimConversation *conv; + + od->direct_ims = g_slist_append(od->direct_ims, dim); + dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, + oscar_callback, dim->conn); + aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIM_ESTABLISHED, + gaim_odc_initiate, 0); + + conv = gaim_conversation_new(GAIM_CONV_TYPE_IM, dim->gc->account, dim->name); + tmp = g_strdup_printf(_("Asking %s to connect to us at %s:%hu for Direct IM."), dim->name, ip, + gaim_network_get_port_from_fd(listenfd)); + gaim_conversation_write(conv, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); + g_free(tmp); + } else { + gaim_notify_error(dim->gc, NULL, _("Unable to open Direct IM"), NULL); + oscar_direct_im_destroy(od, dim); + } + + g_free(dim_l); +} + /* this function is used to initiate a direct im session with someone. * we start listening on a port and send a request. they either connect * or send some kind of reply. If they can't connect, they ask us to @@ -1520,8 +1565,7 @@ static void oscar_direct_im_initiate(GaimConnection *gc, const char *who, const guchar *cookie) { OscarData *od; struct oscar_direct_im *dim; - int listenfd; - const char *ip; + struct dir_im_listen *dim_l; od = (OscarData *)gc->proto_data; @@ -1540,28 +1584,14 @@ dim->gc = gc; g_snprintf(dim->name, sizeof dim->name, "%s", who); - 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); - if (dim->conn != NULL) { - char *tmp; - GaimConversation *conv; - - od->direct_ims = g_slist_append(od->direct_ims, dim); - dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, - oscar_callback, dim->conn); - aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIM_ESTABLISHED, - gaim_odc_initiate, 0); - - conv = gaim_conversation_new(GAIM_CONV_TYPE_IM, dim->gc->account, who); - tmp = g_strdup_printf(_("Asking %s to connect to us at %s:%hu for Direct IM."), who, ip, - gaim_network_get_port_from_fd(listenfd)); - gaim_conversation_write(conv, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); - g_free(tmp); - } else { + dim_l = g_new0(struct dir_im_listen, 1); + dim_l->dim = dim; + dim_l->cookie = cookie; + + if(!gaim_network_listen_range(5190, 5199, SOCK_STREAM, oscar_direct_im_listen_cb, dim)) { gaim_notify_error(gc, NULL, _("Unable to open Direct IM"), NULL); oscar_direct_im_destroy(od, dim); + g_free(dim_l); } } @@ -2545,25 +2575,28 @@ } } - -/* - * Opens a listener socket in preparation for sending a file - * This is not called if we are using a rendezvous proxy server - */ -static void oscar_xfer_init_send(GaimXfer *xfer) -{ - struct aim_oft_info *oft_info = xfer->data; - GaimConnection *gc = oft_info->sess->aux_data; - OscarData *od = gc->proto_data; - int listenfd; - - 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, SOCK_STREAM)) < 0) { +static void +oscar_xfer_init_listen_cb(int listenfd, gpointer data) { + GaimXfer *xfer = data; + struct aim_oft_info *oft_info; + GaimConnection *gc; + OscarData *od; + + /* If the ft was canceled before we get here, don't continue */ + if(gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_CANCEL_LOCAL) { + gaim_xfer_unref(xfer); + return; + } + + oft_info = xfer->data; + gc = oft_info->sess->aux_data; + od = gc->proto_data; + + if (listenfd < 0) { gaim_xfer_cancel_local(xfer); return; } + xfer->local_port = gaim_network_get_port_from_fd(listenfd); oft_info->port = xfer->local_port; if (aim_sendfile_listen(od->sess, oft_info, listenfd) != 0) { @@ -2583,6 +2616,26 @@ oscar_send_file_request(xfer); } + +/* + * Opens a listener socket in preparation for sending a file + * This is not called if we are using a rendezvous proxy server + */ +static void oscar_xfer_init_send(GaimXfer *xfer) +{ + gaim_debug_info("oscar", "AAA - in oscar_xfer_init_send\n"); + + gaim_xfer_ref(xfer); + + /* Create a listening socket and an associated libfaim conn */ + if (!gaim_network_listen_range(5190, 5199, SOCK_STREAM, + oscar_xfer_init_listen_cb, xfer)) { + gaim_xfer_unref(xfer); + gaim_xfer_cancel_local(xfer); + return; + } +} + /* * "On second thought, you don't deserve this file." */