📄 lcr_mod.c
字号:
lcrs_ws_reload_counter = (unsigned int *)shm_malloc(sizeof(unsigned int)); if (lcrs_ws_reload_counter == 0) { LOG(L_ERR, "ERROR: lcr: mod_init(): " "No memory for counter\n"); goto err; } *lcrs_ws_reload_counter = reload_counter = 0; memset(from_uri_reg, 0, sizeof(struct from_uri_regex) * MAX_NO_OF_LCRS); /* First reload */ if (reload_gws() == -1) { LOG(L_CRIT, "ERROR: lcr:mod_init():" " failed to reload gateways and routes\n"); goto err; } /* Assign parameter names */ if (str2int(&gw_uri_avp, &par) == 0) { gw_uri_name.n = par; gw_uri_avp_name_str = 0; } else { gw_uri_name.s = gw_uri_avp; gw_uri_avp_name_str = AVP_NAME_STR; } if (str2int(&ruri_user_avp, &par) == 0) { ruri_user_name.n = par; ruri_user_avp_name_str = 0; } else { ruri_user_name.s = ruri_user_avp; ruri_user_avp_name_str = AVP_NAME_STR; } if (str2int(&contact_avp, &par) == 0) { contact_name.n = par; contact_avp_name_str = 0; } else { contact_name.s = contact_avp; contact_avp_name_str = AVP_NAME_STR; } if (str2int(&rpid_avp, &par) == 0) { rpid_name.n = par; rpid_avp_name_str = 0; } else { rpid_name.s = rpid_avp; rpid_avp_name_str = AVP_NAME_STR; } inv_timer_name.s = inv_timer_avp; return 0;err: return -1;}static void destroy(void){ lcr_db_close();}/* * Sort lcr records by prefix_len and priority. */static int comp_lcrs(const void *m1, const void *m2){ int result = -1; struct mi *mi1 = (struct mi *) m1; struct mi *mi2 = (struct mi *) m2; struct lcr_info lcr_record1 = (*lcrs)[mi1->route_index]; struct lcr_info lcr_record2 = (*lcrs)[mi2->route_index]; /* Sort by prefix. */ if (lcr_record1.prefix_len > lcr_record2.prefix_len) { result = 1; } else if (lcr_record1.prefix_len == lcr_record2.prefix_len) { /* Sort by priority. */ if (lcr_record1.priority < lcr_record2.priority) { result = 1; } else if (lcr_record1.priority == lcr_record2.priority) { /* Nothing to do. */ result = 0; } } return result;}/* * Sort lcr records by rand table. */static int rand_lcrs(const void *m1, const void *m2){ int result = -1; struct mi mi1 = *((struct mi *) m1); struct mi mi2 = *((struct mi *) m2); if (mi1.randomizer > mi2.randomizer) { result = 1; } else if (mi1.randomizer == mi2.randomizer) { result = 0; } return result;}/* * regcomp each from_uri. */int load_from_uri_regex(){ int i, status, result = 0; for (i = 0; i < MAX_NO_OF_LCRS; i++) { if ((*lcrs)[i].end_record != 0) { break; } if (from_uri_reg[i].valid) { regfree(&(from_uri_reg[i].re)); from_uri_reg[i].valid = 0; } memset(&(from_uri_reg[i].re), 0, sizeof(regex_t)); if ((status=regcomp(&(from_uri_reg[i].re),(*lcrs)[i].from_uri,0))!=0){ LOG(L_ERR, "ERROR:lcr:load_regex: bad from_uri re %s\n", (*lcrs)[i].from_uri); result = -1; break; } from_uri_reg[i].valid = 1; } if (result != -1) { reload_counter = *lcrs_ws_reload_counter; } return result;}/* * Reload gws to unused gw table and lcrs to unused lcr table, and, when done * make unused gw and lcr table the one in use. */int reload_gws ( void ){ int i; unsigned int ip_addr, port, strip, prefix_len, from_uri_len, grp_id, priority; uri_type scheme; uri_transport transport; db_con_t* dbh; char *prefix, *from_uri; db_res_t* res; db_row_t* row; db_key_t gw_cols[7]; db_key_t lcr_cols[4]; gw_cols[0] = ip_addr_col.s; gw_cols[1] = port_col.s; gw_cols[2] = uri_scheme_col.s; gw_cols[3] = transport_col.s; gw_cols[4] = strip_col.s; gw_cols[5] = prefix_col.s; /* FIXME: is this ok if we have different names for grp_id in the two tables? (ge vw lcr) */ gw_cols[6] = grp_id_col.s; lcr_cols[0] = prefix_col.s; lcr_cols[1] = from_uri_col.s; /* FIXME: is this ok if we have different names for grp_id in the two tables? (ge vw lcr) */ lcr_cols[2] = grp_id_col.s; lcr_cols[3] = priority_col.s; if (lcr_dbf.init==0){ LOG(L_CRIT, "ERROR: lcr_db_ver: unbound database\n"); return -1; } dbh=lcr_dbf.init(db_url.s); if (dbh==0){ LOG(L_ERR, "ERROR: reload_gws: unable to open database connection\n"); return -1; } if (lcr_dbf.use_table(dbh, gw_table.s) < 0) { LOG(L_ERR, "lcr_reload_gws(): Error while trying to use gw table\n"); return -1; } if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 7, 0, &res) < 0) { LOG(L_ERR, "lcr_reload_gws(): Failed to query gw data\n"); lcr_dbf.close(dbh); return -1; } if (RES_ROW_N(res) + 1 > MAX_NO_OF_GWS) { LOG(L_ERR, "reload_gws(): Too many gateways\n"); lcr_dbf.free_result(dbh, res); lcr_dbf.close(dbh); return -1; } for (i = 0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; if (VAL_NULL(ROW_VALUES(row)) == 1) { LOG(L_ERR, "reload_gws(): IP address of GW is NULL\n"); lcr_dbf.free_result(dbh, res); lcr_dbf.close(dbh); return -1; } ip_addr = (unsigned int)VAL_INT(ROW_VALUES(row)); if (VAL_NULL(ROW_VALUES(row) + 1) == 1) { port = 0; } else { port = (unsigned int)VAL_INT(ROW_VALUES(row) + 1); } if (port > 65536) { LOG(L_ERR, "reload_gws(): Port of GW is too large: %u\n", port); lcr_dbf.free_result(dbh, res); lcr_dbf.close(dbh); return -1; } if (VAL_NULL(ROW_VALUES(row) + 2) == 1) { scheme = SIP_URI_T; } else { scheme = (uri_type)VAL_INT(ROW_VALUES(row) + 2); if ((scheme != SIP_URI_T) && (scheme != SIPS_URI_T)) { LOG(L_ERR, "reload_gws(): Unknown or unsupported URI scheme: %u\n", (unsigned int)scheme); lcr_dbf.free_result(dbh, res); lcr_dbf.close(dbh); return -1; } } if (VAL_NULL(ROW_VALUES(row) + 3) == 1) { transport = PROTO_NONE; } else { transport = (uri_transport)VAL_INT(ROW_VALUES(row) + 3); if ((transport != PROTO_UDP) && (transport != PROTO_TCP) && (transport != PROTO_TLS)) { LOG(L_ERR, "reload_gws(): Unknown or unsupported transport: %u\n", (unsigned int)transport); lcr_dbf.free_result(dbh, res); lcr_dbf.close(dbh); return -1; } } if (VAL_NULL(ROW_VALUES(row) + 4) == 1) { strip = 0; } else { strip = (unsigned int)VAL_INT(ROW_VALUES(row) + 4); } if (VAL_NULL(ROW_VALUES(row) + 5) == 1) { prefix_len = 0; prefix = (char *)0; } else { prefix = (char *)VAL_STRING(ROW_VALUES(row) + 5); prefix_len = strlen(prefix); if (prefix_len > MAX_PREFIX_LEN) { LOG(L_ERR, "reload_gws(): too long gw prefix\n"); lcr_dbf.free_result(dbh, res); lcr_dbf.close(dbh); return -1; } } if (VAL_NULL(ROW_VALUES(row) + 6) == 1) { grp_id = 0; } else { grp_id = VAL_INT(ROW_VALUES(row) + 6); } if (*gws == gws_1) { gws_2[i].ip_addr = ip_addr; gws_2[i].port = port; gws_2[i].grp_id = grp_id; gws_2[i].scheme = scheme; gws_2[i].transport = transport; gws_2[i].strip = strip; gws_2[i].prefix_len = prefix_len; if (prefix_len) memcpy(&(gws_2[i].prefix[0]), prefix, prefix_len); } else { gws_1[i].ip_addr = ip_addr; gws_1[i].port = port; gws_1[i].grp_id = grp_id; gws_1[i].scheme = scheme; gws_1[i].transport = transport; gws_1[i].strip = strip; gws_1[i].prefix_len = prefix_len; if (prefix_len) memcpy(&(gws_1[i].prefix[0]), prefix, prefix_len); } } lcr_dbf.free_result(dbh, res); if (*gws == gws_1) { gws_2[i].ip_addr = 0; *gws = gws_2; } else { gws_1[i].ip_addr = 0; *gws = gws_1; } if (lcr_dbf.use_table(dbh, lcr_table.s) < 0) { LOG(L_ERR, "lcr_reload_gws(): Error while trying to use lcr table\n"); return -1; } if (lcr_dbf.query(dbh, NULL, 0, NULL, lcr_cols, 0, 4, 0, &res) < 0) { LOG(L_ERR, "lcr_reload_gws(): Failed to query lcr data\n"); lcr_dbf.close(dbh); return -1; } if (RES_ROW_N(res) + 1 > MAX_NO_OF_LCRS) { LOG(L_ERR, "reload_gws(): Too many lcr entries\n"); lcr_dbf.free_result(dbh, res); lcr_dbf.close(dbh); return -1; } for (i = 0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; if (VAL_NULL(ROW_VALUES(row)) == 1) { prefix_len = 0; prefix = 0; } else { prefix = (char *)VAL_STRING(ROW_VALUES(row)); prefix_len = strlen(prefix); if (prefix_len > MAX_PREFIX_LEN) { LOG(L_ERR, "reload_gws(): too long lcr prefix\n"); lcr_dbf.free_result(dbh, res); lcr_dbf.close(dbh); return -1; } } if (VAL_NULL(ROW_VALUES(row) + 1) == 1) { from_uri_len = 0; from_uri = 0; } else { from_uri = (char *)VAL_STRING(ROW_VALUES(row) + 1); from_uri_len = strlen(from_uri); if (from_uri_len > MAX_FROM_URI_LEN) { LOG(L_ERR, "reload_gws(): too long from_uri\n"); lcr_dbf.free_result(dbh, res); lcr_dbf.close(dbh); return -1; } } if (VAL_NULL(ROW_VALUES(row) + 2) == 1) { LOG(L_ERR, "reload_gws(): route grp_id is NULL\n"); lcr_dbf.free_result(dbh, res); lcr_dbf.close(dbh); return -1; } grp_id = (unsigned int)VAL_INT(ROW_VALUES(row) + 2); if (VAL_NULL(ROW_VALUES(row) + 3) == 1) { LOG(L_ERR, "reload_gws(): route priority is NULL\n"); lcr_dbf.free_result(dbh, res); lcr_dbf.close(dbh); return -1; } priority = (unsigned int)VAL_INT(ROW_VALUES(row) + 3); if (*lcrs == lcrs_1) { lcrs_2[i].prefix_len = prefix_len; if (prefix_len) memcpy(&(lcrs_2[i].prefix[0]), prefix, prefix_len); lcrs_2[i].from_uri_len = from_uri_len; if (from_uri_len) { memcpy(&(lcrs_2[i].from_uri[0]), from_uri, from_uri_len); lcrs_2[i].from_uri[from_uri_len] = '\0'; } lcrs_2[i].grp_id = grp_id; lcrs_2[i].priority = priority; lcrs_2[i].end_record = 0; } else { lcrs_1[i].prefix_len = prefix_len; if (prefix_len) memcpy(&(lcrs_1[i].prefix[0]), prefix, prefix_len); lcrs_1[i].from_uri_len = from_uri_len; if (from_uri_len) { memcpy(&(lcrs_1[i].from_uri[0]), from_uri, from_uri_len); lcrs_1[i].from_uri[from_uri_len] = '\0'; } lcrs_1[i].grp_id = grp_id; lcrs_1[i].priority = priority; lcrs_1[i].end_record = 0; } } lcr_dbf.free_result(dbh, res); lcr_dbf.close(dbh); if (*lcrs == lcrs_1) { lcrs_2[i].end_record = 1; *lcrs = lcrs_2; } else { lcrs_1[i].end_record = 1; *lcrs = lcrs_1; } (*lcrs_ws_reload_counter)++; if (0 != load_from_uri_regex()) { return -1; } return 1;}/* Print gateways stored in current gw table */void print_gws (FILE *reply_file){ unsigned int i, prefix_len; uri_transport transport; for (i = 0; i < MAX_NO_OF_GWS; i++) { if ((*gws)[i].ip_addr == 0) { break; } fprintf(reply_file, "%d => ", i); fprintf(reply_file, "%d:", (*gws)[i].grp_id); if ((*gws)[i].scheme == SIP_URI_T) { fprintf(reply_file, "sip:"); } else { fprintf(reply_file, "sips:"); } if ((*gws)[i].port == 0) { fprintf(reply_file, "%d.%d.%d.%d", ((*gws)[i].ip_addr << 24) >> 24, (((*gws)[i].ip_addr >> 8) << 24) >> 24, (((*gws)[i].ip_addr >> 16) << 24) >> 24, (*gws)[i].ip_addr >> 24); } else { fprintf(reply_file, "%d.%d.%d.%d:%d", ((*gws)[i].ip_addr << 24) >> 24, (((*gws)[i].ip_addr >> 8) << 24) >> 24, (((*gws)[i].ip_addr >> 16) << 24) >> 24, (*gws)[i].ip_addr >> 24, (*gws)[i].port); } transport = (*gws)[i].transport; if (transport == PROTO_UDP) { fprintf(reply_file, ":udp"); } else if (transport == PROTO_TCP) { fprintf(reply_file, ":tcp"); } else if (transport == PROTO_TLS) { fprintf(reply_file, ":tls"); } else { fprintf(reply_file, ":"); } fprintf(reply_file, ":%d", (*gws)[i].strip); prefix_len = (*gws)[i].prefix_len; if (prefix_len) { fprintf(reply_file, ":%.*s\n", (int)prefix_len, (*gws)[i].prefix); } else { fprintf(reply_file, ":\n"); } } for (i = 0; i < MAX_NO_OF_LCRS; i++) { if ((*lcrs)[i].end_record != 0) { break; } fprintf(reply_file, "%d => ", i); fprintf(reply_file, "%.*s", (*lcrs)[i].prefix_len, (*lcrs)[i].prefix); fprintf(reply_file, ":%.*s", (*lcrs)[i].from_uri_len, (*lcrs)[i].from_uri); fprintf(reply_file, ":%u", (*lcrs)[i].grp_id); fprintf(reply_file, ":%u\n", (*lcrs)[i].priority); }}/* * Load info of matching GWs from database to gw_uri AVPs */static int do_load_gws(struct sip_msg* _m, int grp_id){ db_res_t* res; db_row_t *row, *r; unsigned int q_len; str ruri_user, from_uri, value; char from_uri_str[MAX_FROM_URI_LEN + 1]; char query[MAX_QUERY_SIZE]; char ruri[MAX_URI_SIZE]; unsigned int i, j, k, index; unsigned int addr, port; unsigned int strip, gw_index, duplicated_gw;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -