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  {
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
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 
468  return NULL;
469  out_size = GNUNET_snprintf(index_str,
470  64,
471  "%u",
472  index);
473  if (64 < out_size ||
474  0 > out_size)
475  {
477  "Failed to write string to buffer (size: %i, out_size: %i)\n",
478  64,
479  out_size);
480  }
481  len_file_name = (strlen(prefix) +
482  strlen(index_str) +
483  11)
484  * sizeof(char);
485  file_name = GNUNET_malloc(len_file_name);
486  out_size = GNUNET_snprintf(file_name,
487  len_file_name,
488  "/tmp/rps/%s-%s",
489  prefix,
490  index_str);
491  if (len_file_name < out_size ||
492  0 > out_size)
493  {
495  "Failed to write string to buffer (size: %i, out_size: %i)\n",
496  len_file_name,
497  out_size);
498  }
499  return file_name;
500 }
501 
502 
510 uint32_t fac(uint32_t x)
511 {
512  if (1 >= x)
513  {
514  return x;
515  }
516  return x * fac(x - 1);
517 }
518 
527 uint32_t binom(uint32_t n, uint32_t k)
528 {
529  //GNUNET_assert (n >= k);
530  if (k > n)
531  return 0;
532  /* if (0 > n) return 0; - always false */
533  /* if (0 > k) return 0; - always false */
534  if (0 == k)
535  return 1;
536  return fac(n)
537  /
538  fac(k) * fac(n - k);
539 }
540 
541 
542 /* 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:1339
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:586
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.
#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 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:817
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:66
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: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:1262
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:953
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:857
#define GNUNET_free(ptr)
Wrapper around free.