- case AF_INET6: {
- struct sockaddr_in6 *sin6 = (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) ||
- (memcmp(address, zeroes, 15) == 0 &&
- (address[15] == 0 || address[15] == 1)) ||
- (memcmp(address, v4prefix, 12) == 0);
- }
-
- default:
- return 0;
- }
-}
-
-/* Forget about the ``XOR-metric''. An id is just a path from the
- root of the tree, so bits are numbered from the start. */
-
-static inline int
-id_cmp(const unsigned char *restrict id1, const unsigned char *restrict id2)
-{
- /* Memcmp is guaranteed to perform an unsigned comparison. */
- return memcmp(id1, id2, 20);
-}
-
-/* Our transaction-ids are 4-bytes long, with the first two bytes identi-
- fying the kind of request, and the remaining two a sequence number in
- host order. */
-
-static void
-make_tid(unsigned char *tid_return, const char *prefix, unsigned short seqno)
-{
- tid_return[0] = prefix[0] & 0xFF;
- tid_return[1] = prefix[1] & 0xFF;
- memcpy(tid_return + 2, &seqno, 2);
-}
-
-static int
-tid_match(const unsigned char *tid, const char *prefix, unsigned short *seqno_return)
-{
- if (tid[0] == (prefix[0] & 0xFF) && tid[1] == (prefix[1] & 0xFF)) {
- if (seqno_return)
- memcpy(seqno_return, tid + 2, 2);
- return 1;
- } else
- return 0;
-}
-
-static inline int
-circular(int from, int to)
-{
- int x = to - from;
- if (x < 0)
- return x + CIRCULAR_LIST_SIZE;
- return x;
-}
-
-static int
-list_elements(struct circular_list *list)
-{
- return circular(list->head, list->tail);
-}
-
-static int
-list_empty(struct circular_list *list)
-{
- return list_elements(list) == 0;
-}
-
-static int
-list_free(struct circular_list *list)
-{
- return circular(list->tail + 1, list->head);
-}
-
-static int
-list_pop(struct circular_list *list, struct sockaddr_storage *ss, socklen_t *sslen)
-{
- if (list->head == list->tail)
- return 0;
-
- memcpy(ss, &list->nodes[list->head].ss, list->nodes[list->head].sslen);
- *sslen = list->nodes[list->head].sslen;
- list->head = (list->head + 1) % CIRCULAR_LIST_SIZE;
- return 1;
-}
-
-static int
-list_random(
- struct circular_list *list,
- unsigned char *id,
- struct sockaddr_storage *ss,
- socklen_t *sslen)
-{
- int n;
- if (list->head == list->tail)
- return 0;
-
- n = random() % (list->tail - list->head);
- n = (list->head + n) % CIRCULAR_LIST_SIZE;
-
- if (id)
- memcpy(id, &list->nodes[n].id, 20);
- memcpy(ss, &list->nodes[n].ss, list->nodes[n].sslen);
- *sslen = list->nodes[n].sslen;
- return 1;