GNUnet  0.10.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 
64 
75 get_file_handle (const char *name)
76 {
77  struct GNUNET_HashCode hash;
78  struct GNUNET_DISK_FileHandle *fh;
79 
80  if (NULL == open_files)
81  {
82  open_files = GNUNET_CONTAINER_multihashmap_create (16,
83  GNUNET_NO);
85  "Created map of open files.\n");
86  }
87  GNUNET_CRYPTO_hash (name,
88  strlen (name),
89  &hash);
90  if (NULL != (fh = GNUNET_CONTAINER_multihashmap_get (open_files,
91  &hash)))
92  return fh;
93  fh = GNUNET_DISK_file_open (name,
100  if (NULL == fh)
101  {
103  "Opening file `%s' failed.\n",
104  name);
105  GNUNET_assert (0);
106  }
109  &hash,
110  fh,
112  return fh;
113 }
114 
115 
129 int
130 close_files_iter (void *cls,
131  const struct GNUNET_HashCode *key,
132  void *value)
133 {
134  (void) cls;
135  (void) key;
136  struct GNUNET_DISK_FileHandle *fh = value;
137 
138  if (NULL != fh)
139  {
141  }
142  return GNUNET_YES;
143 }
144 
145 
151 int
153 {
154  int ret;
155 
156  ret = GNUNET_CONTAINER_multihashmap_iterate (open_files,
158  NULL);
160  open_files = NULL;
161  return ret;
162 }
163 
164 
165 
166 void
167 to_file_raw (const char *file_name, const char *buf, size_t size_buf)
168 {
169  struct GNUNET_DISK_FileHandle *f;
170  size_t size_written;
171 
172  if (NULL == (f = GNUNET_DISK_file_open (file_name,
180  {
182  "Not able to open file %s\n",
183  file_name);
184  return;
185  }
186 
187  size_written = GNUNET_DISK_file_write (f, buf, size_buf);
188  if (size_buf != size_written)
189  {
191  "Unable to write to file! (Size: %u, size_written: %u)\n",
192  size_buf,
193  size_written);
194 
197  "Unable to close file\n");
198 
199  return;
200  }
202  "Wrote %u bytes raw.\n",
203  size_written);
206  "Unable to close file\n");
207 }
208 
209 void
211  const char *buf,
212  size_t size_buf,
213  unsigned bits_needed)
214 {
215  // TODO endianness!
216  GNUNET_assert (size_buf >= (bits_needed/8));
217  //if (0 == num_bits_buf_unaligned)
218  //{
219  // if (0 == (bits_needed % 8))
220  // {
221  // to_file_raw (file_name, buf, size_buf);
222  // return;
223  // }
224  // to_file_raw (file_name, buf, size_buf - 1);
225  // buf_unaligned = buf[size_buf - 1];
226  // num_bits_buf_unaligned = bits_needed % 8;
227  // return;
228  //}
230  "Was asked to write %u bits\n", bits_needed);
231 
232  char buf_write[size_buf + 1];
233  const unsigned bytes_iter = (0 != bits_needed % 8?
234  (bits_needed/8)+1:
235  bits_needed/8);
236  // TODO what if no iteration happens?
237  unsigned size_buf_write = 0;
239  "num_bits_buf_unaligned: %u\n",
242  "ua args: size_buf: %u, bits_needed: %u -> iter: %u\n",
243  size_buf,
244  bits_needed,
245  bytes_iter);
246  buf_write[0] = buf_unaligned;
247  /* Iterate over input bytes */
248  for (unsigned i = 0; i < bytes_iter; i++)
249  {
250  /* Number of bits needed in this iteration - 8 for all except last iter */
251  unsigned num_bits_needed_iter;
252  /* Mask for bits to actually use */
253  unsigned mask_bits_needed_iter;
254  char byte_input;
255  /* Number of bits needed to align unaligned byte */
256  unsigned num_bits_to_align;
257  /* Number of bits that are to be moved */
258  unsigned num_bits_to_move;
259  /* Mask for bytes to be moved */
260  char mask_input_to_move;
261  /* Masked bits to be moved */
262  char bits_to_move;
263  /* The amount of bits needed to fit the bits to shift to the nearest spot */
264  unsigned distance_shift_bits;
265  /* Shifted bits on the move */
266  char bits_moving;
267  /* (unaligned) byte being filled with bits */
268  char byte_to_fill;
269  /* mask for needed bits of the input byte that have not been moved */
270  char mask_input_leftover;
271  /* needed bits of the input byte that have not been moved */
272  char byte_input_leftover;
273  unsigned num_bits_leftover;
274  //unsigned num_bits_discard;
275  char byte_unaligned_new;
276 
277  if ( (bits_needed - (i * 8)) <= 8)
278  {
279  /* last iteration */
280  num_bits_needed_iter = bits_needed - (i * 8);
281  }
282  else
283  {
284  num_bits_needed_iter = 8;
285  }
287  "number of bits needed in this iteration: %u\n",
288  num_bits_needed_iter);
289  mask_bits_needed_iter = ((char) 1 << num_bits_needed_iter) - 1;
291  "mask needed bits (current iter): "B2B_PAT"\n",
292  B2B(mask_bits_needed_iter));
294  "Unaligned byte: "B2B_PAT" (%u bits)\n",
297  byte_input = buf[i];
299  "next whole input byte: "B2B_PAT"\n",
300  B2B(byte_input));
301  byte_input &= mask_bits_needed_iter;
302  num_bits_to_align = 8 - num_bits_buf_unaligned;
304  "input byte, needed bits: "B2B_PAT"\n",
305  B2B(byte_input));
307  "number of bits needed to align unaligned bit: %u\n",
308  num_bits_to_align);
309  num_bits_to_move = GNUNET_MIN (num_bits_to_align, num_bits_needed_iter);
311  "number of bits of new byte to move: %u\n",
312  num_bits_to_move);
313  mask_input_to_move = ((char) 1 << num_bits_to_move) - 1;
315  "mask of bits of new byte to take for moving: "B2B_PAT"\n",
316  B2B(mask_input_to_move));
317  bits_to_move = byte_input & mask_input_to_move;
319  "masked bits of new byte to take for moving: "B2B_PAT"\n",
320  B2B(bits_to_move));
321  distance_shift_bits = num_bits_buf_unaligned;
323  "distance needed to shift bits to their correct spot: %u\n",
324  distance_shift_bits);
325  bits_moving = bits_to_move << distance_shift_bits;
327  "shifted, masked bits of new byte being moved: "B2B_PAT"\n",
328  B2B(bits_moving));
329  byte_to_fill = buf_unaligned | bits_moving;
331  "byte being filled: "B2B_PAT"\n",
332  B2B(byte_to_fill));
334  "pending bytes: %u\n",
335  num_bits_buf_unaligned + num_bits_needed_iter);
336  if (num_bits_buf_unaligned + num_bits_needed_iter >= 8)
337  {
338  /* buf_unaligned was aligned by filling
339  * -> can be written to storage */
340  buf_write[i] = byte_to_fill;
341  size_buf_write++;
342 
343  /* store the leftover, unaligned bits in buffer */
344  mask_input_leftover = mask_bits_needed_iter & (~ mask_input_to_move);
346  "mask of leftover bits of new byte: "B2B_PAT"\n",
347  B2B(mask_input_leftover));
348  byte_input_leftover = byte_input & mask_input_leftover;
350  "masked, leftover bits of new byte: "B2B_PAT"\n",
351  B2B(byte_input_leftover));
352  num_bits_leftover = num_bits_needed_iter - num_bits_to_move;
354  "number of unaligned bits left: %u\n",
355  num_bits_leftover);
356  //num_bits_discard = 8 - num_bits_needed_iter;
357  byte_unaligned_new = byte_input_leftover >> num_bits_to_move;
359  "new unaligned byte: "B2B_PAT"\n",
360  B2B(byte_unaligned_new));
361  buf_unaligned = byte_unaligned_new;
362  num_bits_buf_unaligned = num_bits_leftover % 8;
363  }
364  else
365  {
366  /* unaligned buffer still unaligned but 'fuller' */
367  buf_unaligned = byte_to_fill;
369  }
370  }
371  to_file_raw (file_name, buf_write, size_buf_write);
373 }
374 
375 char *
377 {
378  int size;
379  size_t name_buf_size;
380  char *end;
381  char *buf;
382  char *name_buf;
383  size_t keylen = (sizeof (struct GNUNET_CRYPTO_AuthKey)) * 8;
384 
385  name_buf_size = 512 * sizeof (char);
386  name_buf = GNUNET_malloc (name_buf_size);
387 
388  if (keylen % 5 > 0)
389  keylen += 5 - keylen % 5;
390  keylen /= 5;
391  buf = GNUNET_malloc (keylen + 1);
392 
393  end = GNUNET_STRINGS_data_to_string (&(auth_key.key),
394  sizeof (struct GNUNET_CRYPTO_AuthKey),
395  buf,
396  keylen);
397 
398  if (NULL == end)
399  {
400  GNUNET_free (buf);
401  GNUNET_break (0);
402  }
403  else
404  {
405  *end = '\0';
406  }
407 
408  size = GNUNET_snprintf (name_buf, name_buf_size, "sampler_el-%s", buf);
409  if (0 > size)
410  LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to create name_buf\n");
411 
412  GNUNET_free (buf);
413 
414  return name_buf;
415 }
416 
417 #endif /* TO_FILE */
418 
419 
421 string_to_auth_key (const char *str)
422 {
423  struct GNUNET_CRYPTO_AuthKey auth_key;
424 
425  if (GNUNET_OK !=
427  strlen (str),
428  &auth_key.key,
429  sizeof (struct GNUNET_CRYPTO_AuthKey)))
430  {
431  LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to convert string to data\n");
432  }
433 
434  return auth_key;
435 }
436 
437 
444 static int
446 {
447  if (GNUNET_OK !=
448  GNUNET_DISK_directory_create ("/tmp/rps"))
449  {
451  "Could not create directory `/tmp/rps'\n");
452  return GNUNET_SYSERR;
453  }
454  return GNUNET_YES;
455 }
456 
457 
458 char *
459 store_prefix_file_name (const unsigned int index,
460  const char *prefix)
461 {
462  int len_file_name;
463  int out_size;
464  char *file_name;
465  char index_str[64];
466 
467  if (GNUNET_SYSERR == ensure_folder_exist()) return NULL;
468  out_size = GNUNET_snprintf (index_str,
469  64,
470  "%u",
471  index);
472  if (64 < out_size ||
473  0 > out_size)
474  {
476  "Failed to write string to buffer (size: %i, out_size: %i)\n",
477  64,
478  out_size);
479  }
480  len_file_name = (strlen (prefix) +
481  strlen (index_str) +
482  11)
483  * sizeof (char);
484  file_name = GNUNET_malloc (len_file_name);
485  out_size = GNUNET_snprintf (file_name,
486  len_file_name,
487  "/tmp/rps/%s-%s",
488  prefix,
489  index_str);
490  if (len_file_name < out_size ||
491  0 > out_size)
492  {
494  "Failed to write string to buffer (size: %i, out_size: %i)\n",
495  len_file_name,
496  out_size);
497  }
498  return file_name;
499 }
500 
501 
509 uint32_t fac (uint32_t x)
510 {
511  if (1 >= x)
512  {
513  return x;
514  }
515  return x * fac (x - 1);
516 }
517 
526 uint32_t binom (uint32_t n, uint32_t k)
527 {
528  //GNUNET_assert (n >= k);
529  if (k > n) return 0;
530  /* if (0 > n) return 0; - always false */
531  /* if (0 > k) return 0; - always false */
532  if (0 == k) return 1;
533  return fac (n)
534  /
535  fac(k) * fac(n - k);
536 }
537 
538 
539 /* end of gnunet-service-rps.c */
struct GNUNET_DISK_FileHandle * get_file_handle(const char *name)
Get file handle.
Definition: rps-test_util.c:75
Create file if it doesn&#39;t exist.
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1817
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
int close_files_iter(void *cls, const struct GNUNET_HashCode *key, void *value)
Closes the file of the current entry.
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:714
Some utils faciliating 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.
static struct GNUNET_CONTAINER_MultiHashMap * open_files
Definition: rps-test_util.c:61
static char * file_name
Dump file name.
Append to the file.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_HashMapIterator it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static unsigned bits_needed
numer of bits required to represent the largest peer id
static int ret
Final status code.
Definition: gnunet-arm.c:89
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.
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:44
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:1049
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:83
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)]
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.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
Open the file for writing.
const char * name
#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.
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.
#define GNUNET_YES
Definition: gnunet_common.h:80
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:1673
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:1021
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:924
#define GNUNET_free(ptr)
Wrapper around free.