2 This file is part of GNUnet.
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.
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.
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/>.
20 * @file rps/rps-test_util.c
21 * @brief Some utils faciliating the view into the internals for the sampler
22 * needed for evaluation
24 * @author Julius Bünger
28 #include "gnunet_util_lib.h"
29 #include "rps-test_util.h"
33 #define LOG(kind, ...) GNUNET_log_from(kind,"rps-test_util",__VA_ARGS__)
35 #define B2B_PAT "%c%c%c%c%c%c%c%c"
37 (byte & 0x80 ? '1' : '0'), \
38 (byte & 0x40 ? '1' : '0'), \
39 (byte & 0x20 ? '1' : '0'), \
40 (byte & 0x10 ? '1' : '0'), \
41 (byte & 0x08 ? '1' : '0'), \
42 (byte & 0x04 ? '1' : '0'), \
43 (byte & 0x02 ? '1' : '0'), \
44 (byte & 0x01 ? '1' : '0')
50 * @brief buffer for storing the unaligned bits for the next write
52 static char buf_unaligned;
55 * @brief number of bits in unaligned buffer
57 static unsigned num_bits_buf_unaligned;
59 static struct GNUNET_CONTAINER_MultiHashMap *open_files;
64 * @brief Get file handle
66 * If necessary, create file handle and store it with the other file handles.
68 * @param name Name of the file
72 struct GNUNET_DISK_FileHandle *
73 get_file_handle (const char *name)
75 struct GNUNET_HashCode hash;
76 struct GNUNET_DISK_FileHandle *fh;
78 if (NULL == open_files)
80 open_files = GNUNET_CONTAINER_multihashmap_create (16,
81 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
83 GNUNET_CRYPTO_hash (name,
87 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (open_files,
90 fh = GNUNET_DISK_file_open (name,
91 GNUNET_DISK_OPEN_WRITE |
92 GNUNET_DISK_OPEN_CREATE |
93 GNUNET_DISK_OPEN_APPEND,
94 GNUNET_DISK_PERM_USER_READ |
95 GNUNET_DISK_PERM_USER_WRITE |
96 GNUNET_DISK_PERM_GROUP_READ);
99 LOG (GNUNET_ERROR_TYPE_ERROR,
100 "Opening file `%s' failed.\n",
104 GNUNET_CONTAINER_multihashmap_put (open_files,
107 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
112 fh = GNUNET_CONTAINER_multihashmap_get (open_files,
120 * @brief Closes the file of the current entry
122 * Implements #GNUNET_CONTAINER_HashMapIterator
126 * @param value the file handle
128 * @return #GNUNET_YES if we should continue to
133 close_files_iter (void *cls,
134 const struct GNUNET_HashCode *key,
139 struct GNUNET_DISK_FileHandle *fh = value;
143 GNUNET_DISK_file_close (fh);
150 * @brief Close all files that were opened with #get_file_handle
152 * @return Success of iterating over files
159 ret = GNUNET_CONTAINER_multihashmap_iterate (open_files,
162 GNUNET_CONTAINER_multihashmap_destroy (open_files);
169 to_file_raw (const char *file_name, const char *buf, size_t size_buf)
171 struct GNUNET_DISK_FileHandle *f;
174 if (NULL == (f = GNUNET_DISK_file_open (file_name,
175 GNUNET_DISK_OPEN_APPEND |
176 GNUNET_DISK_OPEN_WRITE |
177 GNUNET_DISK_OPEN_CREATE,
178 GNUNET_DISK_PERM_USER_READ |
179 GNUNET_DISK_PERM_USER_WRITE |
180 GNUNET_DISK_PERM_GROUP_READ |
181 GNUNET_DISK_PERM_OTHER_READ)))
183 LOG (GNUNET_ERROR_TYPE_WARNING,
184 "Not able to open file %s\n",
189 size_written = GNUNET_DISK_file_write (f, buf, size_buf);
190 if (size_buf != size_written)
192 LOG (GNUNET_ERROR_TYPE_WARNING,
193 "Unable to write to file! (Size: %u, size_written: %u)\n",
197 if (GNUNET_YES != GNUNET_DISK_file_close (f))
198 LOG (GNUNET_ERROR_TYPE_WARNING,
199 "Unable to close file\n");
203 LOG (GNUNET_ERROR_TYPE_WARNING,
204 "Wrote %u bytes raw.\n",
206 if (GNUNET_YES != GNUNET_DISK_file_close (f))
207 LOG (GNUNET_ERROR_TYPE_WARNING,
208 "Unable to close file\n");
212 to_file_raw_unaligned (const char *file_name,
215 unsigned bits_needed)
218 GNUNET_assert (size_buf >= (bits_needed/8));
219 //if (0 == num_bits_buf_unaligned)
221 // if (0 == (bits_needed % 8))
223 // to_file_raw (file_name, buf, size_buf);
226 // to_file_raw (file_name, buf, size_buf - 1);
227 // buf_unaligned = buf[size_buf - 1];
228 // num_bits_buf_unaligned = bits_needed % 8;
231 LOG (GNUNET_ERROR_TYPE_DEBUG,
232 "Was asked to write %u bits\n", bits_needed);
234 char buf_write[size_buf + 1];
235 const unsigned bytes_iter = (0 != bits_needed % 8?
238 // TODO what if no iteration happens?
239 unsigned size_buf_write = 0;
240 LOG (GNUNET_ERROR_TYPE_DEBUG,
241 "num_bits_buf_unaligned: %u\n",
242 num_bits_buf_unaligned);
243 LOG (GNUNET_ERROR_TYPE_DEBUG,
244 "ua args: size_buf: %u, bits_needed: %u -> iter: %u\n",
248 buf_write[0] = buf_unaligned;
249 /* Iterate over input bytes */
250 for (unsigned i = 0; i < bytes_iter; i++)
252 /* Number of bits needed in this iteration - 8 for all except last iter */
253 unsigned num_bits_needed_iter;
254 /* Mask for bits to actually use */
255 unsigned mask_bits_needed_iter;
257 /* Number of bits needed to align unaligned byte */
258 unsigned num_bits_to_align;
259 /* Number of bits that are to be moved */
260 unsigned num_bits_to_move;
261 /* Mask for bytes to be moved */
262 char mask_input_to_move;
263 /* Masked bits to be moved */
265 /* The amount of bits needed to fit the bits to shift to the nearest spot */
266 unsigned distance_shift_bits;
267 /* Shifted bits on the move */
269 /* (unaligned) byte being filled with bits */
271 /* mask for needed bits of the input byte that have not been moved */
272 char mask_input_leftover;
273 /* needed bits of the input byte that have not been moved */
274 char byte_input_leftover;
275 unsigned num_bits_leftover;
276 //unsigned num_bits_discard;
277 char byte_unaligned_new;
279 if ( (bits_needed - (i * 8)) <= 8)
282 num_bits_needed_iter = bits_needed - (i * 8);
286 num_bits_needed_iter = 8;
288 LOG (GNUNET_ERROR_TYPE_DEBUG,
289 "number of bits needed in this iteration: %u\n",
290 num_bits_needed_iter);
291 mask_bits_needed_iter = ((char) 1 << num_bits_needed_iter) - 1;
292 LOG (GNUNET_ERROR_TYPE_DEBUG,
293 "mask needed bits (current iter): "B2B_PAT"\n",
294 B2B(mask_bits_needed_iter));
295 LOG (GNUNET_ERROR_TYPE_DEBUG,
296 "Unaligned byte: "B2B_PAT" (%u bits)\n",
298 num_bits_buf_unaligned);
300 LOG (GNUNET_ERROR_TYPE_DEBUG,
301 "next whole input byte: "B2B_PAT"\n",
303 byte_input &= mask_bits_needed_iter;
304 num_bits_to_align = 8 - num_bits_buf_unaligned;
305 LOG (GNUNET_ERROR_TYPE_DEBUG,
306 "input byte, needed bits: "B2B_PAT"\n",
308 LOG (GNUNET_ERROR_TYPE_DEBUG,
309 "number of bits needed to align unaligned bit: %u\n",
311 num_bits_to_move = GNUNET_MIN (num_bits_to_align, num_bits_needed_iter);
312 LOG (GNUNET_ERROR_TYPE_DEBUG,
313 "number of bits of new byte to move: %u\n",
315 mask_input_to_move = ((char) 1 << num_bits_to_move) - 1;
316 LOG (GNUNET_ERROR_TYPE_DEBUG,
317 "mask of bits of new byte to take for moving: "B2B_PAT"\n",
318 B2B(mask_input_to_move));
319 bits_to_move = byte_input & mask_input_to_move;
320 LOG (GNUNET_ERROR_TYPE_DEBUG,
321 "masked bits of new byte to take for moving: "B2B_PAT"\n",
323 distance_shift_bits = num_bits_buf_unaligned;
324 LOG (GNUNET_ERROR_TYPE_DEBUG,
325 "distance needed to shift bits to their correct spot: %u\n",
326 distance_shift_bits);
327 bits_moving = bits_to_move << distance_shift_bits;
328 LOG (GNUNET_ERROR_TYPE_DEBUG,
329 "shifted, masked bits of new byte being moved: "B2B_PAT"\n",
331 byte_to_fill = buf_unaligned | bits_moving;
332 LOG (GNUNET_ERROR_TYPE_DEBUG,
333 "byte being filled: "B2B_PAT"\n",
335 LOG (GNUNET_ERROR_TYPE_DEBUG,
336 "pending bytes: %u\n",
337 num_bits_buf_unaligned + num_bits_needed_iter);
338 if (num_bits_buf_unaligned + num_bits_needed_iter >= 8)
340 /* buf_unaligned was aligned by filling
341 * -> can be written to storage */
342 buf_write[i] = byte_to_fill;
345 /* store the leftover, unaligned bits in buffer */
346 mask_input_leftover = mask_bits_needed_iter & (~ mask_input_to_move);
347 LOG (GNUNET_ERROR_TYPE_DEBUG,
348 "mask of leftover bits of new byte: "B2B_PAT"\n",
349 B2B(mask_input_leftover));
350 byte_input_leftover = byte_input & mask_input_leftover;
351 LOG (GNUNET_ERROR_TYPE_DEBUG,
352 "masked, leftover bits of new byte: "B2B_PAT"\n",
353 B2B(byte_input_leftover));
354 num_bits_leftover = num_bits_needed_iter - num_bits_to_move;
355 LOG (GNUNET_ERROR_TYPE_DEBUG,
356 "number of unaligned bits left: %u\n",
358 //num_bits_discard = 8 - num_bits_needed_iter;
359 byte_unaligned_new = byte_input_leftover >> num_bits_to_move;
360 LOG (GNUNET_ERROR_TYPE_DEBUG,
361 "new unaligned byte: "B2B_PAT"\n",
362 B2B(byte_unaligned_new));
363 buf_unaligned = byte_unaligned_new;
364 num_bits_buf_unaligned = num_bits_leftover % 8;
368 /* unaligned buffer still unaligned but 'fuller' */
369 buf_unaligned = byte_to_fill;
370 num_bits_buf_unaligned = (num_bits_buf_unaligned + bits_needed) % 8;
373 to_file_raw (file_name, buf_write, size_buf_write);
374 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
378 auth_key_to_string (struct GNUNET_CRYPTO_AuthKey auth_key)
381 size_t name_buf_size;
385 size_t keylen = (sizeof (struct GNUNET_CRYPTO_AuthKey)) * 8;
387 name_buf_size = 512 * sizeof (char);
388 name_buf = GNUNET_malloc (name_buf_size);
391 keylen += 5 - keylen % 5;
393 buf = GNUNET_malloc (keylen + 1);
395 end = GNUNET_STRINGS_data_to_string (&(auth_key.key),
396 sizeof (struct GNUNET_CRYPTO_AuthKey),
410 size = GNUNET_snprintf (name_buf, name_buf_size, "sampler_el-%s", buf);
412 LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to create name_buf\n");
422 create_file (const char *name)
425 size_t name_buf_size;
430 prefix = "/tmp/rps/";
431 name_buf_size = (strlen (prefix) + strlen (name) + 2) * sizeof (char);
432 name_buf = GNUNET_malloc (name_buf_size);
434 size = GNUNET_snprintf (name_buf, name_buf_size, "%s%s", prefix, name);
436 LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to create name_buf\n");
438 if (GNUNET_YES != GNUNET_DISK_directory_create (prefix))
440 LOG (GNUNET_ERROR_TYPE_WARNING,
441 "Could not create directory %s.\n",
445 if (NULL == strstr (name, "sampler_el"))
446 {/* only append random string to sampler */
447 if (NULL == (file_name = GNUNET_DISK_mktemp (name_buf)))
448 LOG (GNUNET_ERROR_TYPE_WARNING, "Could not create file\n");
450 GNUNET_free (name_buf);
460 struct GNUNET_CRYPTO_AuthKey
461 string_to_auth_key (const char *str)
463 struct GNUNET_CRYPTO_AuthKey auth_key;
466 GNUNET_STRINGS_string_to_data (str,
469 sizeof (struct GNUNET_CRYPTO_AuthKey)))
471 LOG (GNUNET_ERROR_TYPE_WARNING, "Failed to convert string to data\n");
479 * @brief Try to ensure that `/tmp/rps` exists.
481 * @return #GNUNET_YES on success
482 * #GNUNET_SYSERR on failure
484 static int ensure_folder_exist (void)
486 if (GNUNET_NO == GNUNET_DISK_directory_test ("/tmp/rps/", GNUNET_NO))
488 GNUNET_DISK_directory_create ("/tmp/rps");
490 if (GNUNET_YES != GNUNET_DISK_directory_test ("/tmp/rps/", GNUNET_NO))
492 return GNUNET_SYSERR;
498 store_prefix_file_name (const struct GNUNET_PeerIdentity *peer,
504 const char *pid_long;
506 if (GNUNET_SYSERR == ensure_folder_exist()) return NULL;
507 pid_long = GNUNET_i2s_full (peer);
508 len_file_name = (strlen (prefix) +
512 file_name = GNUNET_malloc (len_file_name);
513 out_size = GNUNET_snprintf (file_name,
518 if (len_file_name < out_size ||
521 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
522 "Failed to write string to buffer (size: %i, out_size: %i)\n",
529 /* end of gnunet-service-rps.c */