Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00033 #include "../../parser/hf.h"
00034 #include "../../dprint.h"
00035 #include "../../parser/parse_expires.h"
00036 #include "../../ut.h"
00037 #include "../../qvalue.h"
00038 #include "reg_mod.h"
00039 #include "regtime.h"
00040 #include "rerrno.h"
00041 #include "sip_msg.h"
00042 #include "config.h"
00043 #include <stdlib.h>
00044
00045 static struct hdr_field* act_contact;
00046
00050 static inline int get_expire_val(void)
00051 {
00052 int expires = cfg_get(registrar, registrar_cfg, default_expires);
00053 int range = cfg_get(registrar, registrar_cfg, default_expires_range);
00054
00055 if(range == 0) return expires;
00056
00057 return expires - (float)range/100 * expires + (float)(rand()%100)/100 * 2 * (float)range/100 * expires;
00058 }
00059
00060
00067 static inline int get_expires_hf(struct sip_msg* _m)
00068 {
00069 exp_body_t* p;
00070 if (_m->expires) {
00071 p = (exp_body_t*)_m->expires->parsed;
00072 if (p->valid) {
00073 if (p->val != 0) {
00074 return p->val + act_time;
00075 } else return 0;
00076 } else {
00077 return act_time + get_expire_val();
00078 }
00079 } else
00080 return act_time + get_expire_val();
00081 }
00082
00083
00088 int parse_message(struct sip_msg* _m)
00089 {
00090 struct hdr_field* ptr;
00091
00092 if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
00093 rerrno = R_PARSE;
00094 LM_ERR("failed to parse headers\n");
00095 return -1;
00096 }
00097
00098 if (!_m->to) {
00099 rerrno = R_TO_MISS;
00100 LM_ERR("To not found\n");
00101 return -2;
00102 }
00103
00104 if (!_m->callid) {
00105 rerrno = R_CID_MISS;
00106 LM_ERR("Call-ID not found\n");
00107 return -3;
00108 }
00109
00110 if (!_m->cseq) {
00111 rerrno = R_CS_MISS;
00112 LM_ERR("CSeq not found\n");
00113 return -4;
00114 }
00115
00116 if (_m->expires && !_m->expires->parsed && (parse_expires(_m->expires) < 0)) {
00117 rerrno = R_PARSE_EXP;
00118 LM_ERR("failed to parse expires body\n");
00119 return -5;
00120 }
00121
00122 if (_m->contact) {
00123 ptr = _m->contact;
00124 while(ptr) {
00125 if (ptr->type == HDR_CONTACT_T) {
00126 if (!ptr->parsed && (parse_contact(ptr) < 0)) {
00127 rerrno = R_PARSE_CONT;
00128 LM_ERR("failed to parse Contact body\n");
00129 return -6;
00130 }
00131 }
00132 ptr = ptr->next;
00133 }
00134 }
00135
00136 return 0;
00137 }
00138
00139
00145 int check_contacts(struct sip_msg* _m, int* _s)
00146 {
00147 struct hdr_field* p;
00148 contact_t* c;
00149
00150 *_s = 0;
00151
00152 if (_m->contact == 0) return 0;
00153
00154 if (((contact_body_t*)_m->contact->parsed)->star == 1) {
00155
00156
00157 if (get_expires_hf(_m) > 0) {
00158 rerrno = R_STAR_EXP;
00159 return 1;
00160 }
00161
00162
00163 if (((contact_body_t*)_m->contact->parsed)->contacts) {
00164 rerrno = R_STAR_CONT;
00165 return 1;
00166 }
00167
00168
00169 p = _m->contact->next;
00170 while(p) {
00171 if (p->type == HDR_CONTACT_T) {
00172 rerrno = R_STAR_CONT;
00173 return 1;
00174 }
00175 p = p->next;
00176 }
00177
00178 *_s = 1;
00179 } else {
00180
00181 p = _m->contact->next;
00182 while(p) {
00183 if (p->type == HDR_CONTACT_T) {
00184 if (((contact_body_t*)p->parsed)->star == 1) {
00185 rerrno = R_STAR_CONT;
00186 return 1;
00187 }
00188
00189 for(c=((contact_body_t*)p->parsed)->contacts ; c ; c=c->next) {
00190 if (c->uri.len > CONTACT_MAX_SIZE
00191 || (c->received && c->received->len>RECEIVED_MAX_SIZE) ) {
00192 rerrno = R_CONTACT_LEN;
00193 return 1;
00194 }
00195 }
00196 }
00197 p = p->next;
00198 }
00199 }
00200
00201 return 0;
00202 }
00203
00204
00208 contact_t* get_first_contact(struct sip_msg* _m)
00209 {
00210 if (_m->contact == 0) return 0;
00211
00212 act_contact = _m->contact;
00213 return (((contact_body_t*)_m->contact->parsed)->contacts);
00214 }
00215
00216
00220 contact_t* get_next_contact(contact_t* _c)
00221 {
00222 struct hdr_field* p;
00223 if (_c->next == 0) {
00224 p = act_contact->next;
00225 while(p) {
00226 if (p->type == HDR_CONTACT_T) {
00227 act_contact = p;
00228 return (((contact_body_t*)p->parsed)->contacts);
00229 }
00230 p = p->next;
00231 }
00232 return 0;
00233 } else {
00234 return _c->next;
00235 }
00236 }
00237
00238
00248 void calc_contact_expires(struct sip_msg* _m, param_t* _ep, int* _e)
00249 {
00250 if (!_ep || !_ep->body.len) {
00251 *_e = get_expires_hf(_m);
00252 } else {
00253 if (str2int(&_ep->body, (unsigned int*)_e) < 0) {
00254 *_e = get_expire_val();
00255 }
00256
00257 if (*_e != 0) *_e += act_time;
00258 }
00259
00260 if ((*_e != 0) && ((*_e - act_time) < cfg_get(registrar, registrar_cfg, min_expires))) {
00261 *_e = cfg_get(registrar, registrar_cfg, min_expires) + act_time;
00262 }
00263
00264 if ((*_e != 0) && cfg_get(registrar, registrar_cfg, max_expires) && ((*_e - act_time) > cfg_get(registrar, registrar_cfg, max_expires))) {
00265 *_e = cfg_get(registrar, registrar_cfg, max_expires) + act_time;
00266 }
00267 }
00268
00269
00275 int calc_contact_q(param_t* _q, qvalue_t* _r)
00276 {
00277 if (!_q || (_q->body.len == 0)) {
00278 *_r = cfg_get(registrar, registrar_cfg, default_q);
00279 } else {
00280 if (str2q(_r, _q->body.s, _q->body.len) < 0) {
00281 rerrno = R_INV_Q;
00282 LM_ERR("invalid q parameter\n");
00283 return -1;
00284 }
00285 }
00286 return 0;
00287 }