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 #include <stdio.h>
00030 #include <unistd.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033
00034 #include "../../dprint.h"
00035 #include "../../mem/shm_mem.h"
00036 #include "../../ut.h"
00037
00038 #include "pdtree.h"
00039
00040
00041 extern str pdt_char_list;
00042
00043 pdt_tree_t* pdt_init_tree(str* sdomain)
00044 {
00045 pdt_tree_t *pt = NULL;
00046
00047 pt = (pdt_tree_t*)shm_malloc(sizeof(pdt_tree_t));
00048 if(pt==NULL)
00049 {
00050 LM_ERR("no more shm memory\n");
00051 return NULL;
00052 }
00053 memset(pt, 0, sizeof(pdt_tree_t));
00054
00055 pt->sdomain.s = (char*)shm_malloc((1+sdomain->len)*sizeof(char));
00056 if(pt->sdomain.s==NULL)
00057 {
00058 shm_free(pt);
00059 LM_ERR("no more shm memory\n");
00060 return NULL;
00061 }
00062 memset(pt->sdomain.s, 0,1+sdomain->len );
00063 memcpy(pt->sdomain.s, sdomain->s, sdomain->len);
00064 pt->sdomain.len = sdomain->len;
00065
00066
00067 pt->head = (pdt_node_t*)shm_malloc(PDT_NODE_SIZE*sizeof(pdt_node_t));
00068 if(pt->head == NULL)
00069 {
00070 shm_free(pt->sdomain.s);
00071 shm_free(pt);
00072 LM_ERR("no more shm memory\n");
00073 return NULL;
00074 }
00075 memset(pt->head, 0, PDT_NODE_SIZE*sizeof(pdt_node_t));
00076
00077 return pt;
00078 }
00079
00080 int add_to_tree(pdt_tree_t *pt, str *sp, str *sd)
00081 {
00082 int l;
00083 pdt_node_t *itn, *itn0;
00084
00085 if(pt==NULL || sp==NULL || sp->s==NULL
00086 || sd==NULL || sd->s==NULL)
00087 {
00088 LM_ERR("bad parameters\n");
00089 return -1;
00090 }
00091
00092 if(sp->len>=PDT_MAX_DEPTH)
00093 {
00094 LM_ERR("max prefix len exceeded\n");
00095 return -1;
00096 }
00097
00098 l = 0;
00099 itn0 = pt->head;
00100 itn = itn0[strpos(pdt_char_list.s,sp->s[l])%PDT_NODE_SIZE].child;
00101
00102 while(l < sp->len-1)
00103 {
00104 if(strpos(pdt_char_list.s,sp->s[l]) < 0)
00105 {
00106 LM_ERR("invalid char %d in prefix [%c (0x%x)]\n",
00107 l, sp->s[l], sp->s[l]);
00108 return -1;
00109 }
00110
00111 if(itn == NULL)
00112 {
00113 itn = (pdt_node_t*)shm_malloc(PDT_NODE_SIZE*sizeof(pdt_node_t));
00114 if(itn == NULL)
00115 {
00116 LM_ERR("no more shm mem\n");
00117 return -1;
00118 }
00119 memset(itn, 0, PDT_NODE_SIZE*sizeof(pdt_node_t));
00120 itn0[strpos(pdt_char_list.s,sp->s[l])%PDT_NODE_SIZE].child = itn;
00121 }
00122 l++;
00123 itn0 = itn;
00124 itn = itn0[strpos(pdt_char_list.s,sp->s[l])%PDT_NODE_SIZE].child;
00125 }
00126
00127 if(itn0[strpos(pdt_char_list.s,sp->s[l])%PDT_NODE_SIZE].domain.s!=NULL)
00128 {
00129 LM_ERR("prefix already allocated [%.*s/[%.*s]\n",
00130 sp->len, sp->s, sd->len, sd->s);
00131 return -1;
00132 }
00133
00134 itn0[strpos(pdt_char_list.s,sp->s[l])%PDT_NODE_SIZE].domain.s
00135 = (char*)shm_malloc((sd->len+1)*sizeof(char));
00136 if(itn0[strpos(pdt_char_list.s,sp->s[l])%PDT_NODE_SIZE].domain.s==NULL)
00137 {
00138 LM_ERR("no more shm mem!\n");
00139 return -1;
00140 }
00141 strncpy(itn0[strpos(pdt_char_list.s,sp->s[l])%PDT_NODE_SIZE].domain.s,
00142 sd->s, sd->len);
00143 itn0[strpos(pdt_char_list.s,sp->s[l])%PDT_NODE_SIZE].domain.len = sd->len;
00144 itn0[strpos(pdt_char_list.s,sp->s[l])%PDT_NODE_SIZE].domain.s[sd->len]
00145 = '\0';
00146
00147 return 0;
00148 }
00149
00150 pdt_tree_t* pdt_get_tree(pdt_tree_t *pl, str *sdomain)
00151 {
00152 pdt_tree_t *it;
00153
00154 if(pl==NULL)
00155 return NULL;
00156
00157 if( sdomain==NULL || sdomain->s==NULL)
00158 {
00159 LM_ERR("bad parameters\n");
00160 return NULL;
00161 }
00162
00163 it = pl;
00164
00165 while(it!=NULL && str_strcmp(&it->sdomain, sdomain)<0)
00166 it = it->next;
00167
00168 if(it==NULL || str_strcmp(&it->sdomain, sdomain)>0)
00169 return NULL;
00170
00171 return it;
00172 }
00173
00174 int pdt_add_to_tree(pdt_tree_t **dpt, str *sdomain, str *code, str *domain)
00175 {
00176 pdt_tree_t *ndl, *it, *prev;
00177
00178 if( sdomain==NULL || sdomain->s==NULL
00179 || code==NULL || code->s==NULL
00180 || domain==NULL || domain->s==NULL)
00181 {
00182 LM_ERR("bad parameters\n");
00183 return -1;
00184 }
00185
00186 ndl = NULL;
00187
00188 it = *dpt;
00189 prev = NULL;
00190
00191 while(it!=NULL && str_strcmp(&it->sdomain, sdomain)<0)
00192 {
00193 prev = it;
00194 it = it->next;
00195 }
00196
00197
00198
00199 if(it==NULL || str_strcmp(&it->sdomain, sdomain)>0)
00200 {
00201 ndl = pdt_init_tree(sdomain);
00202 if(ndl==NULL)
00203 {
00204 LM_ERR("no more shm memory\n");
00205 return -1;
00206 }
00207
00208 if(add_to_tree(ndl, code, domain)<0)
00209 {
00210 LM_ERR("internal error!\n");
00211 return -1;
00212 }
00213 ndl->next = it;
00214
00215
00216 if(prev==NULL)
00217 *dpt = ndl;
00218 else
00219 prev->next=ndl;
00220
00221 }
00222 else
00223
00224 if(add_to_tree(it, code, domain)<0)
00225 {
00226 LM_ERR("internal error!\n");
00227 return -1;
00228 }
00229
00230 return 0;
00231 }
00232
00233 str* get_domain(pdt_tree_t *pt, str *sp, int *plen)
00234 {
00235 int l, len;
00236 pdt_node_t *itn;
00237 str *domain;
00238
00239 if(pt==NULL || sp==NULL || sp->s==NULL)
00240 {
00241 LM_ERR("bad parameters\n");
00242 return NULL;
00243 }
00244
00245 l = len = 0;
00246 itn = pt->head;
00247 domain = NULL;
00248
00249 while(itn!=NULL && l < sp->len && l < PDT_MAX_DEPTH)
00250 {
00251
00252 if(strpos(pdt_char_list.s,sp->s[l]) < 0)
00253 {
00254 LM_ERR("invalid char at %d in [%.*s]\n", l, sp->len, sp->s);
00255 return NULL;
00256 }
00257
00258 if(itn[strpos(pdt_char_list.s,sp->s[l])%PDT_NODE_SIZE].domain.s!=NULL)
00259 {
00260 domain = &itn[strpos(pdt_char_list.s,sp->s[l])%PDT_NODE_SIZE].domain;
00261 len = l+1;
00262 }
00263
00264 itn = itn[strpos(pdt_char_list.s,sp->s[l])%PDT_NODE_SIZE].child;
00265 l++;
00266 }
00267
00268 if(plen!=NULL)
00269 *plen = len;
00270
00271 return domain;
00272
00273 }
00274 str* pdt_get_domain(pdt_tree_t *pl, str* sdomain, str *code, int *plen)
00275 {
00276 pdt_tree_t *it;
00277 int len;
00278 str *domain=NULL;
00279
00280 if(pl==NULL || sdomain==NULL || sdomain->s==NULL || code == NULL
00281 || code->s == NULL)
00282 {
00283 LM_ERR("bad parameters\n");
00284 return NULL;
00285 }
00286
00287 it = pl;
00288 while(it!=NULL && str_strcmp(&it->sdomain, sdomain)<0)
00289 it = it->next;
00290
00291 if(it==NULL || str_strcmp(&it->sdomain, sdomain)>0)
00292 return NULL;
00293
00294 domain = get_domain(it, code, &len);
00295 if(plen!=NULL)
00296 *plen = len;
00297 return domain;
00298 }
00299
00300 void pdt_free_node(pdt_node_t *pn)
00301 {
00302 int i;
00303 if(pn==NULL)
00304 return;
00305
00306 for(i=0; i<PDT_NODE_SIZE; i++)
00307 {
00308 if(pn[i].domain.s!=NULL)
00309 {
00310 shm_free(pn[i].domain.s);
00311 pn[i].domain.s = NULL;
00312 pn[i].domain.len = 0;
00313 }
00314 if(pn[i].child!=NULL)
00315 {
00316 pdt_free_node(pn[i].child);
00317 pn[i].child = NULL;
00318 }
00319 }
00320 shm_free(pn);
00321 pn = NULL;
00322
00323 return;
00324 }
00325
00326 void pdt_free_tree(pdt_tree_t *pt)
00327 {
00328 if(pt == NULL)
00329 return;
00330
00331 if(pt->head!=NULL)
00332 pdt_free_node(pt->head);
00333 if(pt->next!=NULL)
00334 pdt_free_tree(pt->next);
00335 if(pt->sdomain.s!=NULL)
00336 shm_free(pt->sdomain.s);
00337
00338 shm_free(pt);
00339 pt = NULL;
00340 return;
00341 }
00342
00343 int pdt_print_node(pdt_node_t *pn, char *code, int len)
00344 {
00345 int i;
00346
00347 if(pn==NULL || code==NULL || len>=PDT_MAX_DEPTH)
00348 return 0;
00349
00350 for(i=0; i<PDT_NODE_SIZE; i++)
00351 {
00352 code[len]=pdt_char_list.s[i];
00353 if(pn[i].domain.s!=NULL)
00354 LM_DBG("[%.*s] [%.*s]\n",
00355 len+1, code, pn[i].domain.len, pn[i].domain.s);
00356 pdt_print_node(pn[i].child, code, len+1);
00357 }
00358
00359 return 0;
00360 }
00361
00362 static char pdt_code_buf[PDT_MAX_DEPTH+1];
00363 int pdt_print_tree(pdt_tree_t *pt)
00364 {
00365 int len;
00366
00367 if(pt == NULL)
00368 {
00369 LM_DBG("tree is empty\n");
00370 return 0;
00371 }
00372
00373 LM_DBG("[%.*s]\n", pt->sdomain.len, pt->sdomain.s);
00374 len = 0;
00375 pdt_print_node(pt->head, pdt_code_buf, len);
00376 return pdt_print_tree(pt->next);
00377 }
00378
00379 int pdt_check_pd_node(pdt_node_t *pn, str *sp, str *sd,
00380 char *code, int len)
00381 {
00382 int i;
00383 int ret;
00384
00385 if(pn==NULL || code==NULL || len>=PDT_MAX_DEPTH)
00386 return 0;
00387 ret = 0;
00388 for(i=0; i<PDT_NODE_SIZE; i++)
00389 {
00390 code[len]=pdt_char_list.s[i];
00391 if(pn[i].domain.s!=NULL)
00392 {
00393
00394 LM_DBG("[%.*s] [%.*s]\n",
00395 len+1, code, pn[i].domain.len, pn[i].domain.s);
00396 if(sp->len == len+1 &&
00397 strncmp(sp->s, code, sp->len)==0)
00398 {
00399 LM_DBG("duplicated prefix\n");
00400 return 1;
00401 }
00402 if(sd->len == pn[i].domain.len &&
00403 strncmp(sd->s, pn[i].domain.s, sd->len)==0)
00404 {
00405 LM_DBG("duplicated domain\n");
00406 return 1;
00407 }
00408 }
00409 ret = pdt_check_pd_node(pn[i].child, sp, sd, code, len+1);
00410 if(ret != 0)
00411 break;
00412 }
00413
00414 return ret;
00415 }
00416
00417
00418
00419
00420
00421
00422 int pdt_check_pd(pdt_tree_t *pt, str* sdomain, str *sp, str *sd)
00423 {
00424 int len;
00425 int ret;
00426 pdt_tree_t *it;
00427
00428 if(pt==NULL || sp==NULL || sd==NULL)
00429 {
00430 LM_ERR("bad parameters\n");
00431 return -1;
00432 }
00433
00434 it = pt;
00435 while(it!=NULL)
00436 {
00437 if(it->sdomain.len==sdomain->len
00438 && strncasecmp(it->sdomain.s, sdomain->s, sdomain->len)==0)
00439 break;
00440 it = it->next;
00441 }
00442 if(it == NULL)
00443 return 0;
00444
00445 len = 0;
00446 ret = pdt_check_pd_node(it->head, sp, sd, pdt_code_buf, len);
00447 return ret;
00448 }
00449