"Fossies" - the Fresh Open Source Software Archive

Member "opensips-3.0.1/modules/drouting/dr_api_internal.c" (1 Oct 2019, 4862 Bytes) of package /linux/misc/opensips-3.0.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "dr_api_internal.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.4.5_vs_3.0.0.

    1 /**
    2  * drouting module developer api
    3  *
    4  * Copyright (C) 2014 OpenSIPS Foundation
    5  *
    6  * This file is part of opensips, a free SIP server.
    7  *
    8  * opensips is free software; you can redistribute it and/or modify
    9  * it under the terms of the GNU General Public License as published by
   10  * the Free Software Foundation; either version 2 of the License, or
   11  * (at your option) any later version
   12  *
   13  * opensips is distributed in the hope that it will be useful,
   14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16  * GNU General Public License for more details.
   17  *
   18  * You should have received a copy of the GNU General Public License
   19  * along with this program; if not, write to the Free Software
   20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
   21  *
   22  * History
   23  * -------
   24  *  2014-08-13  initial version (Andrei Datcu)
   25 */
   26 
   27 #include "dr_api_internal.h"
   28 #include "dr_api.h"
   29 
   30 
   31 #include "../../str.h"
   32 
   33 static rt_info_t *match_number (dr_head_p partition, unsigned int grp_id,
   34         const str *number, unsigned int *matched_len);
   35 static dr_head_p create_dr_head(void);
   36 static void free_dr_head(dr_head_p partition);
   37 static int add_rule_api(dr_head_p partition, unsigned int rid,
   38         str *prefix, unsigned int gr_id, unsigned int priority,
   39         tmrec_t *time_rec, void *attr);
   40 
   41 
   42 /* Warning this function assumes the lock is already taken */
   43 rt_info_t* find_rule_by_prefix_unsafe(ptree_t *pt, ptree_node_t *noprefix,
   44         str prefix, unsigned int grp_id, unsigned int *matched_len)
   45 {
   46     unsigned int rule_idx = 0;
   47     rt_info_t *rt_info;
   48 
   49     rt_info = get_prefix(pt, &prefix, grp_id,matched_len, &rule_idx);
   50 
   51     if (rt_info==NULL) {
   52         LM_DBG("no matching for prefix \"%.*s\"\n",
   53                 prefix.len, prefix.s);
   54 
   55         /* try prefixless rules */
   56         rt_info = check_rt( noprefix, grp_id);
   57         if (rt_info == NULL)
   58             LM_DBG("no prefixless matching for "
   59                     "grp %d\n", grp_id);
   60     }
   61     return rt_info;
   62 }
   63 
   64 int load_dr (struct dr_binds *drb)
   65 {
   66     drb->match_number = match_number;
   67     drb->create_head = create_dr_head;
   68     drb->free_head = free_dr_head;
   69     drb->add_rule = add_rule_api;
   70     drb->register_drcb = register_dr_cb;
   71     return 0;
   72 }
   73 
   74 /* Function which will try to match a number and return the rule id */
   75 static rt_info_t *match_number (dr_head_p partition, unsigned int grp_id,
   76         const str *number, unsigned int *matched_len)
   77 {
   78 
   79     return find_rule_by_prefix_unsafe(partition->pt, &(partition->noprefix),
   80             *number, grp_id, matched_len);
   81 }
   82 
   83 static dr_head_p create_dr_head(void)
   84 {
   85     dr_head_p new = shm_malloc(sizeof(dr_head_t));
   86     if( new == NULL ) {
   87         LM_ERR(" no more shm memory\n");
   88         return NULL;
   89     }
   90     memset( new, 0, sizeof(dr_head_t));
   91 
   92     /* data pointer in shm */
   93     new->pt = shm_malloc(sizeof (ptree_t));
   94     if (new->pt == NULL) {
   95         LM_ERR("no more shm memory\n");
   96         shm_free(new);
   97         return NULL;
   98     }
   99     memset(new->pt, 0, sizeof(ptree_t));
  100 
  101     return new;
  102 }
  103 
  104 static void del_rt_list_api(rt_info_wrp_t *rwl)
  105 {
  106     rt_info_wrp_t* t=rwl;
  107     while(rwl!=NULL) {
  108         t=rwl;
  109         rwl=rwl->next;
  110         if ( (--t->rtl->ref_cnt)==0)
  111             shm_free(t->rtl);
  112         shm_free(t);
  113     }
  114 }
  115 
  116 static void del_tree_api(ptree_t* t)
  117 {
  118     int i,j;
  119     if(NULL == t)
  120         return;
  121     /* delete all the children */
  122     for(i=0; i< PTREE_CHILDREN; i++) {
  123         /* shm_free the rg array of rt_info */
  124         if(NULL!=t->ptnode[i].rg) {
  125             for(j=0;j<t->ptnode[i].rg_pos;j++) {
  126                 /* if non intermediate delete the routing info */
  127                 if(t->ptnode[i].rg[j].rtlw !=NULL)
  128                     del_rt_list_api(t->ptnode[i].rg[j].rtlw);
  129             }
  130             shm_free(t->ptnode[i].rg);
  131         }
  132         /* if non leaf delete all the children */
  133         if(t->ptnode[i].next != NULL)
  134             del_tree_api(t->ptnode[i].next);
  135     }
  136     shm_free(t);
  137 }
  138 
  139 static void free_dr_head(dr_head_p partition)
  140 {
  141     int j;
  142     del_tree_api(partition->pt);
  143     if(NULL!=partition->noprefix.rg) {
  144         for(j=0;j<partition->noprefix.rg_pos;j++) {
  145             if(partition->noprefix.rg[j].rtlw !=NULL) {
  146                 del_rt_list_api(partition->noprefix.rg[j].rtlw);
  147                 partition->noprefix.rg[j].rtlw = 0;
  148             }
  149         }
  150         shm_free(partition->noprefix.rg);
  151         partition->noprefix.rg = 0;
  152     }
  153     shm_free(partition);
  154 }
  155 
  156 static int add_rule_api(dr_head_p partition,unsigned int rid,
  157         str *prefix, unsigned int gr_id, unsigned int priority,
  158         tmrec_t *time_rec, void *attr)
  159 {
  160     rt_info_t * rule = shm_malloc(sizeof(rt_info_t));
  161     if (rule == NULL){
  162         LM_ERR("no more shm mem(1)\n");
  163         return -1;
  164     }
  165 
  166     memset(rule, 0, sizeof(rt_info_t));
  167     rule->id = rid;
  168     rule->priority = priority;
  169     rule->time_rec = time_rec;
  170     rule->attrs.s = (char*) attr;
  171 
  172     if (prefix->len) {
  173         if ( add_prefix(partition->pt, prefix, rule, gr_id,
  174                 shm_malloc_func, shm_free_func)!=0 ) {
  175             LM_ERR("failed to add prefix route\n");
  176             return -1;
  177         }
  178     } else {
  179         if ( add_rt_info( &partition->noprefix, rule, gr_id,
  180                 shm_malloc_func, shm_free_func)!=0 ) {
  181             LM_ERR("failed to add prefixless route\n");
  182             return -1;
  183         }
  184     }
  185     return 0;
  186 }
  187