Changeset 11655


Ignore:
Timestamp:
Jan 9, 2011, 9:48:40 PM (11 years ago)
Author:
jch
Message:

Import dht-0.16.

Location:
trunk/third-party/dht
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/third-party/dht/CHANGES

    r10914 r11655  
     123 December 2010: dht-0.16:
     2
     3  * Change the interface to allow sharing of the UDP socket e.g. with uTP.
     4
    151 July 2010: dht-0.15
    26
  • trunk/third-party/dht/LICENCE

    r8433 r11655  
    1 Copyright (c) 2009 by Juliusz Chroboczek
     1Copyright (c) 2009, 2010 by Juliusz Chroboczek
    22
    33Permission is hereby granted, free of charge, to any person obtaining a copy
  • trunk/third-party/dht/README

    r9549 r11655  
    8787it is a good idea to be late by a random value.)
    8888
    89 The parameter available indicates whether any data is available on the
    90 socket.  If it is 0, dht_periodic will not try to read data; if it is 1, it
    91 will.
     89The parameters buf, buflen, from and fromlen optionally carry a received
     90message.  If buflen is 0, then no message was received.
    9291
    9392Dht_periodic also takes a callback, which will be called whenever something
  • trunk/third-party/dht/dht-example.c

    r9549 r11655  
    8989}
    9090
     91static unsigned char buf[4096];
     92
    9193int
    9294main(int argc, char **argv)
     
    102104    struct sockaddr_in sin;
    103105    struct sockaddr_in6 sin6;
     106    struct sockaddr_storage from;
     107    socklen_t fromlen;
    104108
    105109    memset(&sin, 0, sizeof(sin));
     
    339343            break;
    340344
    341         rc = dht_periodic(rc > 0, &tosleep, callback, NULL);
     345        if(rc > 0) {
     346            fromlen = sizeof(from);
     347            if(s >= 0 && FD_ISSET(s, &readfds))
     348                rc = recvfrom(s, buf, sizeof(buf) - 1, 0,
     349                              (struct sockaddr*)&from, &fromlen);
     350            else if(s6 >= 0 && FD_ISSET(s6, &readfds))
     351                rc = recvfrom(s6, buf, sizeof(buf) - 1, 0,
     352                              (struct sockaddr*)&from, &fromlen);
     353            else
     354                abort();
     355        }
     356
     357        if(rc > 0) {
     358            buf[rc] = '\0';
     359            rc = dht_periodic(buf, rc, (struct sockaddr*)&from, fromlen,
     360                              &tosleep, callback, NULL);
     361        } else {
     362            rc = dht_periodic(NULL, 0, NULL, 0, &tosleep, callback, NULL);
     363        }
    342364        if(rc < 0) {
    343365            if(errno == EINTR) {
  • trunk/third-party/dht/dht.c

    r11350 r11655  
    11/*
    2 Copyright (c) 2010 by Juliusz Chroboczek
     2Copyright (c) 2009, 2010 by Juliusz Chroboczek
    33
    44Permission is hereby granted, free of charge, to any person obtaining a copy
     
    6767
    6868#define EAFNOSUPPORT WSAEAFNOSUPPORT
    69 #define EAGAIN WSAEWOULDBLOCK
    7069static int
    7170set_nonblocking(int fd, int nonblocking)
     
    214213};
    215214
    216 static int send_ping(struct sockaddr *sa, int salen,
     215static int send_ping(const struct sockaddr *sa, int salen,
    217216                     const unsigned char *tid, int tid_len);
    218 static int send_pong(struct sockaddr *sa, int salen,
     217static int send_pong(const struct sockaddr *sa, int salen,
    219218                     const unsigned char *tid, int tid_len);
    220 static int send_find_node(struct sockaddr *sa, int salen,
     219static int send_find_node(const struct sockaddr *sa, int salen,
    221220                          const unsigned char *tid, int tid_len,
    222221                          const unsigned char *target, int want, int confirm);
    223 static int send_nodes_peers(struct sockaddr *sa, int salen,
     222static int send_nodes_peers(const struct sockaddr *sa, int salen,
    224223                            const unsigned char *tid, int tid_len,
    225224                            const unsigned char *nodes, int nodes_len,
     
    227226                            int af, struct storage *st,
    228227                            const unsigned char *token, int token_len);
    229 static int send_closest_nodes(struct sockaddr *sa, int salen,
     228static int send_closest_nodes(const struct sockaddr *sa, int salen,
    230229                              const unsigned char *tid, int tid_len,
    231230                              const unsigned char *id, int want,
    232231                              int af, struct storage *st,
    233232                              const unsigned char *token, int token_len);
    234 static int send_get_peers(struct sockaddr *sa, int salen,
     233static int send_get_peers(const struct sockaddr *sa, int salen,
    235234                          unsigned char *tid, int tid_len,
    236235                          unsigned char *infohash, int want, int confirm);
    237 static int send_announce_peer(struct sockaddr *sa, int salen,
     236static int send_announce_peer(const struct sockaddr *sa, int salen,
    238237                              unsigned char *tid, int tid_len,
    239238                              unsigned char *infohas, unsigned short port,
    240239                              unsigned char *token, int token_len, int confirm);
    241 static int send_peer_announced(struct sockaddr *sa, int salen,
     240static int send_peer_announced(const struct sockaddr *sa, int salen,
    242241                               unsigned char *tid, int tid_len);
    243 static int send_error(struct sockaddr *sa, int salen,
     242static int send_error(const struct sockaddr *sa, int salen,
    244243                      unsigned char *tid, int tid_len,
    245244                      int code, const char *message);
     
    351350
    352351static int
    353 is_martian(struct sockaddr *sa)
     352is_martian(const struct sockaddr *sa)
    354353{
    355354    switch(sa->sa_family) {
     
    689688   the node sent a message, 2 if it sent us a reply. */
    690689static struct node *
    691 new_node(const unsigned char *id, struct sockaddr *sa, int salen, int confirm)
     690new_node(const unsigned char *id, const struct sockaddr *sa, int salen,
     691         int confirm)
    692692{
    693693    struct bucket *b = find_bucket(id, sa->sa_family);
     
    791791        if(split) {
    792792            debugf("Splitting.\n");
    793             split_bucket(b);
     793            b = split_bucket(b);
    794794            return new_node(id, sa, salen, confirm);
    795795        }
     
    881881static int
    882882insert_search_node(unsigned char *id,
    883                    struct sockaddr *sa, int salen,
     883                   const struct sockaddr *sa, int salen,
    884884                   struct search *sr, int replied,
    885885                   unsigned char *token, int token_len)
     
    12221222
    12231223static int
    1224 storage_store(const unsigned char *id, struct sockaddr *sa)
     1224storage_store(const unsigned char *id, const struct sockaddr *sa)
    12251225{
    12261226    int i, len;
     
    13331333/* We've just found out that a node is buggy. */
    13341334static void
    1335 broken_node(const unsigned char *id, struct sockaddr *sa, int salen)
     1335broken_node(const unsigned char *id, const struct sockaddr *sa, int salen)
    13361336{
    13371337    int i;
     
    13831383
    13841384static void
    1385 make_token(struct sockaddr *sa, int old, unsigned char *token_return)
     1385make_token(const struct sockaddr *sa, int old, unsigned char *token_return)
    13861386{
    13871387    void *ip;
     
    14081408}
    14091409static int
    1410 token_match(unsigned char *token, int token_len, struct sockaddr *sa)
     1410token_match(const unsigned char *token, int token_len,
     1411            const struct sockaddr *sa)
    14111412{
    14121413    unsigned char t[TOKEN_SIZE];
     
    18321833
    18331834int
    1834 dht_periodic(int available, time_t *tosleep,
     1835dht_periodic(const void *buf, size_t buflen,
     1836             const struct sockaddr *from, int fromlen,
     1837             time_t *tosleep,
    18351838             dht_callback *callback, void *closure)
    18361839{
     
    18391842    gettimeofday(&now, NULL);
    18401843
    1841     if(available) {
    1842         int rc, message;
     1844    if(buflen > 0) {
     1845        int message;
    18431846        unsigned char tid[16], id[20], info_hash[20], target[20];
    1844         unsigned char buf[1536], nodes[256], nodes6[1024], token[128];
     1847        unsigned char nodes[256], nodes6[1024], token[128];
    18451848        int tid_len = 16, token_len = 128;
    18461849        int nodes_len = 256, nodes6_len = 1024;
     
    18491852        int values_len = 2048, values6_len = 2048;
    18501853        int want;
    1851         struct sockaddr_storage source_storage;
    1852         struct sockaddr *source = (struct sockaddr*)&source_storage;
    1853         socklen_t sourcelen = sizeof(source_storage);
    18541854        unsigned short ttid;
    18551855
    1856         rc = -1;
    1857         if(dht_socket >= 0) {
    1858             rc = recvfrom(dht_socket, buf, 1536, 0, source, &sourcelen);
    1859             if(rc < 0 && errno != EAGAIN) {
    1860                     return rc;
    1861             }
    1862         }
    1863         if(dht_socket6 >= 0 && rc < 0) {
    1864             rc = recvfrom(dht_socket6, buf, 1536, 0,
    1865                           source, &sourcelen);
    1866             if(rc < 0 && errno != EAGAIN) {
    1867                     return rc;
    1868             }
    1869         }
    1870 
    1871         if(rc < 0 || sourcelen > sizeof(struct sockaddr_storage))
     1856        if(is_martian(from))
    18721857            goto dontread;
    18731858
    1874         if(is_martian(source))
    1875             goto dontread;
    1876 
    18771859        for(i = 0; i < DHT_MAX_BLACKLISTED; i++) {
    1878             if(memcmp(&blacklist[i], source, sourcelen) == 0) {
     1860            if(memcmp(&blacklist[i], from, fromlen) == 0) {
    18791861                debugf("Received packet from blacklisted node.\n");
    18801862                goto dontread;
     
    18821864        }
    18831865
    1884         /* There's a bug in parse_message -- it will happily overflow the
    1885            buffer if it's not NUL-terminated.  For now, put a NUL at the
    1886            end of buffers. */
    1887 
    1888         if(rc < 1536) {
    1889             buf[rc] = '\0';
    1890         } else {
    1891             debugf("Overlong message.\n");
    1892             goto dontread;
    1893         }
    1894 
    1895         message = parse_message(buf, rc, tid, &tid_len, id, info_hash,
     1866        /* See parse_message. */
     1867
     1868        if(((char*)buf)[buflen] != '\0') {
     1869            debugf("Unterminated message.\n");
     1870            errno = EINVAL;
     1871            return -1;
     1872        }
     1873
     1874        message = parse_message(buf, buflen, tid, &tid_len, id, info_hash,
    18961875                                target, &port, token, &token_len,
    18971876                                nodes, &nodes_len, nodes6, &nodes6_len,
     
    19011880        if(message < 0 || message == ERROR || id_cmp(id, zeroes) == 0) {
    19021881            debugf("Unparseable message: ");
    1903             debug_printable(buf, rc);
     1882            debug_printable(buf, buflen);
    19041883            debugf("\n");
    19051884            goto dontread;
     
    19231902            if(tid_len != 4) {
    19241903                debugf("Broken node truncates transaction ids: ");
    1925                 debug_printable(buf, rc);
     1904                debug_printable(buf, buflen);
    19261905                debugf("\n");
    19271906                /* This is really annoying, as it means that we will
    19281907                   time-out all our searches that go through this node.
    19291908                   Kill it. */
    1930                 broken_node(id, source, sourcelen);
     1909                broken_node(id, from, fromlen);
    19311910                goto dontread;
    19321911            }
    19331912            if(tid_match(tid, "pn", NULL)) {
    19341913                debugf("Pong!\n");
    1935                 new_node(id, source, sourcelen, 2);
     1914                new_node(id, from, fromlen, 2);
    19361915            } else if(tid_match(tid, "fn", NULL) ||
    19371916                      tid_match(tid, "gp", NULL)) {
     
    19401919                if(tid_match(tid, "gp", &ttid)) {
    19411920                    gp = 1;
    1942                     sr = find_search(ttid, source->sa_family);
     1921                    sr = find_search(ttid, from->sa_family);
    19431922                }
    19441923                debugf("Nodes found (%d+%d)%s!\n", nodes_len/26, nodes6_len/38,
     
    19461925                if(nodes_len % 26 != 0 || nodes6_len % 38 != 0) {
    19471926                    debugf("Unexpected length for node info!\n");
    1948                     broken_node(id, source, sourcelen);
     1927                    broken_node(id, from, fromlen);
    19491928                } else if(gp && sr == NULL) {
    19501929                    debugf("Unknown search!\n");
    1951                     new_node(id, source, sourcelen, 1);
     1930                    new_node(id, from, fromlen, 1);
    19521931                } else {
    19531932                    int i;
    1954                     new_node(id, source, sourcelen, 2);
     1933                    new_node(id, from, fromlen, 2);
    19551934                    for(i = 0; i < nodes_len / 26; i++) {
    19561935                        unsigned char *ni = nodes + i * 26;
     
    19941973                }
    19951974                if(sr) {
    1996                     insert_search_node(id, source, sourcelen, sr,
     1975                    insert_search_node(id, from, fromlen, sr,
    19971976                                       1, token, token_len);
    19981977                    if(values_len > 0 || values6_len > 0) {
     
    20131992                struct search *sr;
    20141993                debugf("Got reply to announce_peer.\n");
    2015                 sr = find_search(ttid, source->sa_family);
     1994                sr = find_search(ttid, from->sa_family);
    20161995                if(!sr) {
    20171996                    debugf("Unknown search!\n");
    2018                     new_node(id, source, sourcelen, 1);
     1997                    new_node(id, from, fromlen, 1);
    20191998                } else {
    20201999                    int i;
    2021                     new_node(id, source, sourcelen, 2);
     2000                    new_node(id, from, fromlen, 2);
    20222001                    for(i = 0; i < sr->numnodes; i++)
    20232002                        if(id_cmp(sr->nodes[i].id, id) == 0) {
     
    20332012            } else {
    20342013                debugf("Unexpected reply: ");
    2035                 debug_printable(buf, rc);
     2014                debug_printable(buf, buflen);
    20362015                debugf("\n");
    20372016            }
     
    20392018        case PING:
    20402019            debugf("Ping (%d)!\n", tid_len);
    2041             new_node(id, source, sourcelen, 1);
     2020            new_node(id, from, fromlen, 1);
    20422021            debugf("Sending pong.\n");
    2043             send_pong(source, sourcelen, tid, tid_len);
     2022            send_pong(from, fromlen, tid, tid_len);
    20442023            break;
    20452024        case FIND_NODE:
    20462025            debugf("Find node!\n");
    2047             new_node(id, source, sourcelen, 1);
     2026            new_node(id, from, fromlen, 1);
    20482027            debugf("Sending closest nodes (%d).\n", want);
    2049             send_closest_nodes(source, sourcelen,
     2028            send_closest_nodes(from, fromlen,
    20502029                               tid, tid_len, target, want,
    20512030                               0, NULL, NULL, 0);
     
    20532032        case GET_PEERS:
    20542033            debugf("Get_peers!\n");
    2055             new_node(id, source, sourcelen, 1);
     2034            new_node(id, from, fromlen, 1);
    20562035            if(id_cmp(info_hash, zeroes) == 0) {
    20572036                debugf("Eek!  Got get_peers with no info_hash.\n");
    2058                 send_error(source, sourcelen, tid, tid_len,
     2037                send_error(from, fromlen, tid, tid_len,
    20592038                           203, "Get_peers with no info_hash");
    20602039                break;
     
    20622041                struct storage *st = find_storage(info_hash);
    20632042                unsigned char token[TOKEN_SIZE];
    2064                 make_token(source, 0, token);
     2043                make_token(from, 0, token);
    20652044                if(st && st->numpeers > 0) {
    20662045                     debugf("Sending found%s peers.\n",
    2067                             source->sa_family == AF_INET6 ? " IPv6" : "");
    2068                      send_closest_nodes(source, sourcelen,
     2046                            from->sa_family == AF_INET6 ? " IPv6" : "");
     2047                     send_closest_nodes(from, fromlen,
    20692048                                        tid, tid_len,
    20702049                                        info_hash, want,
    2071                                         source->sa_family, st,
     2050                                        from->sa_family, st,
    20722051                                        token, TOKEN_SIZE);
    20732052                } else {
    20742053                    debugf("Sending nodes for get_peers.\n");
    2075                     send_closest_nodes(source, sourcelen,
     2054                    send_closest_nodes(from, fromlen,
    20762055                                       tid, tid_len, info_hash, want,
    20772056                                       0, NULL, token, TOKEN_SIZE);
     
    20812060        case ANNOUNCE_PEER:
    20822061            debugf("Announce peer!\n");
    2083             new_node(id, source, sourcelen, 1);
     2062            new_node(id, from, fromlen, 1);
    20842063            if(id_cmp(info_hash, zeroes) == 0) {
    20852064                debugf("Announce_peer with no info_hash.\n");
    2086                 send_error(source, sourcelen, tid, tid_len,
     2065                send_error(from, fromlen, tid, tid_len,
    20872066                           203, "Announce_peer with no info_hash");
    20882067                break;
    20892068            }
    2090             if(!token_match(token, token_len, source)) {
     2069            if(!token_match(token, token_len, from)) {
    20912070                debugf("Incorrect token for announce_peer.\n");
    2092                 send_error(source, sourcelen, tid, tid_len,
     2071                send_error(from, fromlen, tid, tid_len,
    20932072                           203, "Announce_peer with wrong token");
    20942073                break;
     
    20962075            if(port == 0) {
    20972076                debugf("Announce_peer with forbidden port %d.\n", port);
    2098                 send_error(source, sourcelen, tid, tid_len,
     2077                send_error(from, fromlen, tid, tid_len,
    20992078                           203, "Announce_peer with forbidden port number");
    21002079                break;
    21012080            }
    2102             storage_store(info_hash, source);
     2081            storage_store(info_hash, from);
    21032082            /* Note that if storage_store failed, we lie to the requestor.
    21042083               This is to prevent them from backtracking, and hence
    21052084               polluting the DHT. */
    21062085            debugf("Sending peer announced.\n");
    2107             send_peer_announced(source, sourcelen, tid, tid_len);
     2086            send_peer_announced(from, fromlen, tid, tid_len);
    21082087        }
    21092088    }
     
    23292308
    23302309int
    2331 send_ping(struct sockaddr *sa, int salen,
     2310send_ping(const struct sockaddr *sa, int salen,
    23322311          const unsigned char *tid, int tid_len)
    23332312{
     
    23492328
    23502329int
    2351 send_pong(struct sockaddr *sa, int salen,
     2330send_pong(const struct sockaddr *sa, int salen,
    23522331          const unsigned char *tid, int tid_len)
    23532332{
     
    23682347
    23692348int
    2370 send_find_node(struct sockaddr *sa, int salen,
     2349send_find_node(const struct sockaddr *sa, int salen,
    23712350               const unsigned char *tid, int tid_len,
    23722351               const unsigned char *target, int want, int confirm)
     
    23972376
    23982377int
    2399 send_nodes_peers(struct sockaddr *sa, int salen,
     2378send_nodes_peers(const struct sockaddr *sa, int salen,
    24002379                 const unsigned char *tid, int tid_len,
    24012380                 const unsigned char *nodes, int nodes_len,
     
    25242503
    25252504int
    2526 send_closest_nodes(struct sockaddr *sa, int salen,
     2505send_closest_nodes(const struct sockaddr *sa, int salen,
    25272506                   const unsigned char *tid, int tid_len,
    25282507                   const unsigned char *id, int want,
     
    25712550
    25722551int
    2573 send_get_peers(struct sockaddr *sa, int salen,
     2552send_get_peers(const struct sockaddr *sa, int salen,
    25742553               unsigned char *tid, int tid_len, unsigned char *infohash,
    25752554               int want, int confirm)
     
    26012580
    26022581int
    2603 send_announce_peer(struct sockaddr *sa, int salen,
     2582send_announce_peer(const struct sockaddr *sa, int salen,
    26042583                   unsigned char *tid, int tid_len,
    26052584                   unsigned char *infohash, unsigned short port,
     
    26312610
    26322611static int
    2633 send_peer_announced(struct sockaddr *sa, int salen,
     2612send_peer_announced(const struct sockaddr *sa, int salen,
    26342613                    unsigned char *tid, int tid_len)
    26352614{
     
    26522631
    26532632static int
    2654 send_error(struct sockaddr *sa, int salen,
     2633send_error(const struct sockaddr *sa, int salen,
    26552634           unsigned char *tid, int tid_len,
    26562635           int code, const char *message)
  • trunk/third-party/dht/dht.h

    r9549 r11655  
    11/*
    2 Copyright (c) 2009 by Juliusz Chroboczek
     2Copyright (c) 2009, 2010 by Juliusz Chroboczek
    33
    44Permission is hereby granted, free of charge, to any person obtaining a copy
     
    3737int dht_insert_node(const unsigned char *id, struct sockaddr *sa, int salen);
    3838int dht_ping_node(struct sockaddr *sa, int salen);
    39 int dht_periodic(int available, time_t *tosleep,
    40                  dht_callback *callback, void *closure);
     39int dht_periodic(const void *buf, size_t buflen,
     40                 const struct sockaddr *from, int fromlen,
     41                 time_t *tosleep, dht_callback *callback, void *closure);
    4142int dht_search(const unsigned char *id, int port, int af,
    4243               dht_callback *callback, void *closure);
Note: See TracChangeset for help on using the changeset viewer.