/* get name functions */ static inline str* __get_avp_name(int id, map_t m) { map_iterator_t it; int **idp; if (map_first(m, &it) < 0) { LM_ERR("map doesn't exist\n"); return NULL; } for (;;) { if (!iterator_is_valid(&it)) return NULL; idp = (int**)iterator_val(&it); if (!idp) { LM_ERR("[BUG] while getting avp name\n"); return NULL; } if (p2int(*idp) == id) return iterator_key(&it); if (iterator_next(&it) < 0) return NULL; } }
static void broadcast_profiles(utime_t ticks, void *param) { #define REPL_PROF_TRYSEND() \ do { \ nr++; \ if (ret > repl_prof_buffer_th) { \ /* send the buffer */ \ if (nr) \ dlg_replicate_profiles(&packet); \ bin_reset_back_pointer(&packet); \ nr = 0; \ } \ } while (0) struct dlg_profile_table *profile; map_iterator_t it; unsigned int count; int i; int nr = 0; int ret; void **dst; str *value; bin_packet_t packet; if (bin_init(&packet, &prof_repl_cap, REPLICATION_DLG_PROFILE, BIN_VERSION, 0) < 0) { LM_ERR("cannot initiate bin buffer\n"); return; } for (profile = profiles; profile; profile = profile->next) { if (!(profile->repl_type&REPL_PROTOBIN)) continue; count = 0; if (!profile->has_value) { count = noval_get_local_count(profile); if ((ret = repl_prof_add(&packet, &profile->name, 0, NULL, count)) < 0) goto error; /* check if the profile should be sent */ REPL_PROF_TRYSEND(); } else { for (i = 0; i < profile->size; i++) { lock_set_get(profile->locks, i); if (map_first(profile->entries[i], &it) < 0) { LM_ERR("map does not exist\n"); goto next_entry; } while (iterator_is_valid(&it)) { dst = iterator_val(&it); if (!dst || !*dst) { LM_ERR("[BUG] bogus map[%d] state\n", i); goto next_val; } value = iterator_key(&it); if (!value) { LM_ERR("cannot retrieve profile's key\n"); goto next_val; } count = prof_val_get_local_count(dst); if ((ret = repl_prof_add(&packet, &profile->name, 1, value, count)) < 0) goto error; /* check if the profile should be sent */ REPL_PROF_TRYSEND(); next_val: if (iterator_next(&it) < 0) break; } next_entry: lock_set_release(profile->locks, i); } } } goto done; error: LM_ERR("cannot add any more profiles in buffer\n"); bin_free_packet(&packet); done: /* check if there is anything else left to replicate */ if (nr) dlg_replicate_profiles(&packet); bin_free_packet(&packet); #undef REPL_PROF_TRYSEND }
void rl_timer_repl(utime_t ticks, void *param) { static str module_name = str_init("ratelimit"); unsigned int i = 0; map_iterator_t it; rl_pipe_t **pipe; str *key; int nr = 0; int ret; if (bin_init(&module_name, RL_PIPE_COUNTER) < 0) { LM_ERR("cannot initiate bin buffer\n"); return; } /* iterate through each map */ for (i = 0; i < rl_htable.size; i++) { RL_GET_LOCK(i); /* iterate through all the entries */ if (map_first(rl_htable.maps[i], &it) < 0) { LM_ERR("map doesn't exist\n"); goto next_map; } for (; iterator_is_valid(&it);) { pipe = (rl_pipe_t **)iterator_val(&it); if (!pipe || !*pipe) { LM_ERR("[BUG] bogus map[%d] state\n", i); goto next_pipe; } /* ignore cachedb replicated stuff */ if (RL_USE_CDB(*pipe)) goto next_pipe; key = iterator_key(&it); if (!key) { LM_ERR("cannot retrieve pipe key\n"); goto next_pipe; } if (bin_push_str(key) < 0) goto error; if (bin_push_int((*pipe)->algo) < 0) goto error; if (bin_push_int((*pipe)->limit) < 0) goto error; if ((ret = bin_push_int((*pipe)->counter)) < 0) goto error; nr++; if (ret > rl_buffer_th) { /* send the buffer */ if (nr) rl_replicate(); if (bin_init(&module_name, RL_PIPE_COUNTER) < 0) { LM_ERR("cannot initiate bin buffer\n"); RL_RELEASE_LOCK(i); return; } nr = 0; } next_pipe: if (iterator_next(&it) < 0) break; } next_map: RL_RELEASE_LOCK(i); } /* if there is anything else to send, do it now */ if (nr) rl_replicate(); return; error: LM_ERR("cannot add pipe info in buffer\n"); RL_RELEASE_LOCK(i); if (nr) rl_replicate(); }
/* timer housekeeping, invoked each timer interval to reset counters */ void rl_timer(unsigned int ticks, void *param) { unsigned int i = 0; map_iterator_t it, del; rl_pipe_t **pipe; str *key; void *value; unsigned long now = time(0); /* get CPU load */ if (get_cpuload() < 0) { LM_ERR("cannot update CPU load\n"); i = 1; } lock_get(rl_lock); /* if CPU was successfully loaded */ if (!i) do_update_load(); /* update network if needed */ if (*rl_network_count) *rl_network_load = get_total_bytes_waiting(PROTO_NONE); lock_release(rl_lock); /* iterate through each map */ for (i = 0; i < rl_htable.size; i++) { RL_GET_LOCK(i); /* iterate through all the entries */ if (map_first(rl_htable.maps[i], &it) < 0) { LM_ERR("map doesn't exist\n"); goto next_map; } for (; iterator_is_valid(&it);) { pipe = (rl_pipe_t **)iterator_val(&it); if (!pipe || !*pipe) { LM_ERR("[BUG] bogus map[%d] state\n", i); goto next_pipe; } key = iterator_key(&it); if (!key) { LM_ERR("cannot retrieve pipe key\n"); goto next_pipe; } /* check to see if it is expired */ if ((*pipe)->last_used + rl_expire_time < now) { /* this pipe is engaged in a transaction */ del = it; if (iterator_next(&it) < 0) LM_DBG("cannot find next iterator\n"); if ((*pipe)->algo == PIPE_ALGO_NETWORK) { lock_get(rl_lock); (*rl_network_count)--; lock_release(rl_lock); } LM_DBG("Deleting ratelimit pipe key \"%.*s\"\n", key->len, key->s); value = iterator_delete(&del); /* free resources */ if (value) shm_free(value); continue; } else { /* leave the lock if a cachedb query should be done*/ if (RL_USE_CDB(*pipe)) { if (rl_get_counter(key, *pipe) < 0) { LM_ERR("cannot get pipe counter\n"); goto next_pipe; } } switch ((*pipe)->algo) { case PIPE_ALGO_NETWORK: /* handle network algo */ (*pipe)->load = (*rl_network_load > (*pipe)->limit) ? -1 : 1; break; case PIPE_ALGO_RED: if ((*pipe)->limit && rl_timer_interval) (*pipe)->load = (*pipe)->counter / ((*pipe)->limit * rl_timer_interval); break; default: break; } (*pipe)->last_counter = rl_get_all_counters(*pipe); if (RL_USE_CDB(*pipe)) { if (rl_change_counter(key, *pipe, 0) < 0) { LM_ERR("cannot reset counter\n"); } } else { (*pipe)->counter = 0; } } next_pipe: if (iterator_next(&it) < 0) break; } next_map: RL_RELEASE_LOCK(i); } }
static void repl_prof_utimer_f(utime_t ticks, void *param) { #define REPL_PROF_TRYSEND() \ do { \ nr++; \ if (ret > repl_prof_buffer_th) { \ /* send the buffer */ \ if (nr) { \ dlg_replicate_profiles(); \ LM_DBG("sent %d records\n", nr); \ } \ if (bin_init(&module_name, REPLICATION_DLG_PROFILE, BIN_VERSION) < 0) { \ LM_ERR("cannot initiate bin buffer\n"); \ return; \ } \ nr = 0; \ } \ } while (0) struct dlg_profile_table *profile; static str module_name = str_init("dialog"); map_iterator_t it; unsigned int count; int i; int nr = 0; int ret; void **dst; str *value; if (bin_init(&module_name, REPLICATION_DLG_PROFILE, BIN_VERSION) < 0) { LM_ERR("cannot initiate bin buffer\n"); return; } for (profile = profiles; profile; profile = profile->next) { count = 0; if (!profile->has_value) { for (i = 0; i < profile->size; i++) { lock_set_get(profile->locks, i); count += profile->counts[i]; lock_set_release(profile->locks, i); } if ((ret = repl_prof_add(&profile->name, 0, NULL, count)) < 0) goto error; /* check if the profile should be sent */ REPL_PROF_TRYSEND(); } else { for (i = 0; i < profile->size; i++) { lock_set_get(profile->locks, i); if (map_first(profile->entries[i], &it) < 0) { LM_ERR("map does not exist\n"); goto next_entry; } while (iterator_is_valid(&it)) { dst = iterator_val(&it); if (!dst || !*dst) { LM_ERR("[BUG] bogus map[%d] state\n", i); goto next_val; } value = iterator_key(&it); if (!value) { LM_ERR("cannot retrieve profile's key\n"); goto next_val; } count = repl_prof_get(dst); if ((ret = repl_prof_add(&profile->name, 1, value, count)) < 0) goto error; /* check if the profile should be sent */ REPL_PROF_TRYSEND(); next_val: if (iterator_next(&it) < 0) break; } next_entry: lock_set_release(profile->locks, i); } } } goto done; error: LM_ERR("cannot add any more profiles in buffer\n"); done: /* check if there is anything else left to replicate */ LM_DBG("sent %d records\n", nr); if (nr) dlg_replicate_profiles(); #undef REPL_PROF_TRYSEND }
void rl_timer_repl(utime_t ticks, void *param) { unsigned int i = 0; map_iterator_t it; rl_pipe_t **pipe; str *key; int nr = 0; int ret; bin_packet_t packet; if (bin_init(&packet, &pipe_repl_cap, RL_PIPE_COUNTER, BIN_VERSION, 0) < 0) { LM_ERR("cannot initiate bin buffer\n"); return; } /* iterate through each map */ for (i = 0; i < rl_htable.size; i++) { RL_GET_LOCK(i); /* iterate through all the entries */ if (map_first(rl_htable.maps[i], &it) < 0) { LM_ERR("map doesn't exist\n"); goto next_map; } for (; iterator_is_valid(&it);) { pipe = (rl_pipe_t **) iterator_val(&it); if (!pipe || !*pipe) { LM_ERR("[BUG] bogus map[%d] state\n", i); goto next_pipe; } /* ignore cachedb replicated stuff */ if (RL_USE_CDB(*pipe)) goto next_pipe; key = iterator_key(&it); if (!key) { LM_ERR("cannot retrieve pipe key\n"); goto next_pipe; } if (bin_push_str(&packet, key) < 0) goto error; if (bin_push_int(&packet, (*pipe)->algo) < 0) goto error; if (bin_push_int(&packet, (*pipe)->limit) < 0) goto error; /* * for the SBT algorithm it is safe to replicate the current * counter, since it is always updating according to the window */ if ((ret = bin_push_int(&packet, ((*pipe)->algo == PIPE_ALGO_HISTORY ? (*pipe)->counter : (*pipe)->my_last_counter))) < 0) goto error; nr++; if (ret > rl_buffer_th) { /* send the buffer */ if (nr) rl_replicate(&packet); bin_reset_back_pointer(&packet); nr = 0; } next_pipe: if (iterator_next(&it) < 0) break; } next_map: RL_RELEASE_LOCK(i); } /* if there is anything else to send, do it now */ if (nr) rl_replicate(&packet); bin_free_packet(&packet); return; error: LM_ERR("cannot add pipe info in buffer\n"); RL_RELEASE_LOCK(i); if (nr) rl_replicate(&packet); bin_free_packet(&packet); }