00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00030 #include "../../dprint.h"
00031 #include "../../mem/mem.h"
00032 #include "../../mem/shm_mem.h"
00033 #include "carrierroute.h"
00034 #include "cr_db.h"
00035 #include "cr_carrier.h"
00036 #include "config.h"
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039
00040 #define QUERY_LEN 2048
00041
00042 static char query[QUERY_LEN];
00043
00044 str * columns[COLUMN_NUM] = { &carrierroute_id_col, &carrierroute_carrier_col,
00045 &carrierroute_domain_col,
00046 &carrierroute_scan_prefix_col,
00047 &carrierroute_flags_col,
00048 &carrierroute_mask_col,
00049 &carrierroute_prob_col,
00050 &carrierroute_rewrite_host_col,
00051 &carrierroute_strip_col,
00052 &carrierroute_rewrite_prefix_col,
00053 &carrierroute_rewrite_suffix_col,
00054 &carrierroute_description_col
00055 };
00056
00057 str * carrier_name_columns[CARRIER_NAME_COLUMN_NUM] = {
00058 &carrier_name_id_col,
00059 &carrier_name_carrier_col
00060 };
00061
00062 str * domain_name_columns[DOMAIN_NAME_COLUMN_NUM] = {
00063 &domain_name_id_col,
00064 &domain_name_domain_col
00065 };
00066
00067 str * failure_columns[FAILURE_COLUMN_NUM] = {
00068 &carrierfailureroute_id_col,
00069 &carrierfailureroute_carrier_col,
00070 &carrierfailureroute_domain_col,
00071 &carrierfailureroute_scan_prefix_col,
00072 &carrierfailureroute_host_name_col,
00073 &carrierfailureroute_reply_code_col,
00074 &carrierfailureroute_flags_col,
00075 &carrierfailureroute_mask_col,
00076 &carrierfailureroute_next_domain_col,
00077 &carrierfailureroute_description_col
00078 };
00079
00080
00081 static int load_carrier_map(struct route_data_t *rd) {
00082 db1_res_t * res = NULL;
00083 int i, count;
00084 if(!rd){
00085 LM_ERR("invalid parameter\n");
00086 return -1;
00087 }
00088 if (carrierroute_dbf.use_table(carrierroute_dbh, &carrier_name_table) < 0) {
00089 LM_ERR("couldn't use table\n");
00090 return -1;
00091 }
00092
00093 if (carrierroute_dbf.query(carrierroute_dbh, 0, 0, 0, (db_key_t *)carrier_name_columns, 0, CARRIER_NAME_COLUMN_NUM, 0, &res) < 0) {
00094 LM_ERR("couldn't query table\n");
00095 return -1;
00096 }
00097
00098 count = RES_ROW_N(res);
00099 if (count == 0) {
00100 LM_ERR("empty %.*s table", carrier_name_table.len, carrier_name_table.s);
00101 carrierroute_dbf.free_result(carrierroute_dbh, res);
00102 return 0;
00103 }
00104
00105 rd->carrier_map = shm_malloc(sizeof(struct name_map_t) * count);
00106 if (rd->carrier_map == NULL) {
00107 SHM_MEM_ERROR;
00108 carrierroute_dbf.free_result(carrierroute_dbh, res);
00109 return -1;
00110 }
00111 memset(rd->carrier_map, 0, sizeof(struct name_map_t) * count);
00112
00113 for (i=0; i<count; i++) {
00114 rd->carrier_map[i].id = res->rows[i].values[CARRIER_NAME_ID_COL].val.int_val;
00115 rd->carrier_map[i].name.len = strlen(res->rows[i].values[CARRIER_NAME_NAME_COL].val.string_val);
00116 rd->carrier_map[i].name.s = shm_malloc(rd->carrier_map[i].name.len);
00117 if (rd->carrier_map[i].name.s == NULL) {
00118 SHM_MEM_ERROR;
00119 carrierroute_dbf.free_result(carrierroute_dbh, res);
00120 shm_free(rd->carrier_map);
00121 rd->carrier_map = NULL;
00122 return -1;
00123 }
00124 memcpy(rd->carrier_map[i].name.s, res->rows[i].values[CARRIER_NAME_NAME_COL].val.string_val, rd->carrier_map[i].name.len);
00125 }
00126
00127
00128 qsort(rd->carrier_map, count, sizeof(rd->carrier_map[0]), compare_name_map);
00129
00130 carrierroute_dbf.free_result(carrierroute_dbh, res);
00131 return count;
00132 }
00133
00134
00135
00136
00137 static int load_domain_map(struct route_data_t *rd) {
00138 db1_res_t * res = NULL;
00139 int i, count;
00140 if(!rd){
00141 LM_ERR("invalid parameter\n");
00142 return -1;
00143 }
00144 if (carrierroute_dbf.use_table(carrierroute_dbh, &domain_name_table) < 0) {
00145 LM_ERR("couldn't use table\n");
00146 return -1;
00147 }
00148
00149 if (carrierroute_dbf.query(carrierroute_dbh, 0, 0, 0, (db_key_t *)domain_name_columns, 0, DOMAIN_NAME_COLUMN_NUM, 0, &res) < 0) {
00150 LM_ERR("couldn't query table\n");
00151 return -1;
00152 }
00153
00154 count = RES_ROW_N(res);
00155 if (count == 0) {
00156 LM_ERR("empty %.*s table", domain_name_table.len, domain_name_table.s);
00157 carrierroute_dbf.free_result(carrierroute_dbh, res);
00158 return 0;
00159 }
00160
00161 rd->domain_map = shm_malloc(sizeof(struct name_map_t) * count);
00162 if (rd->domain_map == NULL) {
00163 SHM_MEM_ERROR;
00164 carrierroute_dbf.free_result(carrierroute_dbh, res);
00165 return -1;
00166 }
00167 memset(rd->domain_map, 0, sizeof(struct name_map_t) * count);
00168
00169 for (i=0; i<count; i++) {
00170 rd->domain_map[i].id = res->rows[i].values[DOMAIN_NAME_ID_COL].val.int_val;
00171 rd->domain_map[i].name.len = strlen(res->rows[i].values[DOMAIN_NAME_NAME_COL].val.string_val);
00172 rd->domain_map[i].name.s = shm_malloc(rd->domain_map[i].name.len);
00173 if (rd->domain_map[i].name.s == NULL) {
00174 SHM_MEM_ERROR;
00175 carrierroute_dbf.free_result(carrierroute_dbh, res);
00176 shm_free(rd->domain_map);
00177 rd->domain_map = NULL;
00178 return -1;
00179 }
00180 memcpy(rd->domain_map[i].name.s, res->rows[i].values[DOMAIN_NAME_NAME_COL].val.string_val, rd->domain_map[i].name.len);
00181 }
00182
00183
00184 qsort(rd->domain_map, count, sizeof(rd->domain_map[0]), compare_name_map);
00185
00186 carrierroute_dbf.free_result(carrierroute_dbh, res);
00187 return count;
00188 }
00189
00190
00191
00192
00193 int load_user_carrier(str * user, str * domain) {
00194 db1_res_t * res;
00195 db_key_t cols[1];
00196 db_key_t keys[2];
00197 db_val_t vals[2];
00198 db_op_t op[2];
00199 int id;
00200 int use_domain = cfg_get(carrierroute, carrierroute_cfg, use_domain);
00201 if (!user || (use_domain && !domain)) {
00202 LM_ERR("NULL pointer in parameter\n");
00203 return -1;
00204 }
00205
00206 cols[0] = subscriber_columns[SUBSCRIBER_CARRIER_COL];
00207
00208 keys[0] = subscriber_columns[SUBSCRIBER_USERNAME_COL];
00209 op[0] = OP_EQ;
00210 VAL_TYPE(vals) = DB1_STR;
00211 VAL_NULL(vals) = 0;
00212 VAL_STR(vals) = *user;
00213
00214 keys[1] = subscriber_columns[SUBSCRIBER_DOMAIN_COL];
00215 op[1] = OP_EQ;
00216 VAL_TYPE(vals+1) = DB1_STR;
00217 VAL_NULL(vals+1) = 0;
00218 VAL_STR(vals+1) = *domain;
00219
00220 if (carrierroute_dbf.use_table(carrierroute_dbh, &subscriber_table) < 0) {
00221 LM_ERR("can't use table\n");
00222 return -1;
00223 }
00224
00225 if (carrierroute_dbf.query(carrierroute_dbh, keys, op, vals, cols, use_domain ? 2 : 1, 1, NULL, &res) < 0) {
00226 LM_ERR("can't query database\n");
00227 return -1;
00228 }
00229
00230 if (RES_ROW_N(res) == 0) {
00231 carrierroute_dbf.free_result(carrierroute_dbh, res);
00232 return 0;
00233 }
00234
00235 if (VAL_NULL(ROW_VALUES(RES_ROWS(res)))) {
00236 carrierroute_dbf.free_result(carrierroute_dbh, res);
00237 return 0;
00238 }
00239
00240 id = VAL_INT(ROW_VALUES(RES_ROWS(res)));
00241 carrierroute_dbf.free_result(carrierroute_dbh, res);
00242 return id;
00243 }
00244
00245
00246
00247
00258 int load_route_data_db(struct route_data_t * rd) {
00259 db1_res_t * res = NULL;
00260 db_row_t * row = NULL;
00261 int i, ret;
00262 struct carrier_data_t * tmp_carrier_data;
00263 static str query_str;
00264 str tmp_scan_prefix, tmp_rewrite_host, tmp_rewrite_prefix,
00265 tmp_rewrite_suffix, tmp_host_name, tmp_reply_code, tmp_comment;
00266
00267 if( (strlen("SELECT DISTINCT FROM WHERE = ")
00268 + carrierroute_table.len + columns[COL_DOMAIN]->len
00269 + columns[COL_CARRIER]->len + 20) > QUERY_LEN) {
00270 LM_ERR("query too long\n");
00271 return -1;
00272 }
00273
00274 if((rd->carrier_num = load_carrier_map(rd)) <= 0){
00275 LM_ERR("error while retrieving carriers\n");
00276 goto errout;
00277 }
00278
00279 if((rd->domain_num = load_domain_map(rd)) <= 0){
00280 LM_ERR("error while retrieving domains\n");
00281 goto errout;
00282 }
00283
00284 if ((rd->carriers = shm_malloc(sizeof(struct carrier_data_t *) * rd->carrier_num)) == NULL) {
00285 SHM_MEM_ERROR;
00286 goto errout;
00287 }
00288 memset(rd->carriers, 0, sizeof(struct carrier_data_t *) * rd->carrier_num);
00289
00290 for (i=0; i<rd->carrier_num; i++) {
00291 memset(query, 0, QUERY_LEN);
00292 ret = snprintf(query, QUERY_LEN, "SELECT DISTINCT %.*s FROM %.*s WHERE %.*s=%i",
00293 columns[COL_DOMAIN]->len, columns[COL_DOMAIN]->s, carrierroute_table.len,
00294 carrierroute_table.s, columns[COL_CARRIER]->len, columns[COL_CARRIER]->s, rd->carrier_map[i].id);
00295 if (ret < 0) {
00296 LM_ERR("error in snprintf");
00297 goto errout;
00298 }
00299 query_str.s = query;
00300 query_str.len = ret;
00301
00302 if (carrierroute_dbf.raw_query(carrierroute_dbh, &query_str, &res) < 0) {
00303 LM_ERR("Failed to query database.\n");
00304 goto errout;
00305 }
00306 LM_INFO("carrier '%.*s' (id %i) has %i domains\n", rd->carrier_map[i].name.len, rd->carrier_map[i].name.s, rd->carrier_map[i].id, RES_ROW_N(res));
00307 tmp_carrier_data = create_carrier_data(rd->carrier_map[i].id, &rd->carrier_map[i].name, RES_ROW_N(res));
00308 if (tmp_carrier_data == NULL) {
00309 LM_ERR("can't create new carrier '%.*s'\n", rd->carrier_map[i].name.len, rd->carrier_map[i].name.s);
00310 goto errout;
00311 }
00312 if (add_carrier_data(rd, tmp_carrier_data) < 0) {
00313 LM_ERR("can't add carrier '%.*s'\n", rd->carrier_map[i].name.len, rd->carrier_map[i].name.s);
00314 destroy_carrier_data(tmp_carrier_data);
00315 goto errout;
00316 }
00317 carrierroute_dbf.free_result(carrierroute_dbh, res);
00318 res = NULL;
00319 }
00320
00321 if (carrierroute_dbf.use_table(carrierroute_dbh, &carrierroute_table) < 0) {
00322 LM_ERR("Cannot set database table '%.*s'.\n", carrierroute_table.len, carrierroute_table.s);
00323 return -1;
00324 }
00325
00326 if (DB_CAPABILITY(carrierroute_dbf, DB_CAP_FETCH)) {
00327 if (carrierroute_dbf.query(carrierroute_dbh, NULL, NULL, NULL, (db_key_t *) columns, 0,
00328 COLUMN_NUM, NULL, NULL) < 0) {
00329 LM_ERR("Failed to query database to prepare fetch row.\n");
00330 return -1;
00331 }
00332 if(carrierroute_dbf.fetch_result(carrierroute_dbh, &res, cfg_get(carrierroute, carrierroute_cfg, fetch_rows)) < 0) {
00333 LM_ERR("Fetching rows failed\n");
00334 return -1;
00335 }
00336 } else {
00337 if (carrierroute_dbf.query(carrierroute_dbh, NULL, NULL, NULL, (db_key_t *) columns, 0,
00338 COLUMN_NUM, NULL, &res) < 0) {
00339 LM_ERR("Failed to query database.\n");
00340 return -1;
00341 }
00342 }
00343 int n = 0;
00344 do {
00345 LM_DBG("loading, cycle %d", n++);
00346 for (i = 0; i < RES_ROW_N(res); ++i) {
00347 row = &RES_ROWS(res)[i];
00348 tmp_scan_prefix.s=(char *)row->values[COL_SCAN_PREFIX].val.string_val;
00349 tmp_rewrite_host.s=(char *)row->values[COL_REWRITE_HOST].val.string_val;
00350 tmp_rewrite_prefix.s=(char *)row->values[COL_REWRITE_PREFIX].val.string_val;
00351 tmp_rewrite_suffix.s=(char *)row->values[COL_REWRITE_SUFFIX].val.string_val;
00352 tmp_comment.s=(char *)row->values[COL_COMMENT].val.string_val;
00353 if (tmp_scan_prefix.s==NULL) tmp_scan_prefix.s="";
00354 if (tmp_rewrite_host.s==NULL) tmp_rewrite_host.s="";
00355 if (tmp_rewrite_prefix.s==NULL) tmp_rewrite_prefix.s="";
00356 if (tmp_rewrite_suffix.s==NULL) tmp_rewrite_suffix.s="";
00357 if (tmp_comment.s==NULL) tmp_comment.s="";
00358 tmp_scan_prefix.len=strlen(tmp_scan_prefix.s);
00359 tmp_rewrite_host.len=strlen(tmp_rewrite_host.s);
00360 tmp_rewrite_prefix.len=strlen(tmp_rewrite_prefix.s);
00361 tmp_rewrite_suffix.len=strlen(tmp_rewrite_suffix.s);
00362 tmp_comment.len=strlen(tmp_comment.s);
00363 if (add_route(rd,
00364 row->values[COL_CARRIER].val.int_val,
00365 row->values[COL_DOMAIN].val.int_val,
00366 &tmp_scan_prefix,
00367 row->values[COL_FLAGS].val.int_val,
00368 row->values[COL_MASK].val.int_val,
00369 0,
00370 row->values[COL_PROB].val.double_val,
00371 &tmp_rewrite_host,
00372 row->values[COL_STRIP].val.int_val,
00373 &tmp_rewrite_prefix,
00374 &tmp_rewrite_suffix,
00375 1,
00376 0,
00377 -1,
00378 NULL,
00379 &tmp_comment) == -1) {
00380 goto errout;
00381 }
00382 }
00383 if (DB_CAPABILITY(carrierroute_dbf, DB_CAP_FETCH)) {
00384 if(carrierroute_dbf.fetch_result(carrierroute_dbh, &res, cfg_get(carrierroute, carrierroute_cfg, fetch_rows)) < 0) {
00385 LM_ERR("fetching rows failed\n");
00386 carrierroute_dbf.free_result(carrierroute_dbh, res);
00387 return -1;
00388 }
00389 } else {
00390 break;
00391 }
00392 } while(RES_ROW_N(res) > 0);
00393
00394 carrierroute_dbf.free_result(carrierroute_dbh, res);
00395 res = NULL;
00396
00397 if (carrierroute_dbf.use_table(carrierroute_dbh, &carrierfailureroute_table) < 0) {
00398 LM_ERR("cannot set database table '%.*s'.\n",
00399 carrierfailureroute_table.len, carrierfailureroute_table.s);
00400 return -1;
00401 }
00402 if (carrierroute_dbf.query(carrierroute_dbh, NULL, NULL, NULL, (db_key_t *)failure_columns, 0,
00403 FAILURE_COLUMN_NUM, NULL, &res) < 0) {
00404 LM_ERR("failed to query database.\n");
00405 return -1;
00406 }
00407 for (i = 0; i < RES_ROW_N(res); ++i) {
00408 row = &RES_ROWS(res)[i];
00409 tmp_scan_prefix.s=(char *)row->values[FCOL_SCAN_PREFIX].val.string_val;
00410 tmp_host_name.s=(char *)row->values[FCOL_HOST_NAME].val.string_val;
00411 tmp_reply_code.s=(char *)row->values[FCOL_REPLY_CODE].val.string_val;
00412 tmp_comment.s=(char *)row->values[FCOL_COMMENT].val.string_val;
00413 if (tmp_scan_prefix.s==NULL) tmp_scan_prefix.s="";
00414 if (tmp_host_name.s==NULL) tmp_host_name.s="";
00415 if (tmp_reply_code.s==NULL) tmp_reply_code.s="";
00416 if (tmp_comment.s==NULL) tmp_comment.s="";
00417 tmp_scan_prefix.len=strlen(tmp_scan_prefix.s);
00418 tmp_host_name.len=strlen(tmp_host_name.s);
00419 tmp_reply_code.len=strlen(tmp_reply_code.s);
00420 tmp_comment.len=strlen(tmp_comment.s);
00421 if (add_failure_route(rd,
00422 row->values[FCOL_CARRIER].val.int_val,
00423 row->values[COL_DOMAIN].val.int_val,
00424 &tmp_scan_prefix,
00425 &tmp_host_name,
00426 &tmp_reply_code,
00427 row->values[FCOL_FLAGS].val.int_val,
00428 row->values[FCOL_MASK].val.int_val,
00429 row->values[FCOL_NEXT_DOMAIN].val.int_val,
00430 &tmp_comment) == -1) {
00431 goto errout;
00432 }
00433 }
00434
00435 carrierroute_dbf.free_result(carrierroute_dbh, res);
00436 return 0;
00437
00438 errout:
00439 if (res) {
00440 carrierroute_dbf.free_result(carrierroute_dbh, res);
00441 }
00442 return -1;
00443 }