GNUnet  0.11.x
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  {
81  open_files = GNUNET_CONTAINER_multihashmap_create (16,
82  GNUNET_NO);
84  "Created map of open files.\n");
85  }
86  GNUNET_CRYPTO_hash (name,
87  strlen (name),
88  &hash);
89  if (NULL != (fh = GNUNET_CONTAINER_multihashmap_get (open_files,
90  &hash)))
91  return fh;
92  fh = GNUNET_DISK_file_open (name,
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  {
157  ret = GNUNET_CONTAINER_multihashmap_iterate (open_files,
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 */
struct GNUNET_DISK_FileHandle * get_file_handle(const char *name)
Get file handle.
Definition: rps-test_util.c:74
Create file if it doesn&#39;t exist.
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
int close_files_iter(void *cls, const struct GNUNET_HashCode *key, void *value)
Closes the file of the current entry.
Some utils facilitating the view into the internals for the sampler needed for evaluation.
void to_file_raw(const char *file_name, const char *buf, size_t size_buf)
char * auth_key_to_string(struct GNUNET_CRYPTO_AuthKey auth_key)
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1126
static struct GNUNET_CONTAINER_MultiHashMap * open_files
Definition: rps-test_util.c:61
static char * file_name
Dump file name.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
Append to the file.
static unsigned bits_needed
number of bits required to represent the largest peer id
static unsigned num_bits_buf_unaligned
number of bits in unaligned buffer
Definition: rps-test_util.c:59
void to_file_raw_unaligned(const char *file_name, const char *buf, size_t size_buf, unsigned bits_needed)
Internal representation of the hash map.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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.
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.
static char * value
Value of the record to add/remove.
char * store_prefix_file_name(const unsigned int index, const char *prefix)
#define B2B_PAT
Definition: rps-test_util.c:37
#define LOG(kind,...)
Definition: rps-test_util.c:35
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
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:666
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:93
static char buf[2048]
static char buf_unaligned
buffer for storing the unaligned bits for the next write
Definition: rps-test_util.c:54
unsigned char key[(512/8)]
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:476
static int fh
Handle to the unique file.
A 512-bit hashcode.
uint32_t binom(uint32_t n, uint32_t k)
Binomial coefficient (n choose k)
int close_all_files()
Close all files that were opened with get_file_handle.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GNUNET_HashCode key
The key used in the DHT.
static unsigned int size
Size of the "table".
Definition: peer.c:67
Open the file for writing.
#define B2B(byte)
Definition: rps-test_util.c:38
int 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.
uint32_t fac(uint32_t x)
Factorial.
Everybody can read.
const char * name
static int ensure_folder_exist(void)
Try to ensure that /tmp/rps exists.
struct GNUNET_CRYPTO_AuthKey string_to_auth_key(const char *str)
#define GNUNET_log(kind,...)
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
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:1055
Handle used to access files (and pipes).
type for (message) authentication keys
#define GNUNET_malloc(size)
Wrapper around malloc.
int 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:972
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:872
#define GNUNET_free(ptr)
Wrapper around free.