From e00771b4fa5aee1402eb1f0529ef5bb9de12d1ba Mon Sep 17 00:00:00 2001 From: Andreas Granig Date: Mon, 10 Oct 2016 12:51:41 +0200 Subject: [PATCH] TT#3990 Undo stop-rec processing but use pbx/xfer Revert logic to pick peer id from stop record. This needs a better approach somehow. Instead, add logic to always take -pbx_1 and -xfer_1 stop records into account when searching for stop records, to fix duration of CDRs on transfer and park/unpark (which is just a special case of transfer). Change-Id: Ia80add6d5cb762800c563889c0d95ee25ed74168 --- cdr.c | 61 ++++----------------------- config.c | 7 +--- config.h | 1 - debian/mediator.default | 1 - debian/mediator.init | 1 - mediator.c | 6 +-- mediator.h | 8 +--- medmysql.c | 92 ++++++++++++++++++++++------------------- medmysql.h | 2 +- 9 files changed, 62 insertions(+), 117 deletions(-) diff --git a/cdr.c b/cdr.c index 409c955..391db7f 100644 --- a/cdr.c +++ b/cdr.c @@ -40,7 +40,7 @@ static const char* cdr_map_status(const char *sip_status) int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_count, struct medmysql_batches *batches) { - int ret; + int ret = 0; u_int8_t trash = 0; u_int64_t i; @@ -50,7 +50,6 @@ int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_co u_int16_t invite_200 = 0; char *callid = records[0].callid; - int cid_len; cdr_entry_t *cdrs; @@ -61,37 +60,19 @@ int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_co for(i = 0; i < count; ++i) { med_entry_t *e = &(records[i]); - - if (config_pbx_stop_records) { - cid_len = strlen(e->callid); - if (cid_len >= PBX_SUFFIX_LEN - && strcmp(e->callid + cid_len - PBX_SUFFIX_LEN, PBX_SUFFIX) == 0) - { - e->is_pbx = 1; - e->callid[cid_len - PBX_SUFFIX_LEN] = '\0'; /* truncate in place */ - e->valid = 0; - } - } - - /* For pbx records, we ignore everything other than bye records. For regular records, - * we ignore only the stop record. */ - if(strcmp(e->sip_method, MSG_INVITE) == 0) { + ++msg_invites; e->method = MED_INVITE; - if (!e->is_pbx && e->valid) { - ++msg_invites; - if(strncmp("200", e->sip_code, 3) == 0) - { - ++invite_200; - } + if(strncmp("200", e->sip_code, 3) == 0) + { + ++invite_200; } } else if(strcmp(e->sip_method, MSG_BYE) == 0) { + ++msg_byes; e->method = MED_BYE; - if (!e->is_pbx && e->valid) - ++msg_byes; } else { @@ -117,14 +98,7 @@ int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_co } else { - ret = cdr_create_cdrs(records, count, &cdrs, &cdr_count, &trash); - - if (ret == 1) { - // insufficient data - don't trash and wait - return 0; - } - - if(ret != 0) + if(cdr_create_cdrs(records, count, &cdrs, &cdr_count, &trash) != 0) goto error; else { @@ -172,7 +146,7 @@ int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_co if(medmysql_trash_entries(callid, batches) != 0) goto error; } - return 0; + return ret; error: @@ -377,7 +351,6 @@ static int cdr_parse_srcleg(char *srcleg, cdr_entry_t *cdr) g_strlcpy(cdr->source_gpp[i], tmp2, sizeof(cdr->source_gpp[i])); tmp2 = ++tmp1; } - tmp1 = strchr(tmp2, MED_SEP); if(tmp1 == NULL) { @@ -547,7 +520,6 @@ static int cdr_create_cdrs(med_entry_t *records, u_int64_t count, char *endtime = NULL; double unix_endtime = 0, tmp_unix_endtime = 0; const char *call_status; - med_entry_t *pbx_record = NULL; *cdr_count = 0; @@ -560,8 +532,6 @@ static int cdr_create_cdrs(med_entry_t *records, u_int64_t count, { ++invites; } - else if (e->is_pbx) - pbx_record = e; else if(e->method == MED_BYE && endtime == NULL) { endtime = e->timestamp; @@ -639,15 +609,6 @@ static int cdr_create_cdrs(med_entry_t *records, u_int64_t count, *trash = 1; return 0; } - - if (config_pbx_stop_records && !strcmp(cdr->destination_user_id, "0")) { - if (!pbx_record) { - // insufficient data - wait - free(*cdrs); - return 1; - } - cdr->destination_lcr_id = atoll(pbx_record->dst_leg); - } if(cdr_fill_record(cdr) != 0) { @@ -722,12 +683,6 @@ void cdr_set_provider(cdr_entry_t *cdr) else if (cdr->destination_lcr_id) { snprintf(cdr->destination_provider_id, sizeof(cdr->destination_provider_id), "%llu", (unsigned long long) cdr->destination_lcr_id); - if (config_pbx_stop_records) { - // lcr_id determines the destination peer host name - val = g_hash_table_lookup(med_peer_id_hostname_table, cdr->destination_provider_id); - if (val) - g_strlcpy(cdr->destination_domain, val, sizeof(cdr->destination_domain)); - } val = g_hash_table_lookup(med_peer_id_table, cdr->destination_provider_id); g_strlcpy(cdr->destination_provider_id, val ? : "0", sizeof(cdr->destination_provider_id)); } diff --git a/config.c b/config.c index ba50933..2050917 100644 --- a/config.c +++ b/config.c @@ -7,7 +7,6 @@ unsigned int config_interval = MEDIATOR_DEFAULT_INTERVAL; u_int8_t config_dumpcdr = MEDIATOR_DEFAULT_DUMPCDR; u_int8_t config_daemonize = MEDIATOR_DEFAULT_DAEMONIZE; char *config_pid_path = MEDIATOR_DEFAULT_PIDPATH; -int config_pbx_stop_records; char *config_med_host = MEDIATOR_DEFAULT_ACCHOST; char *config_med_user = MEDIATOR_DEFAULT_ACCUSER; @@ -64,7 +63,6 @@ static void config_help(const char *self) " -d\tEnables daemonization of the process (default = disabled).\n" \ " -l\tEnables dumping of CDRs to syslog (default = disabled).\n" \ " -i\tThe creation interval (default = %d).\n" \ - " -s\tExpect additional stop records (default = disabled).\n" \ " -h\tThe ACC db host (default = '%s').\n" \ " -o\tThe ACC db port (default = '%d').\n" \ " -u\tThe ACC db user (default = '%s').\n" \ @@ -99,7 +97,7 @@ int config_parse_cmdopts(int argc, char **argv) { int c; - while((c = getopt(argc, argv, "D:i:dl?sh:u:p:b:o:H:U:P:B:O:S:T:R:A:N:Z:z:W:w:X:x:")) != -1) + while((c = getopt(argc, argv, "D:i:dl?h:u:p:b:o:H:U:P:B:O:S:T:R:A:N:Z:z:W:w:X:x:")) != -1) { if(c == '?') { @@ -114,9 +112,6 @@ int config_parse_cmdopts(int argc, char **argv) { config_dumpcdr = 1; } - else if (c == 's') - config_pbx_stop_records = 1; - else if(c == 'D') { config_pid_path = (char*)strdup(optarg); diff --git a/config.h b/config.h index 90284e9..cd5f430 100644 --- a/config.h +++ b/config.h @@ -7,7 +7,6 @@ extern u_int8_t config_daemonize; extern char *config_pid_path; extern char *config_hostname; -extern int config_pbx_stop_records; extern char *config_med_host; extern unsigned int config_med_port; diff --git a/debian/mediator.default b/debian/mediator.default index 799f6b2..ca75655 100644 --- a/debian/mediator.default +++ b/debian/mediator.default @@ -23,4 +23,3 @@ STATS_USER="mediator" STATS_PASS='GimmeAllUr$$$' STATS_DB="stats" STATS_PERIOD=1 -PEER_PBX_STOP_RECORDS=0 diff --git a/debian/mediator.init b/debian/mediator.init index ca0c959..82541c9 100755 --- a/debian/mediator.init +++ b/debian/mediator.init @@ -65,7 +65,6 @@ OPTIONS="" [ -z "$STATS_PASS" ] || OPTIONS="$OPTIONS -w $STATS_PASS" [ -z "$STATS_DB" ] || OPTIONS="$OPTIONS -X $STATS_DB" [ -z "$STATS_PERIOD" ] || OPTIONS="$OPTIONS -x $STATS_PERIOD" -[ "$PEER_PBX_STOP_RECORDS" = "0" ] || OPTIONS="$OPTIONS -s" if test "$FORK" = "yes" ; then OPTIONS="$OPTIONS -d" fi diff --git a/mediator.c b/mediator.c index ac5e5e6..3132344 100644 --- a/mediator.c +++ b/mediator.c @@ -26,8 +26,6 @@ GHashTable *med_peer_host_table = NULL; GHashTable *med_peer_id_table = NULL; GHashTable *med_uuid_table = NULL; GHashTable *med_call_stat_info_table = NULL; -GHashTable *med_peer_id_host_table = NULL; -GHashTable *med_peer_id_hostname_table = NULL; /**********************************************************************/ static int mediator_load_maps() @@ -36,10 +34,8 @@ static int mediator_load_maps() med_peer_host_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); med_peer_id_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); med_uuid_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); - med_peer_id_host_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); - med_peer_id_hostname_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); - if(medmysql_load_maps()) + if(medmysql_load_maps(med_peer_ip_table, med_peer_host_table, med_peer_id_table)) return -1; if(medmysql_load_uuids(med_uuid_table)) return -1; diff --git a/mediator.h b/mediator.h index 44589b2..8aa5da8 100644 --- a/mediator.h +++ b/mediator.h @@ -53,16 +53,13 @@ #define MED_SEP '|' -#define PBX_SUFFIX "_pbx-1" -#define PBX_SUFFIX_LEN strlen(PBX_SUFFIX) - extern int mediator_lockfd; extern sig_atomic_t mediator_shutdown; typedef enum { MED_INVITE = 1, MED_BYE = 2, - MED_UNRECOGNIZED = 3, + MED_UNRECOGNIZED = 3 } med_method_t; @@ -77,7 +74,6 @@ typedef struct { u_int8_t valid; med_method_t method; char sip_method[32]; - int is_pbx; } med_entry_t; typedef struct { @@ -89,8 +85,6 @@ extern GHashTable *med_peer_ip_table; extern GHashTable *med_peer_id_table; extern GHashTable *med_uuid_table; extern GHashTable *med_call_stat_info_table; -extern GHashTable *med_peer_id_host_table; -extern GHashTable *med_peer_id_hostname_table; void critical(const char *); diff --git a/medmysql.c b/medmysql.c index 0d0e3d5..b7a9a95 100644 --- a/medmysql.c +++ b/medmysql.c @@ -6,17 +6,45 @@ #include "medmysql.h" #include "config.h" -/*#define MED_CALLID_QUERY "(select a.callid, a.time from acc a, acc b where a.callid = b.callid and a.method = 'INVITE' and b.method = 'BYE' group by callid) union (select callid, time from acc where method = 'INVITE' and sip_code != '200') order by time asc limit 0,200000"*/ -#define MED_CALLID_QUERY "select a.callid from acc a left join acc b on a.callid = b.callid and b.method = 'BYE' where a.method = 'INVITE' and (a.sip_code != '200' or b.id is not null) group by a.callid limit 0,200000" - -#define MED_FETCH_QUERY "select distinct sip_code, sip_reason, method, callid, time, time_hires, " \ +#define PBXSUFFIX "_pbx-1" +#define XFERSUFFIX "_xfer-1" + +#define MED_CALLID_QUERY "select a.callid from acc a" \ + " where a.method = 'INVITE' " \ + " and (a.sip_code != '200' " \ + " OR EXISTS " \ + " (select b.id from acc b " \ + " where b.callid = a.callid " \ + " and b.method = 'BYE' " \ + " limit 1) " \ + " OR EXISTS " \ + " (select b.id from acc b " \ + " where b.callid = concat(a.callid, '"PBXSUFFIX"') " \ + " and b.method = 'BYE' " \ + " limit 1) " \ + " OR EXISTS " \ + " (select b.id from acc b " \ + " where b.callid = concat(a.callid, '"XFERSUFFIX"') " \ + " and b.method = 'BYE' " \ + " limit 1) " \ + " ) " \ + " group by a.callid limit 0,200000" + +#define MED_FETCH_QUERY "(select distinct sip_code, sip_reason, method, callid, time, time_hires, " \ + "src_leg, dst_leg " \ + "from acc where method = 'INVITE' and callid = '%s' order by time_hires asc) " \ + "union all " \ + "(select distinct sip_code, sip_reason, method, callid, time, time_hires, " \ "src_leg, dst_leg " \ - "from acc where callid = '%s' order by time_hires asc" -#define MED_FETCH_QUERY_PBX "select distinct sip_code, sip_reason, method, callid, time, time_hires, " \ + "from acc where method = 'BYE' and callid in ('%s', '%s"PBXSUFFIX"') " \ + "order by length(callid) asc, time_hires asc) " \ + "union all " \ + "(select distinct sip_code, sip_reason, method, callid, time, time_hires, " \ "src_leg, dst_leg " \ - "from acc where callid = '%s' or callid = '%s"PBX_SUFFIX"' order by time_hires asc" + "from acc where method = 'BYE' and callid in ('%s', '%s"XFERSUFFIX"') " \ + "order by length(callid) asc, time_hires asc)" -#define MED_LOAD_PEER_QUERY "select h.ip, h.host, g.peering_contract_id, h.id, h.name " \ +#define MED_LOAD_PEER_QUERY "select h.ip, h.host, g.peering_contract_id, h.id " \ "from provisioning.voip_peer_hosts h, provisioning.voip_peer_groups g " \ "where g.id = h.group_id" #define MED_LOAD_UUID_QUERY "select vs.uuid, r.contract_id from billing.voip_subscribers vs, " \ @@ -226,10 +254,10 @@ int medmysql_fetch_records(med_callid_t *callid, *count = 0; - if (!config_pbx_stop_records) - snprintf(query, sizeof(query), MED_FETCH_QUERY, callid->value); - else - snprintf(query, sizeof(query), MED_FETCH_QUERY_PBX, callid->value, callid->value); + snprintf(query, sizeof(query), MED_FETCH_QUERY, + callid->value, + callid->value, callid->value, + callid->value, callid->value); /*syslog(LOG_DEBUG, "q='%s'", query);*/ @@ -298,10 +326,6 @@ int medmysql_trash_entries(const char *callid, struct medmysql_batches *batches) batches->acc_trash.len += sprintf(batches->acc_trash.str + batches->acc_trash.len, "'%s',", callid); - if (config_pbx_stop_records) - batches->acc_trash.len += sprintf(batches->acc_trash.str + batches->acc_trash.len, - "'%s"PBX_SUFFIX"',", callid); - return medmysql_delete_entries(callid, batches); } @@ -318,10 +342,6 @@ int medmysql_backup_entries(const char *callid, struct medmysql_batches *batches batches->acc_backup.len += sprintf(batches->acc_backup.str + batches->acc_backup.len, "'%s',", callid); - if (config_pbx_stop_records) - batches->acc_backup.len += sprintf(batches->acc_backup.str + batches->acc_backup.len, - "'%s"PBX_SUFFIX"',", callid); - return medmysql_delete_entries(callid, batches); } @@ -343,10 +363,6 @@ int medmysql_delete_entries(const char *callid, struct medmysql_batches *batches batches->to_delete.len += sprintf(batches->to_delete.str + batches->to_delete.len, "'%s',", callid); - if (config_pbx_stop_records) - batches->to_delete.len += sprintf(batches->to_delete.str + batches->to_delete.len, - "'%s"PBX_SUFFIX"',", callid); - return 0; } @@ -383,7 +399,7 @@ int medmysql_insert_cdrs(cdr_entry_t *entries, u_int64_t count, struct medmysql_ "source_gpp5, source_gpp6, source_gpp7, source_gpp8, source_gpp9, " \ "destination_gpp0, destination_gpp1, destination_gpp2, destination_gpp3, destination_gpp4, " \ "destination_gpp5, destination_gpp6, destination_gpp7, destination_gpp8, destination_gpp9, " \ - "source_lnp_prefix, destination_lnp_prefix" \ + "source_lnp_prefix, destination_lnp_prefix" \ ") values "); } @@ -579,7 +595,7 @@ int medmysql_update_call_stat_info(const char *call_code, const double start_tim } /**********************************************************************/ -int medmysql_load_maps() +int medmysql_load_maps(GHashTable *ip_table, GHashTable *host_table, GHashTable *id_table) { MYSQL_RES *res; MYSQL_ROW row; @@ -607,30 +623,22 @@ int medmysql_load_maps() goto out; } - if(med_peer_ip_table != NULL) + if(ip_table != NULL) { - if(g_hash_table_lookup(med_peer_ip_table, row[0]) != NULL) + if(g_hash_table_lookup(ip_table, row[0]) != NULL) syslog(LOG_WARNING, "Skipping duplicate IP '%s'", row[0]); else - g_hash_table_insert(med_peer_ip_table, strdup(row[0]), strdup(row[2])); + g_hash_table_insert(ip_table, strdup(row[0]), strdup(row[2])); } - if(med_peer_host_table != NULL && row[1] != NULL) // host column is optional + if(host_table != NULL && row[1] != NULL) // host column is optional { - if(g_hash_table_lookup(med_peer_host_table, row[1]) != NULL) + if(g_hash_table_lookup(host_table, row[1]) != NULL) syslog(LOG_WARNING, "Skipping duplicate host '%s'", row[1]); else - g_hash_table_insert(med_peer_host_table, strdup(row[1]), strdup(row[2])); - } - if (med_peer_id_table) - g_hash_table_insert(med_peer_id_table, strdup(row[3]), strdup(row[2])); - if (med_peer_id_host_table) { - if (row[1] && *row[1]) - g_hash_table_insert(med_peer_id_host_table, strdup(row[3]), strdup(row[1])); - else - g_hash_table_insert(med_peer_id_host_table, strdup(row[3]), strdup(row[0])); + g_hash_table_insert(host_table, strdup(row[1]), strdup(row[2])); } - if (med_peer_id_hostname_table) - g_hash_table_insert(med_peer_id_hostname_table, strdup(row[3]), strdup(row[4])); + if (id_table) + g_hash_table_insert(id_table, strdup(row[3]), strdup(row[2])); } out: diff --git a/medmysql.h b/medmysql.h index 6dab0f1..7b43e54 100644 --- a/medmysql.h +++ b/medmysql.h @@ -36,7 +36,7 @@ int medmysql_trash_entries(const char *callid, struct medmysql_batches *); int medmysql_backup_entries(const char *callid, struct medmysql_batches *); int medmysql_delete_entries(const char *callid, struct medmysql_batches *); int medmysql_insert_cdrs(cdr_entry_t *records, u_int64_t count, struct medmysql_batches *); -int medmysql_load_maps(); +int medmysql_load_maps(GHashTable *ip_table, GHashTable *host_table, GHashTable *id_table); int medmysql_load_uuids(GHashTable *uuid_table); int medmysql_batch_start(struct medmysql_batches *); int medmysql_batch_end(struct medmysql_batches *);