GNUnet  0.19.4
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 
54 static char buf_unaligned;
55 
59 static unsigned num_bits_buf_unaligned;
60 
62 
63 
74 get_file_handle (const char *name)
75 {
76  struct GNUNET_HashCode hash;
77  struct GNUNET_DISK_FileHandle *fh;
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 
128 int
129 close_files_iter (void *cls,
130  const struct GNUNET_HashCode *key,
131  void *value)
132 {
133  (void) cls;
134  (void) key;
135  struct GNUNET_DISK_FileHandle *fh = value;
136 
137  if (NULL != fh)
138  {
140  }
141  return GNUNET_YES;
142 }
143 
144 
150 int
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 
168 void
169 to_file_raw (const char *file_name, const char *buf, size_t size_buf)
170 {
171  struct GNUNET_DISK_FileHandle *f;
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 
212 void
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",
298  B2B (buf_unaligned),
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 
379 char *
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 
397  end = GNUNET_STRINGS_data_to_string (&(auth_key.key),
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 
426 string_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 
449 static 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 
463 char *
464 store_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 
515 uint32_t
516 fac (uint32_t x)
517 {
518  if (1 >= x)
519  {
520  return x;
521  }
522  return x * fac (x - 1);
523 }
524 
525 
534 uint32_t
535 binom (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
Return value of the commandline.
Definition: gnunet-abd.c:81
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 * value
Value of the record to add/remove.
static unsigned bits_needed
number of bits required to represent the largest peer id
static char buf[2048]
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.
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.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash 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.
@ 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:708
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:788
static unsigned int size
Size of the "table".
Definition: peer.c:68
const char * name
struct GNUNET_DISK_FileHandle * get_file_handle(const char *name)
Get file handle.
Definition: rps-test_util.c:74
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.
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
char * store_prefix_file_name(const unsigned int index, const char *prefix)
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)
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
char * auth_key_to_string(struct GNUNET_CRYPTO_AuthKey auth_key)
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.