Changeset 4e365ce for lib/proxy.c


Ignore:
Timestamp:
2015-10-26T03:42:15Z (9 years ago)
Author:
dequis <dx@…>
Branches:
master
Children:
0db6618
Parents:
f710673
git-author:
dequis <dx@…> (25-10-15 04:06:22)
git-committer:
dequis <dx@…> (26-10-15 03:42:15)
Message:

Add proxy_disconnect() to interrupt possibly pending connections

Fixes trac ticket 1198, https://bugs.bitlbee.org/bitlbee/ticket/1198

This function can be used as a safe drop-in replacement to closesocket()

If a proxy connection is pending (connected callback still not called),
it looks up the PHB in a hash table indexed by fd. If it is there, it
closes, frees the phb and avoids further calls to the callback.
If it is not in there, it just does closesocket()

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/proxy.c

    rf710673 r4e365ce  
    5151#endif
    5252
     53static GHashTable *phb_hash = NULL;
     54
    5355struct PHB {
    5456        b_event_handler func, proxy_func;
     
    6769static gboolean phb_free(struct PHB *phb, gboolean success)
    6870{
     71        g_hash_table_remove(phb_hash, &phb->fd);
     72
    6973        if (!success) {
    7074                if (phb->fd > 0) {
     
    100104                                dup2(new_fd, source);
    101105                                closesocket(new_fd);
     106                                phb->fd = source;
    102107                                phb->inpa = b_input_add(source, B_EV_IO_WRITE, proxy_connected, phb);
    103108                                return FALSE;
     
    523528        struct PHB *phb;
    524529        proxy_connect_func fun;
     530        int fd;
     531
     532        if (!phb_hash) {
     533                phb_hash = g_hash_table_new(g_int_hash, g_int_equal);
     534        }
    525535
    526536        if (!host || port <= 0 || !func || strlen(host) > 128) {
     
    538548        }
    539549
    540         return fun(host, port, phb);
    541 }
     550        fd = fun(host, port, phb);
     551
     552        if (fd != -1) {
     553                g_hash_table_insert(phb_hash, &phb->fd, phb);
     554        }
     555
     556        return fd;
     557}
     558
     559void proxy_disconnect(int fd)
     560{
     561        struct PHB *phb = g_hash_table_lookup(phb_hash, &fd);
     562
     563        if (!phb) {
     564                /* not in the early part of the connection - just close the fd */
     565                closesocket(fd);
     566                return;
     567        }
     568
     569        if (phb->inpa) {
     570                b_event_remove(phb->inpa);
     571                phb->inpa = 0;
     572        }
     573
     574        /* avoid calling the callback, which might result in double-free */
     575        phb->func = NULL;
     576
     577        /* close and free */
     578        phb_free(phb, FALSE);
     579}
Note: See TracChangeset for help on using the changeset viewer.