diff options
| author | Michael Biebl <biebl@debian.org> | 2019-02-26 19:01:41 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2019-02-26 19:01:41 +0100 |
| commit | 964ae8cc391520440cf5aa13e2b9cc34850ea6c2 (patch) | |
| tree | 50da9ecaee7fbb612ec18f9e24f7dec215bf7861 /shared/nm-utils | |
| parent | 3626b425d1bc017fdc6f1ea0cfd329d1e1681641 (diff) | |
New upstream version 1.14.6 upstream/1.14.6
Diffstat (limited to 'shared/nm-utils')
| -rw-r--r-- | shared/nm-utils/nm-hash-utils.c | 57 | ||||
| -rw-r--r-- | shared/nm-utils/nm-hash-utils.h | 62 | ||||
| -rw-r--r-- | shared/nm-utils/nm-jansson.h | 3 | ||||
| -rw-r--r-- | shared/nm-utils/nm-macros-internal.h | 13 | ||||
| -rw-r--r-- | shared/nm-utils/nm-shared-utils.c | 23 | ||||
| -rw-r--r-- | shared/nm-utils/nm-shared-utils.h | 42 | ||||
| -rw-r--r-- | shared/nm-utils/nm-test-utils.h | 36 | ||||
| -rw-r--r-- | shared/nm-utils/nm-udev-utils.c | 31 |
8 files changed, 217 insertions, 50 deletions
diff --git a/shared/nm-utils/nm-hash-utils.c b/shared/nm-utils/nm-hash-utils.c index 4bc12b7c..80387c71 100644 --- a/shared/nm-utils/nm-hash-utils.c +++ b/shared/nm-utils/nm-hash-utils.c @@ -40,53 +40,66 @@ static const guint8 *volatile global_seed = NULL; static const guint8 * _get_hash_key_init (void) { + static gsize g_lock; /* the returned hash is aligned to guin64, hence, it is safe * to use it as guint* or guint64* pointer. */ static union { guint8 v8[HASH_KEY_SIZE]; } g_arr _nm_alignas (guint64); - static gsize g_lock; const guint8 *g; - CSipHash siph_state; - uint64_t h; - guint *p; + union { + guint8 v8[HASH_KEY_SIZE]; + guint vuint; + } t_arr; - g = global_seed; +again: + g = g_atomic_pointer_get (&global_seed); if (G_LIKELY (g != NULL)) { nm_assert (g == g_arr.v8); return g; } - if (g_once_init_enter (&g_lock)) { + { + CSipHash siph_state; + uint64_t h; - nm_utils_random_bytes (g_arr.v8, sizeof (g_arr.v8)); + /* initialize a random key in t_arr. */ + + nm_utils_random_bytes (&t_arr, sizeof (t_arr)); /* use siphash() of the key-size, to mangle the first guint. Otherwise, * the first guint has only the entropy that nm_utils_random_bytes() - * generated for the first 4 bytes and relies on a good random generator. */ - c_siphash_init (&siph_state, g_arr.v8); - c_siphash_append (&siph_state, g_arr.v8, sizeof (g_arr.v8)); + * generated for the first 4 bytes and relies on a good random generator. + * + * The first int is especially intersting for nm_hash_static() below, and we + * want to have it all the entropy of t_arr. */ + c_siphash_init (&siph_state, t_arr.v8); + c_siphash_append (&siph_state, (const guint8 *) &t_arr, sizeof (t_arr)); h = c_siphash_finalize (&siph_state); - p = (guint *) g_arr.v8; if (sizeof (guint) < sizeof (h)) - *p = *p ^ ((guint) (h & 0xFFFFFFFFu)) ^ ((guint) (h >> 32)); + t_arr.vuint = t_arr.vuint ^ ((guint) (h & 0xFFFFFFFFu)) ^ ((guint) (h >> 32)); else - *p = *p ^ ((guint) (h & 0xFFFFFFFFu)); + t_arr.vuint = t_arr.vuint ^ ((guint) (h & 0xFFFFFFFFu)); + } - g_atomic_pointer_compare_and_exchange (&global_seed, NULL, g_arr.v8); - g_once_init_leave (&g_lock, 1); + if (!g_once_init_enter (&g_lock)) { + /* lost a race. The random key is already initialized. */ + goto again; } - nm_assert (global_seed == g_arr.v8); - return g_arr.v8; + memcpy (g_arr.v8, t_arr.v8, HASH_KEY_SIZE); + g = g_arr.v8; + g_atomic_pointer_set (&global_seed, g); + g_once_init_leave (&g_lock, 1); + return g; } #define _get_hash_key() \ ({ \ const guint8 *_g; \ \ - _g = global_seed; \ - if (G_UNLIKELY (_g == NULL)) \ + _g = g_atomic_pointer_get (&global_seed); \ + if (G_UNLIKELY (!_g)) \ _g = _get_hash_key_init (); \ _g; \ }) @@ -109,17 +122,17 @@ nm_hash_static (guint static_seed) } void -nm_hash_init (NMHashState *state, guint static_seed) +nm_hash_siphash42_init (CSipHash *h, guint static_seed) { const guint8 *g; guint seed[HASH_KEY_SIZE_GUINT]; - nm_assert (state); + nm_assert (h); g = _get_hash_key (); memcpy (seed, g, HASH_KEY_SIZE); seed[0] ^= static_seed; - c_siphash_init (&state->_state, (const guint8 *) seed); + c_siphash_init (h, (const guint8 *) seed); } guint diff --git a/shared/nm-utils/nm-hash-utils.h b/shared/nm-utils/nm-hash-utils.h index b797fb75..cf71a7e9 100644 --- a/shared/nm-utils/nm-hash-utils.h +++ b/shared/nm-utils/nm-hash-utils.h @@ -25,6 +25,39 @@ #include "c-siphash/src/c-siphash.h" #include "nm-macros-internal.h" +/*****************************************************************************/ + +void nm_hash_siphash42_init (CSipHash *h, guint static_seed); + +/* Siphash24 of binary buffer @arr and @len, using the randomized seed from + * other NMHash functions. + * + * Note, that this is guaranteed to use siphash42 under the hood (contrary to + * all other NMHash API, which leave this undefined). That matters at the point, + * where the caller needs to be sure that a reasonably strong hasing algorithm + * is used. (Yes, NMHash is all about siphash24, but otherwise that is not promised + * anywhere). + * + * Another difference is, that this returns guint64 (not guint like other NMHash functions). + * + * Another difference is, that this may also return zero (not like nm_hash_complete()). + * + * Then, why not use c_siphash_hash() directly? Because this also uses the randomized, + * per-run hash-seed like nm_hash_init(). So, you get siphash24 with a random + * seed (which is cached for the current run of the program). + */ +static inline guint64 +nm_hash_siphash42 (guint static_seed, const void *ptr, gsize n) +{ + CSipHash h; + + nm_hash_siphash42_init (&h, static_seed); + c_siphash_append (&h, ptr, n); + return c_siphash_finalize (&h); +} + +/*****************************************************************************/ + struct _NMHashState { CSipHash _state; }; @@ -33,16 +66,33 @@ typedef struct _NMHashState NMHashState; guint nm_hash_static (guint static_seed); -void nm_hash_init (NMHashState *state, guint static_seed); +static inline void +nm_hash_init (NMHashState *state, guint static_seed) +{ + nm_assert (state); + + nm_hash_siphash42_init (&state->_state, static_seed); +} + +static inline guint64 +nm_hash_complete_u64 (NMHashState *state) +{ + nm_assert (state); + + /* this returns the native u64 hash value. Note that this differs + * from nm_hash_complete() in two ways: + * + * - the type, guint64 vs. guint. + * - nm_hash_complete() never returns zero. */ + return c_siphash_finalize (&state->_state); +} static inline guint nm_hash_complete (NMHashState *state) { guint64 h; - nm_assert (state); - - h = c_siphash_finalize (&state->_state); + h = nm_hash_complete_u64 (state); /* we don't ever want to return a zero hash. * @@ -218,8 +268,8 @@ guint nm_str_hash (gconstpointer str); ({ \ NMHashState _h; \ \ - nm_hash_init (&_h, static_seed); \ - nm_hash_update_val (&_h, val); \ + nm_hash_init (&_h, (static_seed)); \ + nm_hash_update_val (&_h, (val)); \ nm_hash_complete (&_h); \ }) diff --git a/shared/nm-utils/nm-jansson.h b/shared/nm-utils/nm-jansson.h index b00c75c6..cacf87a6 100644 --- a/shared/nm-utils/nm-jansson.h +++ b/shared/nm-utils/nm-jansson.h @@ -41,6 +41,9 @@ n = json_object_iter_next(object, json_object_key_to_iter(key))) #endif +NM_AUTO_DEFINE_FCN0 (json_t *, _nm_auto_decref_json, json_decref) +#define nm_auto_decref_json nm_auto(_nm_auto_decref_json) + #endif /* WITH_JANSON */ #endif /* __NM_JANSSON_H__ */ diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index 084219b4..9059783f 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -639,6 +639,9 @@ NM_G_ERROR_MSG (GError *error) #define NM_PROPAGATE_CONST(test_expr, ptr) (ptr) #endif +#define NM_MAKE_STRV(...) \ + ((const char *const[]) { __VA_ARGS__, NULL }) + /*****************************************************************************/ #define _NM_IN_SET_EVAL_1( op, _x, y) (_x == (y)) @@ -1321,6 +1324,16 @@ nm_strcmp_p (gconstpointer a, gconstpointer b) : NM_UNIQ_T(X,xq)); \ }) +#define NM_MAX_WITH_CMP(cmp, a, b) \ + ({ \ + typeof (a) _a = (a); \ + typeof (b) _b = (b); \ + \ + ( ((cmp (_a, _b)) >= 0) \ + ? _a \ + : _b); \ + }) + /*****************************************************************************/ static inline guint diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c index ba38237b..d399ce3f 100644 --- a/shared/nm-utils/nm-shared-utils.c +++ b/shared/nm-utils/nm-shared-utils.c @@ -1081,11 +1081,24 @@ nm_utils_error_is_cancelled (GError *error, gboolean consider_is_disposing) { if (error) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return TRUE; - if ( consider_is_disposing - && g_error_matches (error, NM_UTILS_ERROR, NM_UTILS_ERROR_CANCELLED_DISPOSING)) - return TRUE; + if (error->domain == G_IO_ERROR) + return NM_IN_SET (error->code, G_IO_ERROR_CANCELLED); + if (consider_is_disposing) { + if (error->domain == NM_UTILS_ERROR) + return NM_IN_SET (error->code, NM_UTILS_ERROR_CANCELLED_DISPOSING); + } + } + return FALSE; +} + +gboolean +nm_utils_error_is_notfound (GError *error) +{ + if (error) { + if (error->domain == G_IO_ERROR) + return NM_IN_SET (error->code, G_IO_ERROR_NOT_FOUND); + if (error->domain == G_FILE_ERROR) + return NM_IN_SET (error->code, G_FILE_ERROR_NOENT); } return FALSE; } diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h index 3ea887b4..82eebc9d 100644 --- a/shared/nm-utils/nm-shared-utils.h +++ b/shared/nm-utils/nm-shared-utils.h @@ -379,6 +379,46 @@ char **_nm_utils_strv_cleanup (char **strv, /*****************************************************************************/ +#define NM_UTILS_CHECKSUM_LENGTH_MD5 16 +#define NM_UTILS_CHECKSUM_LENGTH_SHA1 20 +#define NM_UTILS_CHECKSUM_LENGTH_SHA256 32 + +#define nm_utils_checksum_get_digest(sum, arr) \ + G_STMT_START { \ + GChecksum *const _sum = (sum); \ + gsize _len; \ + \ + G_STATIC_ASSERT_EXPR ( sizeof (arr) == NM_UTILS_CHECKSUM_LENGTH_MD5 \ + || sizeof (arr) == NM_UTILS_CHECKSUM_LENGTH_SHA1 \ + || sizeof (arr) == NM_UTILS_CHECKSUM_LENGTH_SHA256); \ + G_STATIC_ASSERT_EXPR (sizeof (arr) == G_N_ELEMENTS (arr)); \ + \ + nm_assert (_sum); \ + \ + _len = G_N_ELEMENTS (arr); \ + \ + g_checksum_get_digest (_sum, (arr), &_len); \ + nm_assert (_len == G_N_ELEMENTS (arr)); \ + } G_STMT_END + +#define nm_utils_checksum_get_digest_len(sum, buf, len) \ + G_STMT_START { \ + GChecksum *const _sum = (sum); \ + const gsize _len0 = (len); \ + gsize _len; \ + \ + nm_assert (NM_IN_SET (_len0, NM_UTILS_CHECKSUM_LENGTH_MD5, \ + NM_UTILS_CHECKSUM_LENGTH_SHA1, \ + NM_UTILS_CHECKSUM_LENGTH_SHA256)); \ + nm_assert (_sum); \ + \ + _len = _len0; \ + g_checksum_get_digest (_sum, (buf), &_len); \ + nm_assert (_len == _len0); \ + } G_STMT_END + +/*****************************************************************************/ + guint32 _nm_utils_ip4_prefix_to_netmask (guint32 prefix); guint32 _nm_utils_ip4_get_default_prefix (guint32 ip); @@ -605,6 +645,8 @@ void nm_utils_error_set_cancelled (GError **error, gboolean nm_utils_error_is_cancelled (GError *error, gboolean consider_is_disposing); +gboolean nm_utils_error_is_notfound (GError *error); + static inline void nm_utils_error_set_literal (GError **error, int error_code, const char *literal) { diff --git a/shared/nm-utils/nm-test-utils.h b/shared/nm-utils/nm-test-utils.h index c8139862..7decd363 100644 --- a/shared/nm-utils/nm-test-utils.h +++ b/shared/nm-utils/nm-test-utils.h @@ -1337,6 +1337,42 @@ _nmtst_assert_resolve_relative_path_equals (const char *f1, const char *f2, cons /*****************************************************************************/ +#ifdef __NETWORKMANAGER_LOGGING_H__ +static inline gpointer +nmtst_logging_disable (gboolean always) +{ + gpointer p; + + g_assert (nmtst_initialized ()); + if (!always && __nmtst_internal.no_expect_message) { + /* The caller does not want to @always suppress logging. Instead, + * the caller wants to suppress unexpected log messages that would + * fail assertions (since we possibly assert against all unexpected + * log messages). + * + * If the test is run with no-expect-message, then don't suppress + * the loggings, because they also wouldn't fail assertions. */ + return NULL; + } + + p = g_memdup (_nm_logging_enabled_state, sizeof (_nm_logging_enabled_state)); + memset (_nm_logging_enabled_state, 0, sizeof (_nm_logging_enabled_state)); + return p; +} + +static inline void +nmtst_logging_reenable (gpointer old_state) +{ + g_assert (nmtst_initialized ()); + if (old_state) { + memcpy (_nm_logging_enabled_state, old_state, sizeof (_nm_logging_enabled_state)); + g_free (old_state); + } +} +#endif + +/*****************************************************************************/ + #ifdef NM_SETTING_IP_CONFIG_H static inline void nmtst_setting_ip_config_add_address (NMSettingIPConfig *s_ip, diff --git a/shared/nm-utils/nm-udev-utils.c b/shared/nm-utils/nm-udev-utils.c index 709f7590..5d0919b3 100644 --- a/shared/nm-utils/nm-udev-utils.c +++ b/shared/nm-utils/nm-udev-utils.c @@ -241,26 +241,23 @@ nm_udev_client_new (const char *const*subsystems, if (self->subsystems) { /* install subsystem filters to only wake up for certain events */ for (n = 0; self->subsystems[n]; n++) { - if (self->monitor) { - gs_free char *to_free = NULL; - const char *subsystem; - const char *devtype; - - _subsystem_split (self->subsystems[n], &subsystem, &devtype, &to_free); - udev_monitor_filter_add_match_subsystem_devtype (self->monitor, subsystem, devtype); - } + gs_free char *to_free = NULL; + const char *subsystem; + const char *devtype; + + _subsystem_split (self->subsystems[n], &subsystem, &devtype, &to_free); + udev_monitor_filter_add_match_subsystem_devtype (self->monitor, subsystem, devtype); } /* listen to events, and buffer them */ - if (self->monitor) { - udev_monitor_enable_receiving (self->monitor); - channel = g_io_channel_unix_new (udev_monitor_get_fd (self->monitor)); - self->watch_source = g_io_create_watch (channel, G_IO_IN); - g_io_channel_unref (channel); - g_source_set_callback (self->watch_source, (GSourceFunc)(void (*) (void)) monitor_event, self, NULL); - g_source_attach (self->watch_source, g_main_context_get_thread_default ()); - g_source_unref (self->watch_source); - } + udev_monitor_set_receive_buffer_size (self->monitor, 4*1024*1024); + udev_monitor_enable_receiving (self->monitor); + channel = g_io_channel_unix_new (udev_monitor_get_fd (self->monitor)); + self->watch_source = g_io_create_watch (channel, G_IO_IN); + g_io_channel_unref (channel); + g_source_set_callback (self->watch_source, (GSourceFunc)(void (*) (void)) monitor_event, self, NULL); + g_source_attach (self->watch_source, g_main_context_get_thread_default ()); + g_source_unref (self->watch_source); } } |