Commit graph

162 commits

Author SHA1 Message Date
Lubomir Rintel
356f1131f3 shared/utils: don't warn of unknown warning disables with clang
When pushing a warning disable with clang, always disable
-Wunknown-warning-option first -- it might be that clang wouldn't warn
of what we're trying to disable because it doesn't recognize it in the
first place. That is entierely okay.

With clang-5.0.0:

    CC       libnm/tests/libnm_tests_test_secret_agent-test-secret-agent.o
  In file included from libnm/tests/test-secret-agent.c:29:
  In file included from ./shared/nm-test-libnm-utils.h:23:
  ./shared/nm-utils/nm-test-utils.h:432:3: error: unknown warning group '-Wunused-but-set-variable', ignored [-Werror,-Wunknown-warning-option]
                  NM_PRAGMA_WARNING_DISABLE("-Wunused-but-set-variable")
                  ^
  ./shared/nm-utils/nm-macros-internal.h:223:9: note: expanded from macro 'NM_PRAGMA_WARNING_DISABLE'
          _Pragma(_NM_PRAGMA_WARNING_DO(warning))
          ^
  <scratch space>:204:25: note: expanded from here
   GCC diagnostic ignored "-Wunused-but-set-variable"
                          ^
  1 error generated.

(cherry picked from commit fc4552d391)
2018-01-24 09:55:18 +01:00
Thomas Haller
85b1c11b8f shared: propagate type for g_object_ref()
See related bug https://bugzilla.gnome.org/show_bug.cgi?id=790697

(cherry picked from commit 7ca601d529)
2017-12-06 10:44:45 +01:00
Thomas Haller
e36b647c4b shared/trivial: fix type on comment
(cherry picked from commit 011a609bd4)
2017-12-06 09:35:43 +01:00
Thomas Haller
7135097762 shared: fix nm_utils_strsplit_set() to increase buffer size exponentially
(cherry picked from commit de92e88161)
2017-11-29 19:15:30 +01:00
Thomas Haller
bf7661189e c-list: re-import latest version of c-list.h from upstream
Most notably, it renames
  c_list_unlink_init() -> c_list_unlink()
  c_list_unlink() -> c_list_unlink_stale()

  $ sed -e 's/\<c_list_unlink\>/c_list_unlink_old/g' \
        -e 's/\<c_list_unlink_init\>/c_list_unlink/g' \
        -e 's/\<c_list_unlink_old\>/c_list_unlink_stale/g' \
        $(git grep -l c_list_unlink -- ':(exclude)shared/nm-utils/c-list.h') \
        -i

(cherry picked from commit b6efac9ec2)
2017-11-28 12:04:15 +01:00
Thomas Haller
1ec51d02bd shared: add nm_g_object_set_property_*() helper
(cherry picked from commit 5befde7d7d)
2017-11-24 08:29:23 +01:00
Thomas Haller
7e1e1c1f7f shared: add NMUtilsNamedEntry
It is common to have some data indexed by a name.
If you want to sort a list of such data, you would
have to re-implement your own compare function each time.

Instead, add NMUtilsNamedEntry which as first field has
the name. So, you can create your own struct:

  struct my_data {
    const char *name;
    ... other fields
  }

and compare them with with nm_utils_named_entry_cmp().

For convenience, add another struct NMUtilsNamedValue, which
has only one data field, a pointer.

(cherry picked from commit 3adce12898)
2017-11-21 14:14:25 +01:00
Thomas Haller
fc2894508e all: use nm_close() instead of close()
(cherry picked from commit 5b29c2e5b9)
2017-11-14 15:17:02 +01:00
Thomas Haller
334846906e shared: always call close() from nm_close() wrapper
The nm_close() wrapper should behave exactly the same as calling
close() directly. This is well known, documented behavior.

The only addition on top of that, should be the nm_assert() to catch
double-closing.

Prevously, when passing a negative file descriptor, we wouldn't properly
set errno. Also, the call would not show up in strace, which it should
(at least, if libc's close actually makes the syscall).

I would argue, that passing a negative file descriptor is a bug already
and we should never do that. Maybe we should even assert non-negative
fds. I don't do that now, because I am not sufficiently confident.
Anyway, the change should have not practical effect, because we
shouldn't actually pass negative fds already.

(cherry picked from commit f4780f85ae)
2017-11-14 15:17:01 +01:00
Thomas Haller
02b339f170 shared: add nm_ip_addr_set() helper
(cherry picked from commit a9d1f5e543)
2017-11-13 14:43:07 +01:00
Thomas Haller
cfe4d61a12 shared/trivial: move code
(cherry picked from commit 632e8ac885)
2017-11-13 14:43:07 +01:00
Thomas Haller
d9c5f7c9fb build: detect compiler features _Generic() and __auto_type in configure script
There is still a fallback detection in "shared/nm-utils/nm-macros-internal.h",
so that VPN-plugins and applet don't need to bother about adding these
configure checks.

(cherry picked from commit 557d83bf2d)
2017-11-13 14:43:07 +01:00
Thomas Haller
5282469098 shared: propagate constness in _NM_GET_PRIVATE_PTR()
The _NM_GET_PRIVATE() macro already preserved and propagated
the constness of @self to the resulting private pointer.

_NM_GET_PRIVATE_PTR() didn't do that. Extend the macro,
to make that possible.

(cherry picked from commit bdfdabea51)
2017-11-13 14:43:07 +01:00
Thomas Haller
5d940b73fe shared: fix detection of _Generic() support
(cherry picked from commit 03efc9e2c9)
2017-11-13 14:43:07 +01:00
Francesco Giudici
dcdb1e5fd0 shared: trivial: add space before comment close
(cherry picked from commit 85cc5db7a4)
2017-11-13 14:37:37 +01:00
Thomas Haller
dd02e4bfce shared: make NM_CONSTCAST() macro variadic
We need to pass more alias-types. Instead of having numbered
versions, use variadic number of macro arguments.

Also, fix build failure with old compiler:

  In file included from src/nm-ip6-config.c:24:
  ./src/nm-ip6-config.h:44:29: error: controlling expression type 'typeof (ipconf_iter->current->obj)' (aka 'const void *const') not compatible with any generic association type
                  *out_address = has_next ? NMP_OBJECT_CAST_IP6_ADDRESS (ipconf_iter->current->obj) : NULL;
                                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Fixes: b1810d7a68
(cherry picked from commit b339a2742a)
2017-11-13 14:37:30 +01:00
Thomas Haller
fda3458201 shared: rework _NM_GET_PRIVATE() to use _Generic()
_NM_GET_PRIVATE() used typeof() to propagate constness of the @self
pointer. However, that means, it could only be used with a self pointer
of the exact type. That means, you explicitly had to cast from (GObject *)
or from (void *).
The requirement is cumbersome, and often led us to either create @self
pointer we didn't need:

    NMDeviceVlan *self = NM_DEVICE_VLAN (device);
    NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);

or casting:

    NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE ((NMDevice *) device);

In both cases we forcefully cast the source variable, loosing help from
the compiler to detect a bug.

For "nm-linux-platform.c", instead we commonly have a pointer of type
NMPlatform. Hence, we always forcefully cast the type via _NM_GET_PRIVATE_VOID().

Rework the macro to use _Generic(). If compiler supports _Generic(), then we
will get all compile time checks as desired. If the compiler doesn't support
_Generic(), it will still work. You don't get the compile-time checking of course,
but you'd notice that something is wrong once you build with a suitable
compiler.

(cherry picked from commit b1810d7a68)
2017-11-13 14:37:21 +01:00
Thomas Haller
93315d01da tests: add nmtst_assert_connection_has_settings() helper 2017-10-30 21:46:55 +01:00
Thomas Haller
de65d3da91 shared: fix nm_steal_fd() for handling zero file descriptor
Zero is a valid file descriptor.

Fixes: 956b3e8bd5
2017-10-30 11:44:37 +01:00
Beniamino Galvani
ef52122469 shared: fix compilation on 32-bit archictectures
shared/nm-utils/nm-hash-utils.c:110:3: error: right shift count >= width of type [-Werror]
   h = h ^ ((guint) (((uintptr_t) ptr) >> 32)) ^ ((guint) ((uintptr_t) ptr));
   ^

Even if the branch is not reached on 32-bit architectures, the
compiler still emits a warning for the 32-bit right shift.

Fixes: ee76b0979f
2017-10-26 15:13:40 +02:00
Thomas Haller
956b3e8bd5 shared: add nm_steal_fd() helper function 2017-10-19 15:49:58 +02:00
Beniamino Galvani
1bc1809e11 shared: introduce nm_close()
nm_close() is like close(), but throws an assertion if the input fd is
>=0 and invalid. Passing an invalid (i.e. already closed) fd to
close() is a programming error with potentially catastrophic effects,
as another thread may reuse the closed fd.
2017-10-19 15:49:50 +02:00
Thomas Haller
cfe8546df9 all: extend hash functions with an NMHashState argument
We often want to cascade hashing, meaning, to combine the
outcome of various hash functions in a larger hash.

Instead of having each hash function return a guint hash value,
accept a hash state argument. This saves the overhead of initializing
and completing the intermediate hash states.
It also avoids loosing entropy when we reduce the larger hash state
into the intermediate guint hash value.
2017-10-18 13:29:22 +02:00
Thomas Haller
2f56de7492 all: add helper functions for nm_hash_update*()
By using a macro, we don't cast all the types to guint. Instead,
we use their native types directly. Hence, we don't need
nm_hash_update_uint64() nor nm_hash_update_ptr().
Also, for types smaller then guint like char, we save hashing
the all zero bytes.
2017-10-18 13:29:22 +02:00
Thomas Haller
ee76b0979f all: use siphash24 for hashing
siphash24() is wildly used by projects nowadays.

It's certainly slower then our djb hashing that we used before.
But quite likely it's fast enough for us, given how wildly it is
used. I think it would be hard to profile NetworkManager to show
that the performance of hash tables is the issue, be it with
djb or siphash24.

Certainly with siphash24() it's much harder to exploit the hashing
algorithm to cause worst case hash operations (provided that the
seed is kept private). Does this better resistance against a denial
of service matter for us? Probably not, but let's better be safe then
sorry.

Note that systemd's implementation uses a different seed for each hash
table (at least, after the hash table grows to a certain size).
We don't do that and use only one global seed.
2017-10-18 13:27:02 +02:00
Thomas Haller
0e9e35e309 all: refactor hashing by introducing NMHashState
The privious NM_HASH_* macros directly operated on a guint value
and were thus close to the actual implementation.

Replace them by adding a NMHashState struct and accessors to
update the hash state. This hides the implementation better
and would allow us to carry more state. For example, we could
switch to siphash24() transparently.

For now, we still do a form basically djb2 hashing, albeit with
differing start seed.

Also add nm_hash_str() and nm_str_hash():

- nm_hash_str() is our own string hashing implementation

- nm_str_hash() is our own string implementation, but with a
  GHashFunc signature, suitable to pass it to g_hash_table_new().
  Also, it has this name in order to remind you of g_str_hash(),
  which it is replacing.
2017-10-18 13:05:00 +02:00
Thomas Haller
281d2d9fad shared: split random and hash utils
"nm-utils/nm-shared-utils.h" shall contain utility function without other
dependencies. It is intended to be used by other projects as-is.

nm_utils_random_bytes() requires getrandom() and a HAVE_GETRANDOM configure
check. That makes it more cumbersome to re-use "nm-shared-utils.h", in
cases where you don't care about nm_utils_random_bytes().

Split nm_utils_random_bytes() out to a separate file.

Same for hash utils, which depend on nm_utils_random_bytes(). Also, hash
utils will eventually be extended to use siphash24.
2017-10-17 20:02:59 +02:00
Thomas Haller
acbab884ee shared: add _NM_ENSURE_TYPE() macro 2017-10-17 20:02:59 +02:00
Thomas Haller
bdb8e65434 shared: add _nm_align() and _nm_alignof() macros 2017-10-17 20:02:59 +02:00
Thomas Haller
c978b9dfe5 core: randomize hash seed with a global seed
This makes hashing non-deterministic with the aim to
make it harder to exploit hash collisions.

Non-deterministic also means that for unit testing
we will get different values on each run. But since we
shall never assign any meaning to these hash values
nor rely on them being stable between restarts (or
upgrades), that doesn't hurt.
2017-10-13 12:47:55 +02:00
Thomas Haller
4a2798434e core: introduce NM_HASH_INIT() to initialize hash seed
Introduce a NM_HASH_INIT() function. It makes the places
where we initialize a hash with a certain seed visually clear.

Also, move them from "shared/nm-utils/nm-shared-utils.h" to
"shared/nm-utils/nm-macros-internal.h". We might want to
have NM_HASH_INIT() non-inline (hence, define it in the
source file).
2017-10-13 12:47:55 +02:00
Thomas Haller
b01a453ca2 core: add nm_utils_random_bytes() and use getrandom()
Add a new function nm_utils_random_bytes().

This function now preferably uses getrandom() syscall if it is
available.

As fallback, it always tries to fill the buffer from /dev/urandom.
If it cannot, as last fallback it uses GRand, which cannot fail.
Hence, the function always sets some (pseudo) random bytes.

It also returns FALSE if the obtained bytes are possibly not good
randomness.
2017-10-13 12:47:55 +02:00
Thomas Haller
93ea7a5905 shared: move nm_utils_fd_*() from src/ to shared/nm-utils/
The functions are general purpose and independent from NetworkManager core.
Move them to "shared/nm-utils/" so they can be used independently.
2017-10-13 12:47:55 +02:00
Thomas Haller
373684fdc0 shared: add _nm_thread_local macro
Copied and adjusted from systemd.
2017-10-13 12:47:55 +02:00
Beniamino Galvani
d554f535af shared: fix gtk-doc build warning
Fixes the following:

 shared/nm-utils/nm-shared-utils.c:136: Warning: NetworkManager: GTK-Doc comment block end token "*/" should not be preceded by comment text:
 * Returns: the input buffer with the quoted string. */
2017-10-13 12:10:02 +02:00
Thomas Haller
147394687e shared: add nm_utils_addr_family_to_size() 2017-10-09 22:05:35 +02:00
Thomas Haller
6a3005ea72 shared: add nm_strstrip_avoid_copy() 2017-10-09 22:05:35 +02:00
Thomas Haller
a31f1706e5 shared: guarantee output argument of nm_utils_parse_inaddr_bin() is only set on success
The documentation of inet_pton() is not clear about what happens
when parsing fails. Guarantee that the output is only modified
on success.
2017-10-06 11:08:39 +02:00
Thomas Haller
a0aec7efea shared: pass addr_family as first argument to nm_utils_parse_inaddr*()
The addr_family should be the first argument. It mirrors inet_pton()
and is just nicer.

Also, rename the argument from "family" to "addr_family".
2017-10-06 11:08:39 +02:00
Thomas Haller
f1009bcde3 shared: add nm_strquote() util
We already have nm_strquote_a(). That is useful, but uses alloca(), hence it
is ill suited to be called from a macro, inside a loop, or from a function
that should be inlined.

Instead, add nm_strquote() that has the same purpose but writes to a provided
string buffer.
2017-10-06 11:08:39 +02:00
Thomas Haller
1348b7c83a shared: move utils NM_UTILS_ENUM2STR*, NM_UTILS_FLAGS2STR*, and nm_utils_to_string_buffer_init()
These are just simple utility functions, not tied to NetworkManager
core. Move them to shared/nm-utils, so that they may be reused
otherwise.
2017-10-05 11:50:31 +02:00
Thomas Haller
c17e0f7197 shared: add nm_utils_addr_family_to_char() 2017-10-02 13:50:56 +02:00
Thomas Haller
f7616eee1e shared: move nm_dedup_multi_obj_ref() to header as inline
nm_dedup_multi_obj_ref() is a trivial function, that only uses the field
which is already declared in the same header file. Move it to the header
so that it can be inlined (without LTO).
2017-09-26 19:31:17 +02:00
Thomas Haller
daa4604c12 shared: add nm_utils_strsplit_set() helper
A replacement for g_strsplit_set(). While g_strsplit_set()
does (n+1) malloc and n slice allocations, this needs
roughtly (O(log(n))) mallocs.

Another difference from g_strsplit_set() is that this function
treats multiple delimiters as one (and thus never returns empty
words). While I can see that sometimes you may want to keep empty
words (like parsing a CSV file and preserve empty cells), we usually
use this function for splitting user input. In such case, we want
to treat multiple delimiters as one.
2017-09-18 20:14:09 +02:00
Thomas Haller
f6a727685e shared: add nm_utils_parse_inaddr_prefix_bin() helper 2017-09-18 20:14:09 +02:00
Thomas Haller
dd0617547d shared: add NMIPAddr struct 2017-09-18 20:14:09 +02:00
Thomas Haller
569b443233 shared: add nm-glib.h compat implementation for g_variant_new_printf() 2017-09-18 20:14:09 +02:00
Thomas Haller
2cc1813340 core: workaround configuring IPv6 routes with "src" (RTA_PREFSRC)
Kernel does not allow to add IPv6 routes with "src", as long as the
corresponding address is still tentative (related bug rh#1457196).

The workaround for this is cumbersome. First, when we fail to add such a
route with "pref_src", we guess that it happend due to this issue. In
that case, nm_ip6_config_commit() returns the list of routes that could
not be added for the moment (but hopefully can be added later).

We track this list in NMDevice, and keep trying to merge the routes
back into ip6_config. In order to not try indefinitely, keep track of a
timestamp when we tried to add this route for the first time.

Another uglyness is that pending tentative routes don't explicitly block
activation. In practice they may do, because for these routes we also have
an IPv6 address that is still doing DAD, so the IP configuration is
still pending due to that.

https://bugzilla.redhat.com/show_bug.cgi?id=1452684
2017-09-15 17:28:48 +02:00
Thomas Haller
959944d623 shared: add nm_g_object_ref_set() and nm_clear_g_object()
- nm_clear_g_object() is like g_clear_object() but:

  - it returns a boolean value, indicating that something was cleared.

  - it includes an nm_assert() to check that the pointer is still
    valid.

  - it uses typeof() instead of blindly casting the argument.

- nm_g_object_ref_set() combines nm_clear_g_object() and resetting
  the pointer to a new object, including taking a reference.

  - also returns a boolean, indicating whether something changed.

  - it gets the order of operations right: first it increses the
    ref-count, before unrefing the old object.

  - like nm_clear_g_object() and nm_clear_g_free() it first sets
    the destination to NULL, instead of leaving a dangling pointer
    for the duraction of the unref/free call.

- fix nm_clear_g_free() not to use a possibly dangling pointer.
  Striclty speaking, that is undefined behavior.
2017-09-08 11:05:04 +02:00
Thomas Haller
19716df23d shared: add nm_g_object_class_find_property_from_gtype() util
And relax the type for nm_auto_unref_gtypeclass macro. Like
g_type_class_unref() itself, you usually don't use it with a GTypeClass
base class, but some subtype like GObjectClass.
2017-09-07 18:10:06 +02:00