/* vim: set expandtab ts=4 sw=4: */
/*
* You may redistribute this program and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef Address_H
#define Address_H
#include "benc/String.h"
#include "memory/Allocator.h"
#include "util/Linker.h"
Linker_require("dht/Address.c");
#include
#include
#define Address_KEY_SIZE 32
#define Address_NETWORK_ADDR_SIZE 8
#define Address_SEARCH_TARGET_SIZE 16
#define Address_SERIALIZED_SIZE 40
// Don't undefine this yet, new code will depend on it so that it can be tracked down and changed.
#define Address_ROT64
struct Address
{
/** The protocol version of the node. */
uint32_t protocolVersion;
/** unused */
uint32_t padding;
union {
struct {
// tricksy: this is effectively a 64 bit rotate of the following bytes array
uint32_t three_be;
uint32_t four_be;
uint32_t one_be;
uint32_t two_be;
} ints;
struct {
uint64_t two_be;
uint64_t one_be;
} longs;
uint8_t bytes[Address_SEARCH_TARGET_SIZE];
} ip6;
uint8_t key[Address_KEY_SIZE];
uint64_t path;
};
#define Address_SIZE (8 + Address_SEARCH_TARGET_SIZE + Address_KEY_SIZE + Address_NETWORK_ADDR_SIZE)
Assert_compileTime(sizeof(struct Address) == Address_SIZE);
struct Address_List
{
int length;
struct Address* elems;
};
struct Address_List* Address_List_new(uint32_t length, struct Allocator* alloc);
uint32_t Address_getPrefix(struct Address* addr);
uint32_t Address_prefixForIp6(uint8_t ip6[16]);
uint32_t Address_prefixForSearchTarget(const uint8_t searchTarget[16]);
/**
* Address_serialize and Address_parse use the following format:
*
* 1 2 3
* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* 0 | |
* + +
* 4 | |
* + +
* 8 | |
* + +
* 12 | |
* + Public Key +
* 16 | |
* + +
* 20 | |
* + +
* 24 | |
* + +
* 28 | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* 32 | |
* + Route Label +
* 36 | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
void Address_serialize(uint8_t output[Address_SERIALIZED_SIZE], const struct Address* addr);
void Address_parse(struct Address* addr, const uint8_t input[Address_SERIALIZED_SIZE]);
bool Address_isSame(const struct Address* addr,
const struct Address* addr2);
bool Address_isSameIp(const struct Address* addr,
const struct Address* addr2);
bool Address_equalsSearchTarget(struct Address* addr,
const uint8_t searchTarget[Address_SEARCH_TARGET_SIZE]);
void Address_forKey(struct Address* out, const uint8_t key[Address_KEY_SIZE]);
void Address_printIp(uint8_t output[40], struct Address* addr);
void Address_printShortIp(uint8_t output[40], struct Address* addr);
void Address_print(uint8_t output[60], struct Address* addr);
String* Address_toString(struct Address* addr, struct Allocator* alloc);
String* Address_toStringKey(struct Address* addr, struct Allocator* alloc);
struct Address* Address_fromString(String* str, struct Allocator* alloc);
struct Address* Address_clone(struct Address* orig, struct Allocator* alloc);
int Address_xorcmp(uint32_t target,
uint32_t negativeIfCloser,
uint32_t positiveIfCloser);
/**
* Return which node is closer to the target.
*
* @param target the address to test distance against.
* @param negativeIfCloser one address to check distance.
* @param positiveIfCloser another address to check distance.
* @return -1 if negativeIfCloser is closer to target, 1 if positiveIfCloser is closer
* 0 if they are both the same distance.
*/
int Address_closest(struct Address* target,
struct Address* negativeIfCloser,
struct Address* positiveIfCloser);
#endif