aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Zaborowski <andrew.zaborowski@intel.com>2020-04-30 15:48:43 +0200
committerDenis Kenzior <denkenz@gmail.com>2020-05-01 11:38:43 -0500
commitc49b724a2e3e3d9ddf81fb90c6fb68785fbaf932 (patch)
treee42dd2c4fcfde43df6649b00e4d3bd6f74622f89
parentc8edd362345e28ad43e5bdba0d167365d7034215 (diff)
downloadiwd-c49b724a2e3e3d9ddf81fb90c6fb68785fbaf932.tar.gz
p2p: Do DHCP as part of connection setup
Use netconfig.c functions to unconditionally run DHCP negotiation, fail the connection setup if DHCP fails. Only report connection success after netconfig returns.
-rw-r--r--src/p2p.c88
1 files changed, 81 insertions, 7 deletions
diff --git a/src/p2p.c b/src/p2p.c
index be009505c..dc78b8879 100644
--- a/src/p2p.c
+++ b/src/p2p.c
@@ -53,6 +53,7 @@
#include "src/module.h"
#include "src/frame-xchg.h"
#include "src/nl80211util.h"
+#include "src/netconfig.h"
#include "src/p2p.h"
struct p2p_device {
@@ -92,6 +93,8 @@ struct p2p_device {
uint32_t conn_netdev_watch_id;
uint32_t conn_new_intf_cmd_id;
struct wsc_enrollee *conn_enrollee;
+ struct netconfig *conn_netconfig;
+ struct l_timeout *conn_dhcp_timeout;
struct l_timeout *config_timeout;
unsigned long go_config_delay;
@@ -132,6 +135,7 @@ struct p2p_peer {
};
static struct l_queue *p2p_device_list;
+static struct l_settings *p2p_dhcp_settings;
/*
* For now we only scan the common 2.4GHz channels, to be replaced with
@@ -185,7 +189,8 @@ static void p2p_discovery_user_free(void *data)
static inline bool p2p_peer_operational(struct p2p_peer *peer)
{
return peer && peer->dev->conn_netdev && !peer->dev->conn_wsc_bss &&
- !peer->wsc.pending_connect && !peer->dev->disconnecting;
+ !peer->dev->conn_dhcp_timeout && !peer->wsc.pending_connect &&
+ !peer->dev->disconnecting;
}
static bool p2p_peer_match(const void *a, const void *b)
@@ -325,6 +330,12 @@ static void p2p_connection_reset(struct p2p_device *dev)
l_timeout_remove(dev->config_timeout);
l_timeout_remove(dev->go_neg_req_timeout);
+ l_timeout_remove(dev->conn_dhcp_timeout);
+
+ if (dev->conn_netconfig) {
+ netconfig_destroy(dev->conn_netconfig);
+ dev->conn_netconfig = NULL;
+ }
if (dev->conn_new_intf_cmd_id)
/*
@@ -490,6 +501,70 @@ static const struct frame_xchg_prefix p2p_frame_pd_resp = {
.len = 7,
};
+static void p2p_netconfig_event_handler(enum netconfig_event event,
+ void *user_data)
+{
+ struct p2p_device *dev = user_data;
+ struct p2p_peer *peer = dev->conn_peer;
+
+ switch (event) {
+ case NETCONFIG_EVENT_CONNECTED:
+ l_timeout_remove(dev->conn_dhcp_timeout);
+
+ dbus_pending_reply(&peer->wsc.pending_connect,
+ l_dbus_message_new_method_return(
+ peer->wsc.pending_connect));
+ l_dbus_property_changed(dbus_get_bus(),
+ p2p_peer_get_path(dev->conn_peer),
+ IWD_P2P_PEER_INTERFACE, "Connected");
+
+ break;
+ default:
+ l_error("station: Unsupported netconfig event: %d.", event);
+ p2p_connect_failed(dev);
+ break;
+ }
+}
+
+static void p2p_dhcp_timeout(struct l_timeout *timeout, void *user_data)
+{
+ struct p2p_device *dev = user_data;
+
+ l_debug("");
+
+ p2p_connect_failed(dev);
+}
+
+static void p2p_dhcp_timeout_destroy(void *user_data)
+{
+ struct p2p_device *dev = user_data;
+
+ dev->conn_dhcp_timeout = NULL;
+}
+
+static void p2p_start_dhcp(struct p2p_device *dev)
+{
+ uint32_t ifindex = netdev_get_ifindex(dev->conn_netdev);
+ unsigned int dhcp_timeout_val;
+
+ if (!l_settings_get_uint(iwd_get_config(), "P2P", "DHCPTimeout",
+ &dhcp_timeout_val))
+ dhcp_timeout_val = 10; /* 10s default */
+
+ dev->conn_netconfig = netconfig_new(ifindex);
+ if (!dev->conn_netconfig) {
+ p2p_connect_failed(dev);
+ return;
+ }
+
+ netconfig_configure(dev->conn_netconfig, p2p_dhcp_settings,
+ dev->conn_addr, p2p_netconfig_event_handler,
+ dev);
+ dev->conn_dhcp_timeout = l_timeout_create(dhcp_timeout_val,
+ p2p_dhcp_timeout, dev,
+ p2p_dhcp_timeout_destroy);
+}
+
static void p2p_netdev_connect_cb(struct netdev *netdev,
enum netdev_result result,
void *event_data, void *user_data)
@@ -506,12 +581,7 @@ static void p2p_netdev_connect_cb(struct netdev *netdev,
switch (result) {
case NETDEV_RESULT_OK:
- dbus_pending_reply(&peer->wsc.pending_connect,
- l_dbus_message_new_method_return(
- peer->wsc.pending_connect));
- l_dbus_property_changed(dbus_get_bus(),
- p2p_peer_get_path(dev->conn_peer),
- IWD_P2P_PEER_INTERFACE, "Connected");
+ p2p_start_dhcp(dev);
break;
case NETDEV_RESULT_AUTHENTICATION_FAILED:
case NETDEV_RESULT_ASSOCIATION_FAILED:
@@ -3485,6 +3555,7 @@ static int p2p_init(void)
l_error("Unable to register the %s interface",
IWD_P2P_PEER_INTERFACE);
+ p2p_dhcp_settings = l_settings_new();
p2p_device_list = l_queue_new();
return 0;
@@ -3496,8 +3567,11 @@ static void p2p_exit(void)
l_dbus_unregister_interface(dbus_get_bus(), IWD_P2P_PEER_INTERFACE);
l_queue_destroy(p2p_device_list, p2p_device_free);
p2p_device_list = NULL;
+ l_settings_free(p2p_dhcp_settings);
+ p2p_dhcp_settings = NULL;
}
IWD_MODULE(p2p, p2p_init, p2p_exit)
IWD_MODULE_DEPENDS(p2p, wiphy)
IWD_MODULE_DEPENDS(p2p, scan)
+IWD_MODULE_DEPENDS(p2p, netconfig)