void receive_prof_repl(bin_packet_t *packet) { time_t now; str name; str value; unsigned int counter; struct dlg_profile_table *profile; int has_value; int i; void **dst; prof_value_info_t *rp; repl_prof_count_t *destination; /* optimize profile search */ struct dlg_profile_table *old_profile = NULL; str old_name = {NULL,0}; if (!profile_repl_cluster) return; if (packet->type != REPLICATION_DLG_PROFILE) { LM_WARN("Invalid dialog binary packet command: %d (from node: %d in cluster: %d)\n", packet->type, packet->src_id, profile_repl_cluster); return; } now = time(0); //*repl_prof_dests[index].last_msg = now; for (;;) { if (bin_pop_str(packet ,&name) == 1) break; /* pop'ed all pipes */ /* check if the same profile was sent */ if (!old_profile || old_name.len != name.len || memcmp(name.s, old_name.s, name.len) != 0) { old_profile = get_dlg_profile(&name); if (!old_profile) LM_WARN("received unknown profile <%.*s> from node %d\n", name.len, name.s, packet->src_id); old_name = name; } profile = old_profile; if (bin_pop_int(packet, &has_value) < 0) { LM_ERR("cannot pop profile's has_value int\n"); return; } if (has_value) { if (!profile->has_value) { LM_WARN("The other end does not have a value for this profile:" "<%.*s> [node: %d]\n", profile->name.len, profile->name.s, packet->src_id); profile = NULL; } if (bin_pop_str(packet, &value)) { LM_ERR("cannot pop the value of the profile\n"); return; } } if (bin_pop_int(packet, &counter) < 0) { LM_ERR("cannot pop profile's counter\n"); return; } if (profile) { if (!profile->has_value) { lock_get(&profile->noval_repl_info->lock); destination = find_destination(profile->noval_repl_info, packet->src_id); if(destination == NULL){ lock_release(&profile->noval_repl_info->lock); return; } destination->counter = counter; destination->update = now; lock_release(&profile->noval_repl_info->lock); } else { /* XXX: hack to make sure we find the proper index */ i = core_hash(&value, NULL, profile->size); lock_set_get(profile->locks, i); /* if counter is 0 and we don't have it, don't try to create */ if (!counter) { dst = map_find(profile->entries[i], value); if (!dst) goto release; } else { dst = map_get(profile->entries[i], value); } if (!*dst) { rp = shm_malloc(sizeof(prof_value_info_t)); if (!rp) { LM_ERR("no more shm memory to allocate repl_prof_value\n"); goto release; } memset(rp, 0, sizeof(prof_value_info_t)); *dst = rp; } else { rp = (prof_value_info_t *) * dst; } if (!rp->noval) rp->noval = repl_prof_allocate(); if (rp->noval) { lock_release(&rp->noval->lock); destination = find_destination(rp->noval, packet->src_id); if (destination == NULL) { lock_release(&rp->noval->lock); lock_set_release(profile->locks, i); return; } destination->counter = counter; destination ->update = now; lock_release(&rp->noval->lock); } release: lock_set_release(profile->locks, i); } } } return; }
void rl_rcv_bin(bin_packet_t *packet) { rl_algo_t algo; int limit; int counter; str name; rl_pipe_t **pipe; unsigned int hash_idx; time_t now; rl_repl_counter_t *destination; if (packet->type != RL_PIPE_COUNTER) { LM_WARN("Invalid binary packet command: %d (from node: %d in cluster: %d)\n", packet->type, packet->src_id, rl_repl_cluster); return; } now = time(0); for (;;) { if (bin_pop_str(packet, &name) == 1) break; /* pop'ed all pipes */ if (bin_pop_int(packet, &algo) < 0) { LM_ERR("cannot pop pipe's algorithm\n"); return; } if (bin_pop_int(packet, &limit) < 0) { LM_ERR("cannot pop pipe's limit\n"); return; } if (bin_pop_int(packet, &counter) < 0) { LM_ERR("cannot pop pipe's counter\n"); return; } hash_idx = RL_GET_INDEX(name); RL_GET_LOCK(hash_idx); /* try to get the value */ pipe = RL_GET_PIPE(hash_idx, name); if (!pipe) { LM_ERR("cannot get the index\n"); goto release; } if (!*pipe) { /* if the pipe does not exist, allocate it in case we need it later */ if (!(*pipe = rl_create_pipe(limit, algo))) goto release; LM_DBG("Pipe %.*s doesn't exist, but was created %p\n", name.len, name.s, *pipe); } else { LM_DBG("Pipe %.*s found: %p - last used %lu\n", name.len, name.s, *pipe, (*pipe)->last_used); if ((*pipe)->algo != algo) LM_WARN("algorithm %d different from the initial one %d for " "pipe %.*s", algo, (*pipe)->algo, name.len, name.s); /* * XXX: do not output these warnings since they can be triggered * when a custom limit is used if ((*pipe)->limit != limit) LM_WARN("limit %d different from the initial one %d for " "pipe %.*s", limit, (*pipe)->limit, name.len, name.s); */ } /* set the last used time */ (*pipe)->last_used = time(0); /* set the destination's counter */ destination = find_destination(*pipe, packet->src_id); if (!destination) goto release; destination->counter = counter; destination->update = now; RL_RELEASE_LOCK(hash_idx); } return; release: RL_RELEASE_LOCK(hash_idx); }
void rl_rcv_bin(int packet_type, struct receive_info *ri, int server_id) { rl_algo_t algo; int limit; int counter; str name; char *ip; unsigned short port; rl_pipe_t **pipe; unsigned int hash_idx; time_t now; rl_repl_counter_t *destination; if (packet_type == SERVER_TEMP_DISABLED) { get_su_info(&ri->src_su.s, ip, port); LM_WARN("server: %s:%hu temporary disabled\n", ip, port); return; } if (packet_type == SERVER_TIMEOUT) { LM_WARN("server with clustererer id %d timeout\n", server_id); return; } if(get_bin_pkg_version() != BIN_VERSION){ LM_ERR("incompatible bin protocol version\n"); return; } if (packet_type != RL_PIPE_COUNTER) return; if (packet_type != RL_PIPE_COUNTER) return; now = time(0); for (;;) { if (bin_pop_str(&name) == 1) break; /* pop'ed all pipes */ if (bin_pop_int(&algo) < 0) { LM_ERR("cannot pop pipe's algorithm\n"); return; } if (bin_pop_int(&limit) < 0) { LM_ERR("cannot pop pipe's limit\n"); return; } if (bin_pop_int(&counter) < 0) { LM_ERR("cannot pop pipe's counter\n"); return; } hash_idx = RL_GET_INDEX(name); RL_GET_LOCK(hash_idx); /* try to get the value */ pipe = RL_GET_PIPE(hash_idx, name); if (!pipe) { LM_ERR("cannot get the index\n"); goto release; } if (!*pipe) { /* if the pipe does not exist, alocate it in case we need it later */ *pipe = shm_malloc(sizeof(rl_pipe_t)); if (!*pipe) { LM_ERR("no more shm memory\n"); goto release; } memset(*pipe, 0, sizeof(rl_pipe_t)); LM_DBG("Pipe %.*s doesn't exist, but was created %p\n", name.len, name.s, *pipe); (*pipe)->algo = algo; (*pipe)->limit = limit; } else { LM_DBG("Pipe %.*s found: %p - last used %lu\n", name.len, name.s, *pipe, (*pipe)->last_used); if ((*pipe)->algo != algo) LM_WARN("algorithm %d different from the initial one %d for " "pipe %.*s", algo, (*pipe)->algo, name.len, name.s); if ((*pipe)->limit != limit) LM_WARN("limit %d different from the initial one %d for " "pipe %.*s", limit, (*pipe)->limit, name.len, name.s); } /* set the last used time */ (*pipe)->last_used = time(0); /* set the destination's counter */ destination = find_destination(*pipe, server_id); destination->counter = counter; destination->update = now; RL_RELEASE_LOCK(hash_idx); } return; release: RL_RELEASE_LOCK(hash_idx); }
static void dlg_replicated_profiles(struct receive_info *ri, int server_id) { time_t now; str name; str value; char *ip; unsigned short port; unsigned int counter; struct dlg_profile_table *profile; int has_value; int i; void **dst; repl_prof_value_t *rp; repl_prof_count_t *destination; /* optimize profile search */ struct dlg_profile_table *old_profile = NULL; str old_name; now = time(0); //*repl_prof_dests[index].last_msg = now; for (;;) { if (bin_pop_str(&name) == 1) break; /* pop'ed all pipes */ /* check if the same profile was sent */ if (!old_profile || old_name.len != name.len || memcmp(name.s, old_name.s, name.len) != 0) { old_profile = get_dlg_profile(&name); if (!old_profile) { get_su_info(&ri->src_su.s, ip, port); LM_WARN("received unknown profile <%.*s> from %s:%hu\n", name.len, name.s, ip, port); } old_name = name; } profile = old_profile; if (bin_pop_int(&has_value) < 0) { LM_ERR("cannot pop profile's has_value int\n"); return; } if (has_value) { if (!profile->has_value) { get_su_info(&ri->src_su.s, ip, port); LM_WARN("The other end does not have a value for this profile:" "<%.*s> [%s:%hu]\n", profile->name.len, profile->name.s, ip, port); profile = NULL; } if (bin_pop_str(&value)) { LM_ERR("cannot pop the value of the profile\n"); return; } } if (bin_pop_int(&counter) < 0) { LM_ERR("cannot pop profile's counter\n"); return; } if (profile) { if (!profile->has_value) { lock_get(&profile->repl->lock); destination = find_destination(profile->repl, server_id); if(destination == NULL){ lock_release(&profile->repl->lock); return; } destination->counter = counter; destination->update = now; lock_release(&profile->repl->lock); } else { /* XXX: hack to make sure we find the proper index */ i = core_hash(&value, NULL, profile->size); lock_set_get(profile->locks, i); /* if counter is 0 and we don't have it, don't try to create */ if (!counter) { dst = map_find(profile->entries[i], value); if (!dst) goto release; } else { dst = map_get(profile->entries[i], value); } if (!*dst) { rp = shm_malloc(sizeof(repl_prof_value_t)); if (!rp) { LM_ERR("no more shm memory to allocate repl_prof_value\n"); goto release; } memset(rp, 0, sizeof(repl_prof_value_t)); *dst = rp; } else { rp = (repl_prof_value_t *) * dst; } if (!rp->noval) rp->noval = repl_prof_allocate(); if (rp->noval) { lock_release(&rp->noval->lock); destination = find_destination(rp->noval, server_id); if (destination == NULL) { lock_release(&rp->noval->lock); lock_set_release(profile->locks, i); return; } destination->counter = counter; destination ->update = now; lock_release(&rp->noval->lock); } release: lock_set_release(profile->locks, i); } } } return; }
void rl_rcv_bin(int packet_type, struct receive_info *ri) { rl_algo_t algo; int limit; int counter; int rc; int server_id; str name; char *ip; unsigned short port; rl_pipe_t **pipe; unsigned int hash_idx; time_t now; rl_repl_counter_t *destination; LM_DBG("received a binary packet [%d]!\n", packet_type); if (packet_type != RL_PIPE_COUNTER) return; rc = bin_pop_int(&server_id); if (rc < 0) return; if (!clusterer_api.check(accept_repl_pipes, &ri->src_su, server_id, ri->proto)){ get_su_info(&ri->src_su.s, ip, port); LM_WARN("received bin packet from unknown source: %s:%hu\n", ip, port); return; } now = time(0); for (;;) { if (bin_pop_str(&name) == 1) break; /* pop'ed all pipes */ if (bin_pop_int(&algo) < 0) { LM_ERR("cannot pop pipe's algorithm\n"); return; } if (bin_pop_int(&limit) < 0) { LM_ERR("cannot pop pipe's limit\n"); return; } if (bin_pop_int(&counter) < 0) { LM_ERR("cannot pop pipe's counter\n"); return; } hash_idx = RL_GET_INDEX(name); RL_GET_LOCK(hash_idx); /* try to get the value */ pipe = RL_GET_PIPE(hash_idx, name); if (!pipe) { LM_ERR("cannot get the index\n"); goto release; } if (!*pipe) { /* if the pipe does not exist, alocate it in case we need it later */ *pipe = shm_malloc(sizeof(rl_pipe_t)); if (!*pipe) { LM_ERR("no more shm memory\n"); goto release; } memset(*pipe, 0, sizeof(rl_pipe_t)); LM_DBG("Pipe %.*s doesn't exist, but was created %p\n", name.len, name.s, *pipe); (*pipe)->algo = algo; (*pipe)->limit = limit; } else { LM_DBG("Pipe %.*s found: %p - last used %lu\n", name.len, name.s, *pipe, (*pipe)->last_used); if ((*pipe)->algo != algo) LM_WARN("algorithm %d different from the initial one %d for " "pipe %.*s", algo, (*pipe)->algo, name.len, name.s); if ((*pipe)->limit != limit) LM_WARN("limit %d different from the initial one %d for " "pipe %.*s", limit, (*pipe)->limit, name.len, name.s); } /* set the last used time */ (*pipe)->last_used = time(0); /* set the destination's counter */ destination = find_destination(*pipe, server_id); destination->counter = counter; destination->update = now; RL_RELEASE_LOCK(hash_idx); } return; release: RL_RELEASE_LOCK(hash_idx); }