Mercurial > pidgin.yaz
comparison 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 |
comparison
equal
deleted
inserted
replaced
12908:4f2b96f23700 | 12909:8e3b85fe4a55 |
---|---|
1505 static void oscar_cancel_direct_im(struct ask_do_dir_im *data) { | 1505 static void oscar_cancel_direct_im(struct ask_do_dir_im *data) { |
1506 g_free(data->who); | 1506 g_free(data->who); |
1507 g_free(data); | 1507 g_free(data); |
1508 } | 1508 } |
1509 | 1509 |
1510 struct dir_im_listen { | |
1511 struct oscar_direct_im *dim; | |
1512 const guchar *cookie; | |
1513 }; | |
1514 | |
1515 static void | |
1516 oscar_direct_im_listen_cb(int listenfd, gpointer data) { | |
1517 struct dir_im_listen *dim_l = data; | |
1518 const char *ip; | |
1519 OscarData *od; | |
1520 struct oscar_direct_im *dim = dim_l->dim; | |
1521 | |
1522 od = (OscarData *)dim->gc->proto_data; | |
1523 | |
1524 /* XXX: shouldn't this be your public IP or something? */ | |
1525 ip = gaim_network_get_my_ip(od->conn ? od->conn->fd : -1); | |
1526 | |
1527 if (listenfd >= 0) | |
1528 dim->conn = aim_odc_initiate(od->sess, dim->name, listenfd, | |
1529 gaim_network_ip_atoi(ip), | |
1530 gaim_network_get_port_from_fd(listenfd), dim_l->cookie); | |
1531 | |
1532 if (dim->conn != NULL) { | |
1533 char *tmp; | |
1534 GaimConversation *conv; | |
1535 | |
1536 od->direct_ims = g_slist_append(od->direct_ims, dim); | |
1537 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, | |
1538 oscar_callback, dim->conn); | |
1539 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIM_ESTABLISHED, | |
1540 gaim_odc_initiate, 0); | |
1541 | |
1542 conv = gaim_conversation_new(GAIM_CONV_TYPE_IM, dim->gc->account, dim->name); | |
1543 tmp = g_strdup_printf(_("Asking %s to connect to us at %s:%hu for Direct IM."), dim->name, ip, | |
1544 gaim_network_get_port_from_fd(listenfd)); | |
1545 gaim_conversation_write(conv, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
1546 g_free(tmp); | |
1547 } else { | |
1548 gaim_notify_error(dim->gc, NULL, _("Unable to open Direct IM"), NULL); | |
1549 oscar_direct_im_destroy(od, dim); | |
1550 } | |
1551 | |
1552 g_free(dim_l); | |
1553 } | |
1554 | |
1510 /* this function is used to initiate a direct im session with someone. | 1555 /* this function is used to initiate a direct im session with someone. |
1511 * we start listening on a port and send a request. they either connect | 1556 * we start listening on a port and send a request. they either connect |
1512 * or send some kind of reply. If they can't connect, they ask us to | 1557 * or send some kind of reply. If they can't connect, they ask us to |
1513 * connect to them, and so we do that. | 1558 * connect to them, and so we do that. |
1514 * | 1559 * |
1518 * note that cookie is an 8 byte string that isn't NULL terminated | 1563 * note that cookie is an 8 byte string that isn't NULL terminated |
1519 */ | 1564 */ |
1520 static void oscar_direct_im_initiate(GaimConnection *gc, const char *who, const guchar *cookie) { | 1565 static void oscar_direct_im_initiate(GaimConnection *gc, const char *who, const guchar *cookie) { |
1521 OscarData *od; | 1566 OscarData *od; |
1522 struct oscar_direct_im *dim; | 1567 struct oscar_direct_im *dim; |
1523 int listenfd; | 1568 struct dir_im_listen *dim_l; |
1524 const char *ip; | |
1525 | 1569 |
1526 od = (OscarData *)gc->proto_data; | 1570 od = (OscarData *)gc->proto_data; |
1527 | 1571 |
1528 dim = oscar_direct_im_find(od, who); | 1572 dim = oscar_direct_im_find(od, who); |
1529 if (dim) { | 1573 if (dim) { |
1538 } | 1582 } |
1539 dim = g_new0(struct oscar_direct_im, 1); | 1583 dim = g_new0(struct oscar_direct_im, 1); |
1540 dim->gc = gc; | 1584 dim->gc = gc; |
1541 g_snprintf(dim->name, sizeof dim->name, "%s", who); | 1585 g_snprintf(dim->name, sizeof dim->name, "%s", who); |
1542 | 1586 |
1543 listenfd = gaim_network_listen_range(5190, 5199, SOCK_STREAM); | 1587 dim_l = g_new0(struct dir_im_listen, 1); |
1544 ip = gaim_network_get_my_ip(od->conn ? od->conn->fd : -1); | 1588 dim_l->dim = dim; |
1545 if (listenfd >= 0) | 1589 dim_l->cookie = cookie; |
1546 dim->conn = aim_odc_initiate(od->sess, who, listenfd, gaim_network_ip_atoi(ip), gaim_network_get_port_from_fd(listenfd), cookie); | 1590 |
1547 if (dim->conn != NULL) { | 1591 if(!gaim_network_listen_range(5190, 5199, SOCK_STREAM, oscar_direct_im_listen_cb, dim)) { |
1548 char *tmp; | |
1549 GaimConversation *conv; | |
1550 | |
1551 od->direct_ims = g_slist_append(od->direct_ims, dim); | |
1552 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, | |
1553 oscar_callback, dim->conn); | |
1554 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIM_ESTABLISHED, | |
1555 gaim_odc_initiate, 0); | |
1556 | |
1557 conv = gaim_conversation_new(GAIM_CONV_TYPE_IM, dim->gc->account, who); | |
1558 tmp = g_strdup_printf(_("Asking %s to connect to us at %s:%hu for Direct IM."), who, ip, | |
1559 gaim_network_get_port_from_fd(listenfd)); | |
1560 gaim_conversation_write(conv, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
1561 g_free(tmp); | |
1562 } else { | |
1563 gaim_notify_error(gc, NULL, _("Unable to open Direct IM"), NULL); | 1592 gaim_notify_error(gc, NULL, _("Unable to open Direct IM"), NULL); |
1564 oscar_direct_im_destroy(od, dim); | 1593 oscar_direct_im_destroy(od, dim); |
1594 g_free(dim_l); | |
1565 } | 1595 } |
1566 } | 1596 } |
1567 | 1597 |
1568 static void oscar_direct_im(struct ask_do_dir_im *data) { | 1598 static void oscar_direct_im(struct ask_do_dir_im *data) { |
1569 GaimConnection *gc = data->gc; | 1599 GaimConnection *gc = data->gc; |
2543 _("Unable to establish listener socket or no AOL proxy connection present.")); | 2573 _("Unable to establish listener socket or no AOL proxy connection present.")); |
2544 gaim_xfer_cancel_local(xfer); | 2574 gaim_xfer_cancel_local(xfer); |
2545 } | 2575 } |
2546 } | 2576 } |
2547 | 2577 |
2578 static void | |
2579 oscar_xfer_init_listen_cb(int listenfd, gpointer data) { | |
2580 GaimXfer *xfer = data; | |
2581 struct aim_oft_info *oft_info; | |
2582 GaimConnection *gc; | |
2583 OscarData *od; | |
2584 | |
2585 /* If the ft was canceled before we get here, don't continue */ | |
2586 if(gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_CANCEL_LOCAL) { | |
2587 gaim_xfer_unref(xfer); | |
2588 return; | |
2589 } | |
2590 | |
2591 oft_info = xfer->data; | |
2592 gc = oft_info->sess->aux_data; | |
2593 od = gc->proto_data; | |
2594 | |
2595 if (listenfd < 0) { | |
2596 gaim_xfer_cancel_local(xfer); | |
2597 return; | |
2598 } | |
2599 | |
2600 xfer->local_port = gaim_network_get_port_from_fd(listenfd); | |
2601 oft_info->port = xfer->local_port; | |
2602 if (aim_sendfile_listen(od->sess, oft_info, listenfd) != 0) { | |
2603 gaim_xfer_cancel_local(xfer); | |
2604 return; | |
2605 } | |
2606 gaim_debug_misc("oscar", | |
2607 "port is %hu, ip is %s\n", | |
2608 xfer->local_port, oft_info->clientip); | |
2609 | |
2610 if(oft_info->conn) | |
2611 xfer->watcher = gaim_input_add(oft_info->conn->fd, GAIM_INPUT_READ, oscar_callback, | |
2612 oft_info->conn); | |
2613 else | |
2614 gaim_debug_info("oscar","NULL oft_info->conn; not adding watcher\n"); | |
2615 | |
2616 oscar_send_file_request(xfer); | |
2617 } | |
2618 | |
2548 | 2619 |
2549 /* | 2620 /* |
2550 * Opens a listener socket in preparation for sending a file | 2621 * Opens a listener socket in preparation for sending a file |
2551 * This is not called if we are using a rendezvous proxy server | 2622 * This is not called if we are using a rendezvous proxy server |
2552 */ | 2623 */ |
2553 static void oscar_xfer_init_send(GaimXfer *xfer) | 2624 static void oscar_xfer_init_send(GaimXfer *xfer) |
2554 { | 2625 { |
2555 struct aim_oft_info *oft_info = xfer->data; | |
2556 GaimConnection *gc = oft_info->sess->aux_data; | |
2557 OscarData *od = gc->proto_data; | |
2558 int listenfd; | |
2559 | |
2560 gaim_debug_info("oscar", "AAA - in oscar_xfer_init_send\n"); | 2626 gaim_debug_info("oscar", "AAA - in oscar_xfer_init_send\n"); |
2561 | 2627 |
2628 gaim_xfer_ref(xfer); | |
2629 | |
2562 /* Create a listening socket and an associated libfaim conn */ | 2630 /* Create a listening socket and an associated libfaim conn */ |
2563 if ((listenfd = gaim_network_listen_range(5190, 5199, SOCK_STREAM)) < 0) { | 2631 if (!gaim_network_listen_range(5190, 5199, SOCK_STREAM, |
2632 oscar_xfer_init_listen_cb, xfer)) { | |
2633 gaim_xfer_unref(xfer); | |
2564 gaim_xfer_cancel_local(xfer); | 2634 gaim_xfer_cancel_local(xfer); |
2565 return; | 2635 return; |
2566 } | 2636 } |
2567 xfer->local_port = gaim_network_get_port_from_fd(listenfd); | |
2568 oft_info->port = xfer->local_port; | |
2569 if (aim_sendfile_listen(od->sess, oft_info, listenfd) != 0) { | |
2570 gaim_xfer_cancel_local(xfer); | |
2571 return; | |
2572 } | |
2573 gaim_debug_misc("oscar", | |
2574 "port is %hu, ip is %s\n", | |
2575 xfer->local_port, oft_info->clientip); | |
2576 | |
2577 if(oft_info->conn) | |
2578 xfer->watcher = gaim_input_add(oft_info->conn->fd, GAIM_INPUT_READ, oscar_callback, | |
2579 oft_info->conn); | |
2580 else | |
2581 gaim_debug_info("oscar","NULL oft_info->conn; not adding watcher\n"); | |
2582 | |
2583 oscar_send_file_request(xfer); | |
2584 } | 2637 } |
2585 | 2638 |
2586 /* | 2639 /* |
2587 * "On second thought, you don't deserve this file." | 2640 * "On second thought, you don't deserve this file." |
2588 */ | 2641 */ |