/** * receive_binary_packet (callback) - receives a cmd_type, specifying the * purpose of the data encoded in the received UDP packet */ void receive_binary_packet(int info_type) { int rc; LM_DBG("Received a binary packet!\n"); switch (info_type) { case REPLICATION_DLG_CREATED: rc = dlg_replicated_create(NULL, NULL, NULL, 1); if_update_stat(dlg_enable_stats, create_recv, 1); break; case REPLICATION_DLG_UPDATED: rc = dlg_replicated_update(); if_update_stat(dlg_enable_stats, update_recv, 1); break; case REPLICATION_DLG_DELETED: rc = dlg_replicated_delete(); if_update_stat(dlg_enable_stats, delete_recv, 1); break; default: rc = -1; LM_ERR("Invalid dialog binary packet command: %d\n", info_type); } if (rc != 0) LM_ERR("Failed to process a binary packet!\n"); }
void receive_dlg_binary_packet(int packet_type, struct receive_info *ri, void *att) { int rc; char *ip; unsigned short port; int server_id; rc = bin_pop_int(&server_id); if (rc < 0) return; LM_DBG("Received a binary packet!\n"); if(get_bin_pkg_version() != BIN_VERSION){ LM_ERR("incompatible bin protocol version\n"); return; } if (!accept_replicated_dlg) { get_su_info(&ri->src_su.s, ip, port); LM_WARN("Unwanted dialog packet received from %s:%hu (type=%d)\n", ip, port, packet_type); return; } if(!clusterer_api.check(accept_replicated_dlg, &ri->src_su, server_id, ri->proto)) return; switch (packet_type) { case REPLICATION_DLG_CREATED: LM_DBG("AAAA dlg_replicated_create\n"); rc = dlg_replicated_create(NULL, NULL, NULL, 1); if_update_stat(dlg_enable_stats, create_recv, 1); break; case REPLICATION_DLG_UPDATED: LM_DBG("AAAA dlg_replicated_update\n"); rc = dlg_replicated_update(); if_update_stat(dlg_enable_stats, update_recv, 1); break; case REPLICATION_DLG_DELETED: LM_DBG("AAAA dlg_replicated_deleted\n"); rc = dlg_replicated_delete(); if_update_stat(dlg_enable_stats, delete_recv, 1); break; default: rc = -1; get_su_info(&ri->src_su.s, ip, port); LM_WARN("Invalid dialog binary packet command: %d (from %s:%hu)\n", packet_type, ip, port); } if (rc != 0) LM_ERR("Failed to process a binary packet!\n"); }
void receive_dlg_repl(bin_packet_t *packet) { int rc = 0; bin_packet_t *pkt; for (pkt = packet; pkt; pkt = pkt->next) { switch (pkt->type) { case REPLICATION_DLG_CREATED: rc = dlg_replicated_create(pkt, NULL, NULL, NULL, 1); if_update_stat(dlg_enable_stats, create_recv, 1); break; case REPLICATION_DLG_UPDATED: rc = dlg_replicated_update(pkt); if_update_stat(dlg_enable_stats, update_recv, 1); break; case REPLICATION_DLG_DELETED: rc = dlg_replicated_delete(pkt); if_update_stat(dlg_enable_stats, delete_recv, 1); break; case DLG_SHARING_TAG_ACTIVE: rc = receive_shtag_active_msg(pkt); break; case SYNC_PACKET_TYPE: while (clusterer_api.sync_chunk_iter(pkt)) if (dlg_replicated_create(pkt, NULL, NULL, NULL, 1) < 0) { LM_ERR("Failed to process sync packet\n"); return; } break; default: rc = -1; LM_WARN("Invalid dialog binary packet command: %d " "(from node: %d in cluster: %d)\n", pkt->type, pkt->src_id, dialog_repl_cluster); } if (rc != 0) LM_ERR("Failed to process a binary packet!\n"); } }
/** * receive_binary_packet (callback) - receives a cmd_type, specifying the * purpose of the data encoded in the received UDP packet */ void receive_binary_packet(int packet_type, struct receive_info *ri) { int rc; char *ip; unsigned short port; LM_DBG("Received a binary packet!\n"); if(get_bin_pkg_version() != BIN_VERSION){ LM_ERR("incompatible bin protocol version\n"); return; } if (accept_repl_profiles && packet_type == REPLICATION_DLG_PROFILE) { /* TODO: handle this */ dlg_replicated_profiles(ri); return; } if (!accept_replicated_dlg) { get_su_info(&ri->src_su.s, ip, port); LM_WARN("Unwanted dialog packet received from %s:%hu (type=%d)\n", ip, port, packet_type); return; } switch (packet_type) { case REPLICATION_DLG_CREATED: rc = dlg_replicated_create(NULL, NULL, NULL, 1); if_update_stat(dlg_enable_stats, create_recv, 1); break; case REPLICATION_DLG_UPDATED: rc = dlg_replicated_update(); if_update_stat(dlg_enable_stats, update_recv, 1); break; case REPLICATION_DLG_DELETED: rc = dlg_replicated_delete(); if_update_stat(dlg_enable_stats, delete_recv, 1); break; default: rc = -1; get_su_info(&ri->src_su.s, ip, port); LM_WARN("Invalid dialog binary packet command: %d (from %s:%hu)\n", packet_type, ip, port); } if (rc != 0) LM_ERR("Failed to process a binary packet!\n"); }
/** * replicates the remote update of an ongoing dialog locally * by reading the relevant information using the Binary Packet Interface */ int dlg_replicated_update(void) { struct dlg_cell *dlg; str call_id, from_tag, to_tag, from_uri, to_uri, vars, profiles; unsigned int dir, dst_leg; int timeout, h_entry; str st; struct dlg_entry *d_entry; bin_pop_str(&call_id); bin_pop_str(&from_tag); bin_pop_str(&to_tag); bin_pop_str(&from_uri); bin_pop_str(&to_uri); LM_DBG("replicated update for ['%.*s' '%.*s' '%.*s' '%.*s' '%.*s']\n", call_id.len, call_id.s, from_tag.len, from_tag.s, to_tag.len, to_tag.s, from_uri.len, from_uri.s, to_uri.len, to_uri.s); dlg = get_dlg(&call_id, &from_tag, &to_tag, &dir, &dst_leg); h_entry = dlg_hash(&call_id); d_entry = &d_table->entries[h_entry]; dlg_lock(d_table, d_entry); if (!dlg) { /* TODO: change to LM_DBG */ LM_ERR("dialog not found, building new\n"); dlg = build_new_dlg(&call_id, &from_uri, &to_uri, &from_tag); if (!dlg) { LM_ERR("Failed to create replicated dialog!\n"); goto error; } return dlg_replicated_create(dlg, &from_tag, &to_tag, 0); } bin_skip_int(2); bin_pop_int(&dlg->state); bin_skip_str(2); bin_pop_str(&st); if (dlg_update_cseq(dlg, DLG_CALLER_LEG, &st, 0) != 0) { LM_ERR("failed to update caller cseq\n"); goto error; } bin_pop_str(&st); if (dlg_update_cseq(dlg, callee_idx(dlg), &st, 0) != 0) { LM_ERR("failed to update callee cseq\n"); goto error; } bin_skip_str(6); bin_pop_str(&vars); bin_pop_str(&profiles); bin_pop_int(&dlg->user_flags); bin_pop_int(&dlg->flags); bin_pop_int(&timeout); bin_skip_int(2); timeout -= time(0); LM_DBG("Received updated timeout of %d for dialog %.*s\n",timeout,call_id.len,call_id.s); if (dlg->lifetime != timeout) { dlg->lifetime = timeout; if (update_dlg_timer(&dlg->tl, dlg->lifetime) == -1) LM_ERR("failed to update dialog lifetime!\n"); } unref_dlg_unsafe(dlg, 1, d_entry); if (vars.s && vars.len != 0) read_dialog_vars(vars.s, vars.len, dlg); dlg_unlock(d_table, d_entry); if (profiles.s && profiles.len != 0) read_dialog_profiles(profiles.s, profiles.len, dlg, 1, 1); return 0; error: dlg_unlock(d_table, d_entry); return -1; }
/** * replicates the remote update of an ongoing dialog locally * by reading the relevant information using the Binary Packet Interface */ int dlg_replicated_update(bin_packet_t *packet) { struct dlg_cell *dlg; str call_id, from_tag, to_tag, from_uri, to_uri, vars, profiles; unsigned int dir, dst_leg; int timeout, h_entry; str st; struct dlg_entry *d_entry; int rcv_flags, save_new_flag; bin_pop_str(packet, &call_id); bin_pop_str(packet, &from_tag); bin_pop_str(packet, &to_tag); bin_pop_str(packet, &from_uri); bin_pop_str(packet, &to_uri); LM_DBG("replicated update for ['%.*s' '%.*s' '%.*s' '%.*s' '%.*s']\n", call_id.len, call_id.s, from_tag.len, from_tag.s, to_tag.len, to_tag.s, from_uri.len, from_uri.s, to_uri.len, to_uri.s); dlg = get_dlg(&call_id, &from_tag, &to_tag, &dir, &dst_leg); h_entry = dlg_hash(&call_id); d_entry = &d_table->entries[h_entry]; dlg_lock(d_table, d_entry); if (!dlg) { LM_DBG("dialog not found, building new\n"); dlg = build_new_dlg(&call_id, &from_uri, &to_uri, &from_tag); if (!dlg) { LM_ERR("Failed to create replicated dialog!\n"); goto error; } return dlg_replicated_create(packet ,dlg, &from_tag, &to_tag, 0); } bin_skip_int(packet, 2); bin_pop_int(packet, &dlg->state); bin_skip_str(packet, 2); bin_pop_str(packet, &st); if (dlg_update_cseq(dlg, DLG_CALLER_LEG, &st, 0) != 0) { LM_ERR("failed to update caller cseq\n"); goto error; } bin_pop_str(packet, &st); if (dlg_update_cseq(dlg, callee_idx(dlg), &st, 0) != 0) { LM_ERR("failed to update callee cseq\n"); goto error; } bin_skip_str(packet, 6); bin_pop_str(packet, &vars); bin_pop_str(packet, &profiles); bin_pop_int(packet, &dlg->user_flags); bin_pop_int(packet, &dlg->mod_flags); bin_pop_int(packet, &rcv_flags); /* make sure an update received immediately after a create can't * incorrectly erase the DLG_FLAG_NEW before locally writing to DB */ save_new_flag = dlg->flags & DLG_FLAG_NEW; dlg->flags = rcv_flags; dlg->flags |= ((save_new_flag ? DLG_FLAG_NEW : 0) | DLG_FLAG_CHANGED); bin_pop_int(packet, &timeout); bin_skip_int(packet, 2); timeout -= time(0); LM_DBG("Received updated timeout of %d for dialog %.*s\n", timeout, call_id.len, call_id.s); if (dlg->lifetime != timeout) { dlg->lifetime = timeout; switch (update_dlg_timer(&dlg->tl, dlg->lifetime) ) { case -1: LM_ERR("failed to update dialog lifetime!\n"); /* continue */ case 0: /* timeout value was updated */ break; case 1: /* dlg inserted in timer list with new expire (reference it)*/ ref_dlg(dlg,1); } } unref_dlg_unsafe(dlg, 1, d_entry); if (vars.s && vars.len != 0) read_dialog_vars(vars.s, vars.len, dlg); dlg->flags |= DLG_FLAG_VP_CHANGED; dlg_unlock(d_table, d_entry); if (profiles.s && profiles.len != 0) read_dialog_profiles(profiles.s, profiles.len, dlg, 1, 1); return 0; error: dlg_unlock(d_table, d_entry); return -1; }