summaryrefslogtreecommitdiff
path: root/testing/hstox/binary_encode.c
diff options
context:
space:
mode:
Diffstat (limited to 'testing/hstox/binary_encode.c')
-rw-r--r--testing/hstox/binary_encode.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/testing/hstox/binary_encode.c b/testing/hstox/binary_encode.c
new file mode 100644
index 00000000..a39533c0
--- /dev/null
+++ b/testing/hstox/binary_encode.c
@@ -0,0 +1,252 @@
1#include "methods.h"
2
3#include "byteswap.h"
4#include "packet_kinds.h"
5
6#include <DHT.h>
7
8METHOD(bin, Binary_encode, CipherText)
9{
10 uint64_t length = be64toh(args.size);
11
12 SUCCESS {
13 msgpack_pack_bin(res, sizeof(uint64_t) + args.size);
14 msgpack_pack_bin_body(res, &length, sizeof(uint64_t));
15 msgpack_pack_bin_body(res, args.ptr, args.size);
16 }
17 return 0;
18}
19
20METHOD(array, Binary_encode, DhtPacket)
21{
22 return pending;
23}
24
25METHOD(array, Binary_encode, HostAddress)
26{
27 return pending;
28}
29
30METHOD(u64, Binary_encode, Word64)
31{
32 return pending;
33}
34
35METHOD(bin, Binary_encode, Key_PublicKey)
36{
37 return pending;
38}
39
40METHOD(array, Binary_encode, KeyPair)
41{
42 CHECK_SIZE(args, 2);
43 CHECK_TYPE(args.ptr[0], MSGPACK_OBJECT_BIN);
44 CHECK_TYPE(args.ptr[1], MSGPACK_OBJECT_BIN);
45
46 msgpack_object_bin secret_key = args.ptr[0].via.bin;
47 msgpack_object_bin public_key = args.ptr[1].via.bin;
48
49 CHECK_SIZE(secret_key, 32);
50 CHECK_SIZE(public_key, 32);
51
52 SUCCESS {
53 uint8_t data[64];
54 memcpy(data, secret_key.ptr, 32);
55 memcpy(data + 32, public_key.ptr, 32);
56 msgpack_pack_bin(res, 64);
57 msgpack_pack_bin_body(res, data, 64);
58 }
59
60 return 0;
61}
62
63#define PACKED_NODE_SIZE_IP6 (1 + SIZE_IP6 + sizeof(uint16_t) + crypto_box_PUBLICKEYBYTES)
64METHOD(array, Binary_encode, NodeInfo)
65{
66 CHECK_SIZE(args, 3);
67
68 CHECK_TYPE(args.ptr[0], MSGPACK_OBJECT_POSITIVE_INTEGER);
69 uint64_t protocol = args.ptr[0].via.u64;
70
71 CHECK_TYPE(args.ptr[1], MSGPACK_OBJECT_ARRAY);
72 msgpack_object_array address = args.ptr[1].via.array;
73
74 CHECK_SIZE(address, 2);
75 CHECK_TYPE(address.ptr[0], MSGPACK_OBJECT_ARRAY);
76 msgpack_object_array host_address = address.ptr[0].via.array;
77
78 CHECK_TYPE(address.ptr[1], MSGPACK_OBJECT_POSITIVE_INTEGER);
79 uint64_t port_number = address.ptr[1].via.u64;
80
81 CHECK_SIZE(host_address, 2);
82 CHECK_TYPE(host_address.ptr[0], MSGPACK_OBJECT_POSITIVE_INTEGER);
83 uint64_t address_family = host_address.ptr[0].via.u64;
84
85 CHECK_TYPE(args.ptr[2], MSGPACK_OBJECT_BIN);
86 msgpack_object_bin public_key = args.ptr[2].via.bin;
87
88 CHECK_SIZE(public_key, crypto_box_PUBLICKEYBYTES);
89
90 IP_Port ipp;
91 ipp.port = htons(port_number);
92
93 switch (address_family) {
94 case 0: {
95 /* IPv4*/
96 if (protocol == 1) {
97 ipp.ip.family = TCP_INET;
98 } else {
99 ipp.ip.family = AF_INET;
100 }
101
102 CHECK_TYPE(host_address.ptr[1], MSGPACK_OBJECT_POSITIVE_INTEGER);
103 uint64_t addr = host_address.ptr[1].via.u64;
104
105 ipp.ip.ip4.uint32 = htonl(addr);
106 break;
107 }
108
109 case 1: {
110 /* IPv6 */
111 if (protocol == 1) {
112 ipp.ip.family = TCP_INET6;
113 } else {
114 ipp.ip.family = AF_INET6;
115 }
116
117 CHECK_TYPE(host_address.ptr[1], MSGPACK_OBJECT_ARRAY);
118 msgpack_object_array addr = host_address.ptr[1].via.array;
119
120 int i;
121
122 for (i = 0; i < 4; ++i) {
123 CHECK_TYPE(addr.ptr[i], MSGPACK_OBJECT_POSITIVE_INTEGER);
124 uint64_t component = addr.ptr[i].via.u64;
125 ipp.ip.ip6.uint32[i] = htonl(component);
126 }
127
128 break;
129 }
130 }
131
132 Node_format node;
133 node.ip_port = ipp;
134 memcpy(&node.public_key, public_key.ptr, crypto_box_PUBLICKEYBYTES);
135
136 /* We assume IP6 because it's bigger */
137 uint8_t packed_node[PACKED_NODE_SIZE_IP6];
138
139 int len = pack_nodes(packed_node, sizeof packed_node, &node, 1);
140
141 if (len < 0) {
142 return failure;
143 }
144
145 SUCCESS {
146 msgpack_pack_bin(res, len);
147 msgpack_pack_bin_body(res, packed_node, len);
148 }
149 return 0;
150}
151
152METHOD(bin, Binary_encode, NodesRequest)
153{
154 return pending;
155}
156
157METHOD(array, Binary_encode, NodesResponse)
158{
159 return pending;
160}
161
162METHOD(array, Binary_encode, Packet_Word64)
163{
164 return pending;
165}
166
167METHOD(u64, Binary_encode, PacketKind)
168{
169 CHECK(args < sizeof packet_kinds / sizeof * packet_kinds);
170
171 SUCCESS {
172 uint8_t data[] = {packet_kinds[args]};
173 msgpack_pack_bin(res, sizeof data);
174 msgpack_pack_bin_body(res, data, sizeof data);
175 }
176 return 0;
177}
178
179METHOD(u64, Binary_encode, PingPacket)
180{
181 return pending;
182}
183
184METHOD(bin, Binary_encode, PlainText)
185{
186 return pending;
187}
188
189METHOD(u64, Binary_encode, PortNumber)
190{
191 SUCCESS {
192 if (args <= UINT16_MAX)
193 {
194 uint16_t port = ntohs(args);
195 msgpack_pack_bin(res, 2);
196 msgpack_pack_bin_body(res, &port, 2);
197 } else {
198 msgpack_pack_nil(res);
199 }
200 }
201 return 0;
202}
203
204METHOD(array, Binary_encode, RpcPacket_Word64)
205{
206 return pending;
207}
208
209METHOD(array, Binary_encode, SocketAddress)
210{
211 return pending;
212}
213
214METHOD(u64, Binary_encode, TransportProtocol)
215{
216 return pending;
217}
218
219METHOD(array, Binary, encode)
220{
221 CHECK_SIZE(args, 2);
222 CHECK_TYPE(args.ptr[0], MSGPACK_OBJECT_STR);
223
224 msgpack_object_str type = args.ptr[0].via.str;
225#define DISPATCH(TYPE, UTYPE, LTYPE) \
226 do { \
227 if (type.size == sizeof #TYPE - 1 && method_cmp(type.ptr, #TYPE, type.size) == 0) { \
228 CHECK_TYPE(args.ptr[1], MSGPACK_OBJECT_##UTYPE); \
229 return Binary_encode_##TYPE(args.ptr[1].via.LTYPE, res); \
230 } \
231 } while (0)
232 DISPATCH(CipherText, BIN, bin);
233 DISPATCH(DhtPacket, ARRAY, array);
234 DISPATCH(HostAddress, ARRAY, array);
235 DISPATCH(Word64, POSITIVE_INTEGER, u64);
236 DISPATCH(Key_PublicKey, BIN, bin);
237 DISPATCH(KeyPair, ARRAY, array);
238 DISPATCH(NodeInfo, ARRAY, array);
239 DISPATCH(NodesRequest, BIN, bin);
240 DISPATCH(NodesResponse, ARRAY, array);
241 DISPATCH(Packet_Word64, ARRAY, array);
242 DISPATCH(PacketKind, POSITIVE_INTEGER, u64);
243 DISPATCH(PingPacket, POSITIVE_INTEGER, u64);
244 DISPATCH(PlainText, BIN, bin);
245 DISPATCH(PortNumber, POSITIVE_INTEGER, u64);
246 DISPATCH(RpcPacket_Word64, ARRAY, array);
247 DISPATCH(SocketAddress, ARRAY, array);
248 DISPATCH(TransportProtocol, POSITIVE_INTEGER, u64);
249#undef DISPATCH
250
251 return unimplemented;
252}