msg_parser.c

Go to the documentation of this file.
00001 /*
00002  * $Id: msg_parser.c 4892 2008-09-11 17:44:28Z 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  * History:
00023  * ---------
00024  *  2003-02-28  scratchpad compatibility abandoned (jiri)
00025  *  2003-01-29  scrathcpad removed (jiri)
00026  *  2003-01-27  next baby-step to removing ZT - PRESERVE_ZT (jiri)
00027  *  2003-03-31  removed msg->repl_add_rm (andrei)
00028  *  2003-04-26 ZSW (jiri)
00029  *  2003-05-01  parser extended to support Accept header field (janakj)
00030  *  2005-03-02  free_via_list(vb) on via parse error (andrei)
00031  *  2006-02-17 Session-Expires, Min-SE (dhsueh@somanetworks.com)
00032  *  2006-03-02 header of same type are linked as sibling (bogdan)
00033  *  2006-11-28 Added statistic support for bad message headers.
00034  *             (Jeffrey Magder - SOMA Networks)
00035  *  2008-09-09 Added sdp parsing support (osas)
00036  */
00037 
00038 /*!
00039  * \file
00040  * \brief SIP message parser
00041  * \ingroup parser
00042  */
00043 
00044 /*! \defgroup parser SIP message parser
00045  *  \brief SIP message parser 
00046  */
00047 
00048 #include <string.h>
00049 #include <stdlib.h>
00050 
00051 #include "msg_parser.h"
00052 #include "parser_f.h"
00053 #include "../ut.h"
00054 #include "../error.h"
00055 #include "../dprint.h"
00056 #include "../data_lump_rpl.h"
00057 #include "../mem/mem.h"
00058 #include "../error.h"
00059 #include "../globals.h"
00060 #include "../core_stats.h"
00061 #include "../errinfo.h"
00062 #include "parse_hname2.h"
00063 #include "parse_uri.h"
00064 #include "parse_content.h"
00065 
00066 #ifdef DEBUG_DMALLOC
00067 #include <mem/dmalloc.h>
00068 #endif
00069 
00070 
00071 #define parse_hname(_b,_e,_h) parse_hname2((_b),(_e),(_h))
00072 
00073 /*! number of via's encountered */
00074 int via_cnt;
00075 
00076 /*! returns pointer to next header line, and fill hdr_f ;
00077  * if at end of header returns pointer to the last crlf  (always buf)*/
00078 char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
00079 {
00080 
00081    char* tmp;
00082    char *match;
00083    struct via_body *vb;
00084    struct cseq_body* cseq_b;
00085    struct to_body* to_b;
00086    int integer;
00087 
00088    if ((*buf)=='\n' || (*buf)=='\r'){
00089       /* double crlf or lflf or crcr */
00090       LM_DBG("found end of header\n");
00091       hdr->type=HDR_EOH_T;
00092       return buf;
00093    }
00094 
00095    tmp=parse_hname(buf, end, hdr);
00096    if (hdr->type==HDR_ERROR_T){
00097       LM_ERR("bad header\n");
00098       goto error;
00099    }
00100 
00101    /* eliminate leading whitespace */
00102    tmp=eat_lws_end(tmp, end); 
00103    if (tmp>=end) {
00104       LM_ERR("hf empty\n");
00105       goto error;
00106    }
00107 
00108    /* if header-field well-known, parse it, find its end otherwise ;
00109     * after leaving the hdr->type switch, tmp should be set to the
00110     * next header field
00111     */
00112    switch(hdr->type){
00113       case HDR_VIA_T:
00114          /* keep number of vias parsed -- we want to report it in
00115             replies for diagnostic purposes */
00116          via_cnt++;
00117          vb=pkg_malloc(sizeof(struct via_body));
00118          if (vb==0){
00119             LM_ERR("out of pkg memory\n");
00120             goto error;
00121          }
00122          memset(vb,0,sizeof(struct via_body));
00123          hdr->body.s=tmp;
00124          tmp=parse_via(tmp, end, vb);
00125          if (vb->error==PARSE_ERROR){
00126             LM_ERR("bad via\n");
00127             set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
00128                   "error parsing Via");
00129             set_err_reply(400, "bad Via header");
00130 
00131             free_via_list(vb);
00132             goto error;
00133          }
00134          hdr->parsed=vb;
00135          vb->hdr.s=hdr->name.s;
00136          vb->hdr.len=hdr->name.len;
00137          hdr->body.len=tmp-hdr->body.s;
00138          break;
00139       case HDR_CSEQ_T:
00140          cseq_b=pkg_malloc(sizeof(struct cseq_body));
00141          if (cseq_b==0){
00142             LM_ERR("out of pkg memory\n");
00143             goto error;
00144          }
00145          memset(cseq_b, 0, sizeof(struct cseq_body));
00146          hdr->body.s=tmp;
00147          tmp=parse_cseq(tmp, end, cseq_b);
00148          if (cseq_b->error==PARSE_ERROR){
00149             LM_ERR("bad cseq\n");
00150             set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
00151                   "error parsing CSeq`");
00152             set_err_reply(400, "bad CSeq header");
00153             pkg_free(cseq_b);
00154             goto error;
00155          }
00156          hdr->parsed=cseq_b;
00157          hdr->body.len=tmp-hdr->body.s;
00158          LM_DBG("cseq <%.*s>: <%.*s> <%.*s>\n",
00159                hdr->name.len, ZSW(hdr->name.s), 
00160                cseq_b->number.len, ZSW(cseq_b->number.s), 
00161                cseq_b->method.len, cseq_b->method.s);
00162          break;
00163       case HDR_TO_T:
00164          to_b=pkg_malloc(sizeof(struct to_body));
00165          if (to_b==0){
00166             LM_ERR("out of pkg memory\n");
00167             goto error;
00168          }
00169          memset(to_b, 0, sizeof(struct to_body));
00170          hdr->body.s=tmp;
00171          tmp=parse_to(tmp, end,to_b);
00172          if (to_b->error==PARSE_ERROR){
00173             LM_ERR("bad to header\n");
00174             set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
00175                   "error parsing To header");
00176             set_err_reply(400, "bad To header");
00177             pkg_free(to_b);
00178             goto error;
00179          }
00180          hdr->parsed=to_b;
00181          hdr->body.len=tmp-hdr->body.s;
00182          LM_DBG("<%.*s> [%d]; uri=[%.*s] \n",
00183             hdr->name.len, ZSW(hdr->name.s), 
00184             hdr->body.len, to_b->uri.len,ZSW(to_b->uri.s));
00185          LM_DBG("to body [%.*s]\n",to_b->body.len, ZSW(to_b->body.s));
00186          break;
00187       case HDR_CONTENTLENGTH_T:
00188          hdr->body.s=tmp;
00189          tmp=parse_content_length(tmp,end, &integer);
00190          if (tmp==0){
00191             LM_ERR("bad content_length header\n");
00192             set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
00193                   "error parsing Content-Length");
00194             set_err_reply(400, "bad Content-Length header");
00195             goto error;
00196          }
00197          hdr->parsed=(void*)(long)integer;
00198          hdr->body.len=tmp-hdr->body.s;
00199          LM_DBG("content_length=%d\n", (int)(long)hdr->parsed);
00200          break;
00201       case HDR_SUPPORTED_T:
00202       case HDR_CONTENTTYPE_T:
00203       case HDR_FROM_T:
00204       case HDR_CALLID_T:
00205       case HDR_CONTACT_T:
00206       case HDR_ROUTE_T:
00207       case HDR_RECORDROUTE_T:
00208       case HDR_PATH_T:
00209       case HDR_MAXFORWARDS_T:
00210       case HDR_AUTHORIZATION_T:
00211       case HDR_EXPIRES_T:
00212       case HDR_PROXYAUTH_T:
00213       case HDR_PROXYREQUIRE_T:
00214       case HDR_UNSUPPORTED_T:
00215       case HDR_ALLOW_T:
00216       case HDR_EVENT_T:
00217       case HDR_ACCEPT_T:
00218       case HDR_ACCEPTLANGUAGE_T:
00219       case HDR_ORGANIZATION_T:
00220       case HDR_PRIORITY_T:
00221       case HDR_SUBJECT_T:
00222       case HDR_USERAGENT_T:
00223       case HDR_CONTENTDISPOSITION_T:
00224       case HDR_ACCEPTDISPOSITION_T:
00225       case HDR_DIVERSION_T:
00226       case HDR_RPID_T:
00227       case HDR_REFER_TO_T:
00228       case HDR_SESSION_EXPIRES_T:
00229       case HDR_MIN_SE_T:
00230       case HDR_PPI_T:
00231       case HDR_PAI_T:
00232       case HDR_PRIVACY_T:
00233       case HDR_RETRY_AFTER_T:
00234       case HDR_OTHER_T:
00235          /* just skip over it */
00236          hdr->body.s=tmp;
00237          /* find end of header */
00238          /* find lf */
00239          do{
00240             match=memchr(tmp, '\n', end-tmp);
00241             if (match){
00242                match++;
00243             }else {
00244                LM_ERR("bad body for <%s>(%d)\n", hdr->name.s, hdr->type);
00245                /* abort(); */
00246                set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
00247                   "error parsing headers");
00248                set_err_reply(400, "bad headers");
00249                tmp=end;
00250                goto error;
00251             }
00252             tmp=match;
00253          }while( match<end &&( (*match==' ')||(*match=='\t') ) );
00254          tmp=match;
00255          hdr->body.len=match-hdr->body.s;
00256          break;
00257       default:
00258          LM_CRIT("unknown header type %d\n", hdr->type);
00259          goto error;
00260    }
00261    /* jku: if \r covered by current length, shrink it */
00262    trim_r( hdr->body );
00263    hdr->len=tmp-hdr->name.s;
00264    return tmp;
00265 error:
00266    LM_DBG("error exit\n");
00267    update_stat( bad_msg_hdr, 1);
00268    hdr->type=HDR_ERROR_T;
00269    hdr->len=tmp-hdr->name.s;
00270    return tmp;
00271 }
00272 
00273 
00274 
00275 /*! parse the headers and adds them to msg->headers and msg->to, from etc.
00276  * It stops when all the headers requested in flags were parsed, on error
00277  * (bad header) or end of headers
00278    \note: it continues where it previously stopped and goes ahead until
00279    end is encountered or desired HFs are found; if you call it twice
00280    for the same HF which is present only once, it will fail the second
00281    time; if you call it twice and the HF is found on second time too,
00282    it's not replaced in the well-known HF pointer but just added to
00283    header list; if you want to use a dumb convenience function which will
00284    give you the first occurrence of a header you are interested in,
00285    look at check_transaction_quadruple
00286 */
00287 int parse_headers(struct sip_msg* msg, hdr_flags_t flags, int next)
00288 {
00289    struct hdr_field *hf;
00290    struct hdr_field *itr;
00291    char* tmp;
00292    char* rest;
00293    char* end;
00294    hdr_flags_t orig_flag;
00295 
00296 #define link_sibling_hdr(_hook, _hdr) \
00297    do{ \
00298       if (msg->_hook==0) msg->_hook=_hdr;\
00299          else {\
00300             for(itr=msg->_hook;itr->sibling;itr=itr->sibling);\
00301             itr->sibling = _hdr;\
00302          }\
00303    }while(0)
00304 
00305    end=msg->buf+msg->len;
00306    tmp=msg->unparsed;
00307    
00308    if (next) {
00309       orig_flag = msg->parsed_flag;
00310       msg->parsed_flag &= ~flags;
00311    }else
00312       orig_flag=0; 
00313    
00314    LM_DBG("flags=%llx\n", (unsigned long long)flags);
00315    while( tmp<end && (flags & msg->parsed_flag) != flags){
00316       hf=pkg_malloc(sizeof(struct hdr_field));
00317       if (hf==0){
00318          ser_error=E_OUT_OF_MEM;
00319          LM_ERR("pkg memory allocation failed\n");
00320          goto error;
00321       }
00322       memset(hf,0, sizeof(struct hdr_field));
00323       hf->type=HDR_ERROR_T;
00324       rest=get_hdr_field(tmp, msg->buf+msg->len, hf);
00325       switch (hf->type){
00326          case HDR_ERROR_T:
00327             LM_INFO("bad header field\n");
00328             goto  error;
00329          case HDR_EOH_T:
00330             msg->eoh=tmp; /* or rest?*/
00331             msg->parsed_flag|=HDR_EOH_F;
00332             pkg_free(hf);
00333             goto skip;
00334          case HDR_OTHER_T: /*do nothing*/
00335             break;
00336          case HDR_CALLID_T:
00337             if (msg->callid==0) msg->callid=hf;
00338             msg->parsed_flag|=HDR_CALLID_F;
00339             break;
00340          case HDR_TO_T:
00341             if (msg->to==0) msg->to=hf;
00342             msg->parsed_flag|=HDR_TO_F;
00343             break;
00344          case HDR_CSEQ_T:
00345             if (msg->cseq==0) msg->cseq=hf;
00346             msg->parsed_flag|=HDR_CSEQ_F;
00347             break;
00348          case HDR_FROM_T:
00349             if (msg->from==0) msg->from=hf;
00350             msg->parsed_flag|=HDR_FROM_F;
00351             break;
00352          case HDR_CONTACT_T:
00353             link_sibling_hdr(contact,hf);
00354             msg->parsed_flag|=HDR_CONTACT_F;
00355             break;
00356          case HDR_MAXFORWARDS_T:
00357             if(msg->maxforwards==0) msg->maxforwards=hf;
00358             msg->parsed_flag|=HDR_MAXFORWARDS_F;
00359             break;
00360          case HDR_ROUTE_T:
00361             link_sibling_hdr(route,hf);
00362             msg->parsed_flag|=HDR_ROUTE_F;
00363             break;
00364          case HDR_RECORDROUTE_T:
00365             link_sibling_hdr(record_route,hf);
00366             msg->parsed_flag|=HDR_RECORDROUTE_F;
00367             break;
00368          case HDR_PATH_T:
00369             link_sibling_hdr(path,hf);
00370             msg->parsed_flag|=HDR_PATH_F;
00371             break;
00372          case HDR_CONTENTTYPE_T:
00373             if (msg->content_type==0) msg->content_type = hf;
00374             msg->parsed_flag|=HDR_CONTENTTYPE_F;
00375             break;
00376          case HDR_CONTENTLENGTH_T:
00377             if (msg->content_length==0) msg->content_length = hf;
00378             msg->parsed_flag|=HDR_CONTENTLENGTH_F;
00379             break;
00380          case HDR_AUTHORIZATION_T:
00381             link_sibling_hdr(authorization,hf);
00382             msg->parsed_flag|=HDR_AUTHORIZATION_F;
00383             break;
00384          case HDR_EXPIRES_T:
00385             if (msg->expires==0) msg->expires = hf;
00386             msg->parsed_flag|=HDR_EXPIRES_F;
00387             break;
00388          case HDR_PROXYAUTH_T:
00389             link_sibling_hdr(proxy_auth,hf);
00390             msg->parsed_flag|=HDR_PROXYAUTH_F;
00391             break;
00392          case HDR_PROXYREQUIRE_T:
00393             link_sibling_hdr(proxy_require,hf);
00394             msg->parsed_flag|=HDR_PROXYREQUIRE_F;
00395             break;
00396          case HDR_SUPPORTED_T:
00397             link_sibling_hdr(supported,hf);
00398             msg->parsed_flag|=HDR_SUPPORTED_F;
00399             break;
00400          case HDR_UNSUPPORTED_T:
00401             link_sibling_hdr(unsupported,hf);
00402             msg->parsed_flag|=HDR_UNSUPPORTED_F;
00403             break;
00404          case HDR_ALLOW_T:
00405             link_sibling_hdr(allow,hf);
00406             msg->parsed_flag|=HDR_ALLOW_F;
00407             break;
00408          case HDR_EVENT_T:
00409             link_sibling_hdr(event,hf);
00410             msg->parsed_flag|=HDR_EVENT_F;
00411             break;
00412          case HDR_ACCEPT_T:
00413             link_sibling_hdr(accept,hf);
00414             msg->parsed_flag|=HDR_ACCEPT_F;
00415             break;
00416          case HDR_ACCEPTLANGUAGE_T:
00417             link_sibling_hdr(accept_language,hf);
00418             msg->parsed_flag|=HDR_ACCEPTLANGUAGE_F;
00419             break;
00420          case HDR_ORGANIZATION_T:
00421             if (msg->organization==0) msg->organization = hf;
00422             msg->parsed_flag|=HDR_ORGANIZATION_F;
00423             break;
00424          case HDR_PRIORITY_T:
00425             if (msg->priority==0) msg->priority = hf;
00426             msg->parsed_flag|=HDR_PRIORITY_F;
00427             break;
00428          case HDR_SUBJECT_T:
00429             if (msg->subject==0) msg->subject = hf;
00430             msg->parsed_flag|=HDR_SUBJECT_F;
00431             break;
00432          case HDR_USERAGENT_T:
00433             if (msg->user_agent==0) msg->user_agent = hf;
00434             msg->parsed_flag|=HDR_USERAGENT_F;
00435             break;
00436          case HDR_CONTENTDISPOSITION_T:
00437             if (msg->content_disposition==0) msg->content_disposition = hf;
00438             msg->parsed_flag|=HDR_CONTENTDISPOSITION_F;
00439             break;
00440          case HDR_ACCEPTDISPOSITION_T:
00441             link_sibling_hdr(accept_disposition,hf);
00442             msg->parsed_flag|=HDR_ACCEPTDISPOSITION_F;
00443             break;
00444          case HDR_DIVERSION_T:
00445             link_sibling_hdr(diversion,hf);
00446             msg->parsed_flag|=HDR_DIVERSION_F;
00447             break;
00448          case HDR_RPID_T:
00449             if (msg->rpid==0) msg->rpid = hf;
00450             msg->parsed_flag|=HDR_RPID_F;
00451             break;
00452          case HDR_REFER_TO_T:
00453             if (msg->refer_to==0) msg->refer_to = hf;
00454             msg->parsed_flag|=HDR_REFER_TO_F;
00455             break;
00456          case HDR_SESSION_EXPIRES_T:
00457             if ( msg->session_expires == 0 ) msg->session_expires = hf;
00458             msg->parsed_flag |= HDR_SESSION_EXPIRES_F;
00459             break;
00460          case HDR_MIN_SE_T:
00461             if ( msg->min_se == 0 ) msg->min_se = hf;
00462             msg->parsed_flag |= HDR_MIN_SE_F;
00463             break;
00464          case HDR_PPI_T:
00465             if (msg->ppi==0) msg->ppi = hf;
00466             msg->parsed_flag|=HDR_PPI_F;
00467             break;
00468          case HDR_PAI_T:
00469             if (msg->pai==0) msg->pai = hf;
00470             msg->parsed_flag|=HDR_PAI_F;
00471             break;
00472          case HDR_PRIVACY_T:
00473             if (msg->privacy==0) msg->privacy = hf;
00474             msg->parsed_flag|=HDR_PRIVACY_F;
00475             break;
00476          case HDR_RETRY_AFTER_T:
00477             break;
00478          case HDR_VIA_T:
00479             link_sibling_hdr(h_via1,hf);
00480             msg->parsed_flag|=HDR_VIA_F;
00481             LM_DBG("via found, flags=%llx\n", (unsigned long long)flags);
00482             if (msg->via1==0) {
00483                LM_DBG("this is the first via\n");
00484                msg->h_via1=hf;
00485                msg->via1=hf->parsed;
00486                if (msg->via1->next){
00487                   msg->via2=msg->via1->next;
00488                   msg->parsed_flag|=HDR_VIA2_F;
00489                }
00490             }else if (msg->via2==0){
00491                msg->h_via2=hf;
00492                msg->via2=hf->parsed;
00493                msg->parsed_flag|=HDR_VIA2_F;
00494                LM_DBG("parse_headers: this is the second via\n");
00495             }
00496             break;
00497          default:
00498             LM_CRIT("unknown header type %d\n", hf->type);
00499             goto error;
00500       }
00501       /* add the header to the list*/
00502       if (msg->last_header==0){
00503          msg->headers=hf;
00504          msg->last_header=hf;
00505       }else{
00506          msg->last_header->next=hf;
00507          msg->last_header=hf;
00508       }
00509 #ifdef EXTRA_DEBUG
00510       LM_DBG("header field type %d, name=<%.*s>, body=<%.*s>\n",
00511          hf->type, 
00512          hf->name.len, ZSW(hf->name.s), 
00513          hf->body.len, ZSW(hf->body.s));
00514 #endif
00515       tmp=rest;
00516    }
00517 skip:
00518    msg->unparsed=tmp;
00519    return 0;
00520 
00521 error:
00522    ser_error=E_BAD_REQ;
00523    if (hf) pkg_free(hf);
00524    if (next) msg->parsed_flag |= orig_flag;
00525    return -1;
00526 }
00527 
00528 
00529 
00530 
00531 
00532 /*! returns 0 if ok, -1 for errors */
00533 int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
00534 {
00535 
00536    char *tmp;
00537    char* rest;
00538    char* first_via;
00539    char* second_via;
00540    struct msg_start *fl;
00541    int offset;
00542    hdr_flags_t flags;
00543 
00544    /* eat crlf from the beginning */
00545    for (tmp=buf; (*tmp=='\n' || *tmp=='\r')&&
00546          (unsigned int)(tmp-buf) < len ; tmp++);
00547    offset=tmp-buf;
00548    fl=&(msg->first_line);
00549    rest=parse_first_line(tmp, len-offset, fl);
00550    offset+=rest-tmp;
00551    tmp=rest;
00552    switch(fl->type){
00553       case SIP_INVALID:
00554          LM_DBG("invalid message\n");
00555          goto error;
00556          break;
00557       case SIP_REQUEST:
00558          LM_DBG("SIP Request:\n");
00559          LM_DBG(" method:  <%.*s>\n",fl->u.request.method.len,
00560             ZSW(fl->u.request.method.s));
00561          LM_DBG(" uri:     <%.*s>\n",fl->u.request.uri.len,
00562             ZSW(fl->u.request.uri.s));
00563          LM_DBG(" version: <%.*s>\n",fl->u.request.version.len,
00564             ZSW(fl->u.request.version.s));
00565          flags=HDR_VIA_F;
00566          break;
00567       case SIP_REPLY:
00568          LM_DBG("SIP Reply  (status):\n");
00569          LM_DBG(" version: <%.*s>\n",fl->u.reply.version.len,
00570                ZSW(fl->u.reply.version.s));
00571          LM_DBG(" status:  <%.*s>\n", fl->u.reply.status.len,
00572                ZSW(fl->u.reply.status.s));
00573          LM_DBG(" reason:  <%.*s>\n", fl->u.reply.reason.len,
00574                ZSW(fl->u.reply.reason.s));
00575          /* flags=HDR_VIA | HDR_VIA2; */
00576          /* we don't try to parse VIA2 for local messages; -Jiri */
00577          flags=HDR_VIA_F;
00578          break;
00579       default:
00580          LM_DBG("unknown type %d\n",fl->type);
00581          goto error;
00582    }
00583    msg->unparsed=tmp;
00584    /*find first Via: */
00585    first_via=0;
00586    second_via=0;
00587    if (parse_headers(msg, flags, 0)==-1) goto error;
00588 
00589 #ifdef EXTRA_DEBUG
00590    /* dump parsed data */
00591    if (msg->via1){
00592       LM_DBG(" first  via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>",
00593          msg->via1->name.len, 
00594          ZSW(msg->via1->name.s), 
00595          msg->via1->version.len,
00596          ZSW(msg->via1->version.s),
00597          msg->via1->transport.len,
00598          ZSW(msg->via1->transport.s), 
00599          msg->via1->host.len,
00600          ZSW(msg->via1->host.s),
00601          msg->via1->port_str.len, 
00602          ZSW(msg->via1->port_str.s), 
00603          msg->via1->port);
00604       if (msg->via1->params.s)  LM_DBG(";<%.*s>", 
00605             msg->via1->params.len, ZSW(msg->via1->params.s));
00606       if (msg->via1->comment.s) 
00607             LM_DBG(" <%.*s>", 
00608                msg->via1->comment.len, ZSW(msg->via1->comment.s));
00609       LM_DBG ("\n");
00610    }
00611    if (msg->via2){
00612       LM_DBG(" first  via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>",
00613          msg->via2->name.len, 
00614          ZSW(msg->via2->name.s), 
00615          msg->via2->version.len,
00616          ZSW(msg->via2->version.s),
00617          msg->via2->transport.len, 
00618          ZSW(msg->via2->transport.s), 
00619          msg->via2->host.len,
00620          ZSW(msg->via2->host.s),
00621          msg->via2->port_str.len, 
00622          ZSW(msg->via2->port_str.s), 
00623          msg->via2->port);
00624       if (msg->via2->params.s)  LM_DBG(";<%.*s>", 
00625             msg->via2->params.len, ZSW(msg->via2->params.s));
00626       if (msg->via2->comment.s) LM_DBG(" <%.*s>", 
00627             msg->via2->comment.len, ZSW(msg->via2->comment.s));
00628       LM_DBG ("\n");
00629    }
00630 #endif
00631    
00632 
00633 #ifdef EXTRA_DEBUG
00634    LM_DBG("exiting\n");
00635 #endif
00636 
00637    return 0;
00638    
00639 error:
00640    /* more debugging, msg->orig is/should be null terminated*/
00641    LM_ERR("message=<%.*s>\n", (int)msg->len, ZSW(msg->buf));
00642    return -1;
00643 }
00644 
00645 
00646 
00647 void free_reply_lump( struct lump_rpl *lump)
00648 {
00649    struct lump_rpl *foo, *bar;
00650    for(foo=lump;foo;)
00651    {
00652       bar=foo->next;
00653       free_lump_rpl(foo);
00654       foo = bar;
00655    }
00656 }
00657 
00658 
00659 /*only the content*/
00660 void free_sip_msg(struct sip_msg* msg)
00661 {
00662    if (msg->new_uri.s) { pkg_free(msg->new_uri.s); msg->new_uri.len=0; }
00663    if (msg->dst_uri.s) { pkg_free(msg->dst_uri.s); msg->dst_uri.len=0; }
00664    if (msg->path_vec.s) { pkg_free(msg->path_vec.s); msg->path_vec.len=0; }
00665    if (msg->headers)     free_hdr_field_lst(msg->headers);
00666    if (msg->sdp)         free_sdp(&(msg->sdp));
00667    if (msg->add_rm)      free_lump_list(msg->add_rm);
00668    if (msg->body_lumps)  free_lump_list(msg->body_lumps);
00669    if (msg->reply_lump)   free_reply_lump(msg->reply_lump);
00670    /* don't free anymore -- now a pointer to a static buffer */
00671 #  ifdef DYN_BUF
00672    pkg_free(msg->buf); 
00673 #  endif
00674 }
00675 
00676 
00677 /*! make sure all HFs needed for transaction identification have been
00678    parsed; return 0 if those HFs can't be found
00679 */
00680 int check_transaction_quadruple( struct sip_msg* msg )
00681 {
00682    if ( parse_headers(msg, HDR_FROM_F|HDR_TO_F|HDR_CALLID_F|HDR_CSEQ_F,0)!=-1
00683       && msg->from && msg->to && msg->callid && msg->cseq ) {
00684       return 1;
00685    } else {
00686       ser_error=E_BAD_TUPEL;
00687       return 0;
00688    }
00689 }
00690 
00691 
00692 /*!
00693  * Make a private copy of the string and assign it to dst_uri
00694  */
00695 int set_dst_uri(struct sip_msg* msg, str* uri)
00696 {
00697    char* ptr;
00698 
00699    if (!msg || !uri) {
00700       LM_ERR("invalid parameter value\n");
00701       return -1;
00702    }
00703 
00704    if (msg->dst_uri.s && (msg->dst_uri.len >= uri->len)) {
00705       memcpy(msg->dst_uri.s, uri->s, uri->len);
00706       msg->dst_uri.len = uri->len;
00707    } else {
00708       ptr = (char*)pkg_malloc(uri->len);
00709       if (!ptr) {
00710          LM_ERR("not enough pkg memory\n");
00711          return -1;
00712       }
00713 
00714       memcpy(ptr, uri->s, uri->len);
00715       if (msg->dst_uri.s) pkg_free(msg->dst_uri.s);
00716       msg->dst_uri.s = ptr;
00717       msg->dst_uri.len = uri->len;
00718    }
00719    return 0;
00720 }
00721 
00722 /*!
00723  * Make a private copy of the string and assign it to path_vec
00724  */
00725 int set_path_vector(struct sip_msg* msg, str* path)
00726 {
00727    char* ptr;
00728 
00729    if (!msg || !path) {
00730       LM_ERR("invalid parameter value\n");
00731       return -1;
00732    }
00733 
00734    if (msg->path_vec.s && (msg->path_vec.len >= path->len)) {
00735       memcpy(msg->path_vec.s, path->s, path->len);
00736       msg->path_vec.len = path->len;
00737    } else {
00738       ptr = (char*)pkg_malloc(path->len);
00739       if (!ptr) {
00740          LM_ERR("not enough pkg memory\n");
00741          return -1;
00742       }
00743 
00744       memcpy(ptr, path->s, path->len);
00745       if (msg->path_vec.s) pkg_free(msg->path_vec.s);
00746       msg->path_vec.s = ptr;
00747       msg->path_vec.len = path->len;
00748    }
00749    return 0;
00750 }

Generated on Wed May 23 20:00:28 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6