freeswitch/libs/libks/dht_bencode_encoder.diff

408 lines
17 KiB
Diff

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