mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
d4be41a3ad
The new encoding is `0` for `Nothing` and `[1, x]` for `Just x`.
260 lines
6.4 KiB
C
260 lines
6.4 KiB
C
#define _BSD_SOURCE
|
|
#include "methods.h"
|
|
|
|
#include "byteswap.h"
|
|
#include "packet_kinds.h"
|
|
|
|
#include "../../toxcore/DHT.h"
|
|
|
|
METHOD(bin, Binary_encode, CipherText)
|
|
{
|
|
uint64_t length = be64toh(args.size);
|
|
|
|
SUCCESS {
|
|
msgpack_pack_bin(res, sizeof(uint64_t) + args.size);
|
|
msgpack_pack_bin_body(res, &length, sizeof(uint64_t));
|
|
msgpack_pack_bin_body(res, args.ptr, args.size);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
METHOD(array, Binary_encode, DhtPacket)
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
METHOD(array, Binary_encode, DhtRequestPacket)
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
METHOD(array, Binary_encode, HostAddress)
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
METHOD(u64, Binary_encode, Word64)
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
METHOD(bin, Binary_encode, Key_PublicKey)
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
METHOD(array, Binary_encode, KeyPair)
|
|
{
|
|
CHECK_SIZE(args, 2);
|
|
CHECK_TYPE(args.ptr[0], MSGPACK_OBJECT_BIN);
|
|
CHECK_TYPE(args.ptr[1], MSGPACK_OBJECT_BIN);
|
|
|
|
msgpack_object_bin secret_key = args.ptr[0].via.bin;
|
|
msgpack_object_bin public_key = args.ptr[1].via.bin;
|
|
|
|
CHECK_SIZE(secret_key, 32);
|
|
CHECK_SIZE(public_key, 32);
|
|
|
|
SUCCESS {
|
|
uint8_t data[64];
|
|
memcpy(data, secret_key.ptr, 32);
|
|
memcpy(data + 32, public_key.ptr, 32);
|
|
msgpack_pack_bin(res, 64);
|
|
msgpack_pack_bin_body(res, data, 64);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define PACKED_NODE_SIZE_IP6 (1 + SIZE_IP6 + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE)
|
|
METHOD(array, Binary_encode, NodeInfo)
|
|
{
|
|
CHECK_SIZE(args, 3);
|
|
|
|
CHECK_TYPE(args.ptr[0], MSGPACK_OBJECT_POSITIVE_INTEGER);
|
|
uint64_t protocol = args.ptr[0].via.u64;
|
|
|
|
CHECK_TYPE(args.ptr[1], MSGPACK_OBJECT_ARRAY);
|
|
msgpack_object_array address = args.ptr[1].via.array;
|
|
|
|
CHECK_SIZE(address, 2);
|
|
CHECK_TYPE(address.ptr[0], MSGPACK_OBJECT_ARRAY);
|
|
msgpack_object_array host_address = address.ptr[0].via.array;
|
|
|
|
CHECK_TYPE(address.ptr[1], MSGPACK_OBJECT_POSITIVE_INTEGER);
|
|
uint64_t port_number = address.ptr[1].via.u64;
|
|
|
|
CHECK_SIZE(host_address, 2);
|
|
CHECK_TYPE(host_address.ptr[0], MSGPACK_OBJECT_POSITIVE_INTEGER);
|
|
uint64_t address_family = host_address.ptr[0].via.u64;
|
|
|
|
CHECK_TYPE(args.ptr[2], MSGPACK_OBJECT_BIN);
|
|
msgpack_object_bin public_key = args.ptr[2].via.bin;
|
|
|
|
CHECK_SIZE(public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
|
|
|
IP_Port ipp;
|
|
ipp.port = htons(port_number);
|
|
|
|
switch (address_family) {
|
|
case 0: {
|
|
/* IPv4*/
|
|
if (protocol == 1) {
|
|
ipp.ip.family = TCP_INET;
|
|
} else {
|
|
ipp.ip.family = AF_INET;
|
|
}
|
|
|
|
CHECK_TYPE(host_address.ptr[1], MSGPACK_OBJECT_POSITIVE_INTEGER);
|
|
uint64_t addr = host_address.ptr[1].via.u64;
|
|
|
|
ipp.ip.ip4.uint32 = htonl(addr);
|
|
break;
|
|
}
|
|
|
|
case 1: {
|
|
/* IPv6 */
|
|
if (protocol == 1) {
|
|
ipp.ip.family = TCP_INET6;
|
|
} else {
|
|
ipp.ip.family = AF_INET6;
|
|
}
|
|
|
|
CHECK_TYPE(host_address.ptr[1], MSGPACK_OBJECT_ARRAY);
|
|
msgpack_object_array addr = host_address.ptr[1].via.array;
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < 4; ++i) {
|
|
CHECK_TYPE(addr.ptr[i], MSGPACK_OBJECT_POSITIVE_INTEGER);
|
|
uint64_t component = addr.ptr[i].via.u64;
|
|
ipp.ip.ip6.uint32[i] = htonl(component);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
Node_format node;
|
|
node.ip_port = ipp;
|
|
memcpy(&node.public_key, public_key.ptr, CRYPTO_PUBLIC_KEY_SIZE);
|
|
|
|
/* We assume IP6 because it's bigger */
|
|
uint8_t packed_node[PACKED_NODE_SIZE_IP6];
|
|
|
|
int len = pack_nodes(packed_node, sizeof packed_node, &node, 1);
|
|
|
|
if (len < 0) {
|
|
return failure;
|
|
}
|
|
|
|
SUCCESS {
|
|
msgpack_pack_bin(res, len);
|
|
msgpack_pack_bin_body(res, packed_node, len);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
METHOD(bin, Binary_encode, NodesRequest)
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
METHOD(array, Binary_encode, NodesResponse)
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
METHOD(array, Binary_encode, Packet_Word64)
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
METHOD(u64, Binary_encode, PacketKind)
|
|
{
|
|
CHECK(args < sizeof packet_kinds / sizeof * packet_kinds);
|
|
|
|
SUCCESS {
|
|
uint8_t data[] = {packet_kinds[args]};
|
|
msgpack_pack_bin(res, sizeof data);
|
|
msgpack_pack_bin_body(res, data, sizeof data);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
METHOD(u64, Binary_encode, PingPacket)
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
METHOD(bin, Binary_encode, PlainText)
|
|
{
|
|
return Binary_encode_CipherText(args, res);
|
|
}
|
|
|
|
METHOD(u64, Binary_encode, PortNumber)
|
|
{
|
|
SUCCESS {
|
|
if (args <= UINT16_MAX)
|
|
{
|
|
uint16_t port = ntohs(args);
|
|
msgpack_pack_bin(res, 2);
|
|
msgpack_pack_bin_body(res, &port, 2);
|
|
} else {
|
|
msgpack_pack_nil(res);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
METHOD(array, Binary_encode, RpcPacket_Word64)
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
METHOD(array, Binary_encode, SocketAddress)
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
METHOD(u64, Binary_encode, TransportProtocol)
|
|
{
|
|
return pending;
|
|
}
|
|
|
|
METHOD(array, Binary, encode)
|
|
{
|
|
CHECK_SIZE(args, 2);
|
|
CHECK_TYPE(args.ptr[0], MSGPACK_OBJECT_STR);
|
|
|
|
msgpack_object_str type = args.ptr[0].via.str;
|
|
#define DISPATCH(TYPE, UTYPE, LTYPE) \
|
|
do { \
|
|
if (type.size == sizeof #TYPE - 1 && method_cmp(type.ptr, #TYPE, type.size) == 0) { \
|
|
CHECK_TYPE(args.ptr[1], MSGPACK_OBJECT_##UTYPE); \
|
|
return Binary_encode_##TYPE(args.ptr[1].via.LTYPE, res); \
|
|
} \
|
|
} while (0)
|
|
DISPATCH(CipherText, BIN, bin);
|
|
DISPATCH(DhtPacket, ARRAY, array);
|
|
DISPATCH(DhtRequestPacket, ARRAY, array);
|
|
DISPATCH(HostAddress, ARRAY, array);
|
|
DISPATCH(Word64, POSITIVE_INTEGER, u64);
|
|
DISPATCH(Key_PublicKey, BIN, bin);
|
|
DISPATCH(KeyPair, ARRAY, array);
|
|
DISPATCH(NodeInfo, ARRAY, array);
|
|
DISPATCH(NodesRequest, BIN, bin);
|
|
DISPATCH(NodesResponse, ARRAY, array);
|
|
DISPATCH(Packet_Word64, ARRAY, array);
|
|
DISPATCH(PacketKind, POSITIVE_INTEGER, u64);
|
|
DISPATCH(PingPacket, POSITIVE_INTEGER, u64);
|
|
DISPATCH(PlainText, BIN, bin);
|
|
DISPATCH(PortNumber, POSITIVE_INTEGER, u64);
|
|
DISPATCH(RpcPacket_Word64, ARRAY, array);
|
|
DISPATCH(SocketAddress, ARRAY, array);
|
|
DISPATCH(TransportProtocol, POSITIVE_INTEGER, u64);
|
|
#undef DISPATCH
|
|
|
|
return unimplemented;
|
|
}
|