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; }
static void dlg_replicated_profiles(struct receive_info *ri) { int index; 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; /* optimize profile search */ struct dlg_profile_table *old_profile = NULL; str old_name; /* match the server */ for (index = 0; index < repl_prof_dests_nr; index++) { if (su_cmp(&ri->src_su, &repl_prof_dests[index].to)) break; } if (index == repl_prof_dests_nr) { 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); *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); profile->repl->dsts[index].counter = counter; profile->repl->dsts[index].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); rp->noval->dsts[index].counter = counter; rp->noval->dsts[index].update = now; lock_release(&rp->noval->lock); } release: lock_set_release(profile->locks, i); } } } return; }