mirror of
https://github.com/TokTok/c-toxcore
synced 2026-06-03 21:21:36 +00:00
f2b6090eca
This library contains all the code for the old libtoxcore, libtoxav, libtoxdns, and libtoxencryptsave. The build for toxav is still optional, and disabling it causes libtoxcore to simply not contain those symbols and the pkg-config file to not include opus and vpx as dependencies.
260 lines
6.4 KiB
C
260 lines
6.4 KiB
C
#define _DEFAULT_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;
|
|
}
|