cr_domain.c

Go to the documentation of this file.
00001 /*
00002  * $Id: cr_domain.c 5299 2008-12-04 18:12:33Z henningw $
00003  *
00004  * Copyright (C) 2007-2008 1&1 Internet AG
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  */
00022 
00023 /**
00024  * \file cr_domain.c
00025  * \brief Contains the functions to manage routing domains.
00026  * \ingroup carrierroute
00027  * - Module; \ref carrierroute
00028  */
00029 
00030 #include <stdlib.h>
00031 #include "../../mem/shm_mem.h"
00032 #include "../../ut.h"
00033 #include "cr_domain.h"
00034 #include "cr_rule.h"
00035 #include "carrierroute.h"
00036 
00037 
00038 /**
00039  * Destroys route_flags list in shared memory by freing all its memory.
00040  *
00041  * @param data the start of the route_flags list to be destroyed
00042  */
00043 static void destroy_route_flags_list(void *data) {
00044    struct route_flags *rf, *rf_tmp;
00045 
00046    rf=(struct route_flags *)(data);
00047    while (rf!=NULL) {
00048       rf_tmp = rf->next;
00049       destroy_route_flags(rf);
00050       rf = rf_tmp;
00051    }
00052 }
00053 
00054 
00055 /**
00056  * Destroys failure_route_rule list in shared memory by freing all its memory.
00057  *
00058  * @param data the start of the failure_route_rule list to be destroyed
00059  */
00060 static void destroy_failure_route_rule_list(void *data) {
00061    struct failure_route_rule *rs, *rs_tmp;
00062    
00063    rs = (struct failure_route_rule *)(data);
00064    while (rs != NULL) {
00065       rs_tmp = rs->next;
00066       destroy_failure_route_rule(rs);
00067       rs = rs_tmp;
00068    }
00069 }
00070 
00071 
00072 /**
00073  * Create a new domain in shared memory and set it up.
00074  *
00075  * @param domain_id the id of the domain
00076  * @param domain_name the name of the domain
00077  *
00078  * @return a pointer to the newly allocated domain data or NULL on
00079  * error, in which case it LOGs an error message.
00080  */
00081 struct domain_data_t * create_domain_data(int domain_id, str * domain_name) {
00082    struct domain_data_t * tmp;
00083    if ((tmp = shm_malloc(sizeof(struct domain_data_t))) == NULL) {
00084       SHM_MEM_ERROR;
00085       return NULL;
00086    }
00087    memset(tmp, 0, sizeof(struct domain_data_t));
00088    tmp->id = domain_id;
00089    tmp->name = domain_name;
00090    if ((tmp->tree = dtrie_init(cr_match_mode)) == NULL) {
00091       shm_free(tmp);
00092       return NULL;
00093    }
00094    if ((tmp->failure_tree = dtrie_init(cr_match_mode)) == NULL) {
00095       dtrie_destroy(&tmp->tree, NULL, cr_match_mode);
00096       shm_free(tmp);
00097       return NULL;
00098    }
00099    return tmp;
00100 }
00101 
00102 
00103 /**
00104  * Destroys the given domain and frees the used memory.
00105  *
00106  * @param domain_data the structure to be destroyed.
00107  */
00108 void destroy_domain_data(struct domain_data_t *domain_data) {
00109    if (domain_data) {
00110       dtrie_destroy(&domain_data->tree, destroy_route_flags_list, cr_match_mode);
00111       dtrie_destroy(&domain_data->failure_tree, destroy_failure_route_rule_list,
00112             cr_match_mode);
00113       shm_free(domain_data);
00114    }
00115 }
00116 
00117 
00118 /**
00119  * Adds the given route information to the prefix tree identified by
00120  * node. scan_prefix identifies the number for which the information
00121  * is. The rewrite_* parameters define what to do in case of a match.
00122  * prob gives the probability with which this rule applies if there are
00123  * more than one for a given prefix.
00124  *
00125  * @param node the root of the routing tree
00126  * @param scan_prefix the prefix for which to add the rule (must not contain non-digits)
00127  * @param flags user defined flags
00128  * @param mask mask for user defined flags
00129  * @param full_prefix the whole scan prefix
00130  * @param max_targets the number of targets
00131  * @param prob the weight of the rule
00132  * @param rewrite_hostpart the rewrite_host of the rule
00133  * @param strip the number of digits to be stripped off userpart before prepending prefix
00134  * @param rewrite_local_prefix the rewrite prefix
00135  * @param rewrite_local_suffix the rewrite suffix
00136  * @param status the status of the rule
00137  * @param hash_index the hash index of the rule
00138  * @param backup indicates if the route is backed up by another. only 
00139                  useful if status==0, if set, it is the hash value
00140                  of another rule
00141   * @param backed_up an -1-termintated array of hash indices of the route 
00142                     for which this route is backup
00143  * @param comment a comment for the route rule
00144  *
00145  * @return 0 on success, -1 on failure
00146  *
00147  * @see add_route()
00148  */
00149 int add_route_to_tree(struct dtrie_node_t *node, const str * scan_prefix,
00150       flag_t flags, flag_t mask, const str * full_prefix, int max_targets, double prob,
00151       const str * rewrite_hostpart, int strip, const str * rewrite_local_prefix,
00152       const str * rewrite_local_suffix, int status, int hash_index, 
00153       int backup, int * backed_up, const str * comment) {
00154    void **ret;
00155    struct route_flags *rf;
00156 
00157    ret = dtrie_contains(node, scan_prefix->s, scan_prefix->len, cr_match_mode);
00158 
00159    rf = add_route_flags((struct route_flags **)ret, flags, mask);
00160    if (rf == NULL) {
00161       LM_ERR("cannot insert route flags into list\n");
00162       return -1;
00163    }
00164 
00165    if (ret == NULL) {
00166       /* node does not exist */
00167       if (dtrie_insert(node, scan_prefix->s, scan_prefix->len, rf, cr_match_mode) != 0) {
00168          LM_ERR("cannot insert route flags into d-trie\n");
00169          return -1;
00170       }
00171    }
00172 
00173    /* Now add rule to flags */
00174    return add_route_rule(rf, full_prefix, max_targets, prob, rewrite_hostpart, strip,
00175                                     rewrite_local_prefix, rewrite_local_suffix, status, hash_index,
00176                                     backup, backed_up, comment);
00177 }
00178 
00179 
00180 /**
00181  * Adds the given failure route information to the failure prefix tree identified by
00182  * failure_node. scan_prefix, host, reply_code, flags identifies the number for which
00183  * the information is and the next_domain parameters defines where to continue
00184  * routing in case of a match.
00185  *
00186  * @param failure_node the root of the failure routing tree
00187  * @param scan_prefix the prefix for which to add the rule (must not contain non-digits)
00188  * @param full_prefix the whole scan prefix
00189  * @param host the hostname last tried
00190  * @param reply_code the reply code 
00191  * @param flags user defined flags
00192  * @param mask mask for user defined flags
00193  * @param next_domain continue routing with this domain id
00194  * @param comment a comment for the route rule
00195  *
00196  * @return 0 on success, -1 on failure
00197  *
00198  * @see add_route()
00199  */
00200 int add_failure_route_to_tree(struct dtrie_node_t * failure_node, const str * scan_prefix,
00201       const str * full_prefix, const str * host, const str * reply_code,
00202       const flag_t flags, const flag_t mask, const int next_domain, const str * comment) {
00203    void **ret;
00204    struct failure_route_rule *frr;
00205 
00206    ret = dtrie_contains(failure_node, scan_prefix->s, scan_prefix->len, cr_match_mode);
00207 
00208    frr = add_failure_route_rule((struct failure_route_rule **)ret, full_prefix, host, reply_code, flags, mask, next_domain, comment);
00209    if (frr == NULL) {
00210       LM_ERR("cannot insert failure route rule into list\n");
00211       return -1;
00212       }
00213 
00214    if (ret == NULL) {
00215       /* node does not exist */
00216       if (dtrie_insert(failure_node, scan_prefix->s, scan_prefix->len, frr, cr_match_mode) != 0) {
00217          LM_ERR("cannot insert failure route rule into d-trie\n");
00218          return -1;
00219       }
00220    }
00221 
00222    return 0;
00223 }
00224 
00225 
00226 /**
00227  * Compares the IDs of two domain data structures.
00228  * A NULL pointer is always greater than any ID.
00229  *
00230  * @return -1 if v1 < v2, 0 if v1 == v2, 1 if v1 > v2
00231  */
00232 int compare_domain_data(const void *v1, const void *v2) {
00233   struct domain_data_t *d1 = *(struct domain_data_t * const *)v1;
00234    struct domain_data_t *d2 = *(struct domain_data_t * const *)v2;
00235    if (d1 == NULL) {
00236       if (d2 == NULL) return 0;
00237       else return 1;
00238    }
00239    else {
00240       if (d2 == NULL) return -1;
00241       else {
00242          if (d1->id < d2->id) return -1;
00243          else if (d1->id > d2->id) return 1;
00244          else return 0;
00245       }
00246    }
00247 }

Generated on Mon May 21 18:00:25 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6