diff options
| author | Michael Biebl <biebl@debian.org> | 2020-05-08 21:40:53 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-05-08 21:40:53 +0200 |
| commit | d460892bbfece74fb6d3cd846bf6ef548290be41 (patch) | |
| tree | 0474e5be0b5e5fac0d2f3a1e554382e8d1aa6397 /shared | |
| parent | 1e5977b62f896e844b548c3007ace9e1dfa7f9ed (diff) | |
New upstream version 1.24.0 upstream/1.24.0
Diffstat (limited to 'shared')
| -rw-r--r-- | shared/n-dhcp4/src/n-dhcp4-c-connection.c | 29 | ||||
| -rw-r--r-- | shared/n-dhcp4/src/n-dhcp4-c-probe.c | 1 | ||||
| -rw-r--r-- | shared/nm-glib-aux/nm-glib.h | 8 | ||||
| -rw-r--r-- | shared/nm-glib-aux/nm-hash-utils.c | 11 | ||||
| -rw-r--r-- | shared/nm-glib-aux/nm-hash-utils.h | 3 | ||||
| -rw-r--r-- | shared/nm-glib-aux/nm-shared-utils.c | 121 | ||||
| -rw-r--r-- | shared/nm-glib-aux/nm-shared-utils.h | 23 | ||||
| -rw-r--r-- | shared/nm-keyfile/nm-keyfile-utils.c | 1 | ||||
| -rw-r--r-- | shared/nm-keyfile/nm-keyfile.c | 86 | ||||
| -rw-r--r-- | shared/nm-test-utils-impl.c | 2 | ||||
| -rw-r--r-- | shared/nm-version-macros.h | 4 |
11 files changed, 191 insertions, 98 deletions
diff --git a/shared/n-dhcp4/src/n-dhcp4-c-connection.c b/shared/n-dhcp4/src/n-dhcp4-c-connection.c index a5c8ea66..30514e28 100644 --- a/shared/n-dhcp4/src/n-dhcp4-c-connection.c +++ b/shared/n-dhcp4/src/n-dhcp4-c-connection.c @@ -1136,6 +1136,13 @@ int n_dhcp4_c_connection_dispatch_timer(NDhcp4CConnection *connection, return 0; } +/* + * Returns: + * 0 on success + * N_DHCP4_E_MALFORMED if a malformed packet was received + * N_DHCP4_E_UNEXPECTED if the packet received contains unexpected data + * N_DHCP4_E_AGAIN if there was another error (non fatal for the client) + */ int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection, NDhcp4Incoming **messagep) { _c_cleanup_(n_dhcp4_incoming_freep) NDhcp4Incoming *message = NULL; @@ -1150,10 +1157,11 @@ int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection, connection->scratch_buffer, sizeof(connection->scratch_buffer), &message); - if (r) + if (!r) + break; + else if (r == N_DHCP4_E_MALFORMED) return r; - - break; + return N_DHCP4_E_AGAIN; case N_DHCP4_C_CONNECTION_STATE_DRAINING: r = n_dhcp4_c_socket_packet_recv(connection->fd_packet, connection->scratch_buffer, @@ -1161,8 +1169,10 @@ int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection, &message); if (!r) break; - else if (r != N_DHCP4_E_AGAIN) + else if (r == N_DHCP4_E_MALFORMED) return r; + else if (r != N_DHCP4_E_AGAIN) + return N_DHCP4_E_AGAIN; /* * The UDP socket is open and the packet socket has been shut down @@ -1180,18 +1190,21 @@ int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection, connection->scratch_buffer, sizeof(connection->scratch_buffer), &message); - if (r) + if (!r) + break; + else if (r == N_DHCP4_E_MALFORMED) return r; - - break; + return N_DHCP4_E_AGAIN; default: abort(); return -ENOTRECOVERABLE; } r = n_dhcp4_c_connection_verify_incoming(connection, message, &type); - if (r) + if (r == N_DHCP4_E_MALFORMED || r == N_DHCP4_E_UNEXPECTED) return r; + else if (r != 0) + return N_DHCP4_E_AGAIN; if (type == N_DHCP4_MESSAGE_OFFER || type == N_DHCP4_MESSAGE_ACK) { n_dhcp4_c_log(connection->client_config, LOG_INFO, diff --git a/shared/n-dhcp4/src/n-dhcp4-c-probe.c b/shared/n-dhcp4/src/n-dhcp4-c-probe.c index e4477a7c..5e971298 100644 --- a/shared/n-dhcp4/src/n-dhcp4-c-probe.c +++ b/shared/n-dhcp4/src/n-dhcp4-c-probe.c @@ -1242,6 +1242,7 @@ int n_dhcp4_client_probe_dispatch_io(NDhcp4ClientProbe *probe, uint32_t events) return 0; } + abort(); return r; } diff --git a/shared/nm-glib-aux/nm-glib.h b/shared/nm-glib-aux/nm-glib.h index 4ecba9ff..7a5b8edd 100644 --- a/shared/nm-glib-aux/nm-glib.h +++ b/shared/nm-glib-aux/nm-glib.h @@ -622,4 +622,12 @@ g_hash_table_steal_extended (GHashTable *hash_table, /*****************************************************************************/ +__attribute__((__deprecated__("Don't use g_cancellable_reset(). Create a new cancellable instead."))) +void _nm_g_cancellable_reset (GCancellable *cancellable); + +#undef g_cancellable_reset +#define g_cancellable_reset(cancellable) _nm_g_cancellable_reset(cancellable) + +/*****************************************************************************/ + #endif /* __NM_GLIB_H__ */ diff --git a/shared/nm-glib-aux/nm-hash-utils.c b/shared/nm-glib-aux/nm-hash-utils.c index 0a701d06..232c62c0 100644 --- a/shared/nm-glib-aux/nm-hash-utils.c +++ b/shared/nm-glib-aux/nm-hash-utils.c @@ -265,6 +265,17 @@ nm_ppdirect_equal (gconstpointer a, gconstpointer b) /*****************************************************************************/ guint +nm_gbytes_hash (gconstpointer p) +{ + GBytes *ptr = (GBytes *) p; + gconstpointer arr; + gsize len; + + arr = g_bytes_get_data (ptr, &len); + return nm_hash_mem (792701303u, arr, len); +} + +guint nm_pgbytes_hash (gconstpointer p) { GBytes *const*ptr = p; diff --git a/shared/nm-glib-aux/nm-hash-utils.h b/shared/nm-glib-aux/nm-hash-utils.h index 9f2e9766..be69bfa8 100644 --- a/shared/nm-glib-aux/nm-hash-utils.h +++ b/shared/nm-glib-aux/nm-hash-utils.h @@ -315,6 +315,9 @@ gboolean nm_ppdirect_equal (gconstpointer a, gconstpointer b); /*****************************************************************************/ +guint nm_gbytes_hash (gconstpointer p); +#define nm_gbytes_equal g_bytes_equal + guint nm_pgbytes_hash (gconstpointer p); gboolean nm_pgbytes_equal (gconstpointer a, gconstpointer b); diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index c06399dd..5dd099a7 100644 --- a/shared/nm-glib-aux/nm-shared-utils.c +++ b/shared/nm-glib-aux/nm-shared-utils.c @@ -397,6 +397,24 @@ truncate: /*****************************************************************************/ +GBytes * +nm_gbytes_get_empty (void) +{ + static GBytes *bytes = NULL; + GBytes *b; + +again: + b = g_atomic_pointer_get (&bytes); + if (G_UNLIKELY (!b)) { + b = g_bytes_new_static ("", 0); + if (!g_atomic_pointer_compare_and_exchange (&bytes, NULL, b)) { + g_bytes_unref (b); + goto again; + } + } + return b; +} + /** * nm_utils_gbytes_equals: * @bytes: (allow-none): a #GBytes array to compare. Note that @@ -3655,9 +3673,9 @@ _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...) typedef struct { gpointer callback_user_data; GCancellable *cancellable; + GSource *source; NMUtilsInvokeOnIdleCallback callback; gulong cancelled_id; - guint idle_id; } InvokeOnIdleData; static gboolean @@ -3665,12 +3683,13 @@ _nm_utils_invoke_on_idle_cb_idle (gpointer user_data) { InvokeOnIdleData *data = user_data; - data->idle_id = 0; nm_clear_g_signal_handler (data->cancellable, &data->cancelled_id); data->callback (data->callback_user_data, data->cancellable); + nm_g_object_unref (data->cancellable); - g_slice_free (InvokeOnIdleData, data); + g_source_destroy (data->source); + nm_g_slice_free (data); return G_SOURCE_REMOVE; } @@ -3680,41 +3699,87 @@ _nm_utils_invoke_on_idle_cb_cancelled (GCancellable *cancellable, { /* on cancellation, we invoke the callback synchronously. */ nm_clear_g_signal_handler (data->cancellable, &data->cancelled_id); - nm_clear_g_source (&data->idle_id); + nm_clear_g_source_inst (&data->source); data->callback (data->callback_user_data, data->cancellable); nm_g_object_unref (data->cancellable); - g_slice_free (InvokeOnIdleData, data); + nm_g_slice_free (data); } -void -nm_utils_invoke_on_idle (NMUtilsInvokeOnIdleCallback callback, - gpointer callback_user_data, - GCancellable *cancellable) +static void +_nm_utils_invoke_on_idle_start (gboolean use_timeout, + guint timeout_msec, + GCancellable *cancellable, + NMUtilsInvokeOnIdleCallback callback, + gpointer callback_user_data) { InvokeOnIdleData *data; + GSource *source; g_return_if_fail (callback); data = g_slice_new (InvokeOnIdleData); - data->callback = callback; - data->callback_user_data = callback_user_data; - data->cancellable = nm_g_object_ref (cancellable); - if ( cancellable - && !g_cancellable_is_cancelled (cancellable)) { - /* if we are passed a non-cancelled cancellable, we register to the "cancelled" - * signal an invoke the callback synchronously (from the signal handler). - * - * We don't do that, - * - if the cancellable is already cancelled (because we don't want to invoke - * the callback synchronously from the caller). - * - if we have no cancellable at hand. */ - data->cancelled_id = g_signal_connect (cancellable, - "cancelled", - G_CALLBACK (_nm_utils_invoke_on_idle_cb_cancelled), - data); - } else - data->cancelled_id = 0; - data->idle_id = g_idle_add (_nm_utils_invoke_on_idle_cb_idle, data); + *data = (InvokeOnIdleData) { + .callback = callback, + .callback_user_data = callback_user_data, + .cancellable = nm_g_object_ref (cancellable), + .cancelled_id = 0, + }; + + if (cancellable) { + if (g_cancellable_is_cancelled (cancellable)) { + /* the cancellable is already cancelled. We ignore the timeout + * and always schedule an idle action. */ + use_timeout = FALSE; + } else { + /* if we are passed a non-cancelled cancellable, we register to the "cancelled" + * signal an invoke the callback synchronously (from the signal handler). + * + * We don't do that, + * - if the cancellable is already cancelled (because we don't want to invoke + * the callback synchronously from the caller). + * - if we have no cancellable at hand. */ + data->cancelled_id = g_signal_connect (cancellable, + "cancelled", + G_CALLBACK (_nm_utils_invoke_on_idle_cb_cancelled), + data); + } + } + + if (use_timeout) { + source = nm_g_timeout_source_new (timeout_msec, + G_PRIORITY_DEFAULT, + _nm_utils_invoke_on_idle_cb_idle, + data, + NULL); + } else { + source = nm_g_idle_source_new (G_PRIORITY_DEFAULT, + _nm_utils_invoke_on_idle_cb_idle, + data, + NULL); + } + + /* use the current thread default context. */ + g_source_attach (source, + g_main_context_get_thread_default ()); + + data->source = source; +} + +void +nm_utils_invoke_on_idle (GCancellable *cancellable, + NMUtilsInvokeOnIdleCallback callback, + gpointer callback_user_data) +{ + _nm_utils_invoke_on_idle_start (FALSE, 0, cancellable, callback, callback_user_data); +} + +void +nm_utils_invoke_on_timeout (guint timeout_msec, + GCancellable *cancellable, + NMUtilsInvokeOnIdleCallback callback, + gpointer callback_user_data) +{ + _nm_utils_invoke_on_idle_start (TRUE, timeout_msec, cancellable, callback, callback_user_data); } /*****************************************************************************/ diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index 537b402b..d5990c2d 100644 --- a/shared/nm-glib-aux/nm-shared-utils.h +++ b/shared/nm-glib-aux/nm-shared-utils.h @@ -280,6 +280,14 @@ gboolean nm_utils_ipaddr_is_normalized (int addr_family, return (_a < _b) ? -1 : 1; \ } G_STMT_END +/* In the general case, direct pointer comparison is undefined behavior in C. + * Avoid that by casting pointers to void* and then to uintptr_t. This comparison + * is not really meaningful, except that it provides some kind of stable sort order + * between pointers (that can otherwise not be compared). */ +#define NM_CMP_DIRECT_PTR(a, b) \ + NM_CMP_DIRECT ((uintptr_t) ((void *) (a)), \ + (uintptr_t) ((void *) (b))) + #define NM_CMP_DIRECT_MEMCMP(a, b, size) \ NM_CMP_RETURN (memcmp ((a), (b), (size))) @@ -381,6 +389,8 @@ nm_utils_is_separator (const char c) /*****************************************************************************/ +GBytes *nm_gbytes_get_empty (void); + static inline gboolean nm_gbytes_equal0 (GBytes *a, GBytes *b) { @@ -1621,12 +1631,17 @@ void _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...); /*****************************************************************************/ -typedef void (*NMUtilsInvokeOnIdleCallback) (gpointer callback_user_data, +typedef void (*NMUtilsInvokeOnIdleCallback) (gpointer user_data, GCancellable *cancellable); -void nm_utils_invoke_on_idle (NMUtilsInvokeOnIdleCallback callback, - gpointer callback_user_data, - GCancellable *cancellable); +void nm_utils_invoke_on_idle (GCancellable *cancellable, + NMUtilsInvokeOnIdleCallback callback, + gpointer callback_user_data); + +void nm_utils_invoke_on_timeout (guint timeout_msec, + GCancellable *cancellable, + NMUtilsInvokeOnIdleCallback callback, + gpointer callback_user_data); /*****************************************************************************/ diff --git a/shared/nm-keyfile/nm-keyfile-utils.c b/shared/nm-keyfile/nm-keyfile-utils.c index e18db20d..041b5eab 100644 --- a/shared/nm-keyfile/nm-keyfile-utils.c +++ b/shared/nm-keyfile/nm-keyfile-utils.c @@ -124,7 +124,6 @@ nm_keyfile_plugin_kf_get_##stype##_list (GKeyFile *kf, \ list = g_key_file_get_##stype##_list (kf, alias, key, &l, &local); \ } \ } \ - nm_assert ((!local) != (!list)); \ if (local) \ g_propagate_error (error, local); \ if (!list) \ diff --git a/shared/nm-keyfile/nm-keyfile.c b/shared/nm-keyfile/nm-keyfile.c index 15485747..879b1b00 100644 --- a/shared/nm-keyfile/nm-keyfile.c +++ b/shared/nm-keyfile/nm-keyfile.c @@ -167,9 +167,10 @@ read_array_of_uint (GKeyFile *file, gsize length; gsize i; gs_free int *tmp = NULL; + gs_free_error GError *error = NULL; - tmp = nm_keyfile_plugin_kf_get_integer_list (file, nm_setting_get_name (setting), key, &length, NULL); - if (length > G_MAXUINT) + tmp = nm_keyfile_plugin_kf_get_integer_list (file, nm_setting_get_name (setting), key, &length, &error); + if (error) return; array = g_array_sized_new (FALSE, FALSE, sizeof (guint), length); @@ -934,13 +935,19 @@ ip6_addr_gen_mode_parser (KeyfileReaderInfo *info, NMSetting *setting, const cha } static void -mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key, gsize enforce_length, gboolean cloned_mac_addr) +mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key, gsize addr_len, gboolean cloned_mac_addr) { const char *setting_name = nm_setting_get_name (setting); + char addr_str[NM_UTILS_HWADDR_LEN_MAX * 3]; + guint8 addr_bin[NM_UTILS_HWADDR_LEN_MAX]; gs_free char *tmp_string = NULL; - const char *p, *mac_str; - gs_free guint8 *buf_arr = NULL; - guint buf_len = 0; + gs_free int *int_list = NULL; + const char *mac_str; + gsize int_list_len; + gsize i; + + nm_assert (addr_len > 0); + nm_assert (addr_len <= NM_UTILS_HWADDR_LEN_MAX); tmp_string = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL); @@ -950,60 +957,31 @@ mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key goto out; } - if (tmp_string && tmp_string[0]) { - /* Look for enough ':' characters to signify a MAC address */ - guint i = 0; - - p = tmp_string; - while (*p) { - if (*p == ':') - i++; - p++; - } - - if (enforce_length == 0 || enforce_length == i+1) { - /* If we found enough it's probably a string-format MAC address */ - buf_len = i + 1; - buf_arr = g_new (guint8, buf_len); - if (!nm_utils_hwaddr_aton (tmp_string, buf_arr, buf_len)) - nm_clear_g_free (&buf_arr); - } - } - nm_clear_g_free (&tmp_string); - - if (!buf_arr) { - gs_free int *tmp_list = NULL; - gsize length; + if ( tmp_string + && nm_utils_hwaddr_aton (tmp_string, addr_bin, addr_len)) + goto good_addr_bin; - /* Old format; list of ints */ - tmp_list = nm_keyfile_plugin_kf_get_integer_list (info->keyfile, setting_name, key, &length, NULL); - if (length > 0 && (enforce_length == 0 || enforce_length == length)) { - gsize i; + /* Old format; list of ints */ + int_list = nm_keyfile_plugin_kf_get_integer_list (info->keyfile, setting_name, key, &int_list_len, NULL); + if (int_list_len == addr_len) { + for (i = 0; i < addr_len; i++) { + const int val = int_list[i]; - buf_len = length; - buf_arr = g_new (guint8, buf_len); - for (i = 0; i < length; i++) { - int val = tmp_list[i]; - - if (val < 0 || val > 255) { - handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN, - _("ignoring invalid byte element '%d' (not between 0 and 255 inclusive)"), - val); - return; - } - buf_arr[i] = (guint8) val; - } + if (val < 0 || val > 255) + break; + addr_bin[i] = (guint8) val; } + if (i == addr_len) + goto good_addr_bin; } - if (!buf_arr) { - handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN, - _("ignoring invalid MAC address")); - return; - } + handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN, + _("ignoring invalid MAC address")); + return; - tmp_string = nm_utils_hwaddr_ntoa (buf_arr, buf_len); - mac_str = tmp_string; +good_addr_bin: + nm_utils_bin2hexstr_full (addr_bin, addr_len, ':', TRUE, addr_str); + mac_str = addr_str; out: g_object_set (setting, key, mac_str, NULL); diff --git a/shared/nm-test-utils-impl.c b/shared/nm-test-utils-impl.c index 0ef6591f..ce7cc8d1 100644 --- a/shared/nm-test-utils-impl.c +++ b/shared/nm-test-utils-impl.c @@ -454,7 +454,7 @@ _context_object_new_do_cb (GObject *source_object, static GObject * _context_object_new_do (GType gtype, gboolean sync, - const gchar *first_property_name, + const char *first_property_name, va_list var_args) { gs_free_error GError *error = NULL; diff --git a/shared/nm-version-macros.h b/shared/nm-version-macros.h index a085c115..b98a4e1d 100644 --- a/shared/nm-version-macros.h +++ b/shared/nm-version-macros.h @@ -22,7 +22,7 @@ * Evaluates to the minor version number of NetworkManager which this source * is compiled against. */ -#define NM_MINOR_VERSION (23) +#define NM_MINOR_VERSION (24) /** * NM_MICRO_VERSION: @@ -30,7 +30,7 @@ * Evaluates to the micro version number of NetworkManager which this source * compiled against. */ -#define NM_MICRO_VERSION (90) +#define NM_MICRO_VERSION (0) /** * NM_CHECK_VERSION: |