GNUnet 0.21.0
rps-test_util.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C)
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
29#include "platform.h"
30#include "gnunet_util_lib.h"
31#include "rps-test_util.h"
32
33#include <inttypes.h>
34
35#define LOG(kind, ...) GNUNET_log_from (kind, "rps-test_util", __VA_ARGS__)
36
37#define B2B_PAT "%c%c%c%c%c%c%c%c"
38#define B2B(byte) \
39 (byte & 0x80 ? '1' : '0'), \
40 (byte & 0x40 ? '1' : '0'), \
41 (byte & 0x20 ? '1' : '0'), \
42 (byte & 0x10 ? '1' : '0'), \
43 (byte & 0x08 ? '1' : '0'), \
44 (byte & 0x04 ? '1' : '0'), \
45 (byte & 0x02 ? '1' : '0'), \
46 (byte & 0x01 ? '1' : '0')
47
48#ifdef TO_FILE
49
50
54static char buf_unaligned;
55
59static unsigned num_bits_buf_unaligned;
60
62
63
74get_file_handle (const char *name)
75{
76 struct GNUNET_HashCode hash;
78
79 if (NULL == open_files)
80 {
82 GNUNET_NO);
84 "Created map of open files.\n");
85 }
87 strlen (name),
88 &hash);
90 &hash)))
91 return fh;
99 if (NULL == fh)
100 {
102 "Opening file `%s' failed.\n",
103 name);
104 GNUNET_assert (0);
105 }
108 &hash,
109 fh,
111 return fh;
112}
113
114
128int
130 const struct GNUNET_HashCode *key,
131 void *value)
132{
133 (void) cls;
134 (void) key;
136
137 if (NULL != fh)
138 {
140 }
141 return GNUNET_YES;
142}
143
144
150int
152{
153 int ret;
154
155 if (NULL != open_files)
156 {
159 NULL);
161 open_files = NULL;
162 return ret;
163 }
164 return GNUNET_YES;
165}
166
167
168void
169to_file_raw (const char *file_name, const char *buf, size_t size_buf)
170{
172 size_t size_written;
173
174 if (NULL == (f = GNUNET_DISK_file_open (file_name,
182 {
184 "Not able to open file %s\n",
185 file_name);
186 return;
187 }
188
189 size_written = GNUNET_DISK_file_write (f, buf, size_buf);
190 if (size_buf != size_written)
191 {
193 "Unable to write to file! (Size: %llu, size_written: %llu)\n",
194 (unsigned long long) size_buf,
195 (unsigned long long) size_written);
196
199 "Unable to close file\n");
200
201 return;
202 }
204 "Wrote %llu bytes raw.\n",
205 (unsigned long long) size_written);
208 "Unable to close file\n");
209}
210
211
212void
214 const char *buf,
215 size_t size_buf,
216 unsigned bits_needed)
217{
218 // TODO endianness!
219 GNUNET_assert (size_buf >= (bits_needed / 8));
220 // if (0 == num_bits_buf_unaligned)
221 // {
222 // if (0 == (bits_needed % 8))
223 // {
224 // to_file_raw (file_name, buf, size_buf);
225 // return;
226 // }
227 // to_file_raw (file_name, buf, size_buf - 1);
228 // buf_unaligned = buf[size_buf - 1];
229 // num_bits_buf_unaligned = bits_needed % 8;
230 // return;
231 // }
233 "Was asked to write %u bits\n", bits_needed);
234
235 char buf_write[size_buf + 1];
236 const unsigned bytes_iter = (0 != bits_needed % 8 ?
237 (bits_needed / 8) + 1 :
238 bits_needed / 8);
239 // TODO what if no iteration happens?
240 unsigned size_buf_write = 0;
242 "num_bits_buf_unaligned: %u\n",
245 "ua args: size_buf: %llu, bits_needed: %u -> iter: %u\n",
246 (unsigned long long) size_buf,
247 bits_needed,
248 bytes_iter);
249 buf_write[0] = buf_unaligned;
250 /* Iterate over input bytes */
251 for (unsigned i = 0; i < bytes_iter; i++)
252 {
253 /* Number of bits needed in this iteration - 8 for all except last iter */
254 unsigned num_bits_needed_iter;
255 /* Mask for bits to actually use */
256 unsigned mask_bits_needed_iter;
257 char byte_input;
258 /* Number of bits needed to align unaligned byte */
259 unsigned num_bits_to_align;
260 /* Number of bits that are to be moved */
261 unsigned num_bits_to_move;
262 /* Mask for bytes to be moved */
263 char mask_input_to_move;
264 /* Masked bits to be moved */
265 char bits_to_move;
266 /* The amount of bits needed to fit the bits to shift to the nearest spot */
267 unsigned distance_shift_bits;
268 /* Shifted bits on the move */
269 char bits_moving;
270 /* (unaligned) byte being filled with bits */
271 char byte_to_fill;
272 /* mask for needed bits of the input byte that have not been moved */
273 char mask_input_leftover;
274 /* needed bits of the input byte that have not been moved */
275 char byte_input_leftover;
276 unsigned num_bits_leftover;
277 // unsigned num_bits_discard;
278 char byte_unaligned_new;
279
280 if ((bits_needed - (i * 8)) <= 8)
281 {
282 /* last iteration */
283 num_bits_needed_iter = bits_needed - (i * 8);
284 }
285 else
286 {
287 num_bits_needed_iter = 8;
288 }
290 "number of bits needed in this iteration: %u\n",
291 num_bits_needed_iter);
292 mask_bits_needed_iter = ((char) 1 << num_bits_needed_iter) - 1;
294 "mask needed bits (current iter): "B2B_PAT "\n",
295 B2B (mask_bits_needed_iter));
297 "Unaligned byte: "B2B_PAT " (%u bits)\n",
300 byte_input = buf[i];
302 "next whole input byte: "B2B_PAT "\n",
303 B2B (byte_input));
304 byte_input &= mask_bits_needed_iter;
305 num_bits_to_align = 8 - num_bits_buf_unaligned;
307 "input byte, needed bits: "B2B_PAT "\n",
308 B2B (byte_input));
310 "number of bits needed to align unaligned bit: %u\n",
311 num_bits_to_align);
312 num_bits_to_move = GNUNET_MIN (num_bits_to_align, num_bits_needed_iter);
314 "number of bits of new byte to move: %u\n",
315 num_bits_to_move);
316 mask_input_to_move = ((char) 1 << num_bits_to_move) - 1;
318 "mask of bits of new byte to take for moving: "B2B_PAT "\n",
319 B2B (mask_input_to_move));
320 bits_to_move = byte_input & mask_input_to_move;
322 "masked bits of new byte to take for moving: "B2B_PAT "\n",
323 B2B (bits_to_move));
324 distance_shift_bits = num_bits_buf_unaligned;
326 "distance needed to shift bits to their correct spot: %u\n",
327 distance_shift_bits);
328 bits_moving = bits_to_move << distance_shift_bits;
330 "shifted, masked bits of new byte being moved: "B2B_PAT "\n",
331 B2B (bits_moving));
332 byte_to_fill = buf_unaligned | bits_moving;
334 "byte being filled: "B2B_PAT "\n",
335 B2B (byte_to_fill));
337 "pending bytes: %u\n",
338 num_bits_buf_unaligned + num_bits_needed_iter);
339 if (num_bits_buf_unaligned + num_bits_needed_iter >= 8)
340 {
341 /* buf_unaligned was aligned by filling
342 * -> can be written to storage */
343 buf_write[i] = byte_to_fill;
344 size_buf_write++;
345
346 /* store the leftover, unaligned bits in buffer */
347 mask_input_leftover = mask_bits_needed_iter & (~mask_input_to_move);
349 "mask of leftover bits of new byte: "B2B_PAT "\n",
350 B2B (mask_input_leftover));
351 byte_input_leftover = byte_input & mask_input_leftover;
353 "masked, leftover bits of new byte: "B2B_PAT "\n",
354 B2B (byte_input_leftover));
355 num_bits_leftover = num_bits_needed_iter - num_bits_to_move;
357 "number of unaligned bits left: %u\n",
358 num_bits_leftover);
359 // num_bits_discard = 8 - num_bits_needed_iter;
360 byte_unaligned_new = byte_input_leftover >> num_bits_to_move;
362 "new unaligned byte: "B2B_PAT "\n",
363 B2B (byte_unaligned_new));
364 buf_unaligned = byte_unaligned_new;
365 num_bits_buf_unaligned = num_bits_leftover % 8;
366 }
367 else
368 {
369 /* unaligned buffer still unaligned but 'fuller' */
370 buf_unaligned = byte_to_fill;
372 }
373 }
374 to_file_raw (file_name, buf_write, size_buf_write);
376}
377
378
379char *
381{
382 int size;
383 size_t name_buf_size;
384 char *end;
385 char *buf;
386 char *name_buf;
387 size_t keylen = (sizeof(struct GNUNET_CRYPTO_AuthKey)) * 8;
388
389 name_buf_size = 512 * sizeof(char);
390 name_buf = GNUNET_malloc (name_buf_size);
391
392 if (keylen % 5 > 0)
393 keylen += 5 - keylen % 5;
394 keylen /= 5;
395 buf = GNUNET_malloc (keylen + 1);
396
398 sizeof(struct GNUNET_CRYPTO_AuthKey),
399 buf,
400 keylen);
401
402 if (NULL == end)
403 {
404 GNUNET_free (buf);
405 GNUNET_break (0);
406 }
407 else
408 {
409 *end = '\0';
410 }
411
412 size = GNUNET_snprintf (name_buf, name_buf_size, "sampler_el-%s", buf);
413 if (0 > size)
414 LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to create name_buf\n");
415
416 GNUNET_free (buf);
417
418 return name_buf;
419}
420
421
422#endif /* TO_FILE */
423
424
426string_to_auth_key (const char *str)
427{
428 struct GNUNET_CRYPTO_AuthKey auth_key;
429
430 if (GNUNET_OK !=
432 strlen (str),
433 &auth_key.key,
434 sizeof(struct GNUNET_CRYPTO_AuthKey)))
435 {
436 LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to convert string to data\n");
437 }
438
439 return auth_key;
440}
441
442
449static int
451{
452 if (GNUNET_OK !=
453 GNUNET_DISK_directory_create ("/tmp/rps"))
454 {
456 "Could not create directory `/tmp/rps'\n");
457 return GNUNET_SYSERR;
458 }
459 return GNUNET_YES;
460}
461
462
463char *
464store_prefix_file_name (const unsigned int index,
465 const char *prefix)
466{
467 int len_file_name;
468 int out_size;
469 char *file_name;
470 char index_str[64];
471
473 return NULL;
474 out_size = GNUNET_snprintf (index_str,
475 64,
476 "%u",
477 index);
478 if ((64 < out_size) ||
479 (0 > out_size) )
480 {
482 "Failed to write string to buffer (size: %i, out_size: %i)\n",
483 64,
484 out_size);
485 }
486 len_file_name = (strlen (prefix)
487 + strlen (index_str)
488 + 11)
489 * sizeof(char);
490 file_name = GNUNET_malloc (len_file_name);
491 out_size = GNUNET_snprintf (file_name,
492 len_file_name,
493 "/tmp/rps/%s-%s",
494 prefix,
495 index_str);
496 if ((len_file_name < out_size) ||
497 (0 > out_size) )
498 {
500 "Failed to write string to buffer (size: %i, out_size: %i)\n",
501 len_file_name,
502 out_size);
503 }
504 return file_name;
505}
506
507
515uint32_t
516fac (uint32_t x)
517{
518 if (1 >= x)
519 {
520 return x;
521 }
522 return x * fac (x - 1);
523}
524
525
534uint32_t
535binom (uint32_t n, uint32_t k)
536{
537 // GNUNET_assert (n >= k);
538 if (k > n)
539 return 0;
540 /* if (0 > n) return 0; - always false */
541 /* if (0 > k) return 0; - always false */
542 if (0 == k)
543 return 1;
544 return fac (n)
545 /
546 fac (k) * fac (n - k);
547}
548
549
550/* end of gnunet-service-rps.c */
static int ret
Final status code.
Definition: gnunet-arm.c:94
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
static int prefix
If printing the value of PREFIX has been requested.
Definition: gnunet-config.c:59
static char * file_name
Dump file name.
struct GNUNET_HashCode key
The key used in the DHT.
static char * name
Name (label) of the records to list.
static char * value
Value of the record to add/remove.
static struct GNUNET_DISK_FileHandle * fh
File handle to STDIN, for reading restart/quit commands.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1237
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:686
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1308
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:496
@ GNUNET_DISK_OPEN_WRITE
Open the file for writing.
@ GNUNET_DISK_OPEN_CREATE
Create file if it doesn't exist.
@ GNUNET_DISK_OPEN_APPEND
Append to the file.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_GROUP_READ
Group can read.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
@ GNUNET_DISK_PERM_OTHER_READ
Everybody can read.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_log(kind,...)
#define GNUNET_MIN(a, b)
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:709
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:789
static unsigned int size
Size of the "table".
Definition: peer.c:68
char * auth_key_to_string(struct GNUNET_CRYPTO_AuthKey auth_key)
uint32_t fac(uint32_t x)
Factorial.
static char buf_unaligned
buffer for storing the unaligned bits for the next write
Definition: rps-test_util.c:54
int close_files_iter(void *cls, const struct GNUNET_HashCode *key, void *value)
Closes the file of the current entry.
char * store_prefix_file_name(const unsigned int index, const char *prefix)
static int ensure_folder_exist(void)
Try to ensure that /tmp/rps exists.
#define B2B_PAT
Definition: rps-test_util.c:37
void to_file_raw_unaligned(const char *file_name, const char *buf, size_t size_buf, unsigned bits_needed)
static struct GNUNET_CONTAINER_MultiHashMap * open_files
Definition: rps-test_util.c:61
int close_all_files()
Close all files that were opened with get_file_handle.
#define B2B(byte)
Definition: rps-test_util.c:38
void to_file_raw(const char *file_name, const char *buf, size_t size_buf)
struct GNUNET_CRYPTO_AuthKey string_to_auth_key(const char *str)
struct GNUNET_DISK_FileHandle * get_file_handle(const char *name)
Get file handle.
Definition: rps-test_util.c:74
static unsigned num_bits_buf_unaligned
number of bits in unaligned buffer
Definition: rps-test_util.c:59
#define LOG(kind,...)
Definition: rps-test_util.c:35
uint32_t binom(uint32_t n, uint32_t k)
Binomial coefficient (n choose k)
Some utils facilitating the view into the internals for the sampler needed for evaluation.
Internal representation of the hash map.
type for (message) authentication keys
unsigned char key[(512/8)]
Handle used to access files (and pipes).
A 512-bit hashcode.