Re: [PATCH 3/5] peer: Run dhcp server when peer is supposed to be the connection master
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
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
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