settings: cleanup handling of seen-bssids list in NMSettingsConnection

- most connections are not Wi-Fi connections and thus don't have a seen-bssids
  list. Only create the seen_bssids hash when required. This avoids allocating the
  hash in common cases and avoids checking the hash for the content (which is often
  empty).

- nm_settings_connection_get_seen_bssids() should return a sorted list.
  Leaving the sort order undefined is ugly.

- in try_fill_ssid_for_hidden_ap(), we need to check all
  NMSettingsConnection instances whether they know this bssid.
  Reorder the checks, to first call nm_settings_connection_has_seen_bssid(), which
  is faster and in most cases returns a negative result (shortcutting
  the rest).
This commit is contained in:
Thomas Haller
2019-06-27 08:41:58 +02:00
parent 4d03b16f9d
commit 31c4c111d3
3 changed files with 49 additions and 37 deletions

View File

@@ -1513,13 +1513,14 @@ try_fill_ssid_for_hidden_ap (NMDeviceWifi *self,
NMSettingsConnection *sett_conn = connections[i]; NMSettingsConnection *sett_conn = connections[i];
NMSettingWireless *s_wifi; NMSettingWireless *s_wifi;
if (!nm_settings_connection_has_seen_bssid (sett_conn, bssid))
continue;
s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (sett_conn)); s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (sett_conn));
if (s_wifi) { if (!s_wifi)
if (nm_settings_connection_has_seen_bssid (sett_conn, bssid)) { continue;
nm_wifi_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi));
break; nm_wifi_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi));
} break;
}
} }
} }

View File

@@ -169,6 +169,14 @@ static const NMDBusInterfaceInfoExtended interface_info_settings_connection;
/*****************************************************************************/ /*****************************************************************************/
static GHashTable *
_seen_bssids_hash_new (void)
{
return g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL);
}
/*****************************************************************************/
NMConnection * NMConnection *
nm_settings_connection_get_connection (NMSettingsConnection *self) nm_settings_connection_get_connection (NMSettingsConnection *self)
{ {
@@ -1398,7 +1406,7 @@ get_settings_auth_cb (NMSettingsConnection *self,
NMSettingConnection *s_con; NMSettingConnection *s_con;
NMSettingWireless *s_wifi; NMSettingWireless *s_wifi;
guint64 timestamp = 0; guint64 timestamp = 0;
gs_free char **bssids = NULL; gs_free const char **bssids = NULL;
dupl_con = nm_simple_connection_new_clone (nm_settings_connection_get_connection (self)); dupl_con = nm_simple_connection_new_clone (nm_settings_connection_get_connection (self));
@@ -1418,9 +1426,11 @@ get_settings_auth_cb (NMSettingsConnection *self,
* return settings too. * return settings too.
*/ */
bssids = nm_settings_connection_get_seen_bssids (self); bssids = nm_settings_connection_get_seen_bssids (self);
s_wifi = nm_connection_get_setting_wireless (dupl_con); if (bssids) {
if (bssids && bssids[0] && s_wifi) s_wifi = nm_connection_get_setting_wireless (dupl_con);
g_object_set (s_wifi, NM_SETTING_WIRELESS_SEEN_BSSIDS, bssids, NULL); if (s_wifi)
g_object_set (s_wifi, NM_SETTING_WIRELESS_SEEN_BSSIDS, bssids, NULL);
}
/* Secrets should *never* be returned by the GetSettings method, they /* Secrets should *never* be returned by the GetSettings method, they
* get returned by the GetSecrets method which can be better * get returned by the GetSecrets method which can be better
@@ -2347,13 +2357,16 @@ nm_settings_connection_register_kf_dbs (NMSettingsConnection *self,
tmp_strv = nm_key_file_db_get_string_list (priv->kf_db_seen_bssids, connection_uuid, &len); tmp_strv = nm_key_file_db_get_string_list (priv->kf_db_seen_bssids, connection_uuid, &len);
if (tmp_strv) { nm_clear_pointer (&priv->seen_bssids, g_hash_table_unref);
if (len > 0) {
_LOGT ("read %zu seen-bssids from keyfile database \"%s\"", _LOGT ("read %zu seen-bssids from keyfile database \"%s\"",
NM_PTRARRAY_LEN (tmp_strv), len,
nm_key_file_db_get_filename (priv->kf_db_seen_bssids)); nm_key_file_db_get_filename (priv->kf_db_seen_bssids));
g_hash_table_remove_all (priv->seen_bssids); priv->seen_bssids = _seen_bssids_hash_new ();
for (i = len; i > 0; ) for (i = len; i > 0; )
g_hash_table_add (priv->seen_bssids, g_steal_pointer (&tmp_strv[--i])); g_hash_table_add (priv->seen_bssids, g_steal_pointer (&tmp_strv[--i]));
nm_clear_g_free (&tmp_strv);
} else { } else {
NMSettingWireless *s_wifi; NMSettingWireless *s_wifi;
@@ -2368,10 +2381,13 @@ nm_settings_connection_register_kf_dbs (NMSettingsConnection *self,
s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (self)); s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (self));
if (s_wifi) { if (s_wifi) {
len = nm_setting_wireless_get_num_seen_bssids (s_wifi); len = nm_setting_wireless_get_num_seen_bssids (s_wifi);
for (i = 0; i < len; i++) { if (len > 0) {
const char *bssid = nm_setting_wireless_get_seen_bssid (s_wifi, i); priv->seen_bssids = _seen_bssids_hash_new ();
for (i = 0; i < len; i++) {
const char *bssid = nm_setting_wireless_get_seen_bssid (s_wifi, i);
g_hash_table_add (priv->seen_bssids, g_strdup (bssid)); g_hash_table_add (priv->seen_bssids, g_strdup (bssid));
}
} }
} }
} }
@@ -2387,25 +2403,14 @@ nm_settings_connection_register_kf_dbs (NMSettingsConnection *self,
* Returns: (transfer container) list of seen BSSIDs (in the standard hex-digits-and-colons notation). * Returns: (transfer container) list of seen BSSIDs (in the standard hex-digits-and-colons notation).
* The caller is responsible for freeing the list, but not the content. * The caller is responsible for freeing the list, but not the content.
**/ **/
char ** const char **
nm_settings_connection_get_seen_bssids (NMSettingsConnection *self) nm_settings_connection_get_seen_bssids (NMSettingsConnection *self)
{ {
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
GHashTableIter iter;
char **bssids, *bssid;
int i;
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NULL); g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NULL);
bssids = g_new (char *, g_hash_table_size (priv->seen_bssids) + 1); return nm_utils_strdict_get_keys (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->seen_bssids,
TRUE,
i = 0; NULL);
g_hash_table_iter_init (&iter, priv->seen_bssids);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &bssid))
bssids[i++] = bssid;
bssids[i] = NULL;
return bssids;
} }
/** /**
@@ -2419,10 +2424,15 @@ gboolean
nm_settings_connection_has_seen_bssid (NMSettingsConnection *self, nm_settings_connection_has_seen_bssid (NMSettingsConnection *self,
const char *bssid) const char *bssid)
{ {
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); NMSettingsConnectionPrivate *priv;
g_return_val_if_fail (bssid != NULL, FALSE);
return !!g_hash_table_lookup (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->seen_bssids, bssid); g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
g_return_val_if_fail (bssid, FALSE);
priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
return priv->seen_bssids
&& g_hash_table_contains (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->seen_bssids, bssid);
} }
/** /**
@@ -2443,6 +2453,9 @@ nm_settings_connection_add_seen_bssid (NMSettingsConnection *self,
g_return_if_fail (seen_bssid != NULL); g_return_if_fail (seen_bssid != NULL);
if (!priv->seen_bssids)
priv->seen_bssids = _seen_bssids_hash_new ();
g_hash_table_add (priv->seen_bssids, g_strdup (seen_bssid)); g_hash_table_add (priv->seen_bssids, g_strdup (seen_bssid));
if (!priv->kf_db_seen_bssids) if (!priv->kf_db_seen_bssids)
@@ -2718,8 +2731,6 @@ nm_settings_connection_init (NMSettingsConnection *self)
priv->agent_mgr = g_object_ref (nm_agent_manager_get ()); priv->agent_mgr = g_object_ref (nm_agent_manager_get ());
priv->seen_bssids = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL);
priv->autoconnect_retries = AUTOCONNECT_RETRIES_UNSET; priv->autoconnect_retries = AUTOCONNECT_RETRIES_UNSET;
priv->connection = nm_simple_connection_new (); priv->connection = nm_simple_connection_new ();

View File

@@ -228,7 +228,7 @@ gboolean nm_settings_connection_get_timestamp (NMSettingsConnection *self,
void nm_settings_connection_update_timestamp (NMSettingsConnection *self, void nm_settings_connection_update_timestamp (NMSettingsConnection *self,
guint64 timestamp); guint64 timestamp);
char **nm_settings_connection_get_seen_bssids (NMSettingsConnection *self); const char **nm_settings_connection_get_seen_bssids (NMSettingsConnection *self);
gboolean nm_settings_connection_has_seen_bssid (NMSettingsConnection *self, gboolean nm_settings_connection_has_seen_bssid (NMSettingsConnection *self,
const char *bssid); const char *bssid);