glib-aux,all: merge branch 'th/g-random-int'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1517
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "libnm-glib-aux/nm-random-utils.h"
|
||||||
#include "libnm-platform/nm-platform-utils.h"
|
#include "libnm-platform/nm-platform-utils.h"
|
||||||
#include "libnm-platform/nm-platform.h"
|
#include "libnm-platform/nm-platform.h"
|
||||||
#include "libnm-platform/nmp-netns.h"
|
#include "libnm-platform/nmp-netns.h"
|
||||||
@@ -858,7 +859,7 @@ solicit_retransmit_time_jitter(gint32 solicit_retransmit_time_msec)
|
|||||||
ten_percent = NM_MAX(1, solicit_retransmit_time_msec / 10);
|
ten_percent = NM_MAX(1, solicit_retransmit_time_msec / 10);
|
||||||
|
|
||||||
return solicit_retransmit_time_msec - ten_percent
|
return solicit_retransmit_time_msec - ten_percent
|
||||||
+ ((gint32) (g_random_int() % (2u * ((guint32) ten_percent))));
|
+ ((gint32) (nm_random_u32() % (2u * ((guint32) ten_percent))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -936,7 +937,7 @@ solicit_timer_start(NMNDisc *ndisc)
|
|||||||
* a suitable delay in 2021. Wait only up to 250 msec instead. */
|
* a suitable delay in 2021. Wait only up to 250 msec instead. */
|
||||||
|
|
||||||
delay_msec =
|
delay_msec =
|
||||||
g_random_int() % ((guint32) (NM_NDISC_RFC4861_MAX_RTR_SOLICITATION_DELAY * 1000 / 4));
|
nm_random_u32() % ((guint32) (NM_NDISC_RFC4861_MAX_RTR_SOLICITATION_DELAY * 1000 / 4));
|
||||||
|
|
||||||
_LOGD("solicit: schedule sending first solicitation (of %d) in %.3f seconds",
|
_LOGD("solicit: schedule sending first solicitation (of %d) in %.3f seconds",
|
||||||
priv->config.router_solicitations,
|
priv->config.router_solicitations,
|
||||||
@@ -974,8 +975,9 @@ announce_router(NMNDisc *ndisc)
|
|||||||
|
|
||||||
/* Schedule next initial announcement retransmit. */
|
/* Schedule next initial announcement retransmit. */
|
||||||
priv->send_ra_id =
|
priv->send_ra_id =
|
||||||
g_timeout_add_seconds(g_random_int_range(NM_NDISC_ROUTER_ADVERT_DELAY,
|
g_timeout_add_seconds(nm_random_u64_range_full(NM_NDISC_ROUTER_ADVERT_DELAY,
|
||||||
NM_NDISC_ROUTER_ADVERT_INITIAL_INTERVAL),
|
NM_NDISC_ROUTER_ADVERT_INITIAL_INTERVAL,
|
||||||
|
FALSE),
|
||||||
(GSourceFunc) announce_router,
|
(GSourceFunc) announce_router,
|
||||||
ndisc);
|
ndisc);
|
||||||
} else {
|
} else {
|
||||||
@@ -1009,10 +1011,9 @@ announce_router_initial(NMNDisc *ndisc)
|
|||||||
/* Schedule the initial send rather early. Clamp the delay by minimal
|
/* Schedule the initial send rather early. Clamp the delay by minimal
|
||||||
* delay and not the initial advert internal so that we start fast. */
|
* delay and not the initial advert internal so that we start fast. */
|
||||||
if (G_LIKELY(!priv->send_ra_id)) {
|
if (G_LIKELY(!priv->send_ra_id)) {
|
||||||
priv->send_ra_id =
|
priv->send_ra_id = g_timeout_add_seconds(nm_random_u64_range(NM_NDISC_ROUTER_ADVERT_DELAY),
|
||||||
g_timeout_add_seconds(g_random_int_range(0, NM_NDISC_ROUTER_ADVERT_DELAY),
|
(GSourceFunc) announce_router,
|
||||||
(GSourceFunc) announce_router,
|
ndisc);
|
||||||
ndisc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1028,7 +1029,7 @@ announce_router_solicited(NMNDisc *ndisc)
|
|||||||
nm_clear_g_source(&priv->send_ra_id);
|
nm_clear_g_source(&priv->send_ra_id);
|
||||||
|
|
||||||
if (!priv->send_ra_id) {
|
if (!priv->send_ra_id) {
|
||||||
priv->send_ra_id = g_timeout_add(g_random_int_range(0, NM_NDISC_ROUTER_ADVERT_DELAY_MS),
|
priv->send_ra_id = g_timeout_add(nm_random_u64_range(NM_NDISC_ROUTER_ADVERT_DELAY_MS),
|
||||||
(GSourceFunc) announce_router,
|
(GSourceFunc) announce_router,
|
||||||
ndisc);
|
ndisc);
|
||||||
}
|
}
|
||||||
|
@@ -3673,9 +3673,7 @@ _hw_addr_eth_complete(struct ether_addr *addr,
|
|||||||
|
|
||||||
nm_assert((ouis == NULL) ^ (ouis_len != 0));
|
nm_assert((ouis == NULL) ^ (ouis_len != 0));
|
||||||
if (ouis) {
|
if (ouis) {
|
||||||
/* g_random_int() is good enough here. It uses a static GRand instance
|
oui = ouis[nm_random_u64_range(ouis_len)];
|
||||||
* that is seeded from /dev/urandom. */
|
|
||||||
oui = ouis[g_random_int() % ouis_len];
|
|
||||||
g_free(ouis);
|
g_free(ouis);
|
||||||
} else {
|
} else {
|
||||||
if (!nm_utils_hwaddr_aton(current_mac_address, &oui, ETH_ALEN))
|
if (!nm_utils_hwaddr_aton(current_mac_address, &oui, ETH_ALEN))
|
||||||
|
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "nm-libnm-aux.h"
|
#include "nm-libnm-aux.h"
|
||||||
|
|
||||||
|
#include "libnm-glib-aux/nm-random-utils.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
NMClient *
|
NMClient *
|
||||||
@@ -101,7 +103,7 @@ nmc_client_new_waitsync(GCancellable *cancellable,
|
|||||||
* code no longer uses that, we hardly test those code paths. But they should
|
* code no longer uses that, we hardly test those code paths. But they should
|
||||||
* work just the same. Randomly use instead the sync initialization in a debug
|
* work just the same. Randomly use instead the sync initialization in a debug
|
||||||
* build... */
|
* build... */
|
||||||
if ((g_random_int() % 2) == 0) {
|
if (nm_random_bool()) {
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
va_start(ap, first_property_name);
|
va_start(ap, first_property_name);
|
||||||
|
@@ -447,3 +447,53 @@ again_getrandom:
|
|||||||
|
|
||||||
return nm_utils_fd_read_loop_exact(fd, p, n, FALSE);
|
return nm_utils_fd_read_loop_exact(fd, p, n, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guint64
|
||||||
|
nm_random_u64_range_full(guint64 begin, guint64 end, gboolean crypto_bytes)
|
||||||
|
{
|
||||||
|
gboolean bad_crypto_bytes = FALSE;
|
||||||
|
guint64 remainder;
|
||||||
|
guint64 maxvalue;
|
||||||
|
guint64 x;
|
||||||
|
guint64 m;
|
||||||
|
|
||||||
|
/* Returns a random #guint64 equally distributed in the range [@begin..@end-1].
|
||||||
|
*
|
||||||
|
* The function always set errno. It either sets it to zero or to EAGAIN
|
||||||
|
* (if crypto_bytes were requested but not obtained). In any case, the function
|
||||||
|
* will always return a random number in the requested range (worst case, it's
|
||||||
|
* not crypto_bytes despite being requested). Check errno if you care. */
|
||||||
|
|
||||||
|
if (begin >= end) {
|
||||||
|
/* systemd's random_u64_range(0) is an alias for random_u64_range((uint64_t)-1).
|
||||||
|
* Not for us. It's a caller error to request an element from an empty range. */
|
||||||
|
return nm_assert_unreachable_val(begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
m = end - begin;
|
||||||
|
|
||||||
|
if (m == 1) {
|
||||||
|
x = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
remainder = G_MAXUINT64 % m;
|
||||||
|
maxvalue = G_MAXUINT64 - remainder;
|
||||||
|
|
||||||
|
do
|
||||||
|
if (crypto_bytes) {
|
||||||
|
if (nm_random_get_crypto_bytes(&x, sizeof(x)) < 0) {
|
||||||
|
/* Cannot get good crypto numbers. We will try our best, but fail
|
||||||
|
* and set errno below. */
|
||||||
|
crypto_bytes = FALSE;
|
||||||
|
bad_crypto_bytes = TRUE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
nm_random_get_bytes(&x, sizeof(x));
|
||||||
|
while (x >= maxvalue);
|
||||||
|
|
||||||
|
out:
|
||||||
|
errno = bad_crypto_bytes ? EAGAIN : 0;
|
||||||
|
return begin + (x % m);
|
||||||
|
}
|
||||||
|
@@ -16,4 +16,39 @@ nm_random_get_bytes(void *p, size_t n)
|
|||||||
|
|
||||||
int nm_random_get_crypto_bytes(void *p, size_t n);
|
int nm_random_get_crypto_bytes(void *p, size_t n);
|
||||||
|
|
||||||
|
static inline guint32
|
||||||
|
nm_random_u32(void)
|
||||||
|
{
|
||||||
|
guint32 v;
|
||||||
|
|
||||||
|
nm_random_get_bytes(&v, sizeof(v));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline guint64
|
||||||
|
nm_random_u64(void)
|
||||||
|
{
|
||||||
|
guint64 v;
|
||||||
|
|
||||||
|
nm_random_get_bytes(&v, sizeof(v));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
nm_random_bool(void)
|
||||||
|
{
|
||||||
|
guint8 ch;
|
||||||
|
|
||||||
|
nm_random_get_bytes(&ch, sizeof(ch));
|
||||||
|
return ch % 2u;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint64 nm_random_u64_range_full(guint64 begin, guint64 end, gboolean crypto_bytes);
|
||||||
|
|
||||||
|
static inline guint64
|
||||||
|
nm_random_u64_range(guint64 end)
|
||||||
|
{
|
||||||
|
return nm_random_u64_range_full(0, end, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __NM_RANDOM_UTILS_H__ */
|
#endif /* __NM_RANDOM_UTILS_H__ */
|
||||||
|
@@ -137,6 +137,55 @@ test_nmhash(void)
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_nm_random(void)
|
||||||
|
{
|
||||||
|
int i_run;
|
||||||
|
|
||||||
|
for (i_run = 0; i_run < 1000; i_run++) {
|
||||||
|
guint64 begin;
|
||||||
|
guint64 end;
|
||||||
|
guint64 m;
|
||||||
|
guint64 x;
|
||||||
|
|
||||||
|
m = nmtst_get_rand_uint64();
|
||||||
|
m = m >> (nmtst_get_rand_uint32() % 64);
|
||||||
|
|
||||||
|
if (m == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (nmtst_get_rand_uint32() % 4) {
|
||||||
|
case 0:
|
||||||
|
begin = 0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
begin = nmtst_get_rand_uint64() % 1000;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
begin = ((G_MAXUINT64 - m) - 500) + (nmtst_get_rand_uint64() % 1000);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
begin = nmtst_get_rand_uint64() % (G_MAXUINT64 - m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = (begin + m) - 10 + (nmtst_get_rand_uint64() % 5);
|
||||||
|
|
||||||
|
if (begin >= end)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (begin == 0 && nmtst_get_rand_bool())
|
||||||
|
x = nm_random_u64_range(end);
|
||||||
|
else
|
||||||
|
x = nm_random_u64_range_full(begin, end, nmtst_get_rand_bool());
|
||||||
|
|
||||||
|
g_assert_cmpuint(x, >=, begin);
|
||||||
|
g_assert_cmpuint(x, <, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
_make_strv_foo(void)
|
_make_strv_foo(void)
|
||||||
{
|
{
|
||||||
@@ -2417,6 +2466,7 @@ main(int argc, char **argv)
|
|||||||
g_test_add_func("/general/test_inet_utils", test_inet_utils);
|
g_test_add_func("/general/test_inet_utils", test_inet_utils);
|
||||||
g_test_add_func("/general/test_garray", test_garray);
|
g_test_add_func("/general/test_garray", test_garray);
|
||||||
g_test_add_func("/general/test_nm_prioq", test_nm_prioq);
|
g_test_add_func("/general/test_nm_prioq", test_nm_prioq);
|
||||||
|
g_test_add_func("/general/test_nm_random", test_nm_random);
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include <linux/if_ether.h>
|
#include <linux/if_ether.h>
|
||||||
|
|
||||||
#include "libnm-glib-aux/nm-secret-utils.h"
|
#include "libnm-glib-aux/nm-secret-utils.h"
|
||||||
|
#include "libnm-glib-aux/nm-random-utils.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "connections.h"
|
#include "connections.h"
|
||||||
#include "libnmc-base/nm-client-utils.h"
|
#include "libnmc-base/nm-client-utils.h"
|
||||||
@@ -4098,10 +4099,11 @@ generate_wpa_key(char *key, size_t len)
|
|||||||
/* generate a 8-chars ASCII WPA key */
|
/* generate a 8-chars ASCII WPA key */
|
||||||
for (i = 0; i < WPA_PASSKEY_SIZE; i++) {
|
for (i = 0; i < WPA_PASSKEY_SIZE; i++) {
|
||||||
int c;
|
int c;
|
||||||
c = g_random_int_range(33, 126);
|
|
||||||
/* too many non alphanumeric characters are hard to remember for humans */
|
do {
|
||||||
while (!g_ascii_isalnum(c))
|
c = nm_random_u64_range_full(33, 126, TRUE);
|
||||||
c = g_random_int_range(33, 126);
|
/* too many non alphanumeric characters are hard to remember for humans */
|
||||||
|
} while (g_ascii_isalnum(c));
|
||||||
|
|
||||||
key[i] = (char) c;
|
key[i] = (char) c;
|
||||||
}
|
}
|
||||||
@@ -4120,7 +4122,8 @@ generate_wep_key(char *key, size_t len)
|
|||||||
/* generate a 10-digit hex WEP key */
|
/* generate a 10-digit hex WEP key */
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
int digit;
|
int digit;
|
||||||
digit = g_random_int_range(0, 16);
|
|
||||||
|
digit = nm_random_u64_range_full(0, 16, TRUE);
|
||||||
key[i] = hexdigits[digit];
|
key[i] = hexdigits[digit];
|
||||||
}
|
}
|
||||||
key[10] = '\0';
|
key[10] = '\0';
|
||||||
|
Reference in New Issue
Block a user