+static gboolean __reset_time_counter_foreach_rstn(gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ stc_rstn_key_s *rstn_key = (stc_rstn_key_s *)key;
+ stc_rstn_value_s *rstn_value = (stc_rstn_value_s *)value;
+ reset_time_limits_context_s *context = (reset_time_limits_context_s *)data;
+ int i;
+ time_t now_month_start_ts;
+
+ if (rstn_value->month_start_date == 0) {
+ table_counters_info info;
+ memset(&info, 0, sizeof(table_counters_info));
+ table_counters_get_timestamps(rstn_value->restriction_id, &info);
+
+ if (info.month_start_date == 0)
+ rstn_value->month_start_date = 1;
+ else
+ rstn_value->month_start_date = info.month_start_date;
+ rstn_value->month_start_ts = info.month_start_ts;
+ }
+
+ now_month_start_ts =
+ stc_time_get_month_start(context->now,
+ rstn_value->month_start_date);
+
+ if (rstn_value->month_start_ts != now_month_start_ts) {
+ rstn_value->month_start_ts = now_month_start_ts;
+ context->month_start_ts = now_month_start_ts;
+ context->is_updated |= (1 << STC_RSTN_LIMIT_TYPE_MONTHLY);
+ }
+
+ if (context->is_updated) {
+ table_counters_info info;
+ memset(&info, 0, sizeof(table_counters_info));
+
+ info.restriction_id = rstn_value->restriction_id;
+ info.month_start_date = rstn_value->month_start_date;
+ info.month_start_ts = rstn_value->month_start_ts;
+ info.week_start_ts = context->week_start_ts;
+ info.day_start_ts = context->day_start_ts;
+
+ table_counters_update_timestamps(&info);
+ }
+
+ for (i = STC_RSTN_LIMIT_TYPE_MONTHLY; i < STC_RSTN_LIMIT_TYPE_MAX; i++) {
+
+ if ((context->is_updated) & (1 << i)) {
+ /* reset limit */
+ rstn_value->counter[i] = 0;
+
+ if (rstn_value->limit_exceeded & (1 << i)) {
+ /* remove iptables rule */
+ char *default_ifname = stc_default_connection_get_ifname();
+ struct nfacct_rule counter;
+ stc_s *stc = stc_get_manager();
+ if (stc == NULL) {
+ STC_LOGE("Can't get stc data");
+ g_free(default_ifname);
+ goto try_next_callback;
+ }
+
+ if (!stc->carg) {
+ stc->carg = MALLOC0(counter_arg_s, 1);
+ if (stc->carg == NULL) {
+ g_free(default_ifname);
+ goto try_next_callback;
+ }
+
+ stc->carg->sock =
+ stc_monitor_get_counter_socket();
+ }
+
+ counter.carg = stc->carg;
+ counter.classid = rstn_value->classid;
+ counter.intend = NFACCT_BLOCK;
+ counter.iftype = rstn_key->iftype;
+ g_strlcpy(counter.ifname, default_ifname,
+ MAX_IFACE_LENGTH);
+
+ g_free(default_ifname);
+
+ /* iptables rule */
+ __del_iptables_in(&counter);
+ __del_iptables_out(&counter);
+
+ /* ip6tables rule */
+ __del_ip6tables_in(&counter);
+ __del_ip6tables_out(&counter);
+
+ rstn_value->rstn_state = STC_RSTN_STATE_DEACTIVATED;
+ rstn_value->limit_exceeded &= ~(1 << i);
+ rstn_value->limit_notified &= ~(1 << i);
+ }
+ }
+ }
+
+try_next_callback:
+ return FALSE;
+}
+
+static void __reset_time_counters_if_required(void)
+{
+ reset_time_limits_context_s context;
+
+ if (g_system == NULL) {
+ STC_LOGE("stc monitor not initialized!");
+ return;
+ }
+
+ context.now = time(NULL);
+ context.week_start_ts = stc_time_get_week_start(context.now);
+ context.day_start_ts = stc_time_get_day_start(context.now);
+ context.is_updated = 0;
+
+ if (g_system->last_week_ts != context.week_start_ts) {
+ g_system->last_week_ts = context.week_start_ts;
+ context.is_updated |= (1 << STC_RSTN_LIMIT_TYPE_WEEKLY);
+ }
+
+ if (g_system->last_day_ts != context.day_start_ts) {
+ g_system->last_day_ts = context.day_start_ts;
+ context.is_updated |= (1 << STC_RSTN_LIMIT_TYPE_DAILY);
+ }
+
+ if (g_system->rstns) {
+ g_tree_foreach(g_system->rstns,
+ __reset_time_counter_foreach_rstn,
+ &context);
+ if (context.is_updated)
+ STC_LOGD("Counter reset completed month_start [%ld], week_start [%ld], day_start [%ld]",
+ context.month_start_ts, g_system->last_week_ts, g_system->last_day_ts);
+ }
+}
+