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  ret = GNUNET_CONTAINER_multihashmap_iterate (open_files,
157  NULL);
159  open_files = NULL;
160  return ret;
161 }
162 
163 
164 void
165 to_file_raw (const char *file_name, const char *buf, size_t size_buf)
166 {
167  struct GNUNET_DISK_FileHandle *f;
168  size_t size_written;
169 
170  if (NULL == (f = GNUNET_DISK_file_open (file_name,
178  {
180  "Not able to open file %s\n",
181  file_name);
182  return;
183  }
184 
185  size_written = GNUNET_DISK_file_write (f, buf, size_buf);
186  if (size_buf != size_written)
187  {
189  "Unable to write to file! (Size: %u, size_written: %u)\n",
190  size_buf,
191  size_written);
192 
195  "Unable to close file\n");
196 
197  return;
198  }
200  "Wrote %u bytes raw.\n",
201  size_written);
204  "Unable to close file\n");
205 }
206 
207 
208 void
210  const char *buf,
211  size_t size_buf,
212  unsigned bits_needed)
213 {
214  // TODO endianness!
215  GNUNET_assert (size_buf >= (bits_needed / 8));
216  // if (0 == num_bits_buf_unaligned)
217  // {
218  // if (0 == (bits_needed % 8))
219  // {
220  // to_file_raw (file_name, buf, size_buf);
221  // return;
222  // }
223  // to_file_raw (file_name, buf, size_buf - 1);
224  // buf_unaligned = buf[size_buf - 1];
225  // num_bits_buf_unaligned = bits_needed % 8;
226  // return;
227  // }
229  "Was asked to write %u bits\n", bits_needed);
230 
231  char buf_write[size_buf + 1];
232  const unsigned bytes_iter = (0 != bits_needed % 8 ?
233  (bits_needed / 8) + 1 :
234  bits_needed / 8);
235  // TODO what if no iteration happens?
236  unsigned size_buf_write = 0;
238  "num_bits_buf_unaligned: %u\n",
241  "ua args: size_buf: %u, bits_needed: %u -> iter: %u\n",
242  size_buf,
243  bits_needed,
244  bytes_iter);
245  buf_write[0] = buf_unaligned;
246  /* Iterate over input bytes */
247  for (unsigned i = 0; i < bytes_iter; i++)
248  {
249  /* Number of bits needed in this iteration - 8 for all except last iter */
250  unsigned num_bits_needed_iter;
251  /* Mask for bits to actually use */
252  unsigned mask_bits_needed_iter;
253  char byte_input;
254  /* Number of bits needed to align unaligned byte */
255  unsigned num_bits_to_align;
256  /* Number of bits that are to be moved */
257  unsigned num_bits_to_move;
258  /* Mask for bytes to be moved */
259  char mask_input_to_move;
260  /* Masked bits to be moved */
261  char bits_to_move;
262  /* The amount of bits needed to fit the bits to shift to the nearest spot */
263  unsigned distance_shift_bits;
264  /* Shifted bits on the move */
265  char bits_moving;
266  /* (unaligned) byte being filled with bits */
267  char byte_to_fill;
268  /* mask for needed bits of the input byte that have not been moved */
269  char mask_input_leftover;
270  /* needed bits of the input byte that have not been moved */
271  char byte_input_leftover;
272  unsigned num_bits_leftover;
273  // unsigned num_bits_discard;
274  char byte_unaligned_new;
275 
276  if ((bits_needed - (i * 8)) <= 8)
277  {
278  /* last iteration */
279  num_bits_needed_iter = bits_needed - (i * 8);
280  }
281  else
282  {
283  num_bits_needed_iter = 8;
284  }
286  "number of bits needed in this iteration: %u\n",
287  num_bits_needed_iter);
288  mask_bits_needed_iter = ((char) 1 << num_bits_needed_iter) - 1;
290  "mask needed bits (current iter): "B2B_PAT "\n",
291  B2B (mask_bits_needed_iter));
293  "Unaligned byte: "B2B_PAT " (%u bits)\n",
294  B2B (buf_unaligned),
296  byte_input = buf[i];
298  "next whole input byte: "B2B_PAT "\n",
299  B2B (byte_input));
300  byte_input &= mask_bits_needed_iter;
301  num_bits_to_align = 8 - num_bits_buf_unaligned;
303  "input byte, needed bits: "B2B_PAT "\n",
304  B2B (byte_input));
306  "number of bits needed to align unaligned bit: %u\n",
307  num_bits_to_align);
308  num_bits_to_move = GNUNET_MIN (num_bits_to_align, num_bits_needed_iter);
310  "number of bits of new byte to move: %u\n",
311  num_bits_to_move);
312  mask_input_to_move = ((char) 1 << num_bits_to_move) - 1;
314  "mask of bits of new byte to take for moving: "B2B_PAT "\n",
315  B2B (mask_input_to_move));
316  bits_to_move = byte_input & mask_input_to_move;
318  "masked bits of new byte to take for moving: "B2B_PAT "\n",
319  B2B (bits_to_move));
320  distance_shift_bits = num_bits_buf_unaligned;
322  "distance needed to shift bits to their correct spot: %u\n",
323  distance_shift_bits);
324  bits_moving = bits_to_move << distance_shift_bits;
326  "shifted, masked bits of new byte being moved: "B2B_PAT "\n",
327  B2B (bits_moving));
328  byte_to_fill = buf_unaligned | bits_moving;
330  "byte being filled: "B2B_PAT "\n",
331  B2B (byte_to_fill));
333  "pending bytes: %u\n",
334  num_bits_buf_unaligned + num_bits_needed_iter);
335  if (num_bits_buf_unaligned + num_bits_needed_iter >= 8)
336  {
337  /* buf_unaligned was aligned by filling
338  * -> can be written to storage */
339  buf_write[i] = byte_to_fill;
340  size_buf_write++;
341 
342  /* store the leftover, unaligned bits in buffer */
343  mask_input_leftover = mask_bits_needed_iter & (~mask_input_to_move);
345  "mask of leftover bits of new byte: "B2B_PAT "\n",
346  B2B (mask_input_leftover));
347  byte_input_leftover = byte_input & mask_input_leftover;
349  "masked, leftover bits of new byte: "B2B_PAT "\n",
350  B2B (byte_input_leftover));
351  num_bits_leftover = num_bits_needed_iter - num_bits_to_move;
353  "number of unaligned bits left: %u\n",
354  num_bits_leftover);
355  // num_bits_discard = 8 - num_bits_needed_iter;
356  byte_unaligned_new = byte_input_leftover >> num_bits_to_move;
358  "new unaligned byte: "B2B_PAT "\n",
359  B2B (byte_unaligned_new));
360  buf_unaligned = byte_unaligned_new;
361  num_bits_buf_unaligned = num_bits_leftover % 8;
362  }
363  else
364  {
365  /* unaligned buffer still unaligned but 'fuller' */
366  buf_unaligned = byte_to_fill;
368  }
369  }
370  to_file_raw (file_name, buf_write, size_buf_write);
372 }
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 
418 #endif /* TO_FILE */
419 
420 
422 string_to_auth_key (const char *str)
423 {
424  struct GNUNET_CRYPTO_AuthKey auth_key;
425 
426  if (GNUNET_OK !=
428  strlen (str),
429  &auth_key.key,
430  sizeof(struct GNUNET_CRYPTO_AuthKey)))
431  {
432  LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to convert string to data\n");
433  }
434 
435  return auth_key;
436 }
437 
438 
445 static int
447 {
448  if (GNUNET_OK !=
449  GNUNET_DISK_directory_create ("/tmp/rps"))
450  {
452  "Could not create directory `/tmp/rps'\n");
453  return GNUNET_SYSERR;
454  }
455  return GNUNET_YES;
456 }
457 
458 
459 char *
460 store_prefix_file_name (const unsigned int index,
461  const char *prefix)
462 {
463  int len_file_name;
464  int out_size;
465  char *file_name;
466  char index_str[64];
467 
469  return NULL;
470  out_size = GNUNET_snprintf (index_str,
471  64,
472  "%u",
473  index);
474  if ((64 < out_size) ||
475  (0 > out_size) )
476  {
478  "Failed to write string to buffer (size: %i, out_size: %i)\n",
479  64,
480  out_size);
481  }
482  len_file_name = (strlen (prefix)
483  + strlen (index_str)
484  + 11)
485  * sizeof(char);
486  file_name = GNUNET_malloc (len_file_name);
487  out_size = GNUNET_snprintf (file_name,
488  len_file_name,
489  "/tmp/rps/%s-%s",
490  prefix,
491  index_str);
492  if ((len_file_name < out_size) ||
493  (0 > out_size) )
494  {
496  "Failed to write string to buffer (size: %i, out_size: %i)\n",
497  len_file_name,
498  out_size);
499  }
500  return file_name;
501 }
502 
503 
511 uint32_t
512 fac (uint32_t x)
513 {
514  if (1 >= x)
515  {
516  return x;
517  }
518  return x * fac (x - 1);
519 }
520 
521 
530 uint32_t
531 binom (uint32_t n, uint32_t k)
532 {
533  // GNUNET_assert (n >= k);
534  if (k > n)
535  return 0;
536  /* if (0 > n) return 0; - always false */
537  /* if (0 > k) return 0; - always false */
538  if (0 == k)
539  return 1;
540  return fac (n)
541  /
542  fac (k) * fac (n - k);
543 }
544 
545 
546 /* 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.
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1345
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:589
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.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
Append to the file.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static unsigned bits_needed
numer 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.
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:48
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:820
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:80
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:76
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.
#define GNUNET_YES
Definition: gnunet_common.h:77
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:1268
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:952
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:856
#define GNUNET_free(ptr)
Wrapper around free.