From: Seungyoun Ju Date: Mon, 14 Jan 2013 12:13:21 +0000 (+0900) Subject: Below changes are applied X-Git-Tag: 2.1b_release~1^2~12 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=35cacf4867d4ef3d0384025aa14900b4468141ea;p=framework%2Fconnectivity%2Fmobileap-agent.git Below changes are applied - dhcp lease delete is handled based on IP Address - DNS Forward by netfilter is implemented - Vconf key for flight mode is changed Change-Id: I57695d7def889bd036a94bffcc18ac6600644a8f --- diff --git a/include/mobileap_agent.h b/include/mobileap_agent.h index bc6429b..bf9dc9b 100644 --- a/include/mobileap_agent.h +++ b/include/mobileap_agent.h @@ -77,7 +77,6 @@ "dhcp-range=192.168.136.2,192.168.136.150,255.255.255.0\n" \ "dhcp-range=192.168.137.2,192.168.137.150,255.255.255.0\n" \ "dhcp-range=set:blue,192.168.129.4,192.168.129.150,255.255.255.0\n"\ - "dhcp-option=option:dns-server,%s\n" \ "enable-dbus\n" \ "dhcp-option=tag:blue,option:router,192.168.129.3\n" #define DNSMASQ_CONF_FILE "/tmp/dnsmasq.conf" @@ -116,11 +115,10 @@ #define AWK "/usr/bin/awk" #define DATA_USAGE_FILE "/tmp/tethering_data_usage.txt" #define MASQUERADE_RULE "-o %s -j MASQUERADE" -#define DNS_FORWARD_RULE "-p udp -i %s --dport 53 -j DNAT --to %s" +#define DNS_ORDER 1 +#define TCP_DNS_FORWARD_RULE "-i %s -p tcp --dport 53 -j DNAT --to %s:53" +#define UDP_DNS_FORWARD_RULE "-i %s -p udp --dport 53 -j DNAT --to %s:53" #define FORWARD_RULE "-i %s -o %s" -#ifndef __USE_CONNMAN_DNS_ADDR__ -#define GOOGLE_PUBLIC_DNS "8.8.8.8" -#endif /* __USE_CONNMAN_DNS_ADDR__ */ #define MOBILE_AP_STATE_NONE 0 #define MOBILE_AP_STATE_WIFI 1 diff --git a/include/mobileap_common.h b/include/mobileap_common.h index 7716242..137b79c 100644 --- a/include/mobileap_common.h +++ b/include/mobileap_common.h @@ -28,6 +28,7 @@ gint _slist_find_station_by_interface(gconstpointer a, gconstpointer b); gint _slist_find_station_by_mac(gconstpointer a, gconstpointer b); +gint _slist_find_station_by_ip_addr(gconstpointer a, gconstpointer b); void _emit_mobileap_dbus_signal(MobileAPObject *obj, mobile_ap_sig_e num, const gchar *message); diff --git a/include/mobileap_handler.h b/include/mobileap_handler.h index ee640a4..c1bc03b 100644 --- a/include/mobileap_handler.h +++ b/include/mobileap_handler.h @@ -26,4 +26,5 @@ void _start_timeout_cb(mobile_ap_type_e type); void _stop_timeout_cb(mobile_ap_type_e type); void _deinit_timeout_cb(mobile_ap_type_e type); + #endif diff --git a/include/mobileap_network.h b/include/mobileap_network.h index c63847d..985797f 100644 --- a/include/mobileap_network.h +++ b/include/mobileap_network.h @@ -19,7 +19,6 @@ #define __MOBILEAP_NETWORK_H__ #include -#include gboolean _get_network_interface_name(char **if_name); gboolean _set_masquerade(void); diff --git a/packaging/mobileap-agent.spec b/packaging/mobileap-agent.spec index 4b97ee4..356d8a4 100644 --- a/packaging/mobileap-agent.spec +++ b/packaging/mobileap-agent.spec @@ -1,6 +1,6 @@ Name: mobileap-agent Summary: Mobile AP daemon for setting tethering environments -Version: 0.1.80 +Version: 0.1.81 Release: 1 Group: TO_BE/FILLED_IN License: Apache License Version 2.0 @@ -48,6 +48,11 @@ rm -rf %{buildroot} %{_bindir}/mobileap-agent %changelog +* Mon Jan 14 2013 Seungyoun Ju 0.1.81-1 +- dhcp lease delete is handled based on IP Address +- DNS Forward by netfilter is implemented +- Vconf key for flight mode is changed + * Fri Dec 07 2012 Seungyoun Ju 0.1.80-1 - Notification API's usage is changed - Duplicated station information issue is fixed diff --git a/src/mobileap_agent.c b/src/mobileap_agent.c index 7bcca53..68f1c67 100644 --- a/src/mobileap_agent.c +++ b/src/mobileap_agent.c @@ -73,138 +73,6 @@ static int __issue_ioctl(int sock_fd, char *if_name, char *cmd, char *buf) return ret_val; } -static int __get_dns_server(char *dns_server, int len) -{ -#ifndef __USE_CONNMAN_DNS_ADDR__ - g_strlcpy(dns_server, GOOGLE_PUBLIC_DNS, len); - DBG("DNS server [%s]\n", dns_server); - - return EXIT_SUCCESS; -#else - int ret = EXIT_FAILURE; - GError *error = NULL; - DBusGConnection *bus = NULL; - DBusGProxy *manager_proxy = NULL; - DBusGProxy *service_proxy = NULL; - gchar *service_object_path = NULL; - - GHashTable *hash = NULL; - GValue *value; - const gchar *state; - gchar **dns_server_list = NULL; - GPtrArray *service_list = NULL; - - bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); - if (error) { - ERR("Couldn't connect to the System bus[%s]", error->message); - g_error_free(error); - return ret; - } - - manager_proxy = dbus_g_proxy_new_for_name(bus, "net.connman", - "/", - "net.connman.Manager"); - if (!manager_proxy) { - ERR("Couldn't create the proxy object"); - goto done; - } - - dbus_g_proxy_call(manager_proxy, "GetProperties", &error, G_TYPE_INVALID, - dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), - &hash, G_TYPE_INVALID); - if (error) { - ERR("GetProperties failed[%s]", error->message); - g_error_free(error); - goto done; - } - - /* - dict entry( - string "Services" - variant array [ - object path "/profile/default/cellular_45001_cellular_Samsung3G_1" - object path "/profile/default/cellular_45001_cellular_Samsung3G_MMS_2" - ] - ) - */ - value = g_hash_table_lookup(hash, "Services"); - - service_list = g_value_get_boxed(value); - if (!service_list) { - ERR("No service available"); - goto done; - } - - service_object_path = g_ptr_array_index(service_list, 0); - DBG("service object path : %s\n", service_object_path); - - service_proxy = dbus_g_proxy_new_for_name(bus, "net.connman", - service_object_path, - "net.connman.Service"); - if (!service_proxy) { - ERR("Couldn't create the proxy object"); - goto done; - } - - dbus_g_proxy_call(service_proxy, "GetProperties", &error, G_TYPE_INVALID, - dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), - &hash, G_TYPE_INVALID); - if (error) { - ERR("GetProperties failed[%s]", error->message); - g_error_free(error); - goto done; - } - - /* - dict entry( - string "State" - variant string "online" - ) - - dict entry( - string "Nameservers" - variant array [ - string "165.213.73.226" - string "10.32.192.11" - ] - ) - */ - value = g_hash_table_lookup(hash, "State"); - state = value ? g_value_get_string(value) : NULL; - DBG("Network state : %s\n", state); - - if (g_strcmp0(state, "ready") != 0 && g_strcmp0(state, "online") != 0) { - ERR("Network is not connected\n"); - goto done; - } - - value = g_hash_table_lookup(hash, "Nameservers"); - - dns_server_list = g_value_get_boxed(value); - if (!dns_server_list) { - ERR("No Nameserver exist"); - goto done; - } - g_strlcpy(dns_server, *dns_server_list, len); - DBG("DNS server [%s]\n", dns_server); - - ret = EXIT_SUCCESS; -done: - if (dns_server_list) - g_strfreev(dns_server_list); - if (service_list) - g_ptr_array_free(service_list, TRUE); - if (manager_proxy) - g_object_unref(manager_proxy); - if (service_proxy) - g_object_unref(service_proxy); - if (bus) - dbus_g_connection_unref(bus); - - return ret; -#endif -} - static int __get_psk_hexascii(const char *pass, const unsigned char *salt, char *psk, unsigned int psk_len) { if (pass == NULL || salt == NULL || psk == NULL || psk_len == 0) { @@ -951,21 +819,15 @@ int _mh_core_get_device_info(softap_device_info_t *di) int _mh_core_execute_dhcp_server(void) { char buf[DNSMASQ_CONF_LEN] = ""; - char dns_server[MOBILE_AP_STR_INFO_LEN] = {0, }; FILE *fp = NULL; pid_t pid; - if (__get_dns_server(dns_server, sizeof(dns_server))) { - ERR("Getting DNS server failed\n"); - return MOBILE_AP_ERROR_INTERNAL; - } - fp = fopen(DNSMASQ_CONF_FILE, "w"); if (NULL == fp) { ERR("Could not create the file.\n"); return MOBILE_AP_ERROR_RESOURCE; } - snprintf(buf, DNSMASQ_CONF_LEN, DNSMASQ_CONF, dns_server); + snprintf(buf, DNSMASQ_CONF_LEN, DNSMASQ_CONF); fputs(buf, fp); fclose(fp); @@ -976,6 +838,10 @@ int _mh_core_execute_dhcp_server(void) } if (pid == 0) { + /* -d : Debug mode + * -p 0 : DNS off + * -C file : Configuration file path + */ if (execl("/usr/bin/dnsmasq", "/usr/bin/dnsmasq", "-d", "-p", "0", "-C", DNSMASQ_CONF_FILE, (char *)NULL)) { @@ -1007,6 +873,11 @@ int _mh_core_terminate_dhcp_server(void) int _mh_core_enable_masquerade(const char *ext_if) { + if (ext_if == NULL || strlen(ext_if) == 0) { + ERR("ext_if[%s] is invalid\n", ext_if); + return MOBILE_AP_ERROR_INVALID_PARAM; + } + int fd = -1; char cmd[MAX_BUF_SIZE] = {0, }; @@ -1039,6 +910,11 @@ int _mh_core_enable_masquerade(const char *ext_if) int _mh_core_disable_masquerade(const char *ext_if) { + if (ext_if == NULL || strlen(ext_if) == 0) { + ERR("ext_if[%s] is invalid\n", ext_if); + return MOBILE_AP_ERROR_INVALID_PARAM; + } + int fd = -1; char cmd[MAX_BUF_SIZE] = {0, }; diff --git a/src/mobileap_common.c b/src/mobileap_common.c index edba972..ef54323 100644 --- a/src/mobileap_common.c +++ b/src/mobileap_common.c @@ -57,6 +57,14 @@ gint _slist_find_station_by_mac(gconstpointer a, gconstpointer b) return g_ascii_strcasecmp(si->mac, mac); } +gint _slist_find_station_by_ip_addr(gconstpointer a, gconstpointer b) +{ + mobile_ap_station_info_t *si = (mobile_ap_station_info_t *)a; + const char *ip_addr = (const char *)b; + + return g_ascii_strcasecmp(si->ip, ip_addr); +} + void _emit_mobileap_dbus_signal(MobileAPObject *obj, mobile_ap_sig_e num, const gchar *message) { diff --git a/src/mobileap_handler.c b/src/mobileap_handler.c index 461d951..425b12c 100644 --- a/src/mobileap_handler.c +++ b/src/mobileap_handler.c @@ -45,6 +45,8 @@ static sp_timeout_handler_t sp_timeout_handler[MOBILE_AP_TYPE_MAX] = { {0, NULL, NULL}, {0, __bt_timeout_cb, NULL}}; + + static void __handle_flight_mode_changed_cb(keynode_t *key, void *data) { if (key == NULL) { @@ -55,8 +57,8 @@ static void __handle_flight_mode_changed_cb(keynode_t *key, void *data) MobileAPObject *obj = (MobileAPObject *)data; int vconf_key = 0; - if (_mobileap_is_disabled()) { - DBG("Tethering is not enabled\n"); + if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) { + DBG("Wi-Fi tethering is not enabled\n"); return; } @@ -69,10 +71,8 @@ static void __handle_flight_mode_changed_cb(keynode_t *key, void *data) DBG("key = %s, value = %d(bool)\n", vconf_keynode_get_name(key), vconf_key); - if (vconf_key == FALSE) { - DBG("Flight mode is turned off\n"); + if (vconf_key == FALSE) return; - } DBG("Flight mode\n"); _disable_wifi_tethering(obj); @@ -81,7 +81,6 @@ static void __handle_flight_mode_changed_cb(keynode_t *key, void *data) return; } - static void __handle_device_name_changed_cb(keynode_t *key, void *data) { if (key == NULL || data == NULL) { @@ -116,9 +115,6 @@ static void __handle_device_name_changed_cb(keynode_t *key, void *data) return; } - - - void _register_vconf_cb(void *user_data) { if (user_data == NULL) { @@ -127,7 +123,7 @@ void _register_vconf_cb(void *user_data) } vconf_reg_t vconf_reg[] = { - {VCONFKEY_SETAPPL_FLIGHT_MODE_BOOL, + {VCONFKEY_TELEPHONY_FLIGHT_MODE, __handle_flight_mode_changed_cb, NULL}, {VCONFKEY_SETAPPL_DEVICE_NAME_STR, __handle_device_name_changed_cb, NULL}, @@ -167,7 +163,7 @@ void _unregister_vconf_cb(void *user_data) } vconf_reg_t vconf_reg[] = { - {VCONFKEY_SETAPPL_FLIGHT_MODE_BOOL, + {VCONFKEY_TELEPHONY_FLIGHT_MODE, __handle_flight_mode_changed_cb, NULL}, {VCONFKEY_SETAPPL_DEVICE_NAME_STR, __handle_device_name_changed_cb, NULL}, @@ -325,3 +321,4 @@ void _deinit_timeout_cb(mobile_ap_type_e type) { DBG("-\n"); return; } + diff --git a/src/mobileap_main.c b/src/mobileap_main.c index 9a639f9..118839d 100644 --- a/src/mobileap_main.c +++ b/src/mobileap_main.c @@ -233,11 +233,12 @@ gboolean _init_tethering(MobileAPObject *obj) obj->init_count++; - DBG("Set masquerading / Run DHCP\n"); __block_device_sleep(); + DBG("Open network\n"); _open_network(); + DBG("Run DHCP server\n"); _mh_core_execute_dhcp_server(); return TRUE; @@ -367,6 +368,7 @@ gboolean mobileap_get_data_packet_usage(MobileAPObject *obj, return TRUE; } + static DBusHandlerResult __dnsmasq_signal_filter(DBusConnection *conn, DBusMessage *msg, void *user_data) { @@ -462,9 +464,9 @@ static DBusHandlerResult __dnsmasq_signal_filter(DBusConnection *conn, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - DBG("DhcpLeaseDeleted signal : %s %s %s\n", ip_addr, mac, name); + DBG("DhcpLeaseDeleted signal : %s %s %s\n", ip_addr, mac, name); - _remove_station_info(mac, _slist_find_station_by_mac); + _remove_station_info(ip_addr, _slist_find_station_by_ip_addr); return DBUS_HANDLER_RESULT_HANDLED; } diff --git a/src/mobileap_network.c b/src/mobileap_network.c index 1b78f59..a472c35 100644 --- a/src/mobileap_network.c +++ b/src/mobileap_network.c @@ -15,13 +15,20 @@ * limitations under the License. */ +#include #include +#include #include "mobileap_agent.h" +#include "mobileap_common.h" #include "mobileap_network.h" static connection_h connection = NULL; static connection_profile_h cprof = NULL; +static char *dns_addr = NULL; + +static gboolean __set_dns_forward(void); +static gboolean __unset_dns_forward(void); static void __print_profile(connection_profile_h profile) { @@ -92,12 +99,15 @@ static void __connection_opened_cb(connection_error_e result, void *user_data) cprof = NULL; return; } + DBG("connection is opened\n"); if (_mobileap_is_disabled()) { + DBG("Tethering is disabled\n"); _close_network(); return; } + DBG("Set masquerading\n"); if (_set_masquerade() == FALSE) { ERR("_set_masquerade is failed\n"); _close_network(); @@ -156,6 +166,7 @@ static gboolean __is_tethering_cellular_prof(connection_profile_h profile) return FALSE; } + DBG("Service type : %d\n", svc_type); if (svc_type != CONNECTION_CELLULAR_SERVICE_TYPE_TETHERING) return FALSE; @@ -180,11 +191,16 @@ static gboolean __get_tethering_cellular_prof(connection_profile_h *profile, gbo connection_profile_destroy(*profile); return FALSE; } + DBG("Tethering cellular service profile\n"); + __print_profile(*profile); - if (pstat != CONNECTION_PROFILE_STATE_CONNECTED) + if (pstat != CONNECTION_PROFILE_STATE_CONNECTED) { + DBG("Tethering profile is not connected\n"); *is_connected = FALSE; - else + } else { + DBG("Tethering profile is connected\n"); *is_connected = TRUE; + } return TRUE; } @@ -200,16 +216,20 @@ static gboolean __get_network_prof(connection_profile_h *r_prof, gboolean *is_co return FALSE; } + DBG("Current connected net_type : %d\n", net_type); if (net_type == CONNECTION_PROFILE_TYPE_CELLULAR) { + DBG("Cellular profile\n"); + __print_profile(profile); + if (__is_tethering_cellular_prof(profile) == TRUE) goto DONE; - if (__get_tethering_cellular_prof(&tether_prof, is_connected) == FALSE) { - DBG("There is no tethering service cellular\n"); + if (__get_tethering_cellular_prof(&tether_prof, is_connected) == FALSE) goto DONE; - } connection_profile_destroy(profile); + DBG("Getting tethering profile is successful\n"); + *r_prof = tether_prof; return TRUE; } @@ -290,12 +310,90 @@ gboolean _unset_masquerade(void) return TRUE; } +static gboolean __set_dns_forward(void) +{ + if (cprof == NULL) { + ERR("There is no connected network profile\n"); + return FALSE; + } + + char cmd[MAX_BUF_SIZE] = {0, }; + char *interface[] = {WIFI_IF, BT_IF_ALL, USB_IF, NULL}; + int conn_ret; + int i; + + if (dns_addr) + __unset_dns_forward(); + + conn_ret = connection_profile_get_dns_address(cprof, DNS_ORDER, + CONNECTION_ADDRESS_FAMILY_IPV4, &dns_addr); + if (conn_ret != CONNECTION_ERROR_NONE || dns_addr == NULL) { + ERR("connection_profile_get_dns_address is failed : 0x%X, 0x%p\n", + conn_ret, dns_addr); + return FALSE; + } + + if (strlen(dns_addr) == 0) { + ERR("DNS Address has zero length\n"); + free(dns_addr); + dns_addr = NULL; + return FALSE; + } + + DBG("DNS Address : %s\n", dns_addr); + for (i = 0; interface[i] != NULL; i++) { + snprintf(cmd, sizeof(cmd), + "%s -t nat -A PREROUTING "TCP_DNS_FORWARD_RULE, + IPTABLES, interface[i], dns_addr); + _execute_command(cmd); + + snprintf(cmd, sizeof(cmd), + "%s -t nat -A PREROUTING "UDP_DNS_FORWARD_RULE, + IPTABLES, interface[i], dns_addr); + _execute_command(cmd); + } + + return TRUE; +} + +static gboolean __unset_dns_forward(void) +{ + if (dns_addr == NULL) { + DBG("There is no configured dns forward\n"); + return TRUE; + } + + char cmd[MAX_BUF_SIZE] = {0, }; + char *interface[] = {WIFI_IF, BT_IF_ALL, USB_IF, NULL}; + int i; + + DBG("DNS Address : %s\n", dns_addr); + for (i = 0; interface[i] != NULL; i++) { + snprintf(cmd, sizeof(cmd), + "%s -t nat -D PREROUTING "TCP_DNS_FORWARD_RULE, + IPTABLES, interface[i], dns_addr); + _execute_command(cmd); + + snprintf(cmd, sizeof(cmd), + "%s -t nat -D PREROUTING "UDP_DNS_FORWARD_RULE, + IPTABLES, interface[i], dns_addr); + _execute_command(cmd); + } + + free(dns_addr); + dns_addr = NULL; + + return TRUE; +} + gboolean _open_network(void) { connection_profile_h profile = NULL; gboolean is_connected = FALSE; int conn_ret; + DBG("+\n"); + if (__get_network_prof(&profile, &is_connected) == FALSE) { ERR("__get_network_prof is failed\n"); return FALSE; @@ -303,6 +401,7 @@ gboolean _open_network(void) cprof = profile; if (is_connected == FALSE) { + DBG("Profile is not connected\n"); conn_ret = connection_open_profile(connection, cprof, __connection_opened_cb, NULL); if (conn_ret != CONNECTION_ERROR_NONE) { @@ -315,12 +414,23 @@ gboolean _open_network(void) return TRUE; } + DBG("Set masquerading\n"); if (_set_masquerade() == FALSE) { ERR("_set_masquerade is failed\n"); _close_network(); return FALSE; } + DBG("Set dns forwarding\n"); + if (__set_dns_forward() == FALSE) { + ERR("_set_dns_forward is failed\n"); + _unset_masquerade(); + _close_network(); + return FALSE; + } + + DBG("-\n"); + return TRUE; } @@ -331,6 +441,11 @@ gboolean _close_network(void) if (cprof == NULL) return TRUE; + DBG("+\n"); + + if (__unset_dns_forward() == FALSE) + ERR("__unset_dns_forward is failed\n"); + if (_unset_masquerade() == FALSE) ERR("_unset_masquerade is failed\n"); @@ -339,6 +454,8 @@ gboolean _close_network(void) __connection_closed_cb, NULL); if (conn_ret != CONNECTION_ERROR_NONE) { ERR("connection_close_profile is failed : 0x%X\n", conn_ret); + connection_profile_destroy(cprof); + cprof = NULL; return FALSE; } @@ -348,6 +465,7 @@ gboolean _close_network(void) connection_profile_destroy(cprof); cprof = NULL; + DBG("-\n"); return TRUE; } diff --git a/src/mobileap_notification.c b/src/mobileap_notification.c index c6f81ce..ec53043 100644 --- a/src/mobileap_notification.c +++ b/src/mobileap_notification.c @@ -43,6 +43,10 @@ int _create_timeout_noti(const char *content, const char *title, ret = notification_delete(noti); if (ret != NOTIFICATION_ERROR_NONE) { ERR("Fail to notification_delete [%d]\n", ret); + + ret = notification_free(noti); + if (ret != NOTIFICATION_ERROR_NONE) + ERR("Fail to notification_free [%d]\n", ret); return MOBILE_AP_ERROR_INTERNAL; } @@ -243,12 +247,17 @@ int _update_connected_noti(const char *content) content, NULL, NOTIFICATION_VARIABLE_TYPE_NONE); if (ret != NOTIFICATION_ERROR_NONE) { ERR("Fail to notification_set_text [%d]\n", ret); + + ret = notification_free(noti); + if (ret != NOTIFICATION_ERROR_NONE) + ERR("Fail to notification_free [%d]\n", ret); return MOBILE_AP_ERROR_INTERNAL; } ret = notification_update(noti); if (ret != NOTIFICATION_ERROR_NONE) { ERR("Fail to notification_update [%d]\n", ret); + ret = notification_free(noti); if (ret != NOTIFICATION_ERROR_NONE) ERR("Fail to notification_free [%d]\n", ret); @@ -282,6 +291,10 @@ int _delete_connected_noti(void) ret = notification_delete(noti); if (ret != NOTIFICATION_ERROR_NONE) { ERR("Fail to notification_delete [%d]\n", ret); + + ret = notification_free(noti); + if (ret != NOTIFICATION_ERROR_NONE) + ERR("Fail to notification_free [%d]\n", ret); return MOBILE_AP_ERROR_INTERNAL; }