FS-10166: Removed old DHT tests and stuff related to libtorrent, and a straggling diff related to old DHT.
This commit is contained in:
parent
5cff01b2a8
commit
a95f8a8e75
|
@ -1,407 +0,0 @@
|
|||
diff --git a/libs/libks/src/ks_dht.c b/libs/libks/src/ks_dht.c
|
||||
index 27bafd0..126686e 100644
|
||||
--- a/libs/libks/src/ks_dht.c
|
||||
+++ b/libs/libks/src/ks_dht.c
|
||||
@@ -2438,96 +2438,84 @@ static int dht_send(dht_handle_t *h, const void *buf, size_t len, int flags, con
|
||||
return sendto(s, buf, len, flags, sa, salen);
|
||||
}
|
||||
|
||||
+/* Sample ping packet '{"t":"aa", "y":"q", "q":"ping", "a":{"id":"abcdefghij0123456789"}}' */
|
||||
+/* http://www.bittorrent.org/beps/bep_0005.html */
|
||||
int send_ping(dht_handle_t *h, const struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len)
|
||||
{
|
||||
char buf[512];
|
||||
- int i = 0;//, rc;
|
||||
- struct bencode *bencode_p = NULL;
|
||||
- struct bencode *bencode_a_p = NULL;
|
||||
-
|
||||
- /* Sets some default values for message, then encodes 20 characters worth of local node id */
|
||||
- /* also adds the transaction id tid, then a few final key values. */
|
||||
-
|
||||
- /* Sample encoded ping 'd1:ad2:id20:Td2????#?)y1:q4:ping1:t4:pn' */
|
||||
- /* 'd1:ad2:id20:Td2????#?)y1:q4:ping1:t4:pn' */
|
||||
- /* https://en.wikipedia.org/wiki/Bencode */
|
||||
- /* Sample ping packet '{"t":"aa", "y":"q", "q":"ping", "a":{"id":"abcdefghij0123456789"}}' */
|
||||
- /* http://www.bittorrent.org/beps/bep_0005.html */
|
||||
+ int i = 0;
|
||||
+ struct bencode *bencode_p = ben_dict();
|
||||
+ struct bencode *bencode_a_p = ben_dict();
|
||||
|
||||
- bencode_a_p = ben_dict(); /* Initialize empty bencode dictionary */
|
||||
+ ben_dict_set(bencode_p, ben_blob("t", 1), ben_blob(tid, tid_len));
|
||||
+ ben_dict_set(bencode_p, ben_blob("y", 1), ben_blob("q", 1));
|
||||
+ ben_dict_set(bencode_p, ben_blob("q", 1), ben_blob("ping", 4));
|
||||
ben_dict_set(bencode_a_p, ben_blob("id", 2), ben_blob(h->myid, 20));
|
||||
-
|
||||
- bencode_p = ben_dict();
|
||||
ben_dict_set(bencode_p, ben_blob("a", 1), bencode_a_p);
|
||||
- ben_dict_set(bencode_p, ben_blob("q", 1), ben_blob("ping", 4));
|
||||
- ben_dict_set(bencode_p, ben_blob("t", 1), ben_blob(tid, tid_len));
|
||||
- ben_dict_set(bencode_p, ben_blob("y", 1), ben_blob("q", 1));
|
||||
|
||||
- /*
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "d1:ad2:id20:"); INC(i, rc, 512);
|
||||
- COPY(buf, i, h->myid, 20, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "e1:q4:ping1:t%d:", tid_len);
|
||||
- INC(i, rc, 512);
|
||||
- COPY(buf, i, tid, tid_len, 512);
|
||||
- ADD_V(buf, i, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "1:y1:qe"); INC(i, rc, 512);
|
||||
- */
|
||||
ben_encode2(buf, 512, bencode_p);
|
||||
ben_free(bencode_p); /* This SHOULD free the bencode_a_p as well */
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Encoded PING: %s\n\n", buf);
|
||||
return dht_send(h, buf, i, 0, sa, salen);
|
||||
-
|
||||
- /*
|
||||
- // Need to fix, not just disable error handling.
|
||||
- fail:
|
||||
- errno = ENOSPC;
|
||||
- return -1; */
|
||||
}
|
||||
|
||||
+/* Sample pong packet '{"t":"aa", "y":"r", "r": {"id":"mnopqrstuvwxyz123456"}}' */
|
||||
+/* http://www.bittorrent.org/beps/bep_0005.html */
|
||||
int send_pong(dht_handle_t *h, const struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len)
|
||||
{
|
||||
char buf[512];
|
||||
- int i = 0, rc;
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "d1:rd2:id20:"); INC(i, rc, 512);
|
||||
- COPY(buf, i, h->myid, 20, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "e1:t%d:", tid_len); INC(i, rc, 512);
|
||||
- COPY(buf, i, tid, tid_len, 512);
|
||||
- ADD_V(buf, i, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "1:y1:re"); INC(i, rc, 512);
|
||||
- return dht_send(h, buf, i, 0, sa, salen);
|
||||
+ int i = 0;
|
||||
+ struct bencode *bencode_p = ben_dict();
|
||||
+ struct bencode *bencode_a_p = ben_dict();
|
||||
|
||||
- fail:
|
||||
- errno = ENOSPC;
|
||||
- return -1;
|
||||
+ ben_dict_set(bencode_p, ben_blob("t", 1), ben_blob(tid, tid_len));
|
||||
+ ben_dict_set(bencode_p, ben_blob("y", 1), ben_blob("r", 1));
|
||||
+ ben_dict_set(bencode_a_p, ben_blob("id", 2), ben_blob(h->myid, 20));
|
||||
+ ben_dict_set(bencode_p, ben_blob("r", 1), bencode_a_p);
|
||||
+
|
||||
+ ben_encode2(buf, 512, bencode_p);
|
||||
+ ben_free(bencode_p); /* This SHOULD free the bencode_a_p as well */
|
||||
+
|
||||
+ ks_log(KS_LOG_DEBUG, "Encoded PONG: %s\n\n", buf);
|
||||
+ return dht_send(h, buf, i, 0, sa, salen);
|
||||
}
|
||||
|
||||
+/* Sample find_node packet '{"t":"aa", "y":"q", "q":"find_node", "a": {"id":"abcdefghij0123456789", "target":"mnopqrstuvwxyz123456"}}' */
|
||||
+/* Sample find_node packet w/ want '{"t":"aa", "y":"q", "q":"find_node", "a": {"id":"abcdefghij0123456789", "target":"mnopqrstuvwxyz123456", "want":"n4"}}' */
|
||||
+/* http://www.bittorrent.org/beps/bep_0005.html */
|
||||
+/* http://www.bittorrent.org/beps/bep_0032.html for want parameter */
|
||||
int send_find_node(dht_handle_t *h, const struct sockaddr *sa, int salen,
|
||||
const unsigned char *tid, int tid_len,
|
||||
const unsigned char *target, int want, int confirm)
|
||||
{
|
||||
char buf[512];
|
||||
- int i = 0, rc;
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "d1:ad2:id20:"); INC(i, rc, 512);
|
||||
- COPY(buf, i, h->myid, 20, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "6:target20:"); INC(i, rc, 512);
|
||||
- COPY(buf, i, target, 20, 512);
|
||||
- if (want > 0) {
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "4:wantl%s%se", (want & WANT4) ? "2:n4" : "", (want & WANT6) ? "2:n6" : "");
|
||||
- INC(i, rc, 512);
|
||||
- }
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "e1:q9:find_node1:t%d:", tid_len);
|
||||
- INC(i, rc, 512);
|
||||
- COPY(buf, i, tid, tid_len, 512);
|
||||
- ADD_V(buf, i, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "1:y1:qe"); INC(i, rc, 512);
|
||||
- return dht_send(h, buf, i, confirm ? MSG_CONFIRM : 0, sa, salen);
|
||||
+ int i = 0;
|
||||
+ struct bencode *bencode_p = ben_dict();
|
||||
+ struct bencode *bencode_a_p = ben_dict();
|
||||
+ int target_len = target ? strlen((const char*)target) : 0;
|
||||
|
||||
- fail:
|
||||
- errno = ENOSPC;
|
||||
- return -1;
|
||||
-}
|
||||
+ ben_dict_set(bencode_p, ben_blob("t", 1), ben_blob(tid, tid_len));
|
||||
+ ben_dict_set(bencode_p, ben_blob("y", 1), ben_blob("q", 1));
|
||||
+ ben_dict_set(bencode_p, ben_blob("q", 1), ben_blob("find_node", 9));
|
||||
+ ben_dict_set(bencode_a_p, ben_blob("id", 2), ben_blob(h->myid, 20));
|
||||
+ if (target) ben_dict_set(bencode_a_p, ben_blob("target", 6), ben_blob(target, target_len));
|
||||
+ if (want > 0) {
|
||||
+ char *w = NULL;
|
||||
+ if (want & WANT4) w = "n4";
|
||||
+ if (want & WANT6) w = "n6";
|
||||
+ if (w) ben_dict_set(bencode_a_p, ben_blob("want", 4), ben_blob(w, 2));
|
||||
+ }
|
||||
+ ben_dict_set(bencode_p, ben_blob("a", 1), bencode_a_p);
|
||||
|
||||
+ ben_encode2(buf, 512, bencode_p);
|
||||
+ ben_free(bencode_p); /* This SHOULD free the bencode_a_p as well */
|
||||
+
|
||||
+ ks_log(KS_LOG_DEBUG, "Encoded FIND_NODE: %s\n\n", buf);
|
||||
+ return dht_send(h, buf, i, confirm ? MSG_CONFIRM : 0, sa, salen);
|
||||
+}
|
||||
+/* sample find_node response '{"t":"aa", "y":"r", "r": {"id":"0123456789abcdefghij", "nodes": "def456..."}}'*/
|
||||
+/* http://www.bittorrent.org/beps/bep_0005.html */
|
||||
int send_nodes_peers(dht_handle_t *h, const struct sockaddr *sa, int salen,
|
||||
const unsigned char *tid, int tid_len,
|
||||
const unsigned char *nodes, int nodes_len,
|
||||
@@ -2536,30 +2524,28 @@ int send_nodes_peers(dht_handle_t *h, const struct sockaddr *sa, int salen,
|
||||
const unsigned char *token, int token_len)
|
||||
{
|
||||
char buf[2048];
|
||||
- int i = 0, rc, j0, j, k, len;
|
||||
+ int i = 0;//, rc, j0, j, k, len;
|
||||
+ struct bencode *bencode_p = ben_dict();
|
||||
+ struct bencode *bencode_a_p = ben_dict();
|
||||
+ struct bencode *ben_array = ben_list();
|
||||
|
||||
- rc = ks_snprintf(buf + i, 2048 - i, "d1:rd2:id20:"); INC(i, rc, 2048);
|
||||
- COPY(buf, i, h->myid, 20, 2048);
|
||||
- if (nodes_len > 0) {
|
||||
- rc = ks_snprintf(buf + i, 2048 - i, "5:nodes%d:", nodes_len);
|
||||
- INC(i, rc, 2048);
|
||||
- COPY(buf, i, nodes, nodes_len, 2048);
|
||||
- }
|
||||
- if (nodes6_len > 0) {
|
||||
- rc = ks_snprintf(buf + i, 2048 - i, "6:nodes6%d:", nodes6_len);
|
||||
- INC(i, rc, 2048);
|
||||
- COPY(buf, i, nodes6, nodes6_len, 2048);
|
||||
- }
|
||||
- if (token_len > 0) {
|
||||
- rc = ks_snprintf(buf + i, 2048 - i, "5:token%d:", token_len);
|
||||
- INC(i, rc, 2048);
|
||||
- COPY(buf, i, token, token_len, 2048);
|
||||
- }
|
||||
+ ben_dict_set(bencode_p, ben_blob("t", 1), ben_blob(tid, tid_len));
|
||||
+ ben_dict_set(bencode_p, ben_blob("y", 1), ben_blob("r", 1));
|
||||
+ ben_dict_set(bencode_a_p, ben_blob("id", 2), ben_blob(h->myid, 20));
|
||||
+ if (token_len) ben_dict_set(bencode_a_p, ben_blob("token", 5), ben_blob(token, token_len));
|
||||
+ if (nodes_len) ben_dict_set(bencode_a_p, ben_blob("nodes", 5), ben_blob(token, nodes_len));
|
||||
+ if (nodes6_len) ben_dict_set(bencode_a_p, ben_blob("nodes6", 6), ben_blob(token, nodes6_len));
|
||||
|
||||
+ /* its an array, how do i do this??
|
||||
+
|
||||
+Response with peers = {"t":"aa", "y":"r", "r": {"id":"abcdefghij0123456789", "token":"aoeusnth", "values": ["axje.u", "idhtnm"]}}
|
||||
+ */
|
||||
+
|
||||
+ /* TODO XXXXXX find docs and add "values" stuff into this encode
|
||||
if (st && st->numpeers > 0) {
|
||||
- /* We treat the storage as a circular list, and serve a randomly
|
||||
- chosen slice. In order to make sure we fit within 1024 octets,
|
||||
- we limit ourselves to 50 peers. */
|
||||
+ // We treat the storage as a circular list, and serve a randomly
|
||||
+ // chosen slice. In order to make sure we fit within 1024 octets,
|
||||
+ // we limit ourselves to 50 peers.
|
||||
|
||||
len = af == AF_INET ? 4 : 16;
|
||||
j0 = random() % st->numpeers;
|
||||
@@ -2582,19 +2568,13 @@ int send_nodes_peers(dht_handle_t *h, const struct sockaddr *sa, int salen,
|
||||
rc = ks_snprintf(buf + i, 2048 - i, "e");
|
||||
INC(i, rc, 2048);
|
||||
}
|
||||
-
|
||||
- rc = ks_snprintf(buf + i, 2048 - i, "e1:t%d:", tid_len);
|
||||
- INC(i, rc, 2048);
|
||||
- COPY(buf, i, tid, tid_len, 2048);
|
||||
- ADD_V(buf, i, 2048);
|
||||
- rc = ks_snprintf(buf + i, 2048 - i, "1:y1:re");
|
||||
- INC(i, rc, 2048);
|
||||
-
|
||||
- return dht_send(h, buf, i, 0, sa, salen);
|
||||
-
|
||||
- fail:
|
||||
- errno = ENOSPC;
|
||||
- return -1;
|
||||
+*/
|
||||
+ ben_dict_set(bencode_p, ben_blob("r", 1), bencode_a_p);
|
||||
+ ben_encode2(buf, 512, bencode_p);
|
||||
+ ben_free(bencode_p); /* This SHOULD free the bencode_a_p as well */
|
||||
+
|
||||
+ ks_log(KS_LOG_DEBUG, "Encoded FIND_NODE: %s\n\n", buf);
|
||||
+ return dht_send(h, buf, i, 0, sa, salen);
|
||||
}
|
||||
|
||||
static int insert_closest_node(unsigned char *nodes, int numnodes,
|
||||
@@ -2706,104 +2686,107 @@ int send_closest_nodes(dht_handle_t *h, const struct sockaddr *sa, int salen,
|
||||
af, st, token, token_len);
|
||||
}
|
||||
|
||||
+/* sample get_peers request '{"t":"aa", "y":"q", "q":"get_peers", "a": {"id":"abcdefghij0123456789", "info_hash":"mnopqrstuvwxyz123456"}}'*/
|
||||
+/* sample get_peers w/ want '{"t":"aa", "y":"q", "q":"get_peers", "a": {"id":"abcdefghij0123456789", "info_hash":"mnopqrstuvwxyz123456": "want":"n4"}}'*/
|
||||
+/* http://www.bittorrent.org/beps/bep_0005.html */
|
||||
+/* http://www.bittorrent.org/beps/bep_0032.html for want parameter */
|
||||
int send_get_peers(dht_handle_t *h, const struct sockaddr *sa, int salen,
|
||||
unsigned char *tid, int tid_len, unsigned char *infohash,
|
||||
int want, int confirm)
|
||||
{
|
||||
char buf[512];
|
||||
- int i = 0, rc;
|
||||
-
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "d1:ad2:id20:"); INC(i, rc, 512);
|
||||
- COPY(buf, i, h->myid, 20, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "9:info_hash20:"); INC(i, rc, 512);
|
||||
- COPY(buf, i, infohash, 20, 512);
|
||||
- if (want > 0) {
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "4:wantl%s%se", (want & WANT4) ? "2:n4" : "", (want & WANT6) ? "2:n6" : "");
|
||||
- INC(i, rc, 512);
|
||||
- }
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "e1:q9:get_peers1:t%d:", tid_len);
|
||||
- INC(i, rc, 512);
|
||||
- COPY(buf, i, tid, tid_len, 512);
|
||||
- ADD_V(buf, i, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "1:y1:qe"); INC(i, rc, 512);
|
||||
- return dht_send(h, buf, i, confirm ? MSG_CONFIRM : 0, sa, salen);
|
||||
+ int i = 0;
|
||||
+ struct bencode *bencode_p = ben_dict();
|
||||
+ struct bencode *bencode_a_p = ben_dict();
|
||||
+ int infohash_len = infohash ? strlen((const char*)infohash) : 0;
|
||||
|
||||
- fail:
|
||||
- errno = ENOSPC;
|
||||
- return -1;
|
||||
-}
|
||||
+ ben_dict_set(bencode_p, ben_blob("t", 1), ben_blob(tid, tid_len));
|
||||
+ ben_dict_set(bencode_p, ben_blob("y", 1), ben_blob("q", 1));
|
||||
+ ben_dict_set(bencode_p, ben_blob("q", 1), ben_blob("get_peers", 9));
|
||||
+ ben_dict_set(bencode_a_p, ben_blob("id", 2), ben_blob(h->myid, 20));
|
||||
+ if (want > 0) {
|
||||
+ char *w = NULL;
|
||||
+ if (want & WANT4) w = "n4";
|
||||
+ if (want & WANT6) w = "n6";
|
||||
+ if (w) ben_dict_set(bencode_a_p, ben_blob("want", 4), ben_blob(w, 2));
|
||||
+ }
|
||||
+ ben_dict_set(bencode_a_p, ben_blob("info_hash", 9), ben_blob(infohash, infohash_len));
|
||||
+ ben_dict_set(bencode_p, ben_blob("a", 1), bencode_a_p);
|
||||
|
||||
+ ben_encode2(buf, 512, bencode_p);
|
||||
+ ben_free(bencode_p); /* This SHOULD free the bencode_a_p as well */
|
||||
+
|
||||
+ ks_log(KS_LOG_DEBUG, "Encoded GET_PEERS: %s\n\n", buf);
|
||||
+ return dht_send(h, buf, i, confirm ? MSG_CONFIRM : 0, sa, salen);
|
||||
+}
|
||||
+/* '{"t":"aa", "y":"q", "q":"announce_peer", "a": {"id":"abcdefghij0123456789", "implied_port": 1, "info_hash":"mnopqrstuvwxyz123456", "port": 6881, "token": "aoeusnth"}}'*/
|
||||
int send_announce_peer(dht_handle_t *h, const struct sockaddr *sa, int salen,
|
||||
unsigned char *tid, int tid_len,
|
||||
unsigned char *infohash, unsigned short port,
|
||||
unsigned char *token, int token_len, int confirm)
|
||||
{
|
||||
char buf[512];
|
||||
- int i = 0, rc;
|
||||
-
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "d1:ad2:id20:"); INC(i, rc, 512);
|
||||
- COPY(buf, i, h->myid, 20, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "9:info_hash20:"); INC(i, rc, 512);
|
||||
- COPY(buf, i, infohash, 20, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "4:porti%ue5:token%d:", (unsigned)port, token_len);
|
||||
- INC(i, rc, 512);
|
||||
- COPY(buf, i, token, token_len, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "e1:q13:announce_peer1:t%d:", tid_len);
|
||||
- INC(i, rc, 512);
|
||||
- COPY(buf, i, tid, tid_len, 512);
|
||||
- ADD_V(buf, i, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "1:y1:qe"); INC(i, rc, 512);
|
||||
+ int i = 0;
|
||||
+ struct bencode *bencode_p = ben_dict();
|
||||
+ struct bencode *bencode_a_p = ben_dict();
|
||||
+ int infohash_len = infohash ? strlen((const char*)infohash) : 0;
|
||||
|
||||
- return dht_send(h, buf, i, confirm ? MSG_CONFIRM : 0, sa, salen);
|
||||
+ ben_dict_set(bencode_p, ben_blob("t", 1), ben_blob(tid, tid_len));
|
||||
+ ben_dict_set(bencode_p, ben_blob("y", 1), ben_blob("q", 1));
|
||||
+ ben_dict_set(bencode_p, ben_blob("q", 1), ben_blob("announce_peer", 13));
|
||||
+ ben_dict_set(bencode_a_p, ben_blob("id", 2), ben_blob(h->myid, 20));
|
||||
+ ben_dict_set(bencode_a_p, ben_blob("info_hash", 9), ben_blob(infohash, infohash_len));
|
||||
+ ben_dict_set(bencode_a_p, ben_blob("port", 5), ben_int(port));
|
||||
+ ben_dict_set(bencode_a_p, ben_blob("token", 5), ben_blob(token, token_len));
|
||||
+ ben_dict_set(bencode_p, ben_blob("a", 1), bencode_a_p);
|
||||
|
||||
- fail:
|
||||
- errno = ENOSPC;
|
||||
- return -1;
|
||||
+ ben_encode2(buf, 512, bencode_p);
|
||||
+ ben_free(bencode_p); /* This SHOULD free the bencode_a_p as well */
|
||||
+
|
||||
+ ks_log(KS_LOG_DEBUG, "Encoded ANNOUNCE_PEERS: %s\n\n", buf);
|
||||
+ return dht_send(h, buf, i, confirm ? MSG_CONFIRM : 0, sa, salen);
|
||||
}
|
||||
-
|
||||
+/* '{"t":"aa", "y":"r", "r": {"id":"mnopqrstuvwxyz123456"}}'*/
|
||||
static int send_peer_announced(dht_handle_t *h, const struct sockaddr *sa, int salen, unsigned char *tid, int tid_len)
|
||||
{
|
||||
char buf[512];
|
||||
- int i = 0, rc;
|
||||
-
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "d1:rd2:id20:");
|
||||
- INC(i, rc, 512);
|
||||
- COPY(buf, i, h->myid, 20, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "e1:t%d:", tid_len);
|
||||
- INC(i, rc, 512);
|
||||
- COPY(buf, i, tid, tid_len, 512);
|
||||
- ADD_V(buf, i, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "1:y1:re");
|
||||
- INC(i, rc, 512);
|
||||
- return dht_send(h, buf, i, 0, sa, salen);
|
||||
+ int i = 0;
|
||||
+ struct bencode *bencode_p = ben_dict();
|
||||
+ struct bencode *bencode_a_p = ben_dict();
|
||||
|
||||
- fail:
|
||||
- errno = ENOSPC;
|
||||
- return -1;
|
||||
+ ben_dict_set(bencode_p, ben_blob("t", 1), ben_blob(tid, tid_len));
|
||||
+ ben_dict_set(bencode_p, ben_blob("y", 1), ben_blob("r", 1));
|
||||
+ ben_dict_set(bencode_a_p, ben_blob("id", 2), ben_blob(h->myid, 20));
|
||||
+ ben_dict_set(bencode_p, ben_blob("r", 1), bencode_a_p);
|
||||
+
|
||||
+ ben_encode2(buf, 512, bencode_p);
|
||||
+ ben_free(bencode_p); /* This SHOULD free the bencode_a_p as well */
|
||||
+
|
||||
+ ks_log(KS_LOG_DEBUG, "Encoded peer_announced: %s\n\n", buf);
|
||||
+ return dht_send(h, buf, i, 0, sa, salen);
|
||||
}
|
||||
|
||||
+/* '{"t":"aa", "y":"e", "e":[201, "A Generic Error Ocurred"]}'*/
|
||||
static int send_error(dht_handle_t *h, const struct sockaddr *sa, int salen,
|
||||
unsigned char *tid, int tid_len,
|
||||
int code, const char *message)
|
||||
{
|
||||
char buf[512];
|
||||
- int i = 0, rc, message_len;
|
||||
-
|
||||
- message_len = strlen(message);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "d1:eli%de%d:", code, message_len);
|
||||
- INC(i, rc, 512);
|
||||
- COPY(buf, i, message, message_len, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "e1:t%d:", tid_len);
|
||||
- INC(i, rc, 512);
|
||||
- COPY(buf, i, tid, tid_len, 512);
|
||||
- ADD_V(buf, i, 512);
|
||||
- rc = ks_snprintf(buf + i, 512 - i, "1:y1:ee");
|
||||
- INC(i, rc, 512);
|
||||
- return dht_send(h, buf, i, 0, sa, salen);
|
||||
+ int i = 0;
|
||||
+ struct bencode *bencode_p = ben_dict();
|
||||
+ struct bencode *ben_array = ben_list();
|
||||
|
||||
- fail:
|
||||
- errno = ENOSPC;
|
||||
- return -1;
|
||||
+ ben_dict_set(bencode_p, ben_blob("t", 1), ben_blob(tid, tid_len));
|
||||
+ ben_dict_set(bencode_p, ben_blob("y", 1), ben_blob("e", 1));
|
||||
+ ben_list_append(ben_array, ben_int(code));
|
||||
+ ben_list_append(ben_array, ben_blob(message, strlen(message)));
|
||||
+ ben_dict_set(bencode_p, ben_blob("e", 1), ben_array);
|
||||
+
|
||||
+ ben_encode2(buf, 512, bencode_p);
|
||||
+ ben_free(bencode_p);
|
||||
+
|
||||
+ ks_log(KS_LOG_DEBUG, "Encoded error: %s\n\n", buf);
|
||||
+ return dht_send(h, buf, i, 0, sa, salen);
|
||||
}
|
||||
|
||||
#undef CHECK
|
|
@ -54,37 +54,7 @@ testwebsock_SOURCES = testwebsock.c tap.c
|
|||
testwebsock_CFLAGS = $(AM_CFLAGS)
|
||||
testwebsock_LDADD = $(TEST_LDADD)
|
||||
|
||||
#check_PROGRAMS += testdht
|
||||
#testdht_SOURCES = testdht.c tap.c
|
||||
#testdht_CFLAGS = $(AM_CFLAGS)
|
||||
#testdht_LDADD = $(TEST_LDADD)
|
||||
|
||||
#check_PROGRAMS += testdht_net
|
||||
#testdht_net_SOURCES = testdht-net.c tap.c
|
||||
#testdht_net_CFLAGS = $(AM_CFLAGS)
|
||||
#testdht_net_LDADD = $(TEST_LDADD)
|
||||
|
||||
#check_PROGRAMS += testdht_msg
|
||||
#testdht_msg_SOURCES = testdht-msg.c tap.c
|
||||
#testdht_msg_CFLAGS = $(AM_CFLAGS)
|
||||
#testdht_msg_LDADD = $(TEST_LDADD)
|
||||
|
||||
#check_PROGRAMS += dht_example
|
||||
#dht_example_SOURCES = dht-example.c
|
||||
#dht_example_CFLAGS = $(AM_CFLAGS)
|
||||
#dht_example_LDADD = $(abs_top_builddir)/libks.la $(openssl_LIBS) -ledit -lpthread
|
||||
|
||||
#check_PROGRAMS += libtorrent_example
|
||||
#libtorrent_example_SOURCES = libtorrent-example.c
|
||||
#libtorrent_example_CFLAGS = $(AM_CFLAGS)
|
||||
#libtorrent_example_LDADD = $(abs_top_builddir)/libks.la $(abs_top_builddir)/test/libtorrent.so /usr/lib/x86_64-linux-gnu/libboost_system.a $(openssl_LIBS) -ledit -lpthread -ltorrent-rasterbar -lstdc++
|
||||
|
||||
TESTS=$(check_PROGRAMS)
|
||||
|
||||
tests: $(check_PROGRAMS)
|
||||
|
||||
$(abs_top_builddir)/test/libtorrent.so: $(abs_top_builddir)/test/libtorrent.o
|
||||
g++ -shared -o $(abs_top_builddir)/test/libtorrent.so $(abs_top_builddir)/test/libtorrent.o
|
||||
|
||||
$(abs_top_builddir)/test/libtorrent.o: $(abs_top_builddir)/test/libtorrent.cpp
|
||||
g++ -c -fPIC -o $(abs_top_builddir)/test/libtorrent.o -I$(abs_top_builddir)/test/ $(abs_top_builddir)/test/libtorrent.cpp
|
||||
|
|
|
@ -1,409 +0,0 @@
|
|||
/* This example code was written by Juliusz Chroboczek.
|
||||
You are free to cut'n'paste from it to your heart's content. */
|
||||
|
||||
/* For crypt */
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
#include "ks.h"
|
||||
#include "histedit.h"
|
||||
#include "sodium.h"
|
||||
|
||||
#define MAX_BOOTSTRAP_NODES 20
|
||||
static ks_sockaddr_t bootstrap_nodes[MAX_BOOTSTRAP_NODES];
|
||||
static ks_sockaddr_t bind_nodes[MAX_BOOTSTRAP_NODES];
|
||||
static int num_bootstrap_nodes = 0;
|
||||
static int num_bind_nodes = 0;
|
||||
|
||||
/* The call-back function is called by the DHT whenever something
|
||||
interesting happens. Right now, it only happens when we get a new value or
|
||||
when a search completes, but this may be extended in future versions. */
|
||||
static void callback(void *closure, ks_dht_event_t event, const unsigned char *info_hash, const void *data, size_t data_len)
|
||||
{
|
||||
if(event == KS_DHT_EVENT_SEARCH_DONE) {
|
||||
printf("Search done.\n");
|
||||
} else if(event == KS_DHT_EVENT_VALUES) {
|
||||
const uint8_t *bits_8 = data;
|
||||
const uint16_t *bits_16 = data;
|
||||
|
||||
printf("Received %d values.\n", (int)(data_len / 6));
|
||||
printf("Recieved %u.%u.%u.%u:%u\n", bits_8[0], bits_8[1], bits_8[2], bits_8[3], ntohs(bits_16[2]));
|
||||
} else {
|
||||
printf("Unhandled event %d\n", event);
|
||||
}
|
||||
}
|
||||
|
||||
void json_cb(struct dht_handle_s *h, const cJSON *msg, void *arg)
|
||||
{
|
||||
char *pretty = cJSON_Print((cJSON *)msg);
|
||||
|
||||
printf("Received json msg: %s\n", pretty);
|
||||
|
||||
free(pretty);
|
||||
}
|
||||
|
||||
static char * prompt(EditLine *e) {
|
||||
return "dht> ";
|
||||
}
|
||||
|
||||
static dht_handle_t *h;
|
||||
|
||||
|
||||
typedef struct dht_globals_s {
|
||||
int s;
|
||||
int s6;
|
||||
int port;
|
||||
int exiting;
|
||||
} dht_globals_t;
|
||||
|
||||
void *dht_event_thread(ks_thread_t *thread, void *data)
|
||||
{
|
||||
dht_globals_t *globals = data;
|
||||
|
||||
while(!globals->exiting) {
|
||||
ks_dht_one_loop(h, 0);
|
||||
ks_sleep(1000000);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
dht_globals_t globals = {0};
|
||||
int i;
|
||||
//int have_id = 0;
|
||||
//char *id_file = "dht-example.id";
|
||||
int ipv4 = 0, ipv6 = 0;
|
||||
int autobind = 0;
|
||||
int opt;
|
||||
EditLine *el;
|
||||
History *myhistory;
|
||||
int count;
|
||||
const char *line;
|
||||
HistEvent ev;
|
||||
ks_status_t status;
|
||||
static ks_thread_t *threads[1]; /* Main dht event thread */
|
||||
ks_pool_t *pool;
|
||||
int err = 0;
|
||||
unsigned char alice_publickey[crypto_sign_PUBLICKEYBYTES] = {0};
|
||||
unsigned char alice_secretkey[crypto_sign_SECRETKEYBYTES] = {0};
|
||||
|
||||
ks_init();
|
||||
|
||||
el = el_init("test", stdin, stdout, stderr);
|
||||
el_set(el, EL_PROMPT, &prompt);
|
||||
el_set(el, EL_EDITOR, "emacs");
|
||||
myhistory = history_init();
|
||||
history(myhistory, &ev, H_SETSIZE, 800);
|
||||
el_set(el, EL_HIST, history, myhistory);
|
||||
globals.port = 5309;
|
||||
|
||||
|
||||
ks_global_set_default_logger(7);
|
||||
|
||||
while(1) {
|
||||
opt = getopt(argc, argv, "46ap:b:B:");
|
||||
if(opt < 0)
|
||||
break;
|
||||
|
||||
switch(opt) {
|
||||
case '4':
|
||||
ipv4 = 1;
|
||||
break;
|
||||
case '6':
|
||||
ipv6 = 1;
|
||||
break;
|
||||
case 'a':
|
||||
autobind = 1;
|
||||
break;
|
||||
case 'p':
|
||||
globals.port = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
case 'B': {
|
||||
char ip[80];
|
||||
int port = globals.port;
|
||||
char *p;
|
||||
ks_set_string(ip, optarg);
|
||||
|
||||
if ((p = strchr(ip, '+'))) {
|
||||
*p++ = '\0';
|
||||
port = atoi(p);
|
||||
}
|
||||
if (opt == 'B') {
|
||||
printf("Adding bootstrap node %s:%d\n", ip, port);
|
||||
ks_addr_set(&bootstrap_nodes[num_bootstrap_nodes++], ip, port, 0);
|
||||
} else {
|
||||
printf("Adding binding %s:%d\n", ip, port);
|
||||
ks_addr_set(&bind_nodes[num_bind_nodes++], ip, port, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if(argc < 2)
|
||||
goto usage;
|
||||
|
||||
i = optind;
|
||||
|
||||
if(globals.port <= 0 || globals.port >= 0x10000)
|
||||
goto usage;
|
||||
|
||||
|
||||
ks_dht_af_flag_t af_flags = 0;
|
||||
|
||||
if (ipv4) {
|
||||
af_flags |= KS_DHT_AF_INET4;
|
||||
}
|
||||
|
||||
if (ipv6) {
|
||||
af_flags |= KS_DHT_AF_INET6;
|
||||
}
|
||||
|
||||
/* Init the dht. */
|
||||
status = ks_dht_init(&h, af_flags, NULL, globals.port);
|
||||
|
||||
if(status != KS_STATUS_SUCCESS) {
|
||||
perror("dht_init");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for(i = 0; i < num_bind_nodes; i++) {
|
||||
ks_dht_add_ip(h, bind_nodes[i].host, bind_nodes[i].port);
|
||||
}
|
||||
|
||||
if (autobind) {
|
||||
ks_dht_set_param(h, DHT_PARAM_AUTOROUTE, KS_TRUE);
|
||||
}
|
||||
|
||||
ks_dht_start(h);
|
||||
|
||||
ks_dht_set_callback(h, callback, NULL);
|
||||
|
||||
ks_pool_open(&pool);
|
||||
status = ks_thread_create_ex(&threads[0], dht_event_thread, &globals, KS_THREAD_FLAG_DETATCHED, KS_THREAD_DEFAULT_STACK, KS_PRI_NORMAL, pool);
|
||||
|
||||
if ( status != KS_STATUS_SUCCESS) {
|
||||
printf("Failed to start DHT event thread\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* For bootstrapping, we need an initial list of nodes. This could be
|
||||
hard-wired, but can also be obtained from the nodes key of a torrent
|
||||
file, or from the PORT bittorrent message.
|
||||
|
||||
Dht_ping_node is the brutal way of bootstrapping -- it actually
|
||||
sends a message to the peer. If you're going to bootstrap from
|
||||
a massive number of nodes (for example because you're restoring from
|
||||
a dump) and you already know their ids, it's better to use
|
||||
dht_insert_node. If the ids are incorrect, the DHT will recover. */
|
||||
for(i = 0; i < num_bootstrap_nodes; i++) {
|
||||
dht_ping_node(h, &bootstrap_nodes[i]);
|
||||
usleep(random() % 100000);
|
||||
}
|
||||
|
||||
printf("TESTING!!!\n");
|
||||
err = crypto_sign_keypair(alice_publickey, alice_secretkey);
|
||||
printf("Result of generating keypair %d\n", err);
|
||||
|
||||
ks_dht_store_entry_json_cb_set(h, json_cb, NULL);
|
||||
|
||||
while ( !globals.exiting ) {
|
||||
line = el_gets(el, &count);
|
||||
|
||||
if (count > 1) {
|
||||
int line_len = (int)strlen(line) - 1;
|
||||
char *cmd_dup = strdup(line);
|
||||
char *argv[8] = { 0 };
|
||||
int argc = 0;
|
||||
|
||||
history(myhistory, &ev, H_ENTER, line);
|
||||
|
||||
if ( cmd_dup[line_len] == '\n' ) {
|
||||
cmd_dup[line_len] = '\0';
|
||||
}
|
||||
argc = ks_separate_string(cmd_dup, " ", argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
|
||||
if (!strncmp(line, "quit", 4)) {
|
||||
globals.exiting = 1;
|
||||
} else if (!strncmp(line, "show_bind", 9)) {
|
||||
const ks_sockaddr_t **bindings;
|
||||
ks_size_t len = 0;
|
||||
int i;
|
||||
|
||||
ks_dht_get_bind_addrs(h, &bindings, &len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
printf("Bind addr %s:%d\n", bindings[i]->host, bindings[i]->port);
|
||||
}
|
||||
|
||||
} else if (!strncmp(line, "ping ", 5)) {
|
||||
const char *ip = line + 5;
|
||||
ks_sockaddr_t tmp;
|
||||
char *p;
|
||||
|
||||
while ((p = strchr(ip, '\r')) || (p = strchr(ip, '\n'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
ks_addr_set(&tmp, ip, globals.port, 0);
|
||||
dht_ping_node(h, &tmp);
|
||||
} else if (!strncmp(line, "find_node ", 9)) {
|
||||
/* usage: find_node ipv[4|6] [40 character node id] [40 character target id] */
|
||||
ks_bool_t ipv6 = strncmp(argv[1], "ipv4", 4);
|
||||
(void) argc; /* Check to see if it's the right length, else print usage */
|
||||
ks_dht_api_find_node(h, argv[2], argv[3], ipv6);
|
||||
} else if (!strncmp(line, "loglevel", 8)) {
|
||||
ks_global_set_default_logger(atoi(line + 9));
|
||||
} else if (!strncmp(line, "peer_dump", 9)) {
|
||||
dht_dump_tables(h, stdout);
|
||||
} else if (!strncmp(line, "generate_identity", 17)) {
|
||||
/* usage: generate_identity [identity key: first_id] */
|
||||
/* requires an arg, checks identity hash for arg value.
|
||||
|
||||
if found, return already exists.
|
||||
if not found, generate sodium public and private keys, and insert into identities hash.
|
||||
*/
|
||||
} else if (!strncmp(line, "print_identity_key", 18)) {
|
||||
/* usage: print_identity_key [identity key] */
|
||||
} else if (!strncmp(line, "message_mutable", 15)) {
|
||||
char *input = strdup(line);
|
||||
char *identity_key = input + 16;
|
||||
char *identities[2] = { identity_key, NULL };
|
||||
char *message_id = NULL;
|
||||
char *message = NULL;
|
||||
cJSON *output = NULL;
|
||||
int idx = 17; /* this should be the start of the message_id */
|
||||
for ( idx = 17; idx < 100 && input[idx] != '\0'; idx++ ) {
|
||||
if ( input[idx] == ' ' ) {
|
||||
input[idx] = '\0';
|
||||
message_id = input + 1 + idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for ( idx++; idx < 100 && input[idx] != '\0'; idx++ ) {
|
||||
if ( input[idx] == ' ' ) {
|
||||
input[idx] = '\0';
|
||||
message = input + 1 + idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hack for my testing, so that it chomps the new line. Makes debugging print nicer. */
|
||||
for ( idx++; input[idx] != '\0'; idx++) {
|
||||
if ( input[idx] == '\n' ) {
|
||||
input[idx] = '\0';
|
||||
}
|
||||
}
|
||||
/* usage: message_mutable [identity key] [message id: asdf] [your message: Hello from DHT example]*/
|
||||
/*
|
||||
takes an identity, a message id(salt) and a message, then sends out the announcement.
|
||||
*/
|
||||
output = cJSON_CreateString(message);
|
||||
|
||||
ks_dht_send_message_mutable_cjson(h, alice_secretkey, alice_publickey,
|
||||
identities, message_id, 1, output, 600);
|
||||
free(input);
|
||||
cJSON_Delete(output);
|
||||
} else if (!strncmp(line, "message_immutable", 15)) {
|
||||
/* usage: message_immutable [identity key] */
|
||||
/*
|
||||
takes an identity, and a message, then sends out the announcement.
|
||||
*/
|
||||
} else if (!strncmp(line, "message_get", 11)) {
|
||||
/* usage: message_get [40 character sha1 digest b64 encoded]*/
|
||||
|
||||
/* MUST RETURN BENCODE OBJECT */
|
||||
} else if (!strncmp(line, "message_get_mine", 16)) {
|
||||
/* usage: message_get [identity key] [message id: asdf]*/
|
||||
/* This looks up the message token from identity key and the message id(aka message salt) */
|
||||
|
||||
/* MUST RETURN BENCODE OBJECT */
|
||||
} else if (!strncmp(line, "add_buddy", 9)) {
|
||||
/* usage: add_buddy [buddy key] [buddy public key] */
|
||||
|
||||
} else if (!strncmp(line, "get_buddy_message", 17)) {
|
||||
/* usage: get_buddy_message [buddy key] [buddy message_id] */
|
||||
|
||||
|
||||
} else if (!strncmp(line, "search", 6)) {
|
||||
if ( line_len > 7 ) {
|
||||
unsigned char hash[20];
|
||||
memcpy(hash, line + 7, 20);
|
||||
|
||||
if(globals.s >= 0) {
|
||||
dht_search(h, hash, 0, AF_INET, callback, NULL);
|
||||
}
|
||||
} else {
|
||||
printf("Your search string isn't a valid 20 character hash. You entered [%.*s] of length %d\n", line_len - 7, line + 7, line_len - 7);
|
||||
}
|
||||
} else if (!strncmp(line, "announce", 8)) {
|
||||
if ( line_len == 29 ) {
|
||||
unsigned char hash[20];
|
||||
memcpy(hash, line + 9, 20);
|
||||
|
||||
if(globals.s >= 0) {
|
||||
dht_search(h, hash, globals.port, AF_INET, callback, NULL);
|
||||
}
|
||||
} else {
|
||||
printf("Your search string isn't a valid 20 character hash. You entered [%.*s]\n", line_len - 7, line + 7);
|
||||
}
|
||||
} else {
|
||||
printf("Unknown command entered[%.*s]\n", line_len, line);
|
||||
}
|
||||
|
||||
free(cmd_dup);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
struct sockaddr_in sin[500];
|
||||
struct sockaddr_in6 sin6[500];
|
||||
int num = 500, num6 = 500;
|
||||
int i;
|
||||
i = dht_get_nodes(h, sin, &num, sin6, &num6);
|
||||
printf("Found %d (%d + %d) good nodes.\n", i, num, num6);
|
||||
}
|
||||
|
||||
|
||||
history_end(myhistory);
|
||||
el_end(el);
|
||||
dht_uninit(&h);
|
||||
ks_shutdown();
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
printf("Usage: dht-example [-a] [-4] [-6] [-p <port>] [-b <ip>[+<port>]]...\n"
|
||||
" [-B <ip>[+<port>]]...\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
||||
*/
|
|
@ -1,120 +0,0 @@
|
|||
/* This example code was written by Juliusz Chroboczek.
|
||||
You are free to cut'n'paste from it to your heart's content. */
|
||||
|
||||
/* For crypt */
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
#include "ks.h"
|
||||
#include "histedit.h"
|
||||
#include "libtorrent.h"
|
||||
|
||||
static char * prompt(EditLine *e) {
|
||||
return "dht> ";
|
||||
}
|
||||
|
||||
typedef struct dht_globals_s {
|
||||
int exiting;
|
||||
} dht_globals_t;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
dht_globals_t globals = {0};
|
||||
int opt;
|
||||
EditLine *el;
|
||||
History *myhistory;
|
||||
int count;
|
||||
const char *line;
|
||||
HistEvent ev;
|
||||
ks_status_t status = KS_STATUS_SUCCESS;
|
||||
// ks_pool_t *pool;
|
||||
void *session = session_create(SES_LISTENPORT, 8090,
|
||||
SES_LISTENPORT_END, 8098,
|
||||
TAG_END);
|
||||
|
||||
session_start_dht(session);
|
||||
|
||||
|
||||
globals.exiting = 0;
|
||||
|
||||
el = el_init("test", stdin, stdout, stderr);
|
||||
el_set(el, EL_PROMPT, &prompt);
|
||||
el_set(el, EL_EDITOR, "emacs");
|
||||
myhistory = history_init();
|
||||
history(myhistory, &ev, H_SETSIZE, 800);
|
||||
el_set(el, EL_HIST, history, myhistory);
|
||||
|
||||
ks_global_set_default_logger(7);
|
||||
|
||||
while(1) {
|
||||
opt = getopt(argc, argv, "hb:");
|
||||
if(opt < 0)
|
||||
break;
|
||||
|
||||
switch(opt) {
|
||||
case 'b': {
|
||||
printf("Not yet implemented\n");
|
||||
goto usage;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ks_pool_open(&pool);
|
||||
status = ks_thread_create_ex(&threads[0], dht_event_thread, &globals, KS_THREAD_FLAG_DETATCHED, KS_THREAD_DEFAULT_STACK, KS_PRI_NORMAL, pool);
|
||||
*/
|
||||
|
||||
if ( status != KS_STATUS_SUCCESS) {
|
||||
printf("Failed to start DHT event thread\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while ( !globals.exiting ) {
|
||||
line = el_gets(el, &count);
|
||||
|
||||
if (count > 1) {
|
||||
int line_len = (int)strlen(line) - 1;
|
||||
history(myhistory, &ev, H_ENTER, line);
|
||||
|
||||
if (!strncmp(line, "quit", 4)) {
|
||||
globals.exiting = 1;
|
||||
} else if (!strncmp(line, "loglevel", 8)) {
|
||||
ks_global_set_default_logger(atoi(line + 9));
|
||||
} else if (!strncmp(line, "peer_dump", 9)) {
|
||||
printf("Not yet implemented\n");
|
||||
} else if (!strncmp(line, "search", 6)) {
|
||||
printf("Not yet implemented\n");
|
||||
} else if (!strncmp(line, "announce", 8)) {
|
||||
printf("Not yet implemented\n");
|
||||
} else {
|
||||
printf("Unknown command entered[%.*s]\n", line_len, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
history_end(myhistory);
|
||||
el_end(el);
|
||||
session_close(session);
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
printf("Usage: dht-example [-4] [-6] [-i filename] [-b address]...\n"
|
||||
" port [address port]...\n");
|
||||
exit(1);
|
||||
}
|
|
@ -1,601 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2009, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "libtorrent/session.hpp"
|
||||
#include "libtorrent/magnet_uri.hpp"
|
||||
#include "libtorrent/torrent_handle.hpp"
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <libtorrent.h>
|
||||
#include <cstdarg>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::vector<libtorrent::torrent_handle> handles;
|
||||
|
||||
int find_handle(libtorrent::torrent_handle h)
|
||||
{
|
||||
std::vector<libtorrent::torrent_handle>::const_iterator i
|
||||
= std::find(handles.begin(), handles.end(), h);
|
||||
if (i == handles.end()) return -1;
|
||||
return i - handles.begin();
|
||||
}
|
||||
|
||||
libtorrent::torrent_handle get_handle(int i)
|
||||
{
|
||||
if (i < 0 || i >= int(handles.size())) return libtorrent::torrent_handle();
|
||||
return handles[i];
|
||||
}
|
||||
|
||||
int add_handle(libtorrent::torrent_handle const& h)
|
||||
{
|
||||
std::vector<libtorrent::torrent_handle>::iterator i = std::find_if(handles.begin()
|
||||
, handles.end(), !boost::bind(&libtorrent::torrent_handle::is_valid, _1));
|
||||
if (i != handles.end())
|
||||
{
|
||||
*i = h;
|
||||
return i - handles.begin();
|
||||
}
|
||||
|
||||
handles.push_back(h);
|
||||
return handles.size() - 1;
|
||||
}
|
||||
|
||||
int set_int_value(void* dst, int* size, int val)
|
||||
{
|
||||
if ( *size < (int) sizeof(int)) return -2;
|
||||
*((int*)dst) = val;
|
||||
*size = (int) sizeof(int);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void copy_proxy_setting(libtorrent::proxy_settings* s, proxy_setting const* ps)
|
||||
{
|
||||
s->hostname.assign(ps->hostname);
|
||||
s->port = ps->port;
|
||||
s->username.assign(ps->username);
|
||||
s->password.assign(ps->password);
|
||||
s->type = (libtorrent::proxy_settings::proxy_type)ps->type;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
TORRENT_EXPORT void* session_create(int tag, ...)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
va_list lp;
|
||||
va_start(lp, tag);
|
||||
|
||||
fingerprint fing("LT", LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR, 0, 0);
|
||||
std::pair<int, int> listen_range(-1, -1);
|
||||
char const* listen_interface = "0.0.0.0";
|
||||
int flags = session::start_default_features | session::add_default_plugins;
|
||||
int alert_mask = alert::error_notification;
|
||||
|
||||
while (tag != TAG_END)
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case SES_FINGERPRINT:
|
||||
{
|
||||
char const* f = va_arg(lp, char const*);
|
||||
fing.name[0] = f[0];
|
||||
fing.name[1] = f[1];
|
||||
break;
|
||||
}
|
||||
case SES_LISTENPORT:
|
||||
listen_range.first = va_arg(lp, int);
|
||||
break;
|
||||
case SES_LISTENPORT_END:
|
||||
listen_range.second = va_arg(lp, int);
|
||||
break;
|
||||
case SES_VERSION_MAJOR:
|
||||
fing.major_version = va_arg(lp, int);
|
||||
break;
|
||||
case SES_VERSION_MINOR:
|
||||
fing.minor_version = va_arg(lp, int);
|
||||
break;
|
||||
case SES_VERSION_TINY:
|
||||
fing.revision_version = va_arg(lp, int);
|
||||
break;
|
||||
case SES_VERSION_TAG:
|
||||
fing.tag_version = va_arg(lp, int);
|
||||
break;
|
||||
case SES_FLAGS:
|
||||
flags = va_arg(lp, int);
|
||||
break;
|
||||
case SES_ALERT_MASK:
|
||||
alert_mask = va_arg(lp, int);
|
||||
break;
|
||||
case SES_LISTEN_INTERFACE:
|
||||
listen_interface = va_arg(lp, char const*);
|
||||
break;
|
||||
default:
|
||||
// skip unknown tags
|
||||
va_arg(lp, void*);
|
||||
break;
|
||||
}
|
||||
|
||||
tag = va_arg(lp, int);
|
||||
}
|
||||
|
||||
if (listen_range.first != -1 && (listen_range.second == -1
|
||||
|| listen_range.second < listen_range.first))
|
||||
listen_range.second = listen_range.first;
|
||||
|
||||
return new (std::nothrow) session(fing, listen_range, listen_interface, flags, alert_mask);
|
||||
}
|
||||
|
||||
TORRENT_EXPORT void session_close(void* ses)
|
||||
{
|
||||
delete (libtorrent::session*)ses;
|
||||
}
|
||||
|
||||
TORRENT_EXPORT void session_start_dht(void *ses)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
session *s = (session*) ses;
|
||||
|
||||
s->start_dht();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
TORRENT_EXPORT int session_add_torrent(void* ses, int tag, ...)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
va_list lp;
|
||||
va_start(lp, tag);
|
||||
session* s = (session*)ses;
|
||||
add_torrent_params params;
|
||||
|
||||
char const* torrent_data = 0;
|
||||
int torrent_size = 0;
|
||||
|
||||
char const* resume_data = 0;
|
||||
int resume_size = 0;
|
||||
|
||||
char const* magnet_url = 0;
|
||||
|
||||
error_code ec;
|
||||
|
||||
while (tag != TAG_END)
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case TOR_FILENAME:
|
||||
params.ti = new (std::nothrow) torrent_info(va_arg(lp, char const*), ec);
|
||||
break;
|
||||
case TOR_TORRENT:
|
||||
torrent_data = va_arg(lp, char const*);
|
||||
break;
|
||||
case TOR_TORRENT_SIZE:
|
||||
torrent_size = va_arg(lp, int);
|
||||
break;
|
||||
case TOR_INFOHASH:
|
||||
params.ti = new (std::nothrow) torrent_info(sha1_hash(va_arg(lp, char const*)));
|
||||
break;
|
||||
case TOR_INFOHASH_HEX:
|
||||
{
|
||||
sha1_hash ih;
|
||||
from_hex(va_arg(lp, char const*), 40, (char*)&ih[0]);
|
||||
params.ti = new (std::nothrow) torrent_info(ih);
|
||||
break;
|
||||
}
|
||||
case TOR_MAGNETLINK:
|
||||
magnet_url = va_arg(lp, char const*);
|
||||
break;
|
||||
case TOR_TRACKER_URL:
|
||||
params.tracker_url = va_arg(lp, char const*);
|
||||
break;
|
||||
case TOR_RESUME_DATA:
|
||||
resume_data = va_arg(lp, char const*);
|
||||
break;
|
||||
case TOR_RESUME_DATA_SIZE:
|
||||
resume_size = va_arg(lp, int);
|
||||
break;
|
||||
case TOR_SAVE_PATH:
|
||||
params.save_path = va_arg(lp, char const*);
|
||||
break;
|
||||
case TOR_NAME:
|
||||
params.name = va_arg(lp, char const*);
|
||||
break;
|
||||
case TOR_PAUSED:
|
||||
params.paused = va_arg(lp, int) != 0;
|
||||
break;
|
||||
case TOR_AUTO_MANAGED:
|
||||
params.auto_managed = va_arg(lp, int) != 0;
|
||||
break;
|
||||
case TOR_DUPLICATE_IS_ERROR:
|
||||
params.duplicate_is_error = va_arg(lp, int) != 0;
|
||||
break;
|
||||
case TOR_USER_DATA:
|
||||
params.userdata = va_arg(lp, void*);
|
||||
break;
|
||||
case TOR_SEED_MODE:
|
||||
params.seed_mode = va_arg(lp, int) != 0;
|
||||
break;
|
||||
case TOR_OVERRIDE_RESUME_DATA:
|
||||
params.override_resume_data = va_arg(lp, int) != 0;
|
||||
break;
|
||||
case TOR_STORAGE_MODE:
|
||||
params.storage_mode = (libtorrent::storage_mode_t)va_arg(lp, int);
|
||||
break;
|
||||
default:
|
||||
// ignore unknown tags
|
||||
va_arg(lp, void*);
|
||||
break;
|
||||
}
|
||||
|
||||
tag = va_arg(lp, int);
|
||||
}
|
||||
|
||||
if (!params.ti && torrent_data && torrent_size)
|
||||
params.ti = new (std::nothrow) torrent_info(torrent_data, torrent_size);
|
||||
|
||||
std::vector<char> rd;
|
||||
if (resume_data && resume_size)
|
||||
{
|
||||
rd.assign(resume_data, resume_data + resume_size);
|
||||
params.resume_data = &rd;
|
||||
}
|
||||
torrent_handle h;
|
||||
if (!params.ti && magnet_url)
|
||||
{
|
||||
h = add_magnet_uri(*s, magnet_url, params, ec);
|
||||
}
|
||||
else
|
||||
{
|
||||
h = s->add_torrent(params, ec);
|
||||
}
|
||||
|
||||
if (!h.is_valid())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int i = find_handle(h);
|
||||
if (i == -1) i = add_handle(h);
|
||||
|
||||
return i;
|
||||
}
|
||||
*/
|
||||
void session_remove_torrent(void* ses, int tor, int flags)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
torrent_handle h = get_handle(tor);
|
||||
if (!h.is_valid()) return;
|
||||
|
||||
session* s = (session*)ses;
|
||||
s->remove_torrent(h, flags);
|
||||
}
|
||||
|
||||
int session_set_settings(void* ses, int tag, ...)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
// session* s = (session*)ses;
|
||||
|
||||
va_list lp;
|
||||
va_start(lp, tag);
|
||||
|
||||
while (tag != TAG_END)
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
/*
|
||||
case SET_UPLOAD_RATE_LIMIT:
|
||||
s->set_upload_rate_limit(va_arg(lp, int));
|
||||
break;
|
||||
case SET_DOWNLOAD_RATE_LIMIT:
|
||||
s->set_download_rate_limit(va_arg(lp, int));
|
||||
break;
|
||||
case SET_LOCAL_UPLOAD_RATE_LIMIT:
|
||||
s->set_local_upload_rate_limit(va_arg(lp, int));
|
||||
break;
|
||||
case SET_LOCAL_DOWNLOAD_RATE_LIMIT:
|
||||
s->set_local_download_rate_limit(va_arg(lp, int));
|
||||
break;
|
||||
case SET_MAX_UPLOAD_SLOTS:
|
||||
s->set_max_uploads(va_arg(lp, int));
|
||||
break;
|
||||
case SET_MAX_CONNECTIONS:
|
||||
s->set_max_connections(va_arg(lp, int));
|
||||
break;
|
||||
case SET_HALF_OPEN_LIMIT:
|
||||
s->set_max_half_open_connections(va_arg(lp, int));
|
||||
break;
|
||||
case SET_PEER_PROXY:
|
||||
{
|
||||
libtorrent::proxy_settings ps;
|
||||
copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*));
|
||||
s->set_peer_proxy(ps);
|
||||
}
|
||||
case SET_WEB_SEED_PROXY:
|
||||
{
|
||||
libtorrent::proxy_settings ps;
|
||||
copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*));
|
||||
s->set_web_seed_proxy(ps);
|
||||
}
|
||||
case SET_TRACKER_PROXY:
|
||||
{
|
||||
libtorrent::proxy_settings ps;
|
||||
copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*));
|
||||
s->set_tracker_proxy(ps);
|
||||
}
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
case SET_DHT_PROXY:
|
||||
{
|
||||
libtorrent::proxy_settings ps;
|
||||
copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*));
|
||||
s->set_dht_proxy(ps);
|
||||
}
|
||||
#endif
|
||||
case SET_PROXY:
|
||||
{
|
||||
libtorrent::proxy_settings ps;
|
||||
copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*));
|
||||
s->set_peer_proxy(ps);
|
||||
s->set_web_seed_proxy(ps);
|
||||
s->set_tracker_proxy(ps);
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
s->set_dht_proxy(ps);
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
default:
|
||||
// ignore unknown tags
|
||||
va_arg(lp, void*);
|
||||
break;
|
||||
}
|
||||
|
||||
tag = va_arg(lp, int);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int session_get_setting(void* ses, int tag, void* value, int* value_size)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
// session* s = (session*)ses;
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
/*
|
||||
case SET_UPLOAD_RATE_LIMIT:
|
||||
return set_int_value(value, value_size, s->upload_rate_limit());
|
||||
case SET_DOWNLOAD_RATE_LIMIT:
|
||||
return set_int_value(value, value_size, s->download_rate_limit());
|
||||
case SET_LOCAL_UPLOAD_RATE_LIMIT:
|
||||
return set_int_value(value, value_size, s->local_upload_rate_limit());
|
||||
case SET_LOCAL_DOWNLOAD_RATE_LIMIT:
|
||||
return set_int_value(value, value_size, s->local_download_rate_limit());
|
||||
case SET_MAX_UPLOAD_SLOTS:
|
||||
return set_int_value(value, value_size, s->max_uploads());
|
||||
case SET_MAX_CONNECTIONS:
|
||||
return set_int_value(value, value_size, s->max_connections());
|
||||
case SET_HALF_OPEN_LIMIT:
|
||||
return set_int_value(value, value_size, s->max_half_open_connections());
|
||||
*/
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
int session_get_status(void* sesptr, struct session_status* s, int struct_size)
|
||||
{
|
||||
libtorrent::session* ses = (libtorrent::session*)sesptr;
|
||||
|
||||
libtorrent::session_status ss = ses->status();
|
||||
if (struct_size != sizeof(session_status)) return -1;
|
||||
|
||||
s->has_incoming_connections = ss.has_incoming_connections;
|
||||
|
||||
s->upload_rate = ss.upload_rate;
|
||||
s->download_rate = ss.download_rate;
|
||||
s->total_download = ss.total_download;
|
||||
s->total_upload = ss.total_upload;
|
||||
|
||||
s->payload_upload_rate = ss.payload_upload_rate;
|
||||
s->payload_download_rate = ss.payload_download_rate;
|
||||
s->total_payload_download = ss.total_payload_download;
|
||||
s->total_payload_upload = ss.total_payload_upload;
|
||||
|
||||
s->ip_overhead_upload_rate = ss.ip_overhead_upload_rate;
|
||||
s->ip_overhead_download_rate = ss.ip_overhead_download_rate;
|
||||
s->total_ip_overhead_download = ss.total_ip_overhead_download;
|
||||
s->total_ip_overhead_upload = ss.total_ip_overhead_upload;
|
||||
|
||||
s->dht_upload_rate = ss.dht_upload_rate;
|
||||
s->dht_download_rate = ss.dht_download_rate;
|
||||
s->total_dht_download = ss.total_dht_download;
|
||||
s->total_dht_upload = ss.total_dht_upload;
|
||||
|
||||
s->tracker_upload_rate = ss.tracker_upload_rate;
|
||||
s->tracker_download_rate = ss.tracker_download_rate;
|
||||
s->total_tracker_download = ss.total_tracker_download;
|
||||
s->total_tracker_upload = ss.total_tracker_upload;
|
||||
|
||||
s->total_redundant_bytes = ss.total_redundant_bytes;
|
||||
s->total_failed_bytes = ss.total_failed_bytes;
|
||||
|
||||
s->num_peers = ss.num_peers;
|
||||
s->num_unchoked = ss.num_unchoked;
|
||||
s->allowed_upload_slots = ss.allowed_upload_slots;
|
||||
|
||||
s->up_bandwidth_queue = ss.up_bandwidth_queue;
|
||||
s->down_bandwidth_queue = ss.down_bandwidth_queue;
|
||||
|
||||
s->up_bandwidth_bytes_queue = ss.up_bandwidth_bytes_queue;
|
||||
s->down_bandwidth_bytes_queue = ss.down_bandwidth_bytes_queue;
|
||||
|
||||
s->optimistic_unchoke_counter = ss.optimistic_unchoke_counter;
|
||||
s->unchoke_counter = ss.unchoke_counter;
|
||||
|
||||
s->dht_nodes = ss.dht_nodes;
|
||||
s->dht_node_cache = ss.dht_node_cache;
|
||||
s->dht_torrents = ss.dht_torrents;
|
||||
s->dht_global_nodes = ss.dht_global_nodes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int torrent_get_status(int tor, torrent_status* s, int struct_size)
|
||||
{
|
||||
libtorrent::torrent_handle h = get_handle(tor);
|
||||
if (!h.is_valid()) return -1;
|
||||
|
||||
libtorrent::torrent_status ts = h.status();
|
||||
|
||||
if (struct_size != sizeof(torrent_status)) return -1;
|
||||
|
||||
s->state = (state_t)ts.state;
|
||||
s->paused = ts.paused;
|
||||
s->progress = ts.progress;
|
||||
strncpy(s->error, ts.error.c_str(), 1025);
|
||||
s->next_announce = ts.next_announce.total_seconds();
|
||||
s->announce_interval = ts.announce_interval.total_seconds();
|
||||
strncpy(s->current_tracker, ts.current_tracker.c_str(), 512);
|
||||
s->total_download = ts.total_download = ts.total_download = ts.total_download;
|
||||
s->total_upload = ts.total_upload = ts.total_upload = ts.total_upload;
|
||||
s->total_payload_download = ts.total_payload_download;
|
||||
s->total_payload_upload = ts.total_payload_upload;
|
||||
s->total_failed_bytes = ts.total_failed_bytes;
|
||||
s->total_redundant_bytes = ts.total_redundant_bytes;
|
||||
s->download_rate = ts.download_rate;
|
||||
s->upload_rate = ts.upload_rate;
|
||||
s->download_payload_rate = ts.download_payload_rate;
|
||||
s->upload_payload_rate = ts.upload_payload_rate;
|
||||
s->num_seeds = ts.num_seeds;
|
||||
s->num_peers = ts.num_peers;
|
||||
s->num_complete = ts.num_complete;
|
||||
s->num_incomplete = ts.num_incomplete;
|
||||
s->list_seeds = ts.list_seeds;
|
||||
s->list_peers = ts.list_peers;
|
||||
s->connect_candidates = ts.connect_candidates;
|
||||
s->num_pieces = ts.num_pieces;
|
||||
s->total_done = ts.total_done;
|
||||
s->total_wanted_done = ts.total_wanted_done;
|
||||
s->total_wanted = ts.total_wanted;
|
||||
s->distributed_copies = ts.distributed_copies;
|
||||
s->block_size = ts.block_size;
|
||||
s->num_uploads = ts.num_uploads;
|
||||
s->num_connections = ts.num_connections;
|
||||
s->uploads_limit = ts.uploads_limit;
|
||||
s->connections_limit = ts.connections_limit;
|
||||
// s->storage_mode = (storage_mode_t)ts.storage_mode;
|
||||
s->up_bandwidth_queue = ts.up_bandwidth_queue;
|
||||
s->down_bandwidth_queue = ts.down_bandwidth_queue;
|
||||
s->all_time_upload = ts.all_time_upload;
|
||||
s->all_time_download = ts.all_time_download;
|
||||
s->active_time = ts.active_time;
|
||||
s->seeding_time = ts.seeding_time;
|
||||
s->seed_rank = ts.seed_rank;
|
||||
s->last_scrape = ts.last_scrape;
|
||||
s->has_incoming = ts.has_incoming;
|
||||
s->sparse_regions = ts.sparse_regions;
|
||||
s->seed_mode = ts.seed_mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int torrent_set_settings(int tor, int tag, ...)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
torrent_handle h = get_handle(tor);
|
||||
if (!h.is_valid()) return -1;
|
||||
|
||||
va_list lp;
|
||||
va_start(lp, tag);
|
||||
|
||||
while (tag != TAG_END)
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case SET_UPLOAD_RATE_LIMIT:
|
||||
h.set_upload_limit(va_arg(lp, int));
|
||||
break;
|
||||
case SET_DOWNLOAD_RATE_LIMIT:
|
||||
h.set_download_limit(va_arg(lp, int));
|
||||
break;
|
||||
case SET_MAX_UPLOAD_SLOTS:
|
||||
h.set_max_uploads(va_arg(lp, int));
|
||||
break;
|
||||
case SET_MAX_CONNECTIONS:
|
||||
h.set_max_connections(va_arg(lp, int));
|
||||
break;
|
||||
case SET_SEQUENTIAL_DOWNLOAD:
|
||||
h.set_sequential_download(va_arg(lp, int) != 0);
|
||||
break;
|
||||
case SET_SUPER_SEEDING:
|
||||
h.super_seeding(va_arg(lp, int) != 0);
|
||||
break;
|
||||
default:
|
||||
// ignore unknown tags
|
||||
va_arg(lp, void*);
|
||||
break;
|
||||
}
|
||||
|
||||
tag = va_arg(lp, int);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int torrent_get_setting(int tor, int tag, void* value, int* value_size)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
torrent_handle h = get_handle(tor);
|
||||
if (!h.is_valid()) return -1;
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case SET_UPLOAD_RATE_LIMIT:
|
||||
return set_int_value(value, value_size, h.upload_limit());
|
||||
case SET_DOWNLOAD_RATE_LIMIT:
|
||||
return set_int_value(value, value_size, h.download_limit());
|
||||
case SET_MAX_UPLOAD_SLOTS:
|
||||
return set_int_value(value, value_size, h.max_uploads());
|
||||
case SET_MAX_CONNECTIONS:
|
||||
return set_int_value(value, value_size, h.max_connections());
|
||||
case SET_SEQUENTIAL_DOWNLOAD:
|
||||
return set_int_value(value, value_size, h.is_sequential_download());
|
||||
case SET_SUPER_SEEDING:
|
||||
return set_int_value(value, value_size, h.super_seeding());
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
@ -1,278 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2009, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LIBTORRENT_H
|
||||
#define LIBTORRENT_H
|
||||
|
||||
enum tags
|
||||
{
|
||||
TAG_END = 0,
|
||||
|
||||
SES_FINGERPRINT, // char const*, 2 character string
|
||||
SES_LISTENPORT, // int
|
||||
SES_LISTENPORT_END, // int
|
||||
SES_VERSION_MAJOR, // int
|
||||
SES_VERSION_MINOR, // int
|
||||
SES_VERSION_TINY, // int
|
||||
SES_VERSION_TAG, // int
|
||||
SES_FLAGS, // int
|
||||
SES_ALERT_MASK, // int
|
||||
SES_LISTEN_INTERFACE, // char const*
|
||||
|
||||
// === add_torrent tags ===
|
||||
|
||||
// identifying the torrent to add
|
||||
TOR_FILENAME = 0x100, // char const*
|
||||
TOR_TORRENT, // char const*, specify size of buffer with TOR_TORRENT_SIZE
|
||||
TOR_TORRENT_SIZE, // int
|
||||
TOR_INFOHASH, // char const*, must point to a 20 byte array
|
||||
TOR_INFOHASH_HEX, // char const*, must point to a 40 byte string
|
||||
TOR_MAGNETLINK, // char const*, url
|
||||
|
||||
TOR_TRACKER_URL, // char const*
|
||||
TOR_RESUME_DATA, // char const*
|
||||
TOR_RESUME_DATA_SIZE, // int
|
||||
TOR_SAVE_PATH, // char const*
|
||||
TOR_NAME, // char const*
|
||||
TOR_PAUSED, // int
|
||||
TOR_AUTO_MANAGED, // int
|
||||
TOR_DUPLICATE_IS_ERROR, // int
|
||||
TOR_USER_DATA, //void*
|
||||
TOR_SEED_MODE, // int
|
||||
TOR_OVERRIDE_RESUME_DATA, // int
|
||||
TOR_STORAGE_MODE, // int
|
||||
|
||||
SET_UPLOAD_RATE_LIMIT = 0x200, // int
|
||||
SET_DOWNLOAD_RATE_LIMIT, // int
|
||||
SET_LOCAL_UPLOAD_RATE_LIMIT, // int
|
||||
SET_LOCAL_DOWNLOAD_RATE_LIMIT, // int
|
||||
SET_MAX_UPLOAD_SLOTS, // int
|
||||
SET_MAX_CONNECTIONS, // int
|
||||
SET_SEQUENTIAL_DOWNLOAD, // int, torrent only
|
||||
SET_SUPER_SEEDING, // int, torrent only
|
||||
SET_HALF_OPEN_LIMIT, // int, session only
|
||||
SET_PEER_PROXY, // proxy_setting const*, session_only
|
||||
SET_WEB_SEED_PROXY, // proxy_setting const*, session_only
|
||||
SET_TRACKER_PROXY, // proxy_setting const*, session_only
|
||||
SET_DHT_PROXY, // proxy_setting const*, session_only
|
||||
SET_PROXY, // proxy_setting const*, session_only
|
||||
};
|
||||
|
||||
struct proxy_setting
|
||||
{
|
||||
char hostname[256];
|
||||
int port;
|
||||
|
||||
char username[256];
|
||||
char password[256];
|
||||
|
||||
int type;
|
||||
};
|
||||
|
||||
enum proxy_type_t
|
||||
{
|
||||
proxy_none,
|
||||
proxy_socks4,
|
||||
proxy_socks5,
|
||||
proxy_socks5_pw,
|
||||
proxy_http,
|
||||
proxy_http_pw
|
||||
};
|
||||
|
||||
enum storage_mode_t
|
||||
{
|
||||
storage_mode_allocate = 0,
|
||||
storage_mode_sparse,
|
||||
storage_mode_compact
|
||||
};
|
||||
|
||||
enum state_t
|
||||
{
|
||||
queued_for_checking,
|
||||
checking_files,
|
||||
downloading_metadata,
|
||||
downloading,
|
||||
finished,
|
||||
seeding,
|
||||
allocating,
|
||||
checking_resume_data
|
||||
};
|
||||
|
||||
struct torrent_status
|
||||
{
|
||||
enum state_t state;
|
||||
int paused;
|
||||
float progress;
|
||||
char error[1024];
|
||||
int next_announce;
|
||||
int announce_interval;
|
||||
char current_tracker[512];
|
||||
long long total_download;
|
||||
long long total_upload;
|
||||
long long total_payload_download;
|
||||
long long total_payload_upload;
|
||||
long long total_failed_bytes;
|
||||
long long total_redundant_bytes;
|
||||
float download_rate;
|
||||
float upload_rate;
|
||||
float download_payload_rate;
|
||||
float upload_payload_rate;
|
||||
int num_seeds;
|
||||
int num_peers;
|
||||
int num_complete;
|
||||
int num_incomplete;
|
||||
int list_seeds;
|
||||
int list_peers;
|
||||
int connect_candidates;
|
||||
|
||||
// what to do?
|
||||
// bitfield pieces;
|
||||
|
||||
int num_pieces;
|
||||
long long total_done;
|
||||
long long total_wanted_done;
|
||||
long long total_wanted;
|
||||
float distributed_copies;
|
||||
int block_size;
|
||||
int num_uploads;
|
||||
int num_connections;
|
||||
int uploads_limit;
|
||||
int connections_limit;
|
||||
// enum storage_mode_t storage_mode;
|
||||
int up_bandwidth_queue;
|
||||
int down_bandwidth_queue;
|
||||
long long all_time_upload;
|
||||
long long all_time_download;
|
||||
int active_time;
|
||||
int seeding_time;
|
||||
int seed_rank;
|
||||
int last_scrape;
|
||||
int has_incoming;
|
||||
int sparse_regions;
|
||||
int seed_mode;
|
||||
};
|
||||
|
||||
struct session_status
|
||||
{
|
||||
int has_incoming_connections;
|
||||
|
||||
float upload_rate;
|
||||
float download_rate;
|
||||
long long total_download;
|
||||
long long total_upload;
|
||||
|
||||
float payload_upload_rate;
|
||||
float payload_download_rate;
|
||||
long long total_payload_download;
|
||||
long long total_payload_upload;
|
||||
|
||||
float ip_overhead_upload_rate;
|
||||
float ip_overhead_download_rate;
|
||||
long long total_ip_overhead_download;
|
||||
long long total_ip_overhead_upload;
|
||||
|
||||
float dht_upload_rate;
|
||||
float dht_download_rate;
|
||||
long long total_dht_download;
|
||||
long long total_dht_upload;
|
||||
|
||||
float tracker_upload_rate;
|
||||
float tracker_download_rate;
|
||||
long long total_tracker_download;
|
||||
long long total_tracker_upload;
|
||||
|
||||
long long total_redundant_bytes;
|
||||
long long total_failed_bytes;
|
||||
|
||||
int num_peers;
|
||||
int num_unchoked;
|
||||
int allowed_upload_slots;
|
||||
|
||||
int up_bandwidth_queue;
|
||||
int down_bandwidth_queue;
|
||||
|
||||
int up_bandwidth_bytes_queue;
|
||||
int down_bandwidth_bytes_queue;
|
||||
|
||||
int optimistic_unchoke_counter;
|
||||
int unchoke_counter;
|
||||
|
||||
int dht_nodes;
|
||||
int dht_node_cache;
|
||||
int dht_torrents;
|
||||
long long dht_global_nodes;
|
||||
// std::vector<dht_lookup> active_requests;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// the functions whose signature ends with:
|
||||
// , int first_tag, ...);
|
||||
// takes a tag list. The tag list is a series
|
||||
// of tag-value pairs. The tags are constants
|
||||
// identifying which property the value controls.
|
||||
// The type of the value varies between tags.
|
||||
// The enumeration above specifies which type
|
||||
// it expects. All tag lists must always be
|
||||
// terminated by TAG_END.
|
||||
|
||||
// use SES_* tags in tag list
|
||||
void* session_create(int first_tag, ...);
|
||||
void session_close(void* ses);
|
||||
|
||||
void session_start_dht(void *ses);
|
||||
|
||||
// use TOR_* tags in tag list
|
||||
int session_add_torrent(void* ses, int first_tag, ...);
|
||||
void session_remove_torrent(void* ses, int tor, int flags);
|
||||
|
||||
int session_get_status(void* ses, struct session_status* s, int struct_size);
|
||||
|
||||
// use SET_* tags in tag list
|
||||
int session_set_settings(void* ses, int first_tag, ...);
|
||||
int session_get_setting(void* ses, int tag, void* value, int* value_size);
|
||||
|
||||
int torrent_get_status(int tor, struct torrent_status* s, int struct_size);
|
||||
|
||||
// use SET_* tags in tag list
|
||||
int torrent_set_settings(int tor, int first_tag, ...);
|
||||
int torrent_get_setting(int tor, int tag, void* value, int* value_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#include <ks.h>
|
||||
#include <tap.h>
|
||||
|
||||
/*
|
||||
Test should cover all cases of DHT message construction and parsing tests
|
||||
* init ks
|
||||
* init a client if required
|
||||
* TODO: list out msg construction and parsing tests
|
||||
* Immutable messages:
|
||||
* 1. create and validate single immutable messages, and handle error cases such as too large, etc.
|
||||
* Mutable messages:
|
||||
* 1. Create message error cases
|
||||
* 2. Create initial message cases
|
||||
* 3. Update message cases
|
||||
* 4.
|
||||
* cleanup ks
|
||||
*/
|
||||
|
||||
int main() {
|
||||
|
||||
|
||||
done_testing();
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#include <ks.h>
|
||||
#include <tap.h>
|
||||
|
||||
/*
|
||||
Test should cover all cases of DHT networking for ipv4 and ipv6
|
||||
* Find ip
|
||||
* init 2 or more clients(with dedicated ports)
|
||||
* add ip to clients
|
||||
* TODO: list out nework specific tests.
|
||||
* shutdown clients
|
||||
* cleanup ks
|
||||
*/
|
||||
|
||||
int main() {
|
||||
|
||||
|
||||
done_testing();
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
#include <ks.h>
|
||||
#include <tap.h>
|
||||
|
||||
/*
|
||||
Test should cover end to end DHT functionality that isn't covered by a more specific test file
|
||||
* Find ip
|
||||
* init 2 or more clients(with dedicated ports)
|
||||
* add ip to clients
|
||||
* exchange peers between clients
|
||||
* shutdown clients
|
||||
* cleanup ks
|
||||
*/
|
||||
|
||||
int main() {
|
||||
int err = 0;
|
||||
char v4[48] = {0}, v6[48] = {0};
|
||||
int mask = 0, have_v4 = 0, have_v6 = 0;
|
||||
int A_port = 5998, B_port = 5999;
|
||||
dht_handle_t *A_h = NULL, *B_h = NULL;
|
||||
ks_dht_af_flag_t af_flags = 0;
|
||||
static ks_sockaddr_t bootstrap[1];
|
||||
|
||||
err = ks_init();
|
||||
ok(!err);
|
||||
|
||||
err = ks_find_local_ip(v4, sizeof(v4), &mask, AF_INET, NULL);
|
||||
ok(err == KS_STATUS_SUCCESS);
|
||||
have_v4 = !zstr_buf(v4);
|
||||
|
||||
err = ks_find_local_ip(v6, sizeof(v6), NULL, AF_INET6, NULL);
|
||||
ok(err == KS_STATUS_SUCCESS);
|
||||
|
||||
have_v6 = !zstr_buf(v6);
|
||||
|
||||
ok(have_v4 || have_v6);
|
||||
if (have_v4) {
|
||||
af_flags |= KS_DHT_AF_INET4;
|
||||
}
|
||||
diag("Adding local bind ipv4 of (%s) %d\n", v4, have_v4);
|
||||
|
||||
if (have_v6) {
|
||||
af_flags |= KS_DHT_AF_INET6;
|
||||
}
|
||||
diag("Adding local bind ipv6 of (%s) %d\n", v6, have_v6);
|
||||
|
||||
err = ks_dht_init(&A_h, af_flags, NULL, A_port);
|
||||
ok(err == KS_STATUS_SUCCESS);
|
||||
|
||||
if (have_v4) {
|
||||
err = ks_dht_add_ip(A_h, v4, A_port);
|
||||
ok(err == KS_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
if (have_v6) {
|
||||
err = ks_dht_add_ip(A_h, v6, A_port);
|
||||
ok(err == KS_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
err = ks_dht_init(&B_h, af_flags, NULL, B_port);
|
||||
ok(err == KS_STATUS_SUCCESS);
|
||||
|
||||
if (have_v4) {
|
||||
err = ks_dht_add_ip(B_h, v4, B_port);
|
||||
ok(err == KS_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
if (have_v6) {
|
||||
err = ks_dht_add_ip(B_h, v6, B_port);
|
||||
ok(err == KS_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
ks_dht_start(A_h);
|
||||
ks_dht_start(B_h);
|
||||
|
||||
ks_addr_set(&bootstrap[0], v4, B_port, 0);
|
||||
|
||||
/* Have A ping B */
|
||||
dht_ping_node(A_h, &bootstrap[0]);
|
||||
|
||||
/* Start test series */
|
||||
|
||||
/* Absent in Test and Example App */
|
||||
/*
|
||||
This function is called from the test app, with the intent of processing and handling network packets(buf, buflen, from).
|
||||
Tests for this function should include successful processing of new inbound messages, as well as validation of bad inbound messages.
|
||||
KS_DECLARE(int) dht_periodic(dht_handle_t *h, const void *buf, size_t buflen, ks_sockaddr_t *from); */
|
||||
/*
|
||||
This function is like the dht_ping_node, except it only adds the node, and waits for dht_periodic to decide when to ping the node.
|
||||
Doing a node ping first confirms that we have working networking to the new remote node.
|
||||
KS_DECLARE(int) dht_insert_node(dht_handle_t *h, const unsigned char *id, ks_sockaddr_t *sa); */
|
||||
/*
|
||||
Queries for node stats. Will be used for validating that a node was successfully added. Call before the ping, ping, call after, and compare.
|
||||
KS_DECLARE(int) dht_nodes(dht_handle_t *h, int af, int *good_return, int *dubious_return, int *cached_return, int *incoming_return); */
|
||||
/*
|
||||
Sets(or changes?) the local DHT listening port. Would be very interesting to see what happens if this is called after nodes are pinged.
|
||||
KS_DECLARE(void) ks_dht_set_port(dht_handle_t *h, unsigned int port); */
|
||||
|
||||
|
||||
/* Present in Example App but Absent in Test */
|
||||
/*
|
||||
ks_dht_send_message_mutable_cjson(h, alice_secretkey, alice_publickey, NULL, message_id, 1, output, 600); */
|
||||
/*
|
||||
ks_separate_string(cmd_dup, " ", argv, (sizeof(argv) / sizeof(argv[0]))); */
|
||||
/*
|
||||
ks_dht_api_find_node(h, argv[2], argv[3], ipv6); */
|
||||
/*
|
||||
ks_global_set_default_logger(atoi(line + 9)); */
|
||||
/*
|
||||
ks_dht_set_param(h, DHT_PARAM_AUTOROUTE, KS_TRUE); */
|
||||
/*
|
||||
Like dht_periodic, except executes only one loop of work.
|
||||
ks_dht_one_loop(h, 0); */
|
||||
/*
|
||||
Returns a list of local bindings. Most useful after the DHT_PARAM_AUTOROUTE to return which routes it bound to.
|
||||
ks_dht_get_bind_addrs(h, &bindings, &len); */
|
||||
/*
|
||||
Callback for different message type actions. Called from the dht_periodic functions.
|
||||
ks_dht_set_callback(h, callback, NULL); */
|
||||
/*
|
||||
Executes a search for a particular SHA hash. Pings known nodes to see if they have the hash. callback is called with results.
|
||||
dht_search(h, hash, globals.port, AF_INET, callback, NULL); */
|
||||
/*
|
||||
Print the contents of the 'dht tables' to stdout. Need a version that gets info in a testable format.
|
||||
dht_dump_tables(h, stdout); */
|
||||
/* dht_get_nodes(h, sin, &num, sin6, &num6); */
|
||||
/*
|
||||
Shuts down the DHT handle, and should properly clean up.
|
||||
dht_uninit(&h); */
|
||||
|
||||
/* Cleanup and shutdown */
|
||||
|
||||
todo("ks_dht_stop()");
|
||||
todo("ks_dht_destroy()");
|
||||
|
||||
err = ks_shutdown();
|
||||
ok(!err);
|
||||
|
||||
done_testing();
|
||||
}
|
Loading…
Reference in New Issue