Changeset 3fbce97 for lib


Ignore:
Timestamp:
2016-09-24T20:14:34Z (8 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Children:
ba52ac5
Parents:
63cad66 (diff), 82cb190 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into parson

Location:
lib
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • lib/http_client.c

    r63cad66 r3fbce97  
    162162        }
    163163
    164         req->func(req);
     164        if (req->func != NULL) {
     165                req->func(req);
     166        }
    165167        http_free(req);
    166168        return FALSE;
     
    299301        }
    300302
    301         req->func(req);
     303        if (req->func != NULL) {
     304                req->func(req);
     305        }
    302306        http_free(req);
    303307        return FALSE;
     
    412416        }
    413417
    414         if ((req->flags & HTTPC_STREAMING) && req->reply_body) {
     418        if ((req->flags & HTTPC_STREAMING) && req->reply_body && req->func != NULL) {
    415419                req->func(req);
    416420        }
     
    696700                ssl_disconnect(req->ssl);
    697701        } else {
    698                 closesocket(req->fd);
     702                proxy_disconnect(req->fd);
    699703        }
    700704
  • lib/ini.c

    r63cad66 r3fbce97  
    2828ini_t *ini_open(char *file)
    2929{
    30         int fd;
     30        int fd = -1;
    3131        ini_t *ini = NULL;
    3232        struct stat fi;
    3333
    34         if ((fd = open(file, O_RDONLY)) != -1 &&
     34        if (file && (fd = open(file, O_RDONLY)) != -1 &&
    3535            fstat(fd, &fi) == 0 &&
    3636            fi.st_size <= 16384 &&
  • lib/misc.c

    r63cad66 r3fbce97  
    187187                                } else if (g_strncasecmp(cs + 1, "br", taglen) == 0) {
    188188                                        *(s++) = '\n';
     189                                } else if (g_strncasecmp(cs + 1, "br/", taglen) == 0) {
     190                                        *(s++) = '\n';
     191                                } else if (g_strncasecmp(cs + 1, "br /", taglen) == 0) {
     192                                        *(s++) = '\n';
    189193                                }
    190194                                in++;
     
    295299
    296300/* Warning: This one explodes the string. Worst-cases can make the string 3x its original size! */
    297 /* This fuction is safe, but make sure you call it safely as well! */
     301/* This function is safe, but make sure you call it safely as well! */
    298302void http_encode(char *s)
    299303{
     
    767771}
    768772
     773/* Filters all the characters in 'blacklist' replacing them with 'replacement'.
     774 * Modifies the string in-place and returns the string itself.
     775 * For the opposite, use g_strcanon() */
     776char *str_reject_chars(char *string, const char *reject, char replacement)
     777{
     778        char *c = string;
     779
     780        while (*c) {
     781                c += strcspn(c, reject);
     782                if (*c) {
     783                        *c = replacement;
     784                }
     785        }
     786
     787        return string;
     788}
  • lib/misc.h

    r63cad66 r3fbce97  
    150150G_MODULE_EXPORT int truncate_utf8(char *string, int maxlen);
    151151G_MODULE_EXPORT gboolean parse_int64(char *string, int base, guint64 *number);
     152G_MODULE_EXPORT char *str_reject_chars(char *string, const char *reject, char replacement);
    152153
    153154#endif
  • lib/proxy.c

    r63cad66 r3fbce97  
    5151#endif
    5252
     53static GHashTable *phb_hash = NULL;
     54
    5355struct PHB {
    5456        b_event_handler func, proxy_func;
     
    6163};
    6264
     65typedef int (*proxy_connect_func)(const char *host, unsigned short port_, struct PHB *phb);
     66
    6367static int proxy_connect_none(const char *host, unsigned short port_, struct PHB *phb);
    6468
    65 static gboolean phb_close(struct PHB *phb)
    66 {
    67         close(phb->fd);
    68         phb->func(phb->data, -1, B_EV_IO_READ);
     69static gboolean phb_free(struct PHB *phb, gboolean success)
     70{
     71        g_hash_table_remove(phb_hash, &phb->fd);
     72
     73        if (!success) {
     74                if (phb->fd > 0) {
     75                        closesocket(phb->fd);
     76                }
     77                if (phb->func) {
     78                        phb->func(phb->data, -1, B_EV_IO_READ);
     79                }
     80        }
     81        if (phb->gai) {
     82                freeaddrinfo(phb->gai);
     83        }
    6984        g_free(phb->host);
    7085        g_free(phb);
     
    89104                                dup2(new_fd, source);
    90105                                closesocket(new_fd);
     106                                phb->fd = source;
    91107                                phb->inpa = b_input_add(source, B_EV_IO_WRITE, proxy_connected, phb);
    92108                                return FALSE;
     
    101117
    102118        freeaddrinfo(phb->gai);
     119        phb->gai = NULL;
     120
    103121        b_event_remove(phb->inpa);
    104122        phb->inpa = 0;
     123
    105124        if (phb->proxy_func) {
    106125                phb->proxy_func(phb->proxy_data, source, B_EV_IO_READ);
    107126        } else {
    108127                phb->func(phb->data, source, B_EV_IO_READ);
    109                 g_free(phb);
     128                phb_free(phb, TRUE);
    110129        }
    111130
     
    171190
    172191        if (fd < 0 && host) {
    173                 g_free(phb);
     192                phb_free(phb, TRUE);
    174193        }
    175194
     
    204223            (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2)) == 0)) {
    205224                phb->func(phb->data, source, B_EV_IO_READ);
    206                 g_free(phb->host);
    207                 g_free(phb);
    208                 return FALSE;
    209         }
    210 
    211         return phb_close(phb);
     225                return phb_free(phb, TRUE);
     226        }
     227
     228        return phb_free(phb, FALSE);
    212229}
    213230
     
    224241        len = sizeof(error);
    225242        if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
    226                 return phb_close(phb);
     243                return phb_free(phb, FALSE);
    227244        }
    228245        sock_make_blocking(source);
     
    231248                   phb->host, phb->port);
    232249        if (send(source, cmd, strlen(cmd), 0) < 0) {
    233                 return phb_close(phb);
     250                return phb_free(phb, FALSE);
    234251        }
    235252
     
    242259                g_free(t2);
    243260                if (send(source, cmd, strlen(cmd), 0) < 0) {
    244                         return phb_close(phb);
     261                        return phb_free(phb, FALSE);
    245262                }
    246263        }
     
    248265        g_snprintf(cmd, sizeof(cmd), "\r\n");
    249266        if (send(source, cmd, strlen(cmd), 0) < 0) {
    250                 return phb_close(phb);
     267                return phb_free(phb, FALSE);
    251268        }
    252269
     
    279296        if (read(source, packet, 9) >= 4 && packet[1] == 90) {
    280297                phb->func(phb->data, source, B_EV_IO_READ);
    281                 g_free(phb->host);
    282                 g_free(phb);
    283                 return FALSE;
    284         }
    285 
    286         return phb_close(phb);
     298                return phb_free(phb, TRUE);
     299        }
     300
     301        return phb_free(phb, FALSE);
    287302}
    288303
     
    294309        socklen_t len;
    295310        int error = ETIMEDOUT;
     311        gboolean is_socks4a = (proxytype == PROXY_SOCKS4A);
    296312
    297313        if (phb->inpa > 0) {
     
    300316        len = sizeof(error);
    301317        if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
    302                 return phb_close(phb);
     318                return phb_free(phb, FALSE);
    303319        }
    304320        sock_make_blocking(source);
    305321
    306         /* XXX does socks4 not support host name lookups by the proxy? */
    307         if (!(hp = gethostbyname(phb->host))) {
    308                 return phb_close(phb);
     322        if (!is_socks4a && !(hp = gethostbyname(phb->host))) {
     323                return phb_free(phb, FALSE);
    309324        }
    310325
     
    313328        packet[2] = phb->port >> 8;
    314329        packet[3] = phb->port & 0xff;
    315         packet[4] = (unsigned char) (hp->h_addr_list[0])[0];
    316         packet[5] = (unsigned char) (hp->h_addr_list[0])[1];
    317         packet[6] = (unsigned char) (hp->h_addr_list[0])[2];
    318         packet[7] = (unsigned char) (hp->h_addr_list[0])[3];
     330        if (is_socks4a) {
     331                packet[4] = 0;
     332                packet[5] = 0;
     333                packet[6] = 0;
     334                packet[7] = 1;
     335        } else {
     336                packet[4] = (unsigned char) (hp->h_addr_list[0])[0];
     337                packet[5] = (unsigned char) (hp->h_addr_list[0])[1];
     338                packet[6] = (unsigned char) (hp->h_addr_list[0])[2];
     339                packet[7] = (unsigned char) (hp->h_addr_list[0])[3];
     340        }
    319341        packet[8] = 0;
    320342        if (write(source, packet, 9) != 9) {
    321                 return phb_close(phb);
     343                return phb_free(phb, FALSE);
     344        }
     345
     346        if (is_socks4a) {
     347                size_t host_len = strlen(phb->host) + 1; /* include the \0 */
     348
     349                if (write(source, phb->host, host_len) != host_len) {
     350                        return phb_free(phb, FALSE);
     351                }
    322352        }
    323353
     
    348378
    349379        if (read(source, buf, 10) < 10) {
    350                 return phb_close(phb);
     380                return phb_free(phb, FALSE);
    351381        }
    352382        if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
    353                 return phb_close(phb);
     383                return phb_free(phb, FALSE);
    354384        }
    355385
    356386        phb->func(phb->data, source, B_EV_IO_READ);
    357         g_free(phb->host);
    358         g_free(phb);
    359 
    360         return FALSE;
     387        return phb_free(phb, TRUE);
    361388}
    362389
     
    377404
    378405        if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) {
    379                 phb_close(phb);
     406                phb_free(phb, FALSE);
    380407                return;
    381408        }
     
    392419
    393420        if (read(source, buf, 2) < 2) {
    394                 return phb_close(phb);
     421                return phb_free(phb, FALSE);
    395422        }
    396423
    397424        if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
    398                 return phb_close(phb);
     425                return phb_free(phb, FALSE);
    399426        }
    400427
     
    412439
    413440        if (read(source, buf, 2) < 2) {
    414                 return phb_close(phb);
     441                return phb_free(phb, FALSE);
    415442        }
    416443
    417444        if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
    418                 return phb_close(phb);
     445                return phb_free(phb, FALSE);
    419446        }
    420447
     
    427454                memcpy(buf + 2 + i + 1, proxypass, j);
    428455                if (write(source, buf, 3 + i + j) < 3 + i + j) {
    429                         return phb_close(phb);
     456                        return phb_free(phb, FALSE);
    430457                }
    431458
     
    451478        len = sizeof(error);
    452479        if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
    453                 return phb_close(phb);
     480                return phb_free(phb, FALSE);
    454481        }
    455482        sock_make_blocking(source);
     
    469496
    470497        if (write(source, buf, i) < i) {
    471                 return phb_close(phb);
     498                return phb_free(phb, FALSE);
    472499        }
    473500
     
    487514}
    488515
     516static const proxy_connect_func proxy_connect_funcs_array[] = {
     517        proxy_connect_none,   /* PROXY_NONE */
     518        proxy_connect_http,   /* PROXY_HTTP */
     519        proxy_connect_socks4, /* PROXY_SOCKS4 */
     520        proxy_connect_socks5, /* PROXY_SOCKS5 */
     521        proxy_connect_socks4, /* PROXY_SOCKS4A */
     522};
    489523
    490524/* Export functions */
     
    493527{
    494528        struct PHB *phb;
     529        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        }
    495535
    496536        if (!host || port <= 0 || !func || strlen(host) > 128) {
     
    502542        phb->data = data;
    503543
    504         if (proxytype == PROXY_NONE || !proxyhost[0] || proxyport <= 0) {
    505                 return proxy_connect_none(host, port, phb);
    506         } else if (proxytype == PROXY_HTTP) {
    507                 return proxy_connect_http(host, port, phb);
    508         } else if (proxytype == PROXY_SOCKS4) {
    509                 return proxy_connect_socks4(host, port, phb);
    510         } else if (proxytype == PROXY_SOCKS5) {
    511                 return proxy_connect_socks5(host, port, phb);
    512         }
    513 
    514         g_free(phb);
    515         return -1;
    516 }
     544        if (proxyhost[0] && proxyport > 0 && proxytype >= 0 && proxytype < G_N_ELEMENTS(proxy_connect_funcs_array)) {
     545                fun = proxy_connect_funcs_array[proxytype];
     546        } else {
     547                fun = proxy_connect_none;
     548        }
     549
     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}
  • lib/proxy.h

    r63cad66 r3fbce97  
    4040#define PROXY_SOCKS4 2
    4141#define PROXY_SOCKS5 3
     42#define PROXY_SOCKS4A 4
    4243
    4344extern char proxyhost[128];
     
    4849
    4950G_MODULE_EXPORT int proxy_connect(const char *host, int port, b_event_handler func, gpointer data);
     51G_MODULE_EXPORT void proxy_disconnect(int fd);
    5052
    5153#endif /* _PROXY_H_ */
  • lib/ssl_gnutls.c

    r63cad66 r3fbce97  
    455455        }
    456456
    457         closesocket(conn->fd);
     457        proxy_disconnect(conn->fd);
    458458
    459459        if (conn->session) {
  • lib/ssl_nss.c

    r63cad66 r3fbce97  
    226226        if (conn->prfd) {
    227227                PR_Close(conn->prfd);
    228         }
    229         if (source >= 0) {
     228        } else if (source >= 0) {
     229                /* proxy_disconnect() would be redundant here */
    230230                closesocket(source);
    231231        }
     
    305305        if (conn->prfd) {
    306306                PR_Close(conn->prfd);
     307        } else if (conn->fd) {
     308                proxy_disconnect(conn->fd);
    307309        }
    308310
  • lib/ssl_openssl.c

    r63cad66 r3fbce97  
    131131                conn->func(conn->data, 1, NULL, cond);
    132132                if (source >= 0) {
    133                         closesocket(source);
     133                        proxy_disconnect(source);
    134134                }
    135135                ssl_conn_free(conn);
     
    276276        }
    277277
    278         closesocket(conn->fd);
     278        proxy_disconnect(conn->fd);
    279279
    280280        ssl_conn_free(conn);
  • lib/url.c

    r63cad66 r3fbce97  
    4848                } else if (g_strncasecmp(set_url, "socks5", i - set_url) == 0) {
    4949                        url->proto = PROTO_SOCKS5;
     50                } else if (g_strncasecmp(set_url, "socks4a", i - set_url) == 0) {
     51                        url->proto = PROTO_SOCKS4A;
    5052                } else {
    5153                        return 0;
  • lib/url.h

    r63cad66 r3fbce97  
    3030#define PROTO_SOCKS4    3
    3131#define PROTO_SOCKS5    4
     32#define PROTO_SOCKS4A   5
    3233#define PROTO_DEFAULT   PROTO_HTTP
    3334
Note: See TracChangeset for help on using the changeset viewer.