From c880bf865865722ef63947ac0b1b1c282ffcee68 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Thu, 10 Nov 2022 18:22:32 +0300 Subject: [PATCH] More correct integer types --- dht-bootstrap.c | 278 ++++++++++++++++++++++++++---------------------- 1 file changed, 149 insertions(+), 129 deletions(-) diff --git a/dht-bootstrap.c b/dht-bootstrap.c index 2627d82..9320ca7 100644 --- a/dht-bootstrap.c +++ b/dht-bootstrap.c @@ -26,6 +26,7 @@ THE SOFTWARE. #include #include #include +#include #include #include #include @@ -76,12 +77,12 @@ static struct circular_list v4_new, v6_new, v4_confirmed, v6_confirmed; static time_t token_bucket_time; static int token_bucket_tokens; -static int verbose = 1; +static bool verbose = true; // ------------------------ >8 ------------------------ static const char * -getAddr(const struct sockaddr *sa, const size_t saLen) +getAddr(const struct sockaddr *sa, const socklen_t saLen) { static char host[NI_MAXHOST]; static char port[NI_MAXSERV]; @@ -105,29 +106,27 @@ getAddr(const struct sockaddr *sa, const size_t saLen) static int parse_message( const unsigned char *buf, - int buflen, + const size_t buflen, unsigned char *tid_return, - int *tid_len, + size_t *tid_len, unsigned char *id_return, unsigned char *info_hash_return, unsigned char *target_return, unsigned short *port_return, unsigned char *token_return, - int *token_len, + size_t *token_len, unsigned char *nodes_return, - int *nodes_len, + size_t *nodes_len, unsigned char *nodes6_return, - int *nodes6_len, + size_t *nodes6_len, unsigned char *values_return, - int *values_len, + size_t *values_len, unsigned char *values6_return, - int *values6_len, + size_t *values6_len, int *want_return, const struct sockaddr *sa, - const size_t saLen) + const socklen_t saLen) { - const unsigned char *p; - /* This code will happily crash if the buffer is not NUL-terminated. */ if (buf[buflen] != '\0') { if (verbose) @@ -136,15 +135,16 @@ parse_message( } #define CHECK(ptr, len) \ - if (((unsigned char *)ptr) + (len) > (buf) + (buflen)) \ + if (((const unsigned char *)ptr) + (len) > (buf) + (buflen)) \ goto overflow; + unsigned char *p; + unsigned long l = 0; + char *q; if (tid_return) { p = memmem(buf, buflen, "1:t", 3); if (p) { - long l; - char *q; - l = strtol((char *)p + 3, &q, 10); + l = strtoul((const char *)p + 3, &q, 10); if (q && *q == ':' && l > 0 && l < *tid_len) { CHECK(q + 1, l); memcpy(tid_return, q + 1, l); @@ -174,11 +174,9 @@ parse_message( if (port_return) { p = memmem(buf, buflen, "porti", 5); if (p) { - long l; - char *q; - l = strtol((char *)p + 5, &q, 10); + l = strtoul((const char *)p + 5, &q, 10); if (q && *q == 'e' && l > 0 && l < 0x10000) - *port_return = l; + *port_return = (unsigned short)l; else *port_return = 0; } else @@ -196,9 +194,7 @@ parse_message( if (token_return) { p = memmem(buf, buflen, "5:token", 7); if (p) { - long l; - char *q; - l = strtol((char *)p + 7, &q, 10); + l = strtoul((const char *)p + 7, &q, 10); if (q && *q == ':' && l > 0 && l < *token_len) { CHECK(q + 1, l); memcpy(token_return, q + 1, l); @@ -212,9 +208,7 @@ parse_message( if (nodes_len) { p = memmem(buf, buflen, "5:nodes", 7); if (p) { - long l; - char *q; - l = strtol((char *)p + 7, &q, 10); + l = strtoul((const char *)p + 7, &q, 10); if (q && *q == ':' && l > 0 && l < *nodes_len) { CHECK(q + 1, l); memcpy(nodes_return, q + 1, l); @@ -228,9 +222,7 @@ parse_message( if (nodes6_len) { p = memmem(buf, buflen, "6:nodes6", 8); if (p) { - long l; - char *q; - l = strtol((char *)p + 8, &q, 10); + l = strtoul((const char *)p + 8, &q, 10); if (q && *q == ':' && l > 0 && l < *nodes6_len) { CHECK(q + 1, l); memcpy(nodes6_return, q + 1, l); @@ -244,24 +236,22 @@ parse_message( if (values_len || values6_len) { p = memmem(buf, buflen, "6:valuesl", 9); if (p) { - int i = p - buf + 9; - int j = 0, j6 = 0; + size_t i = p - buf + 9; + unsigned long j = 0, j6 = 0; while (1) { - long l; - char *q; - l = strtol((char *)buf + i, &q, 10); + l = strtoul((const char *)buf + i, &q, 10); if (q && *q == ':' && l > 0) { CHECK(q + 1, l); if (l == 6) { if (j + l > *values_len) continue; - i = q + 1 + l - (char *)buf; + i = q + 1 + l - (const char *)buf; memcpy((char *)values_return + j, q + 1, l); j += l; } else if (l == 18) { if (j6 + l > *values6_len) continue; - i = q + 1 + l - (char *)buf; + i = q + 1 + l - (const char *)buf; memcpy((char *)values6_return + j6, q + 1, l); j6 += l; } else { @@ -270,7 +260,7 @@ parse_message( "%s : received weird value: %d bytes\n", getAddr(sa, saLen), (int)l); - i = q + 1 + l - (char *)buf; + i = q + 1 + l - (const char *)buf; } } else { break; @@ -292,7 +282,7 @@ parse_message( if (want_return) { p = memmem(buf, buflen, "4:wantl", 7); if (p) { - int i = p - buf + 7; + size_t i = p - buf + 7; *want_return = 0; while (buf[i] > '0' && buf[i] <= '9' && buf[i + 1] == ':' && i + 2 + buf[i] - '0' < buflen) { @@ -352,7 +342,7 @@ overflow: #define INC(offset, delta, size) \ CHECK(offset, delta, size); \ - offset += delta + offset += delta; #define COPY(buf, offset, src, delta, size) \ CHECK(offset, delta, size); \ @@ -361,18 +351,18 @@ overflow: #define ADD_V(buf, offset, size) COPY(buf, offset, my_v, (sizeof my_v), size) -static int -is_martian(struct sockaddr *sa) +static bool +is_martian(const struct sockaddr *sa) { switch (sa->sa_family) { case AF_INET: { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; + const struct sockaddr_in *sin = (const struct sockaddr_in *)sa; const unsigned char *address = (const unsigned char *)&sin->sin_addr; return sin->sin_port == 0 || (address[0] == 0) || (address[0] == 127) || ((address[0] & 0xE0) == 0xE0); } case AF_INET6: { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; + const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa; const unsigned char *address = (const unsigned char *)&sin6->sin6_addr; return sin6->sin6_port == 0 || (address[0] == 0xFF) || (address[0] == 0xFE && (address[1] & 0xC0) == 0x80) || @@ -380,10 +370,8 @@ is_martian(struct sockaddr *sa) (address[15] == 0 || address[15] == 1)) || (memcmp(address, v4prefix, 12) == 0); } - - default: - return 0; } + return false; } /* Forget about the ``XOR-metric''. An id is just a path from the @@ -401,7 +389,7 @@ id_cmp(const unsigned char *restrict id1, const unsigned char *restrict id2) host order. */ static void -make_tid(unsigned char *tid_return, const char *prefix, unsigned short seqno) +make_tid(unsigned char *tid_return, const char *prefix, const unsigned short seqno) { tid_return[0] = prefix[0] & 0xFF; tid_return[1] = prefix[1] & 0xFF; @@ -434,7 +422,7 @@ list_elements(struct circular_list *list) return circular(list->head, list->tail); } -static int +static bool list_empty(struct circular_list *list) { return list_elements(list) == 0; @@ -481,8 +469,12 @@ list_random( /* We just learnt about a node, not necessarily a new one. Confirm is 1 if the node sent a message, 2 if it sent us a reply. */ -static int -new_node(unsigned char *id, struct sockaddr *sa, socklen_t salen, int confirm) +static bool +new_node( + const unsigned char *id, + const struct sockaddr *sa, + const socklen_t salen, + const int confirm) { struct circular_list *list; if (sa->sa_family == AF_INET) @@ -497,12 +489,12 @@ new_node(unsigned char *id, struct sockaddr *sa, socklen_t salen, int confirm) include such a node if we have plenty of space. */ if (confirm == 1 && list_free(list) < 32) - return 0; + return false; for (int i = list->head; i != list->tail; i = (i + 1) % CIRCULAR_LIST_SIZE) { struct node *n = &list->nodes[i]; if (n->sslen == salen && memcmp(&n->ss, sa, salen) == 0) - return 0; + return false; } memcpy(&list->nodes[list->tail].id, id, 160); @@ -514,10 +506,10 @@ new_node(unsigned char *id, struct sockaddr *sa, socklen_t salen, int confirm) if (verbose) printf("%s : new node\n", getAddr(sa, salen)); - return 1; + return true; } -static int +static bool token_bucket(void) { time_t now = time(NULL); @@ -527,13 +519,17 @@ token_bucket(void) token_bucket_time = now; } if (token_bucket_tokens == 0) - return 0; + return false; token_bucket_tokens--; - return 1; + return true; } -static int -dht_send(const void *buf, size_t len, int flags, const struct sockaddr *sa, int salen) +static ssize_t +dht_send( + const void *buf, + const size_t len, + const struct sockaddr *sa, + const socklen_t salen) { if (salen == 0) abort(); @@ -548,18 +544,22 @@ dht_send(const void *buf, size_t len, int flags, const struct sockaddr *sa, int errno = EAFNOSUPPORT; return -1; } - return sendto(s, buf, len, flags, sa, salen); + return sendto(s, buf, len, 0, sa, salen); } -static int -send_ping(struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len) +static ssize_t +send_ping( + const struct sockaddr *sa, + const socklen_t salen, + const unsigned char *tid, + const size_t tid_len) { char buf[512]; - int i = 0, rc; - rc = snprintf(buf + i, 512 - i, "d1:ad2:id20:"); + int i = 0; + int rc = snprintf(buf + i, 512 - i, "d1:ad2:id20:"); INC(i, rc, 512); COPY(buf, i, myid, 20, 512); - rc = snprintf(buf + i, 512 - i, "e1:q4:ping1:t%d:", tid_len); + rc = snprintf(buf + i, 512 - i, "e1:q4:ping1:t%zu:", tid_len); INC(i, rc, 512); COPY(buf, i, tid, tid_len, 512); ADD_V(buf, i, 512); @@ -567,22 +567,26 @@ send_ping(struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len) INC(i, rc, 512); if (verbose) printf("%s <- PING\n", getAddr(sa, salen)); - return dht_send(buf, i, 0, sa, salen); + return dht_send(buf, (size_t)i, sa, salen); fail: errno = ENOSPC; return -1; } -static int -send_pong(struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len) +static ssize_t +send_pong( + const struct sockaddr *sa, + const socklen_t salen, + const unsigned char *tid, + const size_t tid_len) { char buf[512]; int i = 0; int rc = snprintf(buf + i, 512 - i, "d1:rd2:id20:"); INC(i, rc, 512); COPY(buf, i, myid, 20, 512); - rc = snprintf(buf + i, 512 - i, "e1:t%d:", tid_len); + rc = snprintf(buf + i, 512 - i, "e1:t%zu:", tid_len); INC(i, rc, 512); COPY(buf, i, tid, tid_len, 512); ADD_V(buf, i, 512); @@ -590,21 +594,21 @@ send_pong(struct sockaddr *sa, int salen, const unsigned char *tid, int tid_len) INC(i, rc, 512); if (verbose) printf("%s <- PONG\n", getAddr(sa, salen)); - return dht_send(buf, i, 0, sa, salen); + return dht_send(buf, (size_t)i, sa, salen); fail: errno = ENOSPC; return -1; } -static int +static ssize_t send_find_node( - struct sockaddr *sa, - int salen, + const struct sockaddr *sa, + const socklen_t salen, const unsigned char *tid, - int tid_len, + const size_t tid_len, const unsigned char *target, - int want) + const int want) { char buf[512]; int i = 0; @@ -623,7 +627,7 @@ send_find_node( (want & WANT6) ? "2:n6" : ""); INC(i, rc, 512); } - rc = snprintf(buf + i, 512 - i, "e1:q9:find_node1:t%d:", tid_len); + rc = snprintf(buf + i, 512 - i, "e1:q9:find_node1:t%zu:", tid_len); INC(i, rc, 512); COPY(buf, i, tid, tid_len, 512); ADD_V(buf, i, 512); @@ -631,15 +635,19 @@ send_find_node( INC(i, rc, 512); if (verbose) printf("%s <- FIND_NODE\n", getAddr(sa, salen)); - return dht_send(buf, i, 0, sa, salen); + return dht_send(buf, (size_t)i, sa, salen); fail: errno = ENOSPC; return -1; } -static int -send_request(struct circular_list *list, int dopop, int doping, int want) +static ssize_t +send_request( + struct circular_list *list, + const bool dopop, + const bool doping, + const int want) { if (list_empty(list)) return 0; @@ -702,20 +710,20 @@ rlimited(int res) r.rlim_cur = 0; r.rlim_max = 0; if (setrlimit(res, &r) == -1) { - err(EXIT_FAILURE, "can not setrlimit()"); + err(EXIT_FAILURE, "setrlimit()"); } } -static int +static ssize_t send_nodes( - struct sockaddr *sa, - int salen, + const struct sockaddr *sa, + const socklen_t salen, const unsigned char *tid, - int tid_len, + const size_t tid_len, const unsigned char *nodes, - int nodes_len, + const size_t nodes_len, const unsigned char *nodes6, - int nodes6_len) + const size_t nodes6_len) { char buf[2048]; int i = 0; @@ -723,22 +731,22 @@ send_nodes( INC(i, rc, 2048); COPY(buf, i, myid, 20, 2048); if (nodes_len > 0) { - rc = snprintf(buf + i, 2048 - i, "5:nodes%d:", nodes_len); + rc = snprintf(buf + i, 2048 - i, "5:nodes%zu:", nodes_len); INC(i, rc, 2048); COPY(buf, i, nodes, nodes_len, 2048); } if (nodes6_len > 0) { - rc = snprintf(buf + i, 2048 - i, "6:nodes6%d:", nodes6_len); + rc = snprintf(buf + i, 2048 - i, "6:nodes6%zu:", nodes6_len); INC(i, rc, 2048); COPY(buf, i, nodes6, nodes6_len, 2048); } - rc = snprintf(buf + i, 2048 - i, "e1:t%d:", tid_len); + rc = snprintf(buf + i, 2048 - i, "e1:t%zu:", tid_len); INC(i, rc, 2048); COPY(buf, i, tid, tid_len, 2048); ADD_V(buf, i, 2048); rc = snprintf(buf + i, 2048 - i, "1:y1:re"); INC(i, rc, 2048); - return dht_send(buf, i, 0, sa, salen); + return dht_send(buf, (size_t)i, sa, salen); fail: errno = ENOSPC; @@ -793,12 +801,12 @@ buffer_random_nodes(int af, unsigned char *nodes) return n; } -static int +static ssize_t send_random_nodes( - struct sockaddr *sa, - int salen, + const struct sockaddr *sa, + const socklen_t salen, const unsigned char *tid, - int tid_len, + const size_t tid_len, int want) { unsigned char nodes[8 * 26]; @@ -817,13 +825,13 @@ send_random_nodes( sa, salen, tid, tid_len, nodes, numnodes * 26, nodes6, numnodes6 * 38); } -static int +static ssize_t send_error( - struct sockaddr *sa, - int salen, - unsigned char *tid, - int tid_len, - int code, + const struct sockaddr *sa, + const socklen_t salen, + const unsigned char *tid, + const size_t tid_len, + const int code, const char *message) { char buf[512]; @@ -831,13 +839,13 @@ send_error( int rc = snprintf(buf + i, 512 - i, "d1:eli%de%d:", code, (int)strlen(message)); INC(i, rc, 512); COPY(buf, i, message, (int)strlen(message), 512); - rc = snprintf(buf + i, 512 - i, "e1:t%d:", tid_len); + rc = snprintf(buf + i, 512 - i, "e1:t%zu:", tid_len); INC(i, rc, 512); COPY(buf, i, tid, tid_len, 512); ADD_V(buf, i, 512); rc = snprintf(buf + i, 512 - i, "1:y1:ee"); INC(i, rc, 512); - return dht_send(buf, i, 0, sa, salen); + return dht_send(buf, (size_t)i, sa, salen); fail: errno = ENOSPC; @@ -921,7 +929,7 @@ main(int argc, char **argv) token_bucket_time = time(NULL); token_bucket_tokens = MAX_TOKEN_BUCKET_TOKENS; - int send4 = 0; + bool send4 = false; struct pollfd fds[2]; fds[0].fd = dht_socket; fds[0].events = POLLIN; @@ -963,34 +971,45 @@ main(int argc, char **argv) if (rc > 0) { int message; - unsigned char tid[16], id[20], info_hash[20], target[20]; - unsigned char buf[1536], nodes[256], nodes6[1024], token[128]; - int tid_len = 16, token_len = 128; - int nodes_len = 256, nodes6_len = 1024; + unsigned char tid[16]; + unsigned char id[20]; + unsigned char info_hash[20]; + unsigned char target[20]; + unsigned char buf[1536]; + unsigned char nodes[256]; + unsigned char nodes6[1024]; + unsigned char token[128]; + size_t tid_len = sizeof tid; + size_t token_len = sizeof token; + size_t nodes_len = sizeof nodes; + size_t nodes6_len = sizeof nodes6; unsigned short port; - unsigned char values[2048], values6[2048]; - int values_len = 2048, values6_len = 2048; + unsigned char values[2048]; + unsigned char values6[2048]; + size_t values_len = sizeof values; + size_t values6_len = sizeof values6; int want; struct sockaddr_storage source_storage; struct sockaddr *source = (struct sockaddr *)&source_storage; socklen_t sourcelen = sizeof(source_storage); + ssize_t got = 0; if (fds[0].revents != 0) { if ((fds[0].revents & (POLLERR | POLLNVAL)) > 0) { fprintf(stderr, "error in fds[0]"); - rc = -1; + got = -1; } else { - rc = recvfrom(dht_socket, buf, 1536, 0, source, &sourcelen); + got = recvfrom(dht_socket, buf, 1536, 0, source, &sourcelen); } } else if (fds[1].revents != 0) { if ((fds[1].revents & (POLLERR | POLLNVAL)) > 0) { fprintf(stderr, "error in fds[1]"); - rc = -1; + got = -1; } else { - rc = recvfrom(dht_socket6, buf, 1536, 0, source, &sourcelen); + got = recvfrom(dht_socket6, buf, 1536, 0, source, &sourcelen); } } - if (rc < 0 || sourcelen > sizeof(struct sockaddr_storage)) + if (got < 0 || sourcelen > sizeof(struct sockaddr_storage)) goto dontread; if (is_martian(source)) @@ -1000,8 +1019,8 @@ main(int argc, char **argv) buffer if it's not NUL-terminated. For now, put a NUL at the end of buffers. */ - if (rc < 1536) { - buf[rc] = '\0'; + if (got < 1536) { + buf[got] = '\0'; } else { if (verbose) printf("%s : overlong message\n", getAddr(source, sourcelen)); @@ -1010,7 +1029,7 @@ main(int argc, char **argv) message = parse_message( buf, - rc, + (size_t)got, tid, &tid_len, id, @@ -1066,7 +1085,7 @@ main(int argc, char **argv) } else if (tid_match(tid, "fn", NULL)) { if (verbose) printf( - "%s -> NODES (%d+%d)\n", + "%s -> NODES (%zu+%zu)\n", getAddr(source, sourcelen), nodes_len / 26, nodes6_len / 38); @@ -1077,8 +1096,9 @@ main(int argc, char **argv) getAddr(source, sourcelen)); } else { new_node(id, source, sourcelen, 2); - for (i = 0; i < nodes_len / 26; i++) { - unsigned char *ni = nodes + i * 26; + size_t n; + for (n = 0; n < nodes_len / 26; n++) { + unsigned char *ni = nodes + n * 26; struct sockaddr_in sin; if (id_cmp(ni, myid) == 0) continue; @@ -1088,8 +1108,8 @@ main(int argc, char **argv) memcpy(&sin.sin_port, ni + 24, 2); new_node(ni, (struct sockaddr *)&sin, sizeof(sin), 0); } - for (i = 0; i < nodes6_len / 38; i++) { - unsigned char *ni = nodes6 + i * 38; + for (n = 0; n < nodes6_len / 38; n++) { + unsigned char *ni = nodes6 + n * 38; struct sockaddr_in6 sin6; if (id_cmp(ni, myid) == 0) continue; @@ -1108,7 +1128,7 @@ main(int argc, char **argv) break; case PING: if (verbose) - printf("%s -> PING (%d)\n", getAddr(source, sourcelen), tid_len); + printf("%s -> PING (%zu)\n", getAddr(source, sourcelen), tid_len); new_node(id, source, sourcelen, 1); send_pong(source, sourcelen, tid, tid_len); break; @@ -1145,24 +1165,24 @@ main(int argc, char **argv) loop. */ if (dht_socket6 < 0) - send4 = 1; + send4 = true; else if (dht_socket < 0) - send4 = 0; + send4 = false; else - send4 = random() % 2; + send4 = (random() % 2) == 1; if (send4) { int want = dht_socket6 >= 0 && list_free(&v6_new) > 8 ? (WANT4 | WANT6) : 0; if (!list_empty(&v4_new)) - send_request(&v4_new, 1, list_free(&v4_new) < 8, want); + send_request(&v4_new, true, list_free(&v4_new) < 8, want); else if (!list_empty(&v4_confirmed)) - send_request(&v4_confirmed, 0, 0, want); + send_request(&v4_confirmed, false, false, want); } else { int want = dht_socket >= 0 && list_free(&v4_new) > 8 ? (WANT4 | WANT6) : 0; if (!list_empty(&v6_new)) - send_request(&v6_new, 1, list_free(&v6_new) < 8, want); + send_request(&v6_new, true, list_free(&v6_new) < 8, want); else if (!list_empty(&v6_confirmed)) - send_request(&v6_confirmed, 0, 0, want); + send_request(&v6_confirmed, false, false, want); } } -- 2.44.0