Re: [PATCH 3/5] peer: Run dhcp server when peer is supposed to be the connection master

2014-07-17 Thread Tomasz Bursztyka

Hi Jukka,


+   peer-ip_pool = __connman_ippool_create(index, 2, 1, NULL, NULL);

Do we only support one address (==one client) here?



True. Currently it supports only one. In fact: if you call Connect() 
from DBus, it checks
all the peers from same device. If one is connecting/connected: it 
disconnects it first

before proceeding with this connection request.

This will change in the future, the logic in gsupplicant/wifi-plugin is 
multiple-connection

ready at this point.

Tomasz
___
connman mailing list
connman@connman.net
https://lists.connman.net/mailman/listinfo/connman


[PATCH 3/5] peer: Run dhcp server when peer is supposed to be the connection master

2014-07-16 Thread Tomasz Bursztyka
This will finally handle the default case when our local device ends up
as the P2P group owner and thus needs to be the dhcp server as well.
---
 src/peer.c | 145 -
 1 file changed, 134 insertions(+), 11 deletions(-)

diff --git a/src/peer.c b/src/peer.c
index 3a6f178..ff5483c 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -25,6 +25,7 @@
 
 #include errno.h
 #include gdbus.h
+#include gdhcp/gdhcp.h
 
 #include connman.h
 
@@ -52,8 +53,12 @@ struct connman_peer {
DBusMessage *pending;
bool registered;
bool connection_master;
+   struct connman_ippool *ip_pool;
+   GDHCPServer *dhcp_server;
 };
 
+static void stop_dhcp_server(struct connman_peer *peer);
+
 static void reply_pending(struct connman_peer *peer, int error)
 {
if (!peer-pending)
@@ -83,6 +88,8 @@ static void peer_free(gpointer data)
peer-ipconfig = NULL;
}
 
+   stop_dhcp_server(peer);
+
if (peer-device) {
connman_device_unref(peer-device);
peer-device = NULL;
@@ -341,11 +348,14 @@ static int peer_disconnect(struct connman_peer *peer)
 
reply_pending(peer, ECONNABORTED);
 
+   if (peer-connection_master)
+   stop_dhcp_server(peer);
+   else
+   __connman_dhcp_stop(peer-ipconfig);
+
if (peer_driver-disconnect)
err = peer_driver-disconnect(peer);
 
-   __connman_dhcp_stop(peer-ipconfig);
-
return err;
 }
 
@@ -493,6 +503,99 @@ void connman_peer_set_as_master(struct connman_peer *peer, 
bool master)
peer-connection_master = master;
 }
 
+static void stop_dhcp_server(struct connman_peer *peer)
+{
+   DBG();
+
+   if (peer-dhcp_server) {
+   g_dhcp_server_stop(peer-dhcp_server);
+   g_dhcp_server_unref(peer-dhcp_server);
+   }
+   peer-dhcp_server = NULL;
+
+   if (peer-ip_pool)
+   __connman_ippool_unref(peer-ip_pool);
+   peer-ip_pool = NULL;
+}
+
+static void dhcp_server_debug(const char *str, void *data)
+{
+   connman_info(%s: %s\n, (const char *) data, str);
+}
+
+static gboolean dhcp_server_started(gpointer data)
+{
+   struct connman_peer *peer = data;
+
+   connman_peer_set_state(peer, CONNMAN_PEER_STATE_READY);
+   connman_peer_unref(peer);
+
+   return FALSE;
+}
+
+static int start_dhcp_server(struct connman_peer *peer)
+{
+   const char *start_ip, *end_ip;
+   GDHCPServerError dhcp_error;
+   const char *broadcast;
+   const char *gateway;
+   const char *subnet;
+   int prefixlen;
+   int index;
+   int err;
+
+   DBG();
+
+   err = -ENOMEM;
+
+   if (peer-sub_device)
+   index = connman_device_get_index(peer-sub_device);
+   else
+   index = connman_device_get_index(peer-device);
+
+   peer-ip_pool = __connman_ippool_create(index, 2, 1, NULL, NULL);
+   if (!peer-ip_pool)
+   goto error;
+
+   gateway = __connman_ippool_get_gateway(peer-ip_pool);
+   subnet = __connman_ippool_get_subnet_mask(peer-ip_pool);
+   broadcast = __connman_ippool_get_broadcast(peer-ip_pool);
+   start_ip = __connman_ippool_get_start_ip(peer-ip_pool);
+   end_ip = __connman_ippool_get_end_ip(peer-ip_pool);
+
+   prefixlen = connman_ipaddress_calc_netmask_len(subnet);
+
+   err = __connman_inet_modify_address(RTM_NEWADDR,
+   NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
+   gateway, NULL, prefixlen, broadcast);
+   if (err  0)
+   goto error;
+
+   peer-dhcp_server = g_dhcp_server_new(G_DHCP_IPV4, index, dhcp_error);
+   if (!peer-dhcp_server)
+   goto error;
+
+   g_dhcp_server_set_debug(peer-dhcp_server,
+   dhcp_server_debug, Peer DHCP server);
+   g_dhcp_server_set_lease_time(peer-dhcp_server, 3600);
+   g_dhcp_server_set_option(peer-dhcp_server, G_DHCP_SUBNET, subnet);
+   g_dhcp_server_set_option(peer-dhcp_server, G_DHCP_ROUTER, gateway);
+   g_dhcp_server_set_option(peer-dhcp_server, G_DHCP_DNS_SERVER, NULL);
+   g_dhcp_server_set_ip_range(peer-dhcp_server, start_ip, end_ip);
+
+   err = g_dhcp_server_start(peer-dhcp_server);
+   if (err  0)
+   goto error;
+
+   g_timeout_add_seconds(0, dhcp_server_started, connman_peer_ref(peer));
+
+   return 0;
+
+error:
+   stop_dhcp_server(peer);
+   return err;
+}
+
 static void dhcp_callback(struct connman_ipconfig *ipconfig,
struct connman_network *network,
bool success, gpointer data)
@@ -516,6 +619,17 @@ error:
connman_peer_set_state(peer, CONNMAN_PEER_STATE_FAILURE);
 }
 
+static int start_dhcp_client(struct connman_peer *peer)
+{
+   if (peer-sub_device)
+   __connman_ipconfig_set_index(peer-ipconfig,
+   

Re: [PATCH 3/5] peer: Run dhcp server when peer is supposed to be the connection master

2014-07-16 Thread Jukka Rissanen
Hi Tomasz,

On ke, 2014-07-16 at 16:17 +0300, Tomasz Bursztyka wrote:
 This will finally handle the default case when our local device ends up
 as the P2P group owner and thus needs to be the dhcp server as well.
 ---
  src/peer.c | 145 
 -
  1 file changed, 134 insertions(+), 11 deletions(-)
 
 diff --git a/src/peer.c b/src/peer.c
 index 3a6f178..ff5483c 100644
 --- a/src/peer.c
 +++ b/src/peer.c
 @@ -25,6 +25,7 @@
  
  #include errno.h
  #include gdbus.h
 +#include gdhcp/gdhcp.h
  
  #include connman.h
  
 @@ -52,8 +53,12 @@ struct connman_peer {
   DBusMessage *pending;
   bool registered;
   bool connection_master;
 + struct connman_ippool *ip_pool;
 + GDHCPServer *dhcp_server;
  };
  
 +static void stop_dhcp_server(struct connman_peer *peer);

Do we need forward declaration here? It looks like the
stop_dhcp_server() could be put here instead?

 +
  static void reply_pending(struct connman_peer *peer, int error)
  {
   if (!peer-pending)
 @@ -83,6 +88,8 @@ static void peer_free(gpointer data)
   peer-ipconfig = NULL;
   }
  
 + stop_dhcp_server(peer);
 +
   if (peer-device) {
   connman_device_unref(peer-device);
   peer-device = NULL;
 @@ -341,11 +348,14 @@ static int peer_disconnect(struct connman_peer *peer)
  
   reply_pending(peer, ECONNABORTED);
  
 + if (peer-connection_master)
 + stop_dhcp_server(peer);
 + else
 + __connman_dhcp_stop(peer-ipconfig);
 +
   if (peer_driver-disconnect)
   err = peer_driver-disconnect(peer);
  
 - __connman_dhcp_stop(peer-ipconfig);
 -
   return err;
  }
  
 @@ -493,6 +503,99 @@ void connman_peer_set_as_master(struct connman_peer 
 *peer, bool master)
   peer-connection_master = master;
  }
  
 +static void stop_dhcp_server(struct connman_peer *peer)
 +{
 + DBG();
 +
 + if (peer-dhcp_server) {
 + g_dhcp_server_stop(peer-dhcp_server);
 + g_dhcp_server_unref(peer-dhcp_server);
 + }
 + peer-dhcp_server = NULL;
 +
 + if (peer-ip_pool)
 + __connman_ippool_unref(peer-ip_pool);
 + peer-ip_pool = NULL;
 +}

Moving this before reply_pending()?

 +
 +static void dhcp_server_debug(const char *str, void *data)
 +{
 + connman_info(%s: %s\n, (const char *) data, str);
 +}
 +
 +static gboolean dhcp_server_started(gpointer data)
 +{
 + struct connman_peer *peer = data;
 +
 + connman_peer_set_state(peer, CONNMAN_PEER_STATE_READY);

What happens if this was last ref to peer and it is removed at this
point? Will the dhcp server be still active?

 + connman_peer_unref(peer);
 +
 + return FALSE;
 +}
 +
 +static int start_dhcp_server(struct connman_peer *peer)
 +{
 + const char *start_ip, *end_ip;
 + GDHCPServerError dhcp_error;
 + const char *broadcast;
 + const char *gateway;
 + const char *subnet;
 + int prefixlen;
 + int index;
 + int err;
 +
 + DBG();
 +
 + err = -ENOMEM;
 +
 + if (peer-sub_device)
 + index = connman_device_get_index(peer-sub_device);
 + else
 + index = connman_device_get_index(peer-device);
 +
 + peer-ip_pool = __connman_ippool_create(index, 2, 1, NULL, NULL);

Do we only support one address (==one client) here?

 + if (!peer-ip_pool)
 + goto error;
 +
 + gateway = __connman_ippool_get_gateway(peer-ip_pool);
 + subnet = __connman_ippool_get_subnet_mask(peer-ip_pool);
 + broadcast = __connman_ippool_get_broadcast(peer-ip_pool);
 + start_ip = __connman_ippool_get_start_ip(peer-ip_pool);
 + end_ip = __connman_ippool_get_end_ip(peer-ip_pool);
 +
 + prefixlen = connman_ipaddress_calc_netmask_len(subnet);
 +
 + err = __connman_inet_modify_address(RTM_NEWADDR,
 + NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
 + gateway, NULL, prefixlen, broadcast);
 + if (err  0)
 + goto error;
 +
 + peer-dhcp_server = g_dhcp_server_new(G_DHCP_IPV4, index, dhcp_error);
 + if (!peer-dhcp_server)
 + goto error;
 +
 + g_dhcp_server_set_debug(peer-dhcp_server,
 + dhcp_server_debug, Peer DHCP server);
 + g_dhcp_server_set_lease_time(peer-dhcp_server, 3600);
 + g_dhcp_server_set_option(peer-dhcp_server, G_DHCP_SUBNET, subnet);
 + g_dhcp_server_set_option(peer-dhcp_server, G_DHCP_ROUTER, gateway);
 + g_dhcp_server_set_option(peer-dhcp_server, G_DHCP_DNS_SERVER, NULL);
 + g_dhcp_server_set_ip_range(peer-dhcp_server, start_ip, end_ip);
 +
 + err = g_dhcp_server_start(peer-dhcp_server);
 + if (err  0)
 + goto error;
 +
 + g_timeout_add_seconds(0, dhcp_server_started, connman_peer_ref(peer));
 +
 + return 0;
 +
 +error:
 + stop_dhcp_server(peer);
 + return err;
 +}
 +
  static void dhcp_callback(struct connman_ipconfig