00001 /* 00002 * $Id: sip_msg.c 4518 2008-07-28 15:39:28Z henningw $ 00003 * 00004 * SIP message related functions 00005 * 00006 * Copyright (C) 2001-2003 FhG Fokus 00007 * 00008 * This file is part of Kamailio, a free SIP server. 00009 * 00010 * Kamailio is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version 00014 * 00015 * Kamailio is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with this program; if not, write to the Free Software 00022 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 */ 00024 00025 /*! 00026 * \file 00027 * \brief SIP registrar module - SIP message related functions 00028 * \ingroup registrar 00029 */ 00030 00031 00032 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" /* Module parameters */ 00039 #include "regtime.h" /* act_time */ 00040 #include "rerrno.h" 00041 #include "sip_msg.h" 00042 00043 00044 static struct hdr_field* act_contact; 00045 00046 00047 /*! \brief 00048 * Return value of Expires header field 00049 * if the HF exists converted to absolute 00050 * time, if the HF doesn't exist, returns 00051 * default value; 00052 */ 00053 static inline int get_expires_hf(struct sip_msg* _m) 00054 { 00055 exp_body_t* p; 00056 00057 if (_m->expires) { 00058 p = (exp_body_t*)_m->expires->parsed; 00059 if (p->valid) { 00060 if (p->val != 0) { 00061 return p->val + act_time; 00062 } else return 0; 00063 } else return act_time + default_expires; 00064 } else { 00065 return act_time + default_expires; 00066 } 00067 } 00068 00069 00070 /*! \brief 00071 * Parse the whole message and bodies of all header fields 00072 * that will be needed by registrar 00073 */ 00074 int parse_message(struct sip_msg* _m) 00075 { 00076 struct hdr_field* ptr; 00077 00078 if (parse_headers(_m, HDR_EOH_F, 0) == -1) { 00079 rerrno = R_PARSE; 00080 LM_ERR("failed to parse headers\n"); 00081 return -1; 00082 } 00083 00084 if (!_m->to) { 00085 rerrno = R_TO_MISS; 00086 LM_ERR("To not found\n"); 00087 return -2; 00088 } 00089 00090 if (!_m->callid) { 00091 rerrno = R_CID_MISS; 00092 LM_ERR("Call-ID not found\n"); 00093 return -3; 00094 } 00095 00096 if (!_m->cseq) { 00097 rerrno = R_CS_MISS; 00098 LM_ERR("CSeq not found\n"); 00099 return -4; 00100 } 00101 00102 if (_m->expires && !_m->expires->parsed && (parse_expires(_m->expires) < 0)) { 00103 rerrno = R_PARSE_EXP; 00104 LM_ERR("failed to parse expires body\n"); 00105 return -5; 00106 } 00107 00108 if (_m->contact) { 00109 ptr = _m->contact; 00110 while(ptr) { 00111 if (ptr->type == HDR_CONTACT_T) { 00112 if (!ptr->parsed && (parse_contact(ptr) < 0)) { 00113 rerrno = R_PARSE_CONT; 00114 LM_ERR("failed to parse Contact body\n"); 00115 return -6; 00116 } 00117 } 00118 ptr = ptr->next; 00119 } 00120 } 00121 00122 return 0; 00123 } 00124 00125 00126 /*! \brief 00127 * Check if the originating REGISTER message was formed correctly 00128 * The whole message must be parsed before calling the function 00129 * _s indicates whether the contact was star 00130 */ 00131 int check_contacts(struct sip_msg* _m, int* _s) 00132 { 00133 struct hdr_field* p; 00134 contact_t* c; 00135 00136 *_s = 0; 00137 /* Message without contacts is OK */ 00138 if (_m->contact == 0) return 0; 00139 00140 if (((contact_body_t*)_m->contact->parsed)->star == 1) { 00141 /* The first Contact HF is star */ 00142 /* Expires must be zero */ 00143 if (get_expires_hf(_m) > 0) { 00144 rerrno = R_STAR_EXP; 00145 return 1; 00146 } 00147 00148 /* Message must contain no contacts */ 00149 if (((contact_body_t*)_m->contact->parsed)->contacts) { 00150 rerrno = R_STAR_CONT; 00151 return 1; 00152 } 00153 00154 /* Message must contain no other Contact HFs */ 00155 p = _m->contact->next; 00156 while(p) { 00157 if (p->type == HDR_CONTACT_T) { 00158 rerrno = R_STAR_CONT; 00159 return 1; 00160 } 00161 p = p->next; 00162 } 00163 00164 *_s = 1; 00165 } else { /* The first Contact HF is not star */ 00166 /* Message must contain no star Contact HF */ 00167 p = _m->contact->next; 00168 while(p) { 00169 if (p->type == HDR_CONTACT_T) { 00170 if (((contact_body_t*)p->parsed)->star == 1) { 00171 rerrno = R_STAR_CONT; 00172 return 1; 00173 } 00174 /* check also the lenght of all contacts */ 00175 for(c=((contact_body_t*)p->parsed)->contacts ; c ; c=c->next) { 00176 if (c->uri.len > CONTACT_MAX_SIZE 00177 || (c->received && c->received->len>RECEIVED_MAX_SIZE) ) { 00178 rerrno = R_CONTACT_LEN; 00179 return 1; 00180 } 00181 } 00182 } 00183 p = p->next; 00184 } 00185 } 00186 00187 return 0; 00188 } 00189 00190 00191 /*! \brief 00192 * Get the first contact in message 00193 */ 00194 contact_t* get_first_contact(struct sip_msg* _m) 00195 { 00196 if (_m->contact == 0) return 0; 00197 00198 act_contact = _m->contact; 00199 return (((contact_body_t*)_m->contact->parsed)->contacts); 00200 } 00201 00202 00203 /*! \brief 00204 * Get next contact in message 00205 */ 00206 contact_t* get_next_contact(contact_t* _c) 00207 { 00208 struct hdr_field* p; 00209 if (_c->next == 0) { 00210 p = act_contact->next; 00211 while(p) { 00212 if (p->type == HDR_CONTACT_T) { 00213 act_contact = p; 00214 return (((contact_body_t*)p->parsed)->contacts); 00215 } 00216 p = p->next; 00217 } 00218 return 0; 00219 } else { 00220 return _c->next; 00221 } 00222 } 00223 00224 00225 /*! \brief 00226 * Calculate absolute expires value per contact as follows: 00227 * 1) If the contact has expires value, use the value. If it 00228 * is not zero, add actual time to it 00229 * 2) If the contact has no expires parameter, use expires 00230 * header field in the same way 00231 * 3) If the message contained no expires header field, use 00232 * the default value 00233 */ 00234 void calc_contact_expires(struct sip_msg* _m, param_t* _ep, int* _e) 00235 { 00236 if (!_ep || !_ep->body.len) { 00237 *_e = get_expires_hf(_m); 00238 } else { 00239 if (str2int(&_ep->body, (unsigned int*)_e) < 0) { 00240 *_e = default_expires; 00241 } 00242 /* Convert to absolute value */ 00243 if (*_e != 0) *_e += act_time; 00244 } 00245 00246 if ((*_e != 0) && ((*_e - act_time) < min_expires)) { 00247 *_e = min_expires + act_time; 00248 } 00249 00250 if ((*_e != 0) && max_expires && ((*_e - act_time) > max_expires)) { 00251 *_e = max_expires + act_time; 00252 } 00253 } 00254 00255 00256 /*! \brief 00257 * Calculate contact q value as follows: 00258 * 1) If q parameter exists, use it 00259 * 2) If the parameter doesn't exist, use the default value 00260 */ 00261 int calc_contact_q(param_t* _q, qvalue_t* _r) 00262 { 00263 if (!_q || (_q->body.len == 0)) { 00264 *_r = default_q; 00265 } else { 00266 if (str2q(_r, _q->body.s, _q->body.len) < 0) { 00267 rerrno = R_INV_Q; /* Invalid q parameter */ 00268 LM_ERR("invalid q parameter\n"); 00269 return -1; 00270 } 00271 } 00272 return 0; 00273 }
1.5.6