rr_mod.c

Go to the documentation of this file.
00001 /*
00002  * $Id: rr_mod.c 5575 2009-02-10 10:13:29Z henningw $
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
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
00025  * \brief Route & Record-Route module
00026  * \ingroup rr
00027  */
00028 
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <sys/types.h>
00033 #include <regex.h>
00034 
00035 #include "../../sr_module.h"
00036 #include "../../ut.h"
00037 #include "../../error.h"
00038 #include "../../pvar.h"
00039 #include "../../mem/mem.h"
00040 #include "../../mod_fix.h"
00041 #include "loose.h"
00042 #include "record.h"
00043 #include "rr_cb.h"
00044 #include "api.h"
00045 
00046 #ifdef ENABLE_USER_CHECK
00047 #include <string.h>
00048 #include "../../str.h"
00049 str i_user;
00050 char *ignore_user = NULL;
00051 #endif
00052 
00053 int append_fromtag = 1;    /*!< append from tag by default */
00054 int enable_double_rr = 1;  /*!< enable using of 2 RR by default */
00055 int enable_full_lr = 0;    /*!< compatibilty mode disabled by default */
00056 int add_username = 0;      /*!< do not add username by default */
00057 
00058 static unsigned int last_rr_msg;
00059 
00060 MODULE_VERSION
00061 
00062 static int  mod_init(void);static void mod_destroy(void);
00063 /* fixup functions */
00064 static int direction_fixup(void** param, int param_no);
00065 static int it_list_fixup(void** param, int param_no);
00066 /* wrapper functions */
00067 static int w_record_route(struct sip_msg *,char *, char *);
00068 static int w_record_route_preset(struct sip_msg *,char *, char *);
00069 static int w_add_rr_param(struct sip_msg *,char *, char *);
00070 static int w_check_route_param(struct sip_msg *,char *, char *);
00071 static int w_is_direction(struct sip_msg *,char *, char *);
00072 
00073 /*!
00074  * \brief Exported functions
00075  */
00076 static cmd_export_t cmds[] = {
00077    {"loose_route",          (cmd_function)loose_route,         0, 0, 0,
00078          REQUEST_ROUTE},
00079    {"record_route",         (cmd_function)w_record_route,      0, 0, 0,
00080          REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00081    {"record_route",         (cmd_function)w_record_route,      1, it_list_fixup, 0,
00082          REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00083    {"record_route_preset",  (cmd_function)w_record_route_preset, 1, it_list_fixup, 0,
00084          REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00085    {"add_rr_param",         (cmd_function)w_add_rr_param,   1, it_list_fixup, 0,
00086          REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00087    {"check_route_param",    (cmd_function)w_check_route_param, 1, fixup_regexp_null, fixup_free_regexp_null,
00088          REQUEST_ROUTE},
00089    {"is_direction",         (cmd_function)w_is_direction,      1, direction_fixup, 0,
00090          REQUEST_ROUTE},
00091    {"load_rr",              (cmd_function)load_rr,             0, 0, 0, 0},
00092    {0, 0, 0, 0, 0, 0}
00093 };
00094 
00095 
00096 /*!
00097  * \brief Exported parameters
00098  */
00099 static param_export_t params[] ={ 
00100    {"append_fromtag",   INT_PARAM, &append_fromtag},
00101    {"enable_double_rr", INT_PARAM, &enable_double_rr},
00102    {"enable_full_lr",      INT_PARAM, &enable_full_lr},
00103 #ifdef ENABLE_USER_CHECK
00104    {"ignore_user",      STR_PARAM, &ignore_user},
00105 #endif
00106    {"add_username",     INT_PARAM, &add_username},
00107    {0, 0, 0 }
00108 };
00109 
00110 
00111 struct module_exports exports = {
00112    "rr",
00113    DEFAULT_DLFLAGS,  /*!< dlopen flags */
00114    cmds,       /*!< Exported functions */
00115    params,        /*!< Exported parameters */
00116    0,          /*!< exported statistics */
00117    0,          /*!< exported MI functions */
00118    0,          /*!< exported pseudo-variables */
00119    0,          /*!< extra processes */
00120    mod_init,         /*!< initialize module */
00121    0,          /*!< response function*/
00122    mod_destroy,      /*!< destroy function */
00123    0           /*!< per-child init function */
00124 };
00125 
00126 
00127 static int mod_init(void)
00128 {
00129 #ifdef ENABLE_USER_CHECK
00130    if(ignore_user)
00131    {
00132       i_user.s = ignore_user;
00133       i_user.len = strlen(ignore_user);
00134    }
00135    else
00136    {
00137       i_user.s = 0;
00138       i_user.len = 0;
00139    }
00140 #endif
00141    return 0;
00142 }
00143 
00144 
00145 static void mod_destroy(void)
00146 {
00147    destroy_rrcb_lists();
00148 }
00149 
00150 
00151 static int it_list_fixup(void** param, int param_no)
00152 {
00153    pv_elem_t *model;
00154    str s;
00155    if(*param)
00156    {
00157       s.s = (char*)(*param); s.len = strlen(s.s);
00158       if(pv_parse_format(&s, &model)<0)
00159       {
00160          LM_ERR("wrong format[%s]\n",(char*)(*param));
00161          return E_UNSPEC;
00162       }
00163       *param = (void*)model;
00164    }
00165    return 0;
00166 }
00167 
00168 
00169 static int direction_fixup(void** param, int param_no)
00170 {
00171    char *s;
00172    int n;
00173 
00174    if (!append_fromtag) {
00175       LM_ERR("usage of \"is_direction\" function requires parameter"
00176             "\"append_fromtag\" enabled!!");
00177       return E_CFG;
00178    }
00179    if (param_no==1) {
00180       n = 0;
00181       s = (char*) *param;
00182       if ( strcasecmp(s,"downstream")==0 ) {
00183          n = RR_FLOW_DOWNSTREAM;
00184       } else if ( strcasecmp(s,"upstream")==0 ) {
00185          n = RR_FLOW_UPSTREAM;
00186       } else {
00187          LM_ERR("unknown direction '%s'\n",s);
00188          return E_CFG;
00189       }
00190       /* free string */
00191       pkg_free(*param);
00192       /* replace it with the flag */
00193       *param = (void*)(unsigned long)n;
00194    }
00195    return 0;
00196 }
00197 
00198 
00199 static int w_record_route(struct sip_msg *msg, char *key, char *bar)
00200 {
00201    str s;
00202 
00203    if (msg->id == last_rr_msg) {
00204       LM_ERR("Double attempt to record-route\n");
00205       return -1;
00206    }
00207 
00208    if (key && pv_printf_s(msg, (pv_elem_t*)key, &s)<0) {
00209       LM_ERR("failed to print the format\n");
00210       return -1;
00211    }
00212    if ( record_route( msg, key?&s:0 )<0 )
00213       return -1;
00214 
00215    last_rr_msg = msg->id;
00216    return 1;
00217 }
00218 
00219 
00220 static int w_record_route_preset(struct sip_msg *msg, char *key, char *bar)
00221 {
00222    str s;
00223 
00224    if (msg->id == last_rr_msg) {
00225       LM_ERR("Duble attempt to record-route\n");
00226       return -1;
00227    }
00228 
00229    if (pv_printf_s(msg, (pv_elem_t*)key, &s)<0) {
00230       LM_ERR("failed to print the format\n");
00231       return -1;
00232    }
00233    if ( record_route_preset( msg, &s)<0 )
00234       return -1;
00235 
00236    last_rr_msg = msg->id;
00237    return 1;
00238 }
00239 
00240 
00241 static int w_add_rr_param(struct sip_msg *msg, char *key, char *foo)
00242 {
00243    str s;
00244 
00245    if (pv_printf_s(msg, (pv_elem_t*)key, &s)<0) {
00246       LM_ERR("failed to print the format\n");
00247       return -1;
00248    }
00249    return ((add_rr_param( msg, &s)==0)?1:-1);
00250 }
00251 
00252 
00253 
00254 static int w_check_route_param(struct sip_msg *msg,char *re, char *foo)
00255 {
00256    return ((check_route_param(msg,(regex_t*)re)==0)?1:-1);
00257 }
00258 
00259 
00260 
00261 static int w_is_direction(struct sip_msg *msg,char *dir, char *foo)
00262 {
00263    return ((is_direction(msg,(int)(long)dir)==0)?1:-1);
00264 }

Generated on Thu May 24 12:00:30 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6