|
@@ -17,185 +17,20 @@
|
|
|
#include "../mem/mem.h"
|
|
|
#include "../error.h"
|
|
|
#include "../globals.h"
|
|
|
+#include "parse_hname.h"
|
|
|
+#include "parse_hname2.h"
|
|
|
+
|
|
|
|
|
|
#ifdef DEBUG_DMALLOC
|
|
|
#include <mem/dmalloc.h>
|
|
|
#endif
|
|
|
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/* parses the first line, returns pointer to next line & fills fl;
|
|
|
- also modifies buffer (to avoid extra copy ops) */
|
|
|
-char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl)
|
|
|
-{
|
|
|
-
|
|
|
- char *tmp;
|
|
|
- char* second;
|
|
|
- char* third;
|
|
|
- char* nl;
|
|
|
- int offset;
|
|
|
- /* int l; */
|
|
|
- char* end;
|
|
|
- char s1,s2,s3;
|
|
|
- char *prn;
|
|
|
- unsigned int t;
|
|
|
-
|
|
|
- /* grammar:
|
|
|
- request = method SP uri SP version CRLF
|
|
|
- response = version SP status SP reason CRLF
|
|
|
- (version = "SIP/2.0")
|
|
|
- */
|
|
|
-
|
|
|
-
|
|
|
- end=buffer+len;
|
|
|
- /* see if it's a reply (status) */
|
|
|
-
|
|
|
- /* jku -- parse well-known methods */
|
|
|
-
|
|
|
- /* drop messages which are so short they are for sure useless;
|
|
|
- utilize knowledge of minimum size in parsing the first
|
|
|
- token
|
|
|
- */
|
|
|
- if (len <=16 ) {
|
|
|
- LOG(L_INFO, "ERROR: parse_first_line: message too short: %d\n", len);
|
|
|
- goto error1;
|
|
|
- }
|
|
|
-
|
|
|
- tmp=buffer;
|
|
|
- /* is it perhaps a reply, ie does it start with "SIP...." ? */
|
|
|
- if ( (*tmp=='S' || *tmp=='s') &&
|
|
|
- strncasecmp( tmp+1, SIP_VERSION+1, SIP_VERSION_LEN-1)==0 &&
|
|
|
- (*(tmp+SIP_VERSION_LEN)==' ')) {
|
|
|
- fl->type=SIP_REPLY;
|
|
|
- fl->u.reply.version.len=SIP_VERSION_LEN;
|
|
|
- tmp=buffer+SIP_VERSION_LEN;
|
|
|
- } else IFISMETHOD( INVITE, 'I' )
|
|
|
- else IFISMETHOD( CANCEL, 'C')
|
|
|
- else IFISMETHOD( ACK, 'A' )
|
|
|
- else IFISMETHOD( BYE, 'B' )
|
|
|
- /* if you want to add another method XXX, include METHOD_XXX in
|
|
|
- H-file (this is the value which you will take later in
|
|
|
- processing and define XXX_LEN as length of method name;
|
|
|
- then just call IFISMETHOD( XXX, 'X' ) ... 'X' is the first
|
|
|
- latter; everything must be capitals
|
|
|
- */
|
|
|
- else {
|
|
|
- /* neither reply, nor any of known method requests,
|
|
|
- let's believe it is an unknown method request
|
|
|
- */
|
|
|
- tmp=eat_token_end(buffer,buffer+len);
|
|
|
- if ((tmp==buffer)||(tmp>=end)){
|
|
|
- LOG(L_INFO, "ERROR:parse_first_line: empty or bad first line\n");
|
|
|
- goto error1;
|
|
|
- }
|
|
|
- if (*tmp!=' ') {
|
|
|
- LOG(L_INFO, "ERROR:parse_first_line: method not followed by SP\n");
|
|
|
- goto error1;
|
|
|
- }
|
|
|
- fl->type=SIP_REQUEST;
|
|
|
- fl->u.request.method_value=METHOD_OTHER;
|
|
|
- fl->u.request.method.len=tmp-buffer;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /* identifying type of message over now;
|
|
|
- tmp points at space after; go ahead */
|
|
|
-
|
|
|
- fl->u.request.method.s=buffer; /* store ptr to first token */
|
|
|
- (*tmp)=0; /* mark the 1st token end */
|
|
|
- second=tmp+1; /* jump to second token */
|
|
|
- offset=second-buffer;
|
|
|
-
|
|
|
-/* EoJku */
|
|
|
-
|
|
|
- /* next element */
|
|
|
- tmp=eat_token_end(second, second+len-offset);
|
|
|
- if (tmp>=end){
|
|
|
- goto error;
|
|
|
- }
|
|
|
- offset+=tmp-second;
|
|
|
- third=eat_space_end(tmp, tmp+len-offset);
|
|
|
- offset+=third-tmp;
|
|
|
- if ((third==tmp)||(tmp>=end)){
|
|
|
- goto error;
|
|
|
- }
|
|
|
- *tmp=0; /* mark the end of the token */
|
|
|
- fl->u.request.uri.s=second;
|
|
|
- fl->u.request.uri.len=tmp-second;
|
|
|
-
|
|
|
- /* jku: parse status code */
|
|
|
- if (fl->type==SIP_REPLY) {
|
|
|
- if (fl->u.request.uri.len!=3) {
|
|
|
- LOG(L_INFO, "ERROR:parse_first_line: len(status code)!=3: %s\n",
|
|
|
- second );
|
|
|
- goto error;
|
|
|
- }
|
|
|
- s1=*second; s2=*(second+1);s3=*(second+2);
|
|
|
- if (s1>='0' && s1<='9' &&
|
|
|
- s2>='0' && s2<='9' &&
|
|
|
- s3>='0' && s3<='9' ) {
|
|
|
- fl->u.reply.statuscode=(s1-'0')*100+10*(s2-'0')+(s3-'0');
|
|
|
- } else {
|
|
|
- LOG(L_INFO, "ERROR:parse_first_line: status_code non-numerical: %s\n",
|
|
|
- second );
|
|
|
- goto error;
|
|
|
- }
|
|
|
- }
|
|
|
- /* EoJku */
|
|
|
-
|
|
|
- /* last part: for a request it must be the version, for a reply
|
|
|
- * it can contain almost anything, including spaces, so we don't care
|
|
|
- * about it*/
|
|
|
- if (fl->type==SIP_REQUEST){
|
|
|
- tmp=eat_token_end(third,third+len-offset);
|
|
|
- offset+=tmp-third;
|
|
|
- if ((tmp==third)||(tmp>=end)){
|
|
|
- goto error;
|
|
|
- }
|
|
|
- if (! is_empty_end(tmp, tmp+len-offset)){
|
|
|
- goto error;
|
|
|
- }
|
|
|
- }else{
|
|
|
- tmp=eat_token2_end(third,third+len-offset,'\r'); /* find end of line
|
|
|
- ('\n' or '\r') */
|
|
|
- if (tmp>=end){ /* no crlf in packet => invalid */
|
|
|
- goto error;
|
|
|
- }
|
|
|
- offset+=tmp-third;
|
|
|
- }
|
|
|
- nl=eat_line(tmp,len-offset);
|
|
|
- if (nl>=end){ /* no crlf in packet or only 1 line > invalid */
|
|
|
- goto error;
|
|
|
- }
|
|
|
- *tmp=0;
|
|
|
- fl->u.request.version.s=third;
|
|
|
- fl->u.request.version.len=tmp-third;
|
|
|
-
|
|
|
- return nl;
|
|
|
-
|
|
|
-error:
|
|
|
- LOG(L_INFO, "ERROR:parse_first_line: bad %s first line\n",
|
|
|
- (fl->type==SIP_REPLY)?"reply(status)":"request");
|
|
|
-
|
|
|
- LOG(L_INFO, "ERROR: at line 0 char %d: \n", offset );
|
|
|
- prn=pkg_malloc( offset );
|
|
|
- if (prn) {
|
|
|
- for (t=0; t<offset; t++)
|
|
|
- if (*(buffer+t)) *(prn+t)=*(buffer+t);
|
|
|
- else *(prn+t)='°';
|
|
|
- LOG(L_INFO, "ERROR: parsed so far: %.*s\n", offset, prn );
|
|
|
- pkg_free( prn );
|
|
|
- };
|
|
|
-error1:
|
|
|
- fl->type=SIP_INVALID;
|
|
|
- LOG(L_INFO, "ERROR:parse_first_line: bad message\n");
|
|
|
- /* skip line */
|
|
|
- nl=eat_line(buffer,len);
|
|
|
- return nl;
|
|
|
-}
|
|
|
-
|
|
|
+#ifdef NEW_HNAME
|
|
|
+# define parse_hname(_b,_e,_h) parse_hname2((_b),(_e),(_h))
|
|
|
+#else
|
|
|
+# define parse_hname(_b,_e,_h) parse_hname1((_b),(_e),(_h))
|
|
|
+#endif
|
|
|
|
|
|
|
|
|
/* returns pointer to next header line, and fill hdr_f ;
|
|
@@ -326,267 +161,6 @@ error:
|
|
|
|
|
|
|
|
|
|
|
|
-char* parse_hostport(char* buf, str* host, short int* port)
|
|
|
-{
|
|
|
- char *tmp;
|
|
|
- int err;
|
|
|
-
|
|
|
- host->s=buf;
|
|
|
- for(tmp=buf;(*tmp)&&(*tmp!=':');tmp++);
|
|
|
- host->len=tmp-buf;
|
|
|
- if (*tmp==0){
|
|
|
- *port=0;
|
|
|
- }else{
|
|
|
- *tmp=0;
|
|
|
- *port=str2s((unsigned char*)(tmp+1), strlen(tmp+1), &err);
|
|
|
- if (err ){
|
|
|
- LOG(L_INFO,
|
|
|
- "ERROR: hostport: trailing chars in port number: %s\n",
|
|
|
- tmp+1);
|
|
|
- /* report error? */
|
|
|
- }
|
|
|
- }
|
|
|
- return host->s;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/*BUGGY*/
|
|
|
-char * parse_cseq(char *buf, char* end, struct cseq_body* cb)
|
|
|
-{
|
|
|
- char *t, *m, *m_end;
|
|
|
- char c;
|
|
|
-
|
|
|
- cb->error=PARSE_ERROR;
|
|
|
- t=eat_space_end(buf, end);
|
|
|
- if (t>=end) goto error;
|
|
|
-
|
|
|
- cb->number.s=t;
|
|
|
- t=eat_token_end(t, end);
|
|
|
- if (t>=end) goto error;
|
|
|
- m=eat_space_end(t, end);
|
|
|
- m_end=eat_token_end(m, end);
|
|
|
- *t=0; /*null terminate it*/
|
|
|
- cb->number.len=t-cb->number.s;
|
|
|
-
|
|
|
- if (m_end>=end) goto error;
|
|
|
- if (m_end==m){
|
|
|
- /* null method*/
|
|
|
- LOG(L_ERR, "ERROR:parse_cseq: no method found\n");
|
|
|
- goto error;
|
|
|
- }
|
|
|
- cb->method.s=m;
|
|
|
- t=m_end;
|
|
|
- c=*t;
|
|
|
- *t=0; /*null terminate it*/
|
|
|
- cb->method.len=t-cb->method.s;
|
|
|
- t++;
|
|
|
- /*check if the header ends here*/
|
|
|
- if (c=='\n') goto check_continue;
|
|
|
- do{
|
|
|
- for (;(t<end)&&((*t==' ')||(*t=='\t')||(*t=='\r'));t++);
|
|
|
- if (t>=end) goto error;
|
|
|
- if (*t!='\n'){
|
|
|
- LOG(L_ERR, "ERROR:parse_cseq: unexpected char <%c> at end of"
|
|
|
- " cseq\n", *t);
|
|
|
- goto error;
|
|
|
- }
|
|
|
- t++;
|
|
|
-check_continue:
|
|
|
- ;
|
|
|
- }while( (t<end) && ((*t==' ')||(*t=='\t')) );
|
|
|
-
|
|
|
- cb->error=PARSE_OK;
|
|
|
- return t;
|
|
|
-error:
|
|
|
- LOG(L_ERR, "ERROR: parse_cseq: bad cseq\n");
|
|
|
- return t;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/* buf= pointer to begining of uri (sip:[email protected]:5060;a=b?h=i)
|
|
|
- len= len of uri
|
|
|
-returns: fills uri & returns <0 on error or 0 if ok */
|
|
|
-int parse_uri(char *buf, int len, struct sip_uri* uri)
|
|
|
-{
|
|
|
- char* next, *end;
|
|
|
- char *user, *passwd, *host, *port, *params, *headers, *ipv6;
|
|
|
- int host_len, port_len, params_len, headers_len;
|
|
|
- int ret;
|
|
|
-
|
|
|
-
|
|
|
- ret=0;
|
|
|
- host_len=0;
|
|
|
- end=buf+len;
|
|
|
- memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure */
|
|
|
- /* look for "sip:"*/;
|
|
|
- next=q_memchr(buf, ':', len);
|
|
|
- if ((next==0)||(strncmp(buf,"sip",next-buf)!=0)){
|
|
|
- LOG(L_DBG, "ERROR: parse_uri: bad sip uri\n");
|
|
|
- ser_error=ret=E_BAD_URI;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- buf=next+1; /* next char after ':' */
|
|
|
- if (buf>end){
|
|
|
- LOG(L_DBG, "ERROR: parse_uri: uri too short\n");
|
|
|
- ser_error=ret=E_BAD_URI;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- /*look for '@' */
|
|
|
- next=q_memchr(buf,'@', end-buf);
|
|
|
- if (next==0){
|
|
|
- /* no '@' found, => no userinfo */
|
|
|
- uri->user.s=0;
|
|
|
- uri->passwd.s=0;
|
|
|
- host=buf;
|
|
|
- }else{
|
|
|
- /* found it */
|
|
|
- user=buf;
|
|
|
- /* try to find passwd */
|
|
|
- passwd=q_memchr(user,':', next-user);
|
|
|
- if (passwd==0){
|
|
|
- /* no ':' found => no password */
|
|
|
- uri->passwd.s=0;
|
|
|
- uri->user.s=(char*)pkg_malloc(next-user+1);
|
|
|
- if (uri->user.s==0){
|
|
|
- LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
|
|
|
- ser_error=ret=E_OUT_OF_MEM;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- memcpy(uri->user.s, user, next-user);
|
|
|
- uri->user.len=next-user;
|
|
|
- uri->user.s[next-user]=0; /* null terminate it,
|
|
|
- usefull for easy printing*/
|
|
|
- }else{
|
|
|
- uri->user.s=(char*)pkg_malloc(passwd-user+1);
|
|
|
- if (uri->user.s==0){
|
|
|
- LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
|
|
|
- ser_error=ret=E_OUT_OF_MEM;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- memcpy(uri->user.s, user, passwd-user);
|
|
|
- uri->user.len=passwd-user;
|
|
|
- uri->user.s[passwd-user]=0;
|
|
|
- passwd++; /*skip ':' */
|
|
|
- uri->passwd.s=(char*)pkg_malloc(next-passwd+1);
|
|
|
- if (uri->passwd.s==0){
|
|
|
- LOG(L_ERR,"ERROR:parse_uri: memory allocation failure\n");
|
|
|
- ser_error=ret=E_OUT_OF_MEM;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- memcpy(uri->passwd.s, passwd, next-passwd);
|
|
|
- uri->passwd.len=next-passwd;
|
|
|
- uri->passwd.s[next-passwd]=0;
|
|
|
- }
|
|
|
- host=next+1; /* skip '@' */
|
|
|
- }
|
|
|
- /* try to find the rest */
|
|
|
- if(host>=end){
|
|
|
- LOG(L_DBG, "ERROR: parse_uri: missing hostport\n");
|
|
|
- ser_error=ret=E_UNSPEC;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- next=host;
|
|
|
- ipv6=q_memchr(host, '[', end-host);
|
|
|
- if (ipv6){
|
|
|
- host=ipv6+1; /* skip '[' in "[3ffe::abbcd]" */
|
|
|
- if (host>=end){
|
|
|
- LOG(L_DBG, "ERROR: parse_uri: bad ipv6 uri\n");
|
|
|
- ret=E_UNSPEC;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- ipv6=q_memchr(host, ']', end-host);
|
|
|
- if ((ipv6==0)||(ipv6==host)){
|
|
|
- LOG(L_DBG, "ERROR: parse_uri: bad ipv6 uri - null address"
|
|
|
- " or missing ']'\n");
|
|
|
- ret=E_UNSPEC;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- host_len=ipv6-host;
|
|
|
- next=ipv6;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- headers=q_memchr(next,'?',end-next);
|
|
|
- params=q_memchr(next,';',end-next);
|
|
|
- port=q_memchr(next,':',end-next);
|
|
|
- if (host_len==0){ /* host not ipv6 addr */
|
|
|
- host_len=(port)?port-host:(params)?params-host:(headers)?headers-host:
|
|
|
- end-host;
|
|
|
- }
|
|
|
- /* get host */
|
|
|
- uri->host.s=pkg_malloc(host_len+1);
|
|
|
- if (uri->host.s==0){
|
|
|
- LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
|
|
|
- ret=E_OUT_OF_MEM;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- memcpy(uri->host.s, host, host_len);
|
|
|
- uri->host.len=host_len;
|
|
|
- uri->host.s[host_len]=0;
|
|
|
- /* get port*/
|
|
|
- if ((port)&&(port+1<end)){
|
|
|
- port++;
|
|
|
- if ( ((params) &&(params<port))||((headers) &&(headers<port)) ){
|
|
|
- /* error -> invalid uri we found ';' or '?' before ':' */
|
|
|
- LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
|
|
|
- ser_error=ret=E_BAD_URI;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- port_len=(params)?params-port:(headers)?headers-port:end-port;
|
|
|
- uri->port.s=pkg_malloc(port_len+1);
|
|
|
- if (uri->port.s==0){
|
|
|
- LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
|
|
|
- ser_error=ret=E_OUT_OF_MEM;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- memcpy(uri->port.s, port, port_len);
|
|
|
- uri->port.len=port_len;
|
|
|
- uri->port.s[port_len]=0;
|
|
|
- }else uri->port.s=0;
|
|
|
- /* get params */
|
|
|
- if ((params)&&(params+1<end)){
|
|
|
- params++;
|
|
|
- if ((headers) && (headers<params)){
|
|
|
- /* error -> invalid uri we found '?' or '?' before ';' */
|
|
|
- LOG(L_DBG, "ERROR: parse_uri: malformed sip uri\n");
|
|
|
- ser_error=ret=E_BAD_URI;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- params_len=(headers)?headers-params:end-params;
|
|
|
- uri->params.s=pkg_malloc(params_len+1);
|
|
|
- if (uri->params.s==0){
|
|
|
- LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
|
|
|
- ser_error=ret=E_OUT_OF_MEM;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- memcpy(uri->params.s, params, params_len);
|
|
|
- uri->params.len=params_len;
|
|
|
- uri->params.s[params_len]=0;
|
|
|
- }else uri->params.s=0;
|
|
|
- /*get headers */
|
|
|
- if ((headers)&&(headers+1<end)){
|
|
|
- headers++;
|
|
|
- headers_len=end-headers;
|
|
|
- uri->headers.s=pkg_malloc(headers_len+1);
|
|
|
- if(uri->headers.s==0){
|
|
|
- LOG(L_ERR, "ERROR: parse_uri: memory allocation error\n");
|
|
|
- ser_error=ret=E_OUT_OF_MEM;
|
|
|
- goto error;
|
|
|
- }
|
|
|
- memcpy(uri->headers.s, headers, headers_len);
|
|
|
- uri->headers.len=headers_len;
|
|
|
- uri->headers.s[headers_len]=0;
|
|
|
- }else uri->headers.s=0;
|
|
|
-
|
|
|
- return ret;
|
|
|
-error:
|
|
|
- free_uri(uri);
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
/* parse the headers and adds them to msg->headers and msg->to, from etc.
|
|
|
* It stops when all the headers requested in flags were parsed, on error
|
|
|
* (bad header) or end of headers */
|
|
@@ -811,18 +385,6 @@ error:
|
|
|
|
|
|
|
|
|
|
|
|
-void free_uri(struct sip_uri* u)
|
|
|
-{
|
|
|
- if (u){
|
|
|
- if (u->user.s) pkg_free(u->user.s);
|
|
|
- if (u->passwd.s) pkg_free(u->passwd.s);
|
|
|
- if (u->host.s) pkg_free(u->host.s);
|
|
|
- if (u->port.s) pkg_free(u->port.s);
|
|
|
- if (u->params.s) pkg_free(u->params.s);
|
|
|
- if (u->headers.s) pkg_free(u->headers.s);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
void free_reply_lump( struct lump_rpl *lump)
|
|
|
{
|
|
|
struct lump_rpl *foo, *bar;
|
|
@@ -834,80 +396,6 @@ void free_reply_lump( struct lump_rpl *lump)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void free_via_param_list(struct via_param* vp)
|
|
|
-{
|
|
|
- struct via_param* foo;
|
|
|
- while(vp){
|
|
|
- foo=vp;
|
|
|
- vp=vp->next;
|
|
|
- pkg_free(foo);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-void free_via_list(struct via_body* vb)
|
|
|
-{
|
|
|
- struct via_body* foo;
|
|
|
- while(vb){
|
|
|
- foo=vb;
|
|
|
- vb=vb->next;
|
|
|
- if (foo->param_lst) free_via_param_list(foo->param_lst);
|
|
|
- pkg_free(foo);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void free_to(struct to_body* tb)
|
|
|
-{
|
|
|
- struct to_param *tp=tb->param_lst;
|
|
|
- struct to_param *foo;
|
|
|
- while (tp){
|
|
|
- foo = tp->next;
|
|
|
- pkg_free(tp);
|
|
|
- tp=foo;
|
|
|
- }
|
|
|
- pkg_free(tb);
|
|
|
-}
|
|
|
-
|
|
|
-/* frees a hdr_field structure,
|
|
|
- * WARNING: it frees only parsed (and not name.s, body.s)*/
|
|
|
-void clean_hdr_field(struct hdr_field* hf)
|
|
|
-{
|
|
|
- if (hf->parsed){
|
|
|
- switch(hf->type){
|
|
|
- case HDR_VIA:
|
|
|
- free_via_list(hf->parsed);
|
|
|
- break;
|
|
|
- case HDR_TO:
|
|
|
- free_to(hf->parsed);
|
|
|
- break;
|
|
|
- case HDR_CSEQ:
|
|
|
- pkg_free(hf->parsed);
|
|
|
- break;
|
|
|
- default:
|
|
|
- LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
|
|
|
- hf->type);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-/* frees a hdr_field list,
|
|
|
- * WARNING: frees only ->parsed and ->next*/
|
|
|
-void free_hdr_field_lst(struct hdr_field* hf)
|
|
|
-{
|
|
|
- struct hdr_field* foo;
|
|
|
-
|
|
|
- while(hf){
|
|
|
- foo=hf;
|
|
|
- hf=hf->next;
|
|
|
- clean_hdr_field(foo);
|
|
|
- pkg_free(foo);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
|
|
|
/*only the content*/
|
|
|
void free_sip_msg(struct sip_msg* msg)
|