diff options
Diffstat (limited to 'testing/hstox/binary_encode.c')
-rw-r--r-- | testing/hstox/binary_encode.c | 252 |
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 | |||
8 | METHOD(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 | |||
20 | METHOD(array, Binary_encode, DhtPacket) | ||
21 | { | ||
22 | return pending; | ||
23 | } | ||
24 | |||
25 | METHOD(array, Binary_encode, HostAddress) | ||
26 | { | ||
27 | return pending; | ||
28 | } | ||
29 | |||
30 | METHOD(u64, Binary_encode, Word64) | ||
31 | { | ||
32 | return pending; | ||
33 | } | ||
34 | |||
35 | METHOD(bin, Binary_encode, Key_PublicKey) | ||
36 | { | ||
37 | return pending; | ||
38 | } | ||
39 | |||
40 | METHOD(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) | ||
64 | METHOD(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 | |||
152 | METHOD(bin, Binary_encode, NodesRequest) | ||
153 | { | ||
154 | return pending; | ||
155 | } | ||
156 | |||
157 | METHOD(array, Binary_encode, NodesResponse) | ||
158 | { | ||
159 | return pending; | ||
160 | } | ||
161 | |||
162 | METHOD(array, Binary_encode, Packet_Word64) | ||
163 | { | ||
164 | return pending; | ||
165 | } | ||
166 | |||
167 | METHOD(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 | |||
179 | METHOD(u64, Binary_encode, PingPacket) | ||
180 | { | ||
181 | return pending; | ||
182 | } | ||
183 | |||
184 | METHOD(bin, Binary_encode, PlainText) | ||
185 | { | ||
186 | return pending; | ||
187 | } | ||
188 | |||
189 | METHOD(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 | |||
204 | METHOD(array, Binary_encode, RpcPacket_Word64) | ||
205 | { | ||
206 | return pending; | ||
207 | } | ||
208 | |||
209 | METHOD(array, Binary_encode, SocketAddress) | ||
210 | { | ||
211 | return pending; | ||
212 | } | ||
213 | |||
214 | METHOD(u64, Binary_encode, TransportProtocol) | ||
215 | { | ||
216 | return pending; | ||
217 | } | ||
218 | |||
219 | METHOD(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 | } | ||