00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include "../../lib/srdb2/db.h"
00033 #include "../../rpc.h"
00034 #include "../../sr_module.h"
00035 #include "../../mem/mem.h"
00036 #include "../../data_lump_rpl.h"
00037 #include "../../parser/parse_uri.h"
00038 #include "../../parser/msg_parser.h"
00039 #include "../../locking.h"
00040 #include "../../action.h"
00041 #include "../../route.h"
00042 #include "tree.h"
00043 #include "pr.h"
00044
00045
00046 MODULE_VERSION
00047
00048
00049
00050 static char *db_url = DEFAULT_DB_URL;
00051 static char *db_table = "prefix_route";
00052
00053
00054 static int add_route(struct tree_item *root, const char *prefix,
00055 const char *route)
00056 {
00057 int ix, err;
00058
00059
00060
00061
00062 ix = route_lookup(&main_rt, (char *)route);
00063 if (ix < 0) {
00064 LOG(L_CRIT, "prefix_route: db_load(): "
00065 "route name '%s' is not defined\n", route);
00066 return -1;
00067 }
00068
00069 if (ix >= main_rt.entries) {
00070 LOG(L_CRIT, "prefix_route: route %d > n_entries (%d)\n",
00071 ix, main_rt.entries);
00072 return -1;
00073 }
00074
00075 err = tree_item_add(root, prefix, route, ix);
00076 if (0 != err) {
00077 LOG(L_CRIT, "prefix_route: db_load(): "
00078 "tree_item_add() failed (%d)\n", err);
00079 return err;
00080 }
00081
00082 return 0;
00083 }
00084
00085
00089 int pr_db_load(void)
00090 {
00091 db_ctx_t *ctx;
00092 db_cmd_t *cmd = NULL;
00093 db_res_t* res = NULL;
00094 db_rec_t* rec;
00095 struct tree_item *root;
00096 int err = -1;
00097 int count = 0;
00098 db_fld_t match[] = {
00099 { .name = "prefix", .type = DB_CSTR },
00100 { .name = "route", .type = DB_CSTR },
00101 { .name = "comment", .type = DB_CSTR },
00102 { .name = NULL, .type = DB_NONE }
00103 };
00104
00105 ctx = db_ctx("prefix_route");
00106 if (!ctx) {
00107 LOG(L_ERR, "prefix_route: db_load(): db_ctx() failed\n");
00108 return -1;
00109 }
00110 if (db_add_db(ctx, db_url) < 0) {
00111 LOG(L_ERR, "prefix_route: db_load(): could not add db\n");
00112 goto out;
00113 }
00114 if (db_connect(ctx) < 0) {
00115 LOG(L_ERR, "prefix_route: db_load(): could not connect\n");
00116 goto out;
00117 }
00118
00119 cmd = db_cmd(DB_GET, ctx, db_table, match, NULL, NULL);
00120 if (!cmd) {
00121 LOG(L_ERR, "prefix_route: db_load(): db_cmd() failed\n");
00122 goto out;
00123 }
00124
00125 if (db_exec(&res, cmd) < 0) {
00126 LOG(L_ERR, "prefix_route: db_load(): db_exec() failed\n");
00127 goto out;
00128 }
00129
00130 root = tree_item_alloc();
00131 if (NULL == root) {
00132 LOG(L_ERR, "prefix_route: db_load() tree alloc failed\n");
00133 err = -1;
00134 goto out;
00135 }
00136
00137
00138 err = 0;
00139
00140
00141 for (rec = db_first(res); rec != NULL && !err; rec = db_next(res)) {
00142 const char *prefix, *route, *comment;
00143
00144 ++count;
00145
00146 if (rec->fld[0].flags & DB_NULL) {
00147 LOG(L_CRIT, "prefix_route: ERROR: bad 'prefix' "
00148 "record in table %s, skipping...\n", db_table);
00149 continue;
00150 }
00151 if (rec->fld[1].flags & DB_NULL) {
00152 LOG(L_CRIT, "prefix_route: ERROR: bad 'route' "
00153 "record in table %s, skipping...\n", db_table);
00154 continue;
00155 }
00156
00157 prefix = rec->fld[0].v.cstr;
00158 route = rec->fld[1].v.cstr;
00159 comment = rec->fld[2].v.cstr;
00160
00161 LOG(L_INFO, " %d: prefix=%-10s route=%-15s comment=%s\n",
00162 count, prefix, route, comment);
00163
00164 err = add_route(root, prefix, route);
00165 }
00166
00167 LOG(L_NOTICE, "prefix_route: Total prefix routes loaded: %d\n", count);
00168
00169
00170 if (0 != err) {
00171 LOG(L_ERR, "prefix_route: db_load(): error, flushing tree\n");
00172 tree_item_free(root);
00173 goto out;
00174 }
00175
00176
00177 err = tree_swap(root);
00178 if (0 != err)
00179 goto out;
00180
00181 out:
00182
00183 if (res)
00184 db_res_free(res);
00185 if (cmd)
00186 db_cmd_free(cmd);
00187
00188
00189 if (ctx)
00190 db_ctx_free(ctx);
00191
00192 return err;
00193 }
00194
00195
00199 static int mod_init(void)
00200 {
00201
00202 if (0 != tree_init()) {
00203 LOG(L_CRIT, "prefix_route: tree_init() failed\n\n");
00204 return -1;
00205 }
00206
00207
00208 if (0 != pr_db_load()) {
00209 LOG(L_CRIT, "prefix_route: db_load() failed\n\n");
00210 return -1;
00211 }
00212
00213 return 0;
00214 }
00215
00216
00220 static void mod_destroy(void)
00221 {
00222 tree_close();
00223 }
00224
00225
00231 static int get_username(struct sip_msg* msg, str *user)
00232 {
00233 if (!msg || !user)
00234 return -1;
00235
00236 if (parse_sip_msg_uri(msg) < 0){
00237 LOG(L_ERR, "get_username(): bad uri\n");
00238 return -1;
00239 }
00240
00241 if (msg->parsed_uri.user.s == 0){
00242
00243 LOG(L_ERR, "get_username(): no user in uri\n");
00244 return -2;
00245 }
00246
00247 *user = msg->parsed_uri.user;
00248
00249 return 0;
00250 }
00251
00252
00256 static int prefix_route(struct sip_msg *msg, char *p1, char *p2)
00257 {
00258 struct run_act_ctx ra_ctx;
00259 str user;
00260 int err;
00261 int route;
00262
00263
00264 (void)p1;
00265 (void)p2;
00266
00267
00268 err = get_username(msg, &user);
00269 if (0 != err) {
00270 LOG(L_ERR, "prefix_route: could not get username in"
00271 " Request URI (%d)\n", err);
00272 return err;
00273 }
00274
00275 route = tree_route_get(&user);
00276 if (route <= 0)
00277 return -1;
00278
00279
00280 init_run_actions_ctx(&ra_ctx);
00281
00282 err = run_actions(&ra_ctx, main_rt.rlist[route], msg);
00283 if (err < 0) {
00284 LOG(L_ERR, "prefix_route: run_actions failed (%d)\n", err);
00285 return -1;
00286 }
00287
00288
00289 return 0;
00290 }
00291
00292
00293
00294
00295
00296 static cmd_export_t cmds[] = {
00297 {"prefix_route", prefix_route, 0, 0, REQUEST_ROUTE},
00298 {0, 0, 0, 0, 0 }
00299 };
00300
00301
00302
00303
00304 static param_export_t params[] = {
00305 {"db_url", STR_PARAM, &db_url },
00306 {"db_table", STR_PARAM, &db_table},
00307 {0, 0, 0 }
00308 };
00309
00310
00311
00312
00313 struct module_exports exports = {
00314 "prefix_route",
00315 cmds,
00316 pr_rpc,
00317 params,
00318 mod_init,
00319 0,
00320 mod_destroy,
00321 0,
00322 0
00323 };