Modified to update firewall rule
[platform/core/connectivity/stc-manager.git] / src / stc-firewall.c
old mode 100644 (file)
new mode 100755 (executable)
index 236169b..ff4bc02
@@ -190,9 +190,11 @@ static void __fw_rule_make_key(firewall_rule_s *rule,
        g_string_append_printf(str, "_%s", (rule->ifname) ? rule->ifname : "");
        g_string_append_printf(str, "_%u", rule->target);
 
+       FREE(rule->identifier);
        rule->identifier = g_string_free(str, FALSE);
        rule->key = g_str_hash(rule->identifier);
 
+       FREE(info->identifier);
        info->identifier = g_strdup(rule->identifier);
        info->key = rule->key;
 
@@ -728,6 +730,7 @@ static stc_error_e __fw_rule_add(firewall_rule_s *info)
        comp = g_slist_find_custom(lookup->rules, rule, __fw_rule_comp);
        if (comp) {
                STC_LOGD("rule already present");
+               __fw_rule_free(rule);
                return STC_ERROR_ALREADY_DATA;
        }
 
@@ -777,7 +780,8 @@ static stc_error_e __fw_rule_update(const firewall_rule_s *info)
        stc_fw_data_s *lookup;
        GSList *rule_list;
        GSList *comp;
-       firewall_rule_s *rule;
+       firewall_rule_s *origin_rule;
+       firewall_rule_s *update_rule;
 
        ret_value_msg_if(g_firewalls == NULL,
                STC_ERROR_FAIL,
@@ -801,8 +805,29 @@ static stc_error_e __fw_rule_update(const firewall_rule_s *info)
                return STC_ERROR_NO_DATA;
        }
 
-       rule = comp->data;
-       __fw_rule_copy(rule, info);
+       origin_rule = comp->data;
+
+       update_rule = MALLOC0(firewall_rule_s, 1);
+       if (!update_rule) {
+               STC_LOGE("rule allocation failed");
+               return STC_ERROR_OUT_OF_MEMORY;
+       }
+
+       memset(update_rule, 0, sizeof(firewall_rule_s));
+       __fw_rule_copy(update_rule, info);
+       __fw_rule_make_key(update_rule, info);
+
+       comp = g_slist_find_custom(lookup->rules, update_rule, __fw_rule_comp);
+       if (comp) {
+               STC_LOGD("rule already present");
+               __fw_rule_free(update_rule);
+               return STC_ERROR_ALREADY_DATA;
+       }
+
+       lookup->rules = g_slist_remove(lookup->rules, origin_rule);
+       __fw_rule_free(origin_rule);
+
+       lookup->rules = g_slist_append(lookup->rules, update_rule);
 
        return STC_ERROR_NONE;
 }
@@ -1486,6 +1511,7 @@ gboolean handle_firewall_update_rule(StcFirewall *object,
        __STC_LOG_FUNC_ENTER__;
        GVariantIter *iter = NULL;
        firewall_rule_s *rule;
+       guint key;
        int ret = STC_ERROR_NONE;
 
        STC_FIREWALL_CHECK_LOCK_STATE(invocation);
@@ -1514,9 +1540,10 @@ gboolean handle_firewall_update_rule(StcFirewall *object,
                return TRUE;
        }
 
+       key = rule->key;
        ret = __fw_rule_update(rule);
        if (ret == STC_ERROR_NONE) {
-               table_firewall_update_rule(rule);
+               table_firewall_update_rule(rule, key);
        } else {
                __fw_rule_free(rule);
                STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);