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
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <stdio.h>
00039 #include <string.h>
00040 #include <stdlib.h>
00041
00042 #include "../../sr_module.h"
00043 #include "../../dprint.h"
00044 #include "../../error.h"
00045 #include "../../ut.h"
00046 #include "../../mem/mem.h"
00047 #include "mf_funcs.h"
00048
00049 MODULE_VERSION
00050
00051 #define MAXFWD_UPPER_LIMIT 256
00052
00053 static int max_limit = MAXFWD_UPPER_LIMIT;
00054
00055 static int fixup_maxfwd_header(void** param, int param_no);
00056 static int w_process_maxfwd_header(struct sip_msg* msg,char* str,char* str2);
00057 static int is_maxfwd_lt(struct sip_msg *msg, char *slimit, char *foo);
00058 static int mod_init(void);
00059
00060 static cmd_export_t cmds[]={
00061 {"mf_process_maxfwd_header", (cmd_function)w_process_maxfwd_header, 1,
00062 fixup_maxfwd_header, 0, REQUEST_ROUTE},
00063 {"is_maxfwd_lt", (cmd_function)is_maxfwd_lt, 1,
00064 fixup_maxfwd_header, 0, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
00065 {0,0,0,0,0,0}
00066 };
00067
00068 static param_export_t params[]={
00069 {"max_limit", INT_PARAM, &max_limit},
00070 {0,0,0}
00071 };
00072
00073
00074
00075 struct module_exports exports= {
00076 "maxfwd",
00077 DEFAULT_DLFLAGS,
00078 cmds,
00079 params,
00080 0,
00081 0,
00082 0,
00083 0,
00084 mod_init,
00085 0,
00086 0,
00087 0
00088 };
00089
00090
00091
00092 static int mod_init(void)
00093 {
00094 if ( max_limit<1 || max_limit>MAXFWD_UPPER_LIMIT ) {
00095 LM_ERR("invalid max limit (%d) [1,%d]\n",
00096 max_limit,MAXFWD_UPPER_LIMIT);
00097 return E_CFG;
00098 }
00099 return 0;
00100 }
00101
00102
00103
00104 static int fixup_maxfwd_header(void** param, int param_no)
00105 {
00106 unsigned long code;
00107 int err;
00108
00109 if (param_no==1){
00110 code=str2s(*param, strlen(*param), &err);
00111 if (err==0){
00112 if (code<1 || code>MAXFWD_UPPER_LIMIT){
00113 LM_ERR("invalid MAXFWD number <%ld> [1,%d]\n",
00114 code,MAXFWD_UPPER_LIMIT);
00115 return E_UNSPEC;
00116 }
00117 if (code>max_limit) {
00118 LM_ERR("default value <%ld> bigger than max limit(%d)\n",
00119 code, max_limit);
00120 return E_UNSPEC;
00121 }
00122 pkg_free(*param);
00123 *param=(void*)code;
00124 return 0;
00125 }else{
00126 LM_ERR("bad number <%s>\n",(char*)(*param));
00127 return E_UNSPEC;
00128 }
00129 }
00130 return 0;
00131 }
00132
00133
00134
00135 static int w_process_maxfwd_header(struct sip_msg* msg, char* str1,char* str2)
00136 {
00137 int val;
00138 str mf_value;
00139
00140 val=is_maxfwd_present(msg, &mf_value);
00141 switch (val) {
00142
00143 case -1:
00144 if (add_maxfwd_header( msg, (unsigned int)(unsigned long)str1)!=0)
00145 goto error;
00146 return 2;
00147
00148 case -2:
00149 break;
00150
00151 case 0:
00152 return -1;
00153 default:
00154 if (val>max_limit){
00155 LM_DBG("value %d decreased to %d\n", val, max_limit);
00156 val = max_limit+1;
00157 }
00158 if ( decrement_maxfwd(msg, val, &mf_value)!=0 ) {
00159 LM_ERR("decrement failed!\n");
00160 goto error;
00161 }
00162 }
00163
00164 return 1;
00165 error:
00166 return -2;
00167 }
00168
00169
00170
00171 static int is_maxfwd_lt(struct sip_msg *msg, char *slimit, char *foo)
00172 {
00173 str mf_value;
00174 int limit;
00175 int val;
00176
00177 limit = (int)(long)slimit;
00178 val = is_maxfwd_present( msg, &mf_value);
00179 LM_DBG("value = %d \n",val);
00180
00181 if ( val<0 ) {
00182
00183 return val-1;
00184 } else if ( val>=limit ) {
00185
00186 return -1;
00187 }
00188
00189 return 1;
00190 }
00191