cr_domain.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2007-2008 1&1 Internet AG
00005  *
00006  * This file is part of SIP-router, a free SIP server.
00007  *
00008  * SIP-router 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  * SIP-router 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 
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 
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 
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 
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 
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 
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 
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 
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 }