/* restore callbacks */ void acc_loaded_callback(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) { str flags_s; unsigned int flags_l; if (!dlg) { LM_ERR("null dialog - cannot fetch message flags\n"); return; } if (dlg_api.fetch_dlg_value(dlg, &flags_str, &flags_s, 0) < 0) { LM_DBG("flags were not saved in dialog\n"); return; } flags_l = flag_list_to_bitmask(&flags_s, FLAG_TYPE_MSG, FLAG_DELIM); /* register database callbacks */ if (dlg_api.register_dlgcb(dlg, DLGCB_TERMINATED | DLGCB_EXPIRED, acc_dlg_callback, (void*)(long)flags_l, 0)){ LM_ERR("cannot register callback for database accounting\n"); return; } }
static int get_all_db_ucontacts(void *buf, int len, unsigned int flags, unsigned int part_idx, unsigned int part_max) { static char query_buf[512]; static str query_str; static struct sip_uri puri; struct socket_info *sock; struct proxy_l next_hop; db_res_t *res = NULL; db_row_t *row; db_val_t *val; dlist_t *dom; str uri, host, flag_list; int i, no_rows = 10; int now_len; char now_s[25]; char *p, *p1; int port, proto, p_len, p1_len; unsigned int dbflags; int needed; int shortage = 0; shortage = 0; /* Reserve space for terminating 0000 */ len -= sizeof p_len; /* get the current time in DB format */ now_len = 25; if (db_time2str(time(NULL), now_s, &now_len) != 0) { LM_ERR("failed to print now time\n"); return -1; } LM_DBG("buf: %p. flags: %d\n", buf, flags); /* for each table */ for (dom = root; dom; dom = dom->next) { if (db_check_table_version(&ul_dbf, ul_dbh, dom->d->name, UL_TABLE_VERSION)) goto error; /* read the destinations */ if (ul_dbf.use_table(ul_dbh, dom->d->name) < 0) { LM_ERR("cannot select table \"%.*s\"\n", dom->d->name->len, dom->d->name->s); goto error; } i = snprintf(query_buf, sizeof query_buf, "select %.*s, %.*s, %.*s," #ifdef ORACLE_USRLOC " %.*s, %.*s from %s where %.*s > %.*s and mod(id, %u) = %u", #else " %.*s, %.*s from %s where %.*s > %.*s and id %% %u = %u", #endif received_col.len, received_col.s, contact_col.len, contact_col.s, sock_col.len, sock_col.s, cflags_col.len, cflags_col.s, path_col.len, path_col.s, dom->d->name->s, expires_col.len, expires_col.s, now_len, now_s, part_max, part_idx); LM_DBG("query: %.*s\n", (int)(sizeof query_buf), query_buf); if (i >= sizeof query_buf) { LM_ERR("DB query too long\n"); goto error; } query_str.s = query_buf; query_str.len = i; if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) { if (ul_dbf.raw_query(ul_dbh, &query_str, 0) < 0) { LM_ERR("raw_query failed\n"); goto error; } no_rows = estimate_available_rows(20+128+20+128+64, 5); if (no_rows == 0) no_rows = 10; LM_DBG("fetching %d rows\n", no_rows); if (ul_dbf.fetch_result(ul_dbh, &res, no_rows) < 0) { LM_ERR("Error fetching rows\n"); goto error; } } else if (ul_dbf.raw_query(ul_dbh, &query_str, &res) < 0) { LM_ERR("raw_query failed\n"); goto error; } do { for (i = 0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; val = ROW_VALUES(row) + 3; /* cflags */ flag_list.s = (char *)VAL_STRING(val); flag_list.len = strlen(flag_list.s); LM_DBG("contact cflags: '%.*s'\n", flag_list.len, flag_list.s); /* contact is not flagged at all */ if (flags && (val->nul || !flag_list.s)) continue; dbflags = flag_list_to_bitmask(&flag_list, FLAG_TYPE_BRANCH, FLAG_DELIM); LM_DBG("masks: param: %d --- %d :db\n", flags, dbflags); /* check if contact flags match the given bitmask */ if ((dbflags & flags) != flags) continue; /* received */ p = (char*)VAL_STRING(ROW_VALUES(row)); if (VAL_NULL(ROW_VALUES(row)) || !p || !p[0]) { /* contact */ p = (char*)VAL_STRING(ROW_VALUES(row) + 1); if (VAL_NULL(ROW_VALUES(row) + 1) || !p || *p == '\0') { LM_ERR("empty contact -> skipping\n"); continue; } } p_len = strlen(p); /* path */ p1 = (char*)VAL_STRING(ROW_VALUES(row) + 4); if (VAL_NULL(ROW_VALUES(row) + 4) || !p1 || *p1 == '\0') { p1 = NULL; p1_len = 0; } else p1_len = strlen(p1); needed = (int)(p_len + sizeof p_len + p1_len + sizeof p1_len + sizeof sock + sizeof dbflags + sizeof next_hop); LM_DBG("len: %d, needed: %d\n", len, needed); if (len < needed) { shortage += needed; continue; } /* determine and parse the URI of this contact's next hop */ if (p1_len > 0) { /* send to first URI in path */ host.s = p1; host.len = p1_len; if (get_path_dst_uri(&host, &uri) < 0) { LM_ERR("failed to get dst_uri for Path\n"); continue; } if (parse_uri(uri.s, uri.len, &puri) < 0) { LM_ERR("failed to parse path URI of next hop: '%*.s'\n", p1_len, p1); return -1; } } else { if (parse_uri(p, p_len, &puri) < 0) { LM_ERR("failed to parse contact of next hop: '%*.s'\n", p_len, p); return -1; } } /* write received/contact */ memcpy(buf, &p_len, sizeof p_len); buf += sizeof p_len; memcpy(buf, p, p_len); buf += p_len; /* write path */ memcpy(buf, &p1_len, sizeof p1_len); buf += sizeof p1_len; memcpy(buf, p1, p1_len); buf += p1_len; /* sock */ p = (char*)VAL_STRING(ROW_VALUES(row) + 2); if (VAL_NULL(ROW_VALUES(row)+2) || !p || *p == '\0') { sock = NULL; } else { if (parse_phostport(p, strlen(p), &host.s, &host.len, &port, &proto) != 0) { LM_ERR("bad socket <%s>...ignoring\n", p); sock = NULL; } else { sock = grep_sock_info(&host, (unsigned short)port, proto); if (!sock) LM_DBG("non-local socket <%s>...ignoring\n", p); } } /* write sock and flags */ memcpy(buf, &sock, sizeof sock); buf += sizeof sock; memcpy(buf, &dbflags, sizeof dbflags); buf += sizeof dbflags; memset(&next_hop, 0, sizeof next_hop); next_hop.port = puri.port_no; next_hop.proto = puri.proto; next_hop.name = puri.host; /* write the next hop */ memcpy(buf, &next_hop, sizeof next_hop); buf += sizeof next_hop; len -= needed; } if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) { if (ul_dbf.fetch_result(ul_dbh, &res, no_rows) < 0) { LM_ERR("fetching rows (1)\n"); goto error; } } else break; } while (RES_ROW_N(res) > 0); ul_dbf.free_result(ul_dbh, res); } /* len < 0 is possible, if size of the buffer < sizeof c->c.len */ if (len >= 0) memset(buf, 0, sizeof p_len); /* Shouldn't happen */ if (shortage > 0 && len > shortage) abort(); shortage -= len; return shortage > 0 ? shortage : 0; error: if (res) ul_dbf.free_result(ul_dbh, res); return -1; }