summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_time_lib.h31
-rw-r--r--src/include/gnunet_transport_communication_service.h39
-rw-r--r--src/util/disk.c6
-rw-r--r--src/util/gnunet-service-resolver.c1
-rw-r--r--src/util/test_regex.c2
-rw-r--r--src/util/test_time.c25
-rw-r--r--src/util/test_tun.c2
-rw-r--r--src/util/time.c126
8 files changed, 220 insertions, 12 deletions
diff --git a/src/include/gnunet_time_lib.h b/src/include/gnunet_time_lib.h
index c7a06ba23..674a95534 100644
--- a/src/include/gnunet_time_lib.h
+++ b/src/include/gnunet_time_lib.h
@@ -365,7 +365,8 @@ GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future);
* assuming it continues at the same speed
*/
struct GNUNET_TIME_Relative
-GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start, uint64_t finished,
+GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start,
+ uint64_t finished,
uint64_t total);
@@ -565,6 +566,34 @@ unsigned int
GNUNET_TIME_time_to_year (struct GNUNET_TIME_Absolute at);
+/**
+ * A configuration object.
+ */
+struct GNUNET_CONFIGURATION_Handle;
+
+
+/**
+ * Obtain the current time and make sure it is monotonically
+ * increasing. Guards against systems without an RTC or
+ * clocks running backwards and other nasty surprises. Does
+ * not guarantee that the returned time is near the current
+ * time returned by #GNUNET_TIME_absolute_get(). Two
+ * subsequent calls (within a short time period) may return the
+ * same value. Persists the last returned time on disk to
+ * ensure that time never goes backwards. As a result, the
+ * resulting value can be used to check if a message is the
+ * "most recent" value and replays of older messages (from
+ * the same origin) would be discarded.
+ *
+ * @param cfg configuration, used to determine where to
+ * store the time; user can also insist RTC is working
+ * nicely and disable the feature
+ * @return monotonically increasing time
+ */
+struct GNUNET_TIME_Absolute
+GNUNET_TIME_absolute_get_monotonic (const struct GNUNET_CONFIGURATION_Handle *cfg);
+
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
diff --git a/src/include/gnunet_transport_communication_service.h b/src/include/gnunet_transport_communication_service.h
index f81ee6d9a..8cf275660 100644
--- a/src/include/gnunet_transport_communication_service.h
+++ b/src/include/gnunet_transport_communication_service.h
@@ -103,6 +103,19 @@ enum GNUNET_TRANSPORT_CommunicatorCharacteristics {
/**
+ * Function called when the transport service has received an
+ * acknowledgement for this communicator (!) via a different return
+ * path.
+ */
+typedef void
+(*GNUNET_TRANSPORT_CommunicatorNotify) (void *cls,
+ const struct GNUNET_PeerIdentity *sender,
+ struct GNUNET_TIME_Absolute monotonic_time,
+ struct GNUNET_TIME_Relative validity,
+ const struct GNUNET_HashCode *token
+ );
+
+/**
* Connect to the transport service.
*
* @param cfg configuration to use
@@ -122,7 +135,9 @@ GNUNET_TRANSPORT_communicator_connect (const struct GNUNET_CONFIGURATION_Handle
const char *addr_prefix,
enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc,
GNUNET_TRANSPORT_CommunicatorMqInit mq_init,
- void *mq_init_cls);
+ void *mq_init_cls,
+ GNUNET_TRANSPORT_CommunicatorNotify notify_cb,
+ void *notify_cb_cls);
/**
@@ -275,6 +290,28 @@ void
GNUNET_TRANSPORT_communicator_address_remove (struct GNUNET_TRANSPORT_AddressIdentifier *ai);
+/**
+ * The communicator asks the transport service to route a message via
+ * a different path to another communicator service at another peer.
+ * This must only be done for special control traffic (as there is no
+ * flow control for this API), such as acknowledgements, and generally
+ * only be done if the communicator is uni-directional (i.e. cannot
+ * send the message back itself).
+ *
+ * @param ch handle of this communicator
+ * @param target_pid peer to send the message to
+ * @param target_comm name of the communicator to send the message to
+ */
+void
+GNUNET_TRANSPORT_communicator_notify (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
+ const struct GNUNET_PeerIdentity *pid,
+ const char *comm,
+ struct GNUNET_TIME_Absolute monotonic_time,
+ struct GNUNET_TIME_Relative validity,
+ const struct GNUNET_HashCode *token
+ );
+
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
diff --git a/src/util/disk.c b/src/util/disk.c
index dc38d1137..d723303d8 100644
--- a/src/util/disk.c
+++ b/src/util/disk.c
@@ -236,7 +236,8 @@ GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh,
* @return the new position on success, #GNUNET_SYSERR otherwise
*/
off_t
-GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, off_t offset,
+GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h,
+ off_t offset,
enum GNUNET_DISK_Seek whence)
{
if (h == NULL)
@@ -1034,7 +1035,8 @@ GNUNET_DISK_fn_read (const char *fn,
*/
ssize_t
GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle * h,
- const void *buffer, size_t n)
+ const void *buffer,
+ size_t n)
{
if (NULL == h)
{
diff --git a/src/util/gnunet-service-resolver.c b/src/util/gnunet-service-resolver.c
index 065a224eb..5f8957d8c 100644
--- a/src/util/gnunet-service-resolver.c
+++ b/src/util/gnunet-service-resolver.c
@@ -1123,7 +1123,6 @@ check_get (void *cls,
(void) cls;
size = ntohs (get->header.size) - sizeof (*get);
- const char *str = &get[1];
direction = ntohl (get->direction);
if (GNUNET_NO == direction)
{
diff --git a/src/util/test_regex.c b/src/util/test_regex.c
index 2e7d52828..4eb7cf87d 100644
--- a/src/util/test_regex.c
+++ b/src/util/test_regex.c
@@ -21,7 +21,7 @@
* @author Maximilian Szengel
*/
#include "platform.h"
-#include "gnunet_tun_lib.h"
+#include "gnunet_util_lib.h"
/**
* 'wildcard', matches all possible values (for HEX encoding).
diff --git a/src/util/test_time.c b/src/util/test_time.c
index 2ac93e01d..80c4e5337 100644
--- a/src/util/test_time.c
+++ b/src/util/test_time.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2001-2013 GNUnet e.V.
+ Copyright (C) 2001-2013, 2018 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
@@ -223,7 +223,28 @@ main (int argc, char *argv[])
/*check GNUNET_TIME_absolute_max */
GNUNET_assert (now.abs_value_us ==
GNUNET_TIME_absolute_max (now, last).abs_value_us);
-
+ for (unsigned int i=0;i<30;i++)
+ {
+ struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ cfg = GNUNET_CONFIGURATION_create ();
+ last = GNUNET_TIME_absolute_get_monotonic (cfg);
+ now = GNUNET_TIME_absolute_get_monotonic (cfg);
+ GNUNET_assert (now.abs_value_us > last.abs_value_us);
+ (void) GNUNET_TIME_absolute_get_monotonic (NULL);
+ GNUNET_CONFIGURATION_set_value_string (cfg,
+ "util",
+ "MONOTONIC_TIME_FILENAME",
+ "monotonic-time.dat");
+ last = GNUNET_TIME_absolute_get_monotonic (cfg);
+ now = GNUNET_TIME_absolute_get_monotonic (cfg);
+ (void) GNUNET_TIME_absolute_get_monotonic (NULL);
+ GNUNET_assert (now.abs_value_us > last.abs_value_us);
+ GNUNET_CONFIGURATION_destroy (cfg);
+ }
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_DISK_directory_remove ("monotonic-time.dat"));
+
return 0;
}
diff --git a/src/util/test_tun.c b/src/util/test_tun.c
index edbd4c05d..429678fd5 100644
--- a/src/util/test_tun.c
+++ b/src/util/test_tun.c
@@ -22,7 +22,7 @@
* @author Christian Grothoff
*/
#include "platform.h"
-#include "gnunet_tun_lib.h"
+#include "gnunet_util_lib.h"
static int ret;
diff --git a/src/util/time.c b/src/util/time.c
index b02c43c1b..46d3a2b65 100644
--- a/src/util/time.c
+++ b/src/util/time.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2001-2013 GNUnet e.V.
+ Copyright (C) 2001-2013, 2018 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
@@ -22,8 +22,7 @@
* @brief functions for handling time and time arithmetic
*/
#include "platform.h"
-#include "gnunet_crypto_lib.h"
-#include "gnunet_time_lib.h"
+#include "gnunet_util_lib.h"
#define LOG(kind,...) GNUNET_log_from (kind, "util-time", __VA_ARGS__)
@@ -757,6 +756,127 @@ GNUNET_TIME_randomized_backoff(struct GNUNET_TIME_Relative rt, struct GNUNET_TIM
}
+/**
+ * Obtain the current time and make sure it is monotonically
+ * increasing. Guards against systems without an RTC or
+ * clocks running backwards and other nasty surprises. Does
+ * not guarantee that the returned time is near the current
+ * time returned by #GNUNET_TIME_absolute_get(). Two
+ * subsequent calls (within a short time period) may return the
+ * same value. Persists the last returned time on disk to
+ * ensure that time never goes backwards. As a result, the
+ * resulting value can be used to check if a message is the
+ * "most recent" value and replays of older messages (from
+ * the same origin) would be discarded.
+ *
+ * @param cfg configuration, used to determine where to
+ * store the time; user can also insist RTC is working
+ * nicely and disable the feature
+ * @return monotonically increasing time
+ */
+struct GNUNET_TIME_Absolute
+GNUNET_TIME_absolute_get_monotonic (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ static const struct GNUNET_CONFIGURATION_Handle *last_cfg;
+ static struct GNUNET_TIME_Absolute last_time;
+ static struct GNUNET_DISK_MapHandle *map_handle;
+ static struct GNUNET_TIME_AbsoluteNBO *map;
+ struct GNUNET_TIME_Absolute now;
+
+ now = GNUNET_TIME_absolute_get ();
+ if (last_cfg != cfg)
+ {
+ char *filename;
+
+ if (NULL != map_handle)
+ {
+ GNUNET_DISK_file_unmap (map_handle);
+ map_handle = NULL;
+ }
+ map = NULL;
+
+ last_cfg = cfg;
+ if ( (NULL != cfg) &&
+ (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_filename (cfg,
+ "util",
+ "MONOTONIC_TIME_FILENAME",
+ &filename)) )
+ {
+ struct GNUNET_DISK_FileHandle *fh;
+
+ fh = GNUNET_DISK_file_open (filename,
+ GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE,
+ GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_GROUP_WRITE |
+ GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_GROUP_READ);
+ if (NULL == fh)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to map `%s', cannot assure monotonic time!\n"),
+ filename);
+ }
+ else
+ {
+ off_t size;
+
+ size = 0;
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_DISK_file_handle_size (fh,
+ &size));
+ if (size < sizeof (*map))
+ {
+ struct GNUNET_TIME_AbsoluteNBO o;
+
+ o = GNUNET_TIME_absolute_hton (now);
+ if (sizeof (o) !=
+ GNUNET_DISK_file_write (fh,
+ &o,
+ sizeof (o)))
+ size = 0;
+ else
+ size = sizeof (o);
+ }
+ if (size == sizeof (*map))
+ {
+ map = GNUNET_DISK_file_map (fh,
+ &map_handle,
+ GNUNET_DISK_MAP_TYPE_READWRITE,
+ sizeof (*map));
+ if (NULL == map)
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to map `%s', cannot assure monotonic time!\n"),
+ filename);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to setup monotonic time file `%s', cannot assure monotonic time!\n"),
+ filename);
+ }
+ }
+ GNUNET_DISK_file_close (fh);
+ GNUNET_free (filename);
+ }
+ }
+ if (NULL != map)
+ last_time = GNUNET_TIME_absolute_max (GNUNET_TIME_absolute_ntoh (*map),
+ last_time);
+ if (now.abs_value_us <= last_time.abs_value_us)
+ now.abs_value_us = last_time.abs_value_us+1;
+ last_time = now;
+ if (NULL != map)
+ *map = GNUNET_TIME_absolute_hton (now);
+ return now;
+}
+
+/**
+ * Destructor
+ */
+void __attribute__ ((destructor))
+GNUNET_util_time_fini ()
+{
+ (void) GNUNET_TIME_absolute_get_monotonic (NULL);
+}
/* end of time.c */