00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00030 #include "../../mem/shm_mem.h"
00031 #include "../../hashes.h"
00032 #include "lcr_mod.h"
00033
00034 #define rule_hash(_s) core_hash(_s, 0, lcr_rule_hash_size_param)
00035
00036
00037 int rule_hash_table_insert(struct rule_info **hash_table,
00038 unsigned int lcr_id, unsigned int rule_id,
00039 unsigned short prefix_len, char *prefix,
00040 unsigned short from_uri_len, char *from_uri,
00041 pcre *from_uri_re, unsigned short request_uri_len,
00042 char *request_uri, pcre *request_uri_re,
00043 unsigned short stopper)
00044 {
00045 struct rule_info *rule;
00046 str prefix_str;
00047 unsigned int hash_val;
00048 struct rule_id_info *rid;
00049
00050 rule = (struct rule_info *)shm_malloc(sizeof(struct rule_info));
00051 if (rule == NULL) {
00052 LM_ERR("no shm memory for rule hash table entry\n");
00053 if (from_uri_re) shm_free(from_uri_re);
00054 if (request_uri_re) shm_free(request_uri_re);
00055 return 0;
00056 }
00057 memset(rule, 0, sizeof(struct rule_info));
00058
00059 rule->rule_id = rule_id;
00060 rule->prefix_len = prefix_len;
00061 if (prefix_len) {
00062 memcpy(rule->prefix, prefix, prefix_len);
00063 }
00064 rule->from_uri_len = from_uri_len;
00065 if (from_uri_len) {
00066 memcpy(rule->from_uri, from_uri, from_uri_len);
00067 (rule->from_uri)[from_uri_len] = '\0';
00068 rule->from_uri_re = from_uri_re;
00069 }
00070 rule->request_uri_len = request_uri_len;
00071 if (request_uri_len) {
00072 memcpy(rule->request_uri, request_uri, request_uri_len);
00073 (rule->request_uri)[request_uri_len] = '\0';
00074 rule->request_uri_re = request_uri_re;
00075 }
00076 rule->stopper = stopper;
00077 rule->targets = (struct target *)NULL;
00078
00079 prefix_str.len = rule->prefix_len;
00080 prefix_str.s = rule->prefix;
00081
00082 hash_val = rule_hash(&prefix_str);
00083 rule->next = hash_table[hash_val];
00084 hash_table[hash_val] = rule;
00085
00086 LM_DBG("inserted rule_id <%u>, prefix <%.*s>, from_uri <%.*s>, "
00087 "request_uri <%.*s>, stopper <%u>, into index <%u>\n",
00088 rule_id, prefix_len, prefix, from_uri_len, from_uri,
00089 request_uri_len, request_uri, stopper, hash_val);
00090
00091
00092 rid = (struct rule_id_info *)pkg_malloc(sizeof(struct rule_id_info));
00093 if (rid == NULL) {
00094 LM_ERR("no pkg memory for rule_id hash table entry\n");
00095 return 0;
00096 }
00097 memset(rid, 0, sizeof(struct rule_id_info));
00098 rid->rule_id = rule_id;
00099 rid->rule_addr = rule;
00100 hash_val = rule_id % lcr_rule_hash_size_param;
00101 rid->next = rule_id_hash_table[hash_val];
00102 rule_id_hash_table[hash_val] = rid;
00103 LM_DBG("inserted rule_id <%u> addr <%p> into rule_id hash table "
00104 "index <%u>\n", rule_id, rule, hash_val);
00105
00106 return 1;
00107 }
00108
00109
00110
00111 int get_gw_index(struct gw_info *gws, unsigned int gw_id,
00112 unsigned short *gw_index)
00113 {
00114 unsigned short gw_count, i;
00115
00116 gw_count = gws[0].ip_addr.u.addr32[0];
00117
00118 for (i = 1; i <= gw_count; i++) {
00119 if (gws[i].gw_id == gw_id) {
00120 *gw_index = i;
00121 return 1;
00122 }
00123 }
00124 return 0;
00125 }
00126
00127
00128
00129 int rule_hash_table_insert_target(struct rule_info **hash_table,
00130 struct gw_info *gws,
00131 unsigned int rule_id, unsigned int gw_id,
00132 unsigned int priority, unsigned int weight)
00133 {
00134 unsigned short gw_index;
00135 struct target *target;
00136 struct rule_id_info *rid;
00137
00138 target = (struct target *)shm_malloc(sizeof(struct target));
00139 if (target == NULL) {
00140 LM_ERR("cannot allocate memory for rule target\n");
00141 return 0;
00142 }
00143
00144 if (get_gw_index(gws, gw_id, &gw_index) == 0) {
00145 LM_DBG("could not find (disabled) gw with id <%u>\n", gw_id);
00146 shm_free(target);
00147 return 2;
00148 }
00149
00150 target->gw_index = gw_index;
00151 target->priority = priority;
00152 target->weight = weight;
00153
00154 rid = rule_id_hash_table[rule_id % lcr_rule_hash_size_param];
00155 while (rid) {
00156 if (rid->rule_id == rule_id) {
00157 target->next = rid->rule_addr->targets;
00158 rid->rule_addr->targets = target;
00159 LM_DBG("found rule with id <%u> and addr <%p>\n",
00160 rule_id, rid->rule_addr);
00161 return 1;
00162 }
00163 rid = rid->next;
00164 }
00165
00166 LM_DBG("could not find (disabled) rule with id <%u>\n", rule_id);
00167 shm_free(target);
00168 return 2;
00169 }
00170
00171
00172
00173
00174
00175 struct rule_info *rule_hash_table_lookup(struct rule_info **hash_table,
00176 unsigned short prefix_len,
00177 char *prefix)
00178 {
00179 str prefix_str;
00180
00181 prefix_str.len = prefix_len;
00182 prefix_str.s = prefix;
00183
00184 return (hash_table)[rule_hash(&prefix_str)];
00185 }
00186
00187
00188
00189 void rule_hash_table_contents_free(struct rule_info **hash_table)
00190 {
00191 int i;
00192 struct rule_info *r, *next_r;
00193 struct target *t, *next_t;
00194
00195 if (hash_table == 0)
00196 return;
00197
00198 for (i = 0; i <= lcr_rule_hash_size_param; i++) {
00199 r = hash_table[i];
00200 while (r) {
00201 if (r->from_uri_re) {
00202 shm_free(r->from_uri_re);
00203 }
00204 if (r->request_uri_re)
00205 shm_free(r->request_uri_re);
00206 t = r->targets;
00207 while (t) {
00208 next_t = t->next;
00209 shm_free(t);
00210 t = next_t;
00211 }
00212 next_r = r->next;
00213 shm_free(r);
00214 r = next_r;
00215 }
00216 hash_table[i] = NULL;
00217 }
00218 }
00219
00220
00221 void rule_id_hash_table_contents_free()
00222 {
00223 int i;
00224 struct rule_id_info *r, *next_r;
00225
00226 if (rule_id_hash_table == 0)
00227 return;
00228
00229 for (i = 0; i <= lcr_rule_hash_size_param; i++) {
00230 r = rule_id_hash_table[i];
00231 while (r) {
00232 next_r = r->next;
00233 pkg_free(r);
00234 r = next_r;
00235 }
00236 rule_id_hash_table[i] = NULL;
00237 }
00238 }