2
0
Эх сурвалжийг харах

To parsing and tag used in ACK matching

Bogdan-Andrei Iancu 23 жил өмнө
parent
commit
0fcc274175

+ 1 - 0
modules/tm/h_table.c

@@ -170,6 +170,7 @@ struct cell*  build_cell( struct sip_msg* p_msg )
 	goto error;
    new_cell->relaied_reply_branch   = -1;
    new_cell->T_canceled = T_UNDEFINED;
+   new_cell->tag=&(get_to(new_cell->inbound_request)->tag_value);
 #ifndef USE_SYNONIM
    src[0]= p_msg->from->body;
    src[1]= p_msg->to->body;

+ 9 - 10
modules/tm/h_table.h

@@ -78,18 +78,17 @@ typedef struct cell
 
 	/* useful data */
 	/* UA Server */
-	struct sip_msg 		*inbound_request;
+	struct sip_msg             *inbound_request;
 	struct retrans_buff	outbound_response;
-	unsigned int		status;
-	str*				tag;
-	unsigned int		inbound_request_isACKed;
-	int					relaied_reply_branch;
-	int					nr_of_outgoings;
+	unsigned int                status;
+	str                                 *tag;
+	unsigned int                inbound_request_isACKed;
+	int                                 relaied_reply_branch;
+	int                                 nr_of_outgoings;
 	/* UA Clients */
-	struct retrans_buff	*outbound_request[ MAX_FORK ];
-	struct sip_msg		*inbound_response[ MAX_FORK ];
-	/* unsigned int		outbound_request_isACKed[MAX_FORK]; */
-	struct retrans_buff	*outbound_ack[ MAX_FORK ];
+	struct retrans_buff      *outbound_request[ MAX_FORK ];
+	struct sip_msg             *inbound_response[ MAX_FORK ];
+	struct retrans_buff      *outbound_ack[ MAX_FORK ];
 
 	/* protection against concurrent reply processing */
 	ser_lock_t	reply_mutex;

+ 49 - 472
modules/tm/sip_msg.c

@@ -12,474 +12,6 @@
 
 #define ROUND4(s) ((s)%4)?((s)+4)/4*4:(s)
 
-struct via_body* via_body_cloner( char* new_buf , char *org_buf , struct via_body *org_via);
-struct hdr_field* header_cloner( struct sip_msg *new_msg , struct sip_msg *org_msg, struct hdr_field *hdr);
-
-struct via_body* via_body_cloner_2( char* new_buf , char *org_buf , struct via_body *org_via, char **p);
-
-
-struct sip_msg* sip_msg_cloner_1( struct sip_msg *org_msg )
-{
-    struct sip_msg   *new_msg=0;
-    struct hdr_field  *header, *last_hdr, *new_hdr;
-
-    /* clones the sip_msg structure */
-    new_msg = (struct sip_msg*)sh_malloc( sizeof( struct sip_msg) );
-    if (!new_msg) {
-	DBG("DEBUG: sip_msg_cloner: sip_msg allocation failed\n");
-	return NULL;
-    }
-    memcpy( new_msg , org_msg , sizeof( struct sip_msg) );
-
-    /* if something bad happens during the allocation process,
-       don't try to release pointers which were cloned
-    */
-    new_msg->new_uri.s=NULL;
-    new_msg->headers=NULL;
-    new_msg->add_rm=NULL;
-    new_msg->repl_add_rm=NULL;
-    new_msg->orig=NULL;
-    new_msg->buf=NULL;
-
-    /* the original message - orig ( char*  type) */
-    new_msg->orig = (char*)sh_malloc( new_msg->len+1 );
-    if (!new_msg->orig) {
-	DBG("DEBUG: sip_msg_cloner: new_msg->orig allocation failed\n");
-	goto error;
-    }
-    memcpy( new_msg->orig , org_msg->orig, new_msg->len );
-    new_msg->orig[ new_msg->len ] = 0;
-
-    /* the scratch pad - buf ( char* type) */
-    new_msg->buf = (char*)sh_malloc( new_msg->len+1 );
-    if (!new_msg->buf) {
-	DBG("DEBUG: sip_msg_cloner:  new_msg->buf allocation failed\n");
-	goto error;
-    }
-    memcpy( new_msg->buf , org_msg->buf, new_msg->len );
-    new_msg->buf[ new_msg->len ] = 0;
-
-    /* where the parse stopped - unparsed (char* type)*/
-    new_msg->unparsed = translate_pointer( new_msg->buf , org_msg->buf , org_msg->unparsed );
-
-    /* end of header - eoh (char* type)*/
-    new_msg->eoh = translate_pointer( new_msg->buf , org_msg->buf , org_msg->eoh );
-
-    /* first_line (struct msg_start type) */
-    if ( org_msg->first_line.type==SIP_REQUEST )
-    {
-	/* method (str type) */
-	new_msg->first_line.u.request.method.s = translate_pointer( new_msg->buf , org_msg->buf , org_msg->first_line.u.request.method.s );
-	/* uri (str type) */
-	new_msg->first_line.u.request.uri.s = translate_pointer( new_msg->buf , org_msg->buf , org_msg->first_line.u.request.uri.s );
-	/* version (str type) */
-	new_msg->first_line.u.request.version.s = translate_pointer( new_msg->buf , org_msg->buf , org_msg->first_line.u.request.version.s );
-    }
-    else if ( org_msg->first_line.type==SIP_REPLY )
-    {
-	/* version (str type) */
-	new_msg->first_line.u.reply.version.s = translate_pointer( new_msg->buf , org_msg->buf , org_msg->first_line.u.reply.version.s );
-	/* status (str type) */
-	new_msg->first_line.u.reply.status.s =  translate_pointer( new_msg->buf , org_msg->buf , org_msg->first_line.u.reply.status.s );
-	/* reason (str type) */
-	new_msg->first_line.u.reply.reason.s =  translate_pointer( new_msg->buf , org_msg->buf , org_msg->first_line.u.reply.reason.s );
-    }
-
-    /* new_uri  ( str type )*/
-	if (org_msg->new_uri.s){
-		if (!(new_msg->new_uri.s = (char*)sh_malloc( org_msg->new_uri.len )))
-		{
-			DBG("DEBUG: sip_msg_cloner: new_msg->new_uri.s allocation failed\n");
-			goto error;
-		}
-		memcpy( new_msg->new_uri.s , org_msg->new_uri.s ,
-				org_msg->new_uri.len );
-	}
-
-    /* add_rm ( struct lump* )  -> have to be changed!!!!!!! */
-    new_msg->add_rm  = 0;
-    /* repl_add_rm ( struct lump* ) -> have to be changed!!!!!!!  */
-    new_msg->repl_add_rm  = 0;
-
-    /* all the headers */
-    new_msg->via1=0;
-    new_msg->via2=0;
-    for( header = org_msg->headers , last_hdr=0  ;  header ; header=header->next)
-    {
-	new_hdr = header_cloner( new_msg , org_msg , header );
-	if (!new_hdr) {
-		DBG("DEBUG: sip_msg_cloner: new_hdr allocation failed\n");
-		goto error;
-	}
-	switch ( header->type )
-	{
-	    case HDR_VIA :
-		if ( !new_msg->via1 )
-		{
-		    new_msg->h_via1 = new_hdr;
-		    new_msg->via1 = via_body_cloner( new_msg->buf , org_msg->buf , (struct via_body*)header->parsed );
-		    if (!new_msg->via1) {
-			DBG("DEBUG: sip_msg_cloner:  new_msg->via1 allocation failed\n");
-			goto hf_error;
-		    }
-
-		    new_hdr->parsed  = (void*)new_msg->via1;
-		     if ( new_msg->via1->next )
-		        new_msg->via2 = new_msg->via1->next;
-		}
-		else if ( !new_msg->via2 && new_msg->via1 )
-		{
-		     new_msg->h_via2 = new_hdr;
-		     if ( new_msg->via1->next )
-		        new_hdr->parsed = (void*)new_msg->via1->next;
-		     else{
-		        new_msg->via2 = via_body_cloner( new_msg->buf , org_msg->buf , (struct via_body*)header->parsed );
-			if (!new_msg->via2) {
-				DBG("DEBUG: sip_msg_cloner:  new_msg->via2 allocation failed\n");
-				goto hf_error;
-			}
-		        new_hdr->parsed  = (void*)new_msg->via2;
-		     }
-		}
-		else if ( new_msg->via2 && new_msg->via1 )
-		{
-		    new_hdr->parsed  = new_msg->via1 = via_body_cloner( new_msg->buf , org_msg->buf , (struct via_body*)header->parsed );
-		    if (!new_hdr->parsed) {
-				DBG("DEBUG: sip_msg_cloner:  new_hdr->parsed  via1 allocation failed\n");
-				goto hf_error;
-		    }
-		}
-		break;
-	    case HDR_FROM :
-		new_msg->from = new_hdr;
-		break;
-	    case HDR_TO :
-		new_msg->to = new_hdr;
-		break;
-	    case HDR_CSEQ :
-		if (header->parsed)
-		{
-		  new_hdr->parsed = (void*)sh_malloc( sizeof(struct cseq_body) );
-		  if (!new_hdr->parsed) {
-			DBG("DEBUG: sip_msg_cloner:  new_hdr->parsed  cseq allocation failed\n");
-			goto hf_error;
-		  }
-		  memcpy( new_hdr->parsed , header->parsed , sizeof(struct cseq_body) );
-		  ((struct cseq_body*)new_hdr->parsed)->number.s = translate_pointer( new_msg->buf , org_msg->buf , ((struct cseq_body*)header->parsed)->number.s );
-		  ((struct cseq_body*)new_hdr->parsed)->method.s = translate_pointer( new_msg->buf , org_msg->buf , ((struct cseq_body*)header->parsed)->method.s );
-		}
-		new_msg->cseq = new_hdr;
-		break;
-	    case HDR_CALLID :
-		new_msg->callid = new_hdr;
-		break;
-	    case HDR_CONTACT :
-		new_msg->contact = new_hdr;
-		break;
-	    case HDR_MAXFORWARDS :
-		new_msg->maxforwards = new_hdr;
-		break;
-	    case HDR_ROUTE :
-		new_msg->route = new_hdr;
-		break;
-	    default :
-		break;
-	}
-
-	if ( last_hdr )
-	{
-	    last_hdr->next = new_hdr;
-	    last_hdr=last_hdr->next;
-	 }
-	 else
-	 {
-	    last_hdr=new_hdr;
-	    new_msg->headers =new_hdr;
-	}
-    	last_hdr->next = 0;
-    	new_msg->last_header = last_hdr;
-    }
-
-    return new_msg;
-
-hf_error:
-	sh_free( new_hdr );
-error:
-	sip_msg_free( new_msg );
-	/* sh_free( new_msg ); */
-	return 0;
-
-}
-
-
-
-
-struct via_body* via_body_cloner( char* new_buf , char *org_buf , struct via_body *org_via)
-{
-    struct via_body *new_via;
-
-    /* clones the via_body structure */
-    new_via = (struct via_body*)sh_malloc( sizeof( struct via_body) );
-    if (!new_via) return NULL;
-    memcpy( new_via , org_via , sizeof( struct via_body) );
-
-    /* hdr (str type) */
-    new_via->hdr.s = translate_pointer( new_buf , org_buf , org_via->hdr.s );
-    /* name (str type) */
-    new_via->name.s = translate_pointer( new_buf , org_buf , org_via->name.s );
-    /* version (str type) */
-    new_via->version.s = translate_pointer( new_buf , org_buf , org_via->version.s );
-    /* transport (str type) */
-    new_via->transport.s = translate_pointer( new_buf , org_buf , org_via->transport.s );
-    /* host (str type) */
-    new_via->host.s = translate_pointer( new_buf , org_buf , org_via->host.s );
-    /* port_str (str type) */
-    new_via->port_str.s = translate_pointer( new_buf , org_buf , org_via->port_str.s );
-    /* params (str type) */
-    new_via->params.s = translate_pointer( new_buf , org_buf , org_via->params.s );
-    /* comment (str type) */
-    new_via->comment.s = translate_pointer( new_buf , org_buf , org_via->comment.s );
-
-    if ( org_via->next ) {
-        new_via->next = via_body_cloner( new_buf , org_buf , org_via->next );
-	if (!new_via->next)
-		goto error;
-    }
-
-    new_via->param_lst = NULL;
-    if ( org_via->param_lst )
-    {
-       struct via_param *vp, *new_vp, *last_new_vp, *delete_i, *dummy;
-       for( vp=org_via->param_lst, last_new_vp=0 ; vp ; vp=vp->next )
-       {
-          new_vp = (struct via_param*)sh_malloc(sizeof(struct via_param));
-	  if (!new_vp) {
-		for (delete_i=new_via->param_lst; delete_i;  ) {
-			dummy=delete_i->next;
-			sh_free( delete_i );
-			delete_i = dummy;
-		}
-		goto error;
-	  }
-          memcpy( new_vp , vp , sizeof(struct via_param));
-          new_vp->name.s = translate_pointer( new_buf , org_buf , vp->name.s );
-          new_vp->value.s = translate_pointer( new_buf , org_buf , vp->value.s );
-
-          if (new_vp->type==PARAM_BRANCH)
-             new_via->branch = new_vp;
-
-          if (last_new_vp)
-             last_new_vp->next = new_vp;
-          else
-             new_via->param_lst = new_vp;
-
-          last_new_vp = new_vp;
-	  last_new_vp->next = NULL;
-       }
-       new_via->last_param = new_vp;
-    }
-
-
-
-   return new_via;
-
-error:
-	sh_free(new_via);
-	return NULL;
-}
-
-
-
-
-struct hdr_field* header_cloner( struct sip_msg *new_msg , struct sip_msg *org_msg, struct hdr_field *org_hdr)
-{
-    struct hdr_field* new_hdr;
-
-    new_hdr = (struct hdr_field*)sh_malloc( sizeof(struct hdr_field) );
-    if (!new_hdr) return NULL;
-    memcpy( new_hdr , org_hdr , sizeof(struct hdr_field) );
-
-    /* name */
-    new_hdr->name.s =  translate_pointer( new_msg->buf , org_msg->buf , org_hdr->name.s );
-    /* body */
-    new_hdr->body.s =  translate_pointer( new_msg->buf , org_msg->buf , org_hdr->body.s );
-
-    return new_hdr;
-}
-
-
- /*
-char*   translate_pointer( char* new_buf , char *org_buf , char* p)
-{
-    if (!p)
-	return 0;
-    else
-	return new_buf + (p-org_buf);
-}
-*/
-
-
-
-/* Frees the memory occupied by a SIP message
-  */
-void sh_free_lump(struct lump* lmp)
-{
-	if (lmp && (lmp->op==LUMP_ADD)){
-		if (lmp->u.value) sh_free(lmp->u.value);
-		lmp->u.value=0;
-		lmp->len=0;
-	}
-}
-
-
-
-void sh_free_lump_list(struct lump* l)
-{
-	struct lump* t, *r, *foo,*crt;
-	t=l;
-	while(t){
-		crt=t;
-		t=t->next;
-	/*
-		 dangerous recursive clean
-		if (crt->before) free_lump_list(crt->before);
-		if (crt->after)  free_lump_list(crt->after);
-	*/
-		/* no more recursion, clean after and before and that's it */
-		r=crt->before;
-		while(r){
-			foo=r; r=r->before;
-			sh_free_lump(foo);
-			sh_free(foo);
-		}
-		r=crt->after;
-		while(r){
-			foo=r; r=r->after;
-			sh_free_lump(foo);
-			sh_free(foo);
-		}
-
-		/*clean current elem*/
-		sh_free_lump(crt);
-		sh_free(crt);
-	}
-}
-
-
-
-void sh_free_uri(struct sip_uri* u)
-{
-   if (u)
-   {
-     if (u->user.s)
-         sh_free(u->user.s);
-     if (u->passwd.s)
-         sh_free(u->passwd.s);
-     if (u->host.s)
-         sh_free(u->host.s);
-     if (u->port.s)
-         sh_free(u->port.s);
-     if (u->params.s)
-         sh_free(u->params.s);
-     if (u->headers.s)
-         sh_free(u->headers.s);
-   }
-}
-
-
-
-void sh_free_via_param_list(struct via_param* vp)
-{
-   struct via_param* foo;
-   while(vp)
-    {
-       foo=vp;
-       vp=vp->next;
-       sh_free(foo);
-    }
-}
-
-
-
-void sh_free_via_list(struct via_body* vb)
-{
-   struct via_body* foo;
-   while(vb)
-    {
-      foo=vb;
-      vb=vb->next;
-     if (foo->param_lst)
-        sh_free_via_param_list(foo->param_lst);
-      sh_free(foo);
-    }
-}
-
-
-/* frees a hdr_field structure,
- * WARNING: it frees only parsed (and not name.s, body.s)*/
-void sh_clean_hdr_field(struct hdr_field* hf)
-{
-   if (hf->parsed)
-   {
-      switch(hf->type)
-      {
-         case HDR_VIA:
-               sh_free_via_list(hf->parsed);
-             break;
-         case HDR_CSEQ:
-                sh_free(hf->parsed);
-             break;
-         default:
-      }
-   }
-}
-
-
-
-/* frees a hdr_field list,
- * WARNING: frees only ->parsed and ->next*/
-void sh_free_hdr_field_lst(struct hdr_field* hf)
-{
-   struct hdr_field* foo;
-
-   while(hf)
-    {
-       foo=hf;
-       hf=hf->next;
-       sh_clean_hdr_field(foo);
-       sh_free(foo);
-    }
-}
-
-
-
-void sip_msg_free_1(struct sip_msg* msg)
-{
-   if (!msg) return;
-
-   DBG("DEBUG: sip_msg_free : start\n");
-
-   if (msg->new_uri.s)
-   {
-      sh_free(msg->new_uri.s);
-      msg->new_uri.len=0;
-   }
-   if (msg->headers)
-      sh_free_hdr_field_lst(msg->headers);
-   if (msg->add_rm)
-      sh_free_lump_list(msg->add_rm);
-   if (msg->repl_add_rm)
-      sh_free_lump_list(msg->repl_add_rm);
-   if (msg->orig) sh_free( msg->orig );
-   if (msg->buf) sh_free( msg->buf );
-
-   sh_free(msg);
-   DBG("DEBUG: sip_msg_free : done\n");
-}
-
-
-/******************************* New fuctions ************************************/
-
 #define  lump_len( _lump)  (ROUND4(sizeof(struct lump)) + \
                ROUND4( ((_lump)->op==LUMP_ADD)?(_lump)->len:0 ))
 
@@ -493,12 +25,15 @@ void sip_msg_free_1(struct sip_msg* msg)
           (_ptr)+=ROUND4((_old)->len);}\
       }
 
-struct sip_msg*  sip_msg_cloner_2( struct sip_msg *org_msg )
+struct via_body* via_body_cloner_2( char* new_buf , char *org_buf , struct via_body *org_via, char **p);
+
+struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg )
 {
    unsigned int         len;
    struct hdr_field    *hdr,*new_hdr,*last_hdr;
    struct via_body    *via;
    struct via_param *prm;
+   struct to_param   *to_prm,*new_to_prm;
    struct sip_msg     *new_msg;
    struct lump          *lump_chain, *lump_tmp, **lump_anchor, **lump_anchor2;
    char                       *p;
@@ -521,6 +56,13 @@ struct sip_msg*  sip_msg_cloner_2( struct sip_msg *org_msg )
          case HDR_CSEQ:
                    len+=ROUND4(sizeof(struct cseq_body));
                    break;
+         case HDR_TO:
+                   len+=ROUND4(sizeof(struct to_body));
+                   /*to param*/
+                   to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
+                   for(;to_prm;to_prm=to_prm->next)
+                      len+=ROUND4(sizeof(struct to_param ));
+                   break;
          case HDR_VIA:
                    for (via=(struct via_body*)hdr->parsed;via;via=via->next)
                    {
@@ -643,12 +185,47 @@ struct sip_msg*  sip_msg_cloner_2( struct sip_msg *org_msg )
                    ((struct cseq_body*)new_hdr->parsed)->method.s =  translate_pointer( new_msg->buf , org_msg->buf , ((struct cseq_body*)hdr->parsed)->method.s );
                    new_msg->cseq = new_hdr;
                    break;
-         case HDR_CALLID:
-                   new_msg->callid = new_hdr;
-                   break;
          case HDR_TO:
+                   new_hdr->parsed = p;
+                   p +=ROUND4(sizeof(struct to_body));
+                   memcpy( new_hdr->parsed , hdr->parsed ,
+                    sizeof(struct to_body) );
+                   ((struct to_body*)new_hdr->parsed)->body.s =
+                        translate_pointer( new_msg->buf , org_msg->buf ,
+                        ((struct to_body*)hdr->parsed)->body.s );
+                   if ( ((struct to_body*)hdr->parsed)->tag_value.s )
+                         ((struct to_body*)new_hdr->parsed)->tag_value.s
+                         = translate_pointer( new_msg->buf , org_msg->buf ,
+                            ((struct to_body*)hdr->parsed)->tag_value.s );
+                    /*to params*/
+                   to_prm = ((struct to_body*)(hdr->parsed))->param_lst;
+                   for(;to_prm;to_prm=to_prm->next)
+                   {
+                      /*alloc*/
+                      new_to_prm = (struct to_param*)p;
+                      p +=ROUND4(sizeof(struct to_param ));
+                      /*coping*/
+                      memcpy( new_to_prm, to_prm, sizeof(struct to_param ));
+                      ((struct to_body*)new_hdr->parsed)->param_lst = 0;
+                      new_to_prm->name.s = translate_pointer( new_msg->buf,
+                         org_msg->buf , to_prm->name.s );
+                      new_to_prm->value.s = translate_pointer( new_msg->buf,
+                         org_msg->buf , to_prm->value.s );
+                      /*linking*/
+                      if ( !((struct to_body*)new_hdr->parsed)->param_lst )
+                         ((struct to_body*)new_hdr->parsed)->param_lst
+                            = new_to_prm;
+                      else
+                         ((struct to_body*)new_hdr->parsed)->last_param->next
+                            = new_to_prm;
+                      ((struct to_body*)new_hdr->parsed)->last_param
+                         = new_to_prm;
+                   }
                    new_msg->to = new_hdr;
                    break;
+         case HDR_CALLID:
+                   new_msg->callid = new_hdr;
+                   break;
          case HDR_FROM:
                    new_msg->from = new_hdr;
                    break;

+ 1 - 10
modules/tm/sip_msg.h

@@ -10,20 +10,11 @@
 
 #include "sh_malloc.h"
 
-#define sip_msg_cloner(p_msg) \
-    sip_msg_cloner_2(p_msg)
-
 #define  sip_msg_free(_p_msg) shm_free( (_p_msg ))
 #define  sip_msg_free_unsafe(_p_msg) shm_free_unsafe( (_p_msg) )
 
 
-struct sip_msg*  sip_msg_cloner_1( struct sip_msg *org_msg );
-struct sip_msg*  sip_msg_cloner_2( struct sip_msg *org_msg );
-void                     sip_msg_free_1( struct sip_msg *org_msg );
-
-
-
-//char*   translate_pointer( char* new_buf , char *org_buf , char* p);
+struct sip_msg*  sip_msg_cloner( struct sip_msg *org_msg );
 
 
 #endif

+ 1 - 0
modules/tm/t_funcs.c

@@ -450,6 +450,7 @@ int t_on_reply_received( struct sip_msg  *p_msg )
 		/* release previously hold message */
 		backup = T->inbound_response[branch];
 		T->inbound_response[branch] = clone;
+		T->tag=&(get_to(clone)->tag_value);
 	} else {
 		backup = NULL;
 		sip_msg_free( clone );

+ 15 - 13
modules/tm/t_lookup.c

@@ -15,7 +15,8 @@
 
 
 #define EQ_LEN(_hf) (t_msg->_hf->body.len==p_msg->_hf->body.len)
-#define EQ_STR(_hf) (memcmp(t_msg->_hf->body.s, p_msg->_hf->body.s, \
+#define EQ_STR(_hf) (memcmp(t_msg->_hf->body.s,\
+	translate_pointer(p_msg->orig,p_msg->buf,p_msg->_hf->body.s), \
 	p_msg->_hf->body.len)==0)
 #define EQ_REQ_URI_LEN\
 	(p_msg->first_line.u.request.uri.len==t_msg->first_line.u.request.uri.len)
@@ -115,15 +116,16 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked )
          if ( EQ_LEN(callid) && EQ_LEN(cseq) )
             if ( EQ_REQ_URI_LEN )
                 if ( EQ_VIA_LEN(via1) )
-                   if ( EQ_LEN(from) && EQ_LEN(to) )
-                     /* so far the lengths are the same -> let's check the contents */
+                   if ( EQ_LEN(from) && EQ_LEN(to)  )
+                     /* so far the lengths are the same
+                     -> let's check the contents */
                      if ( EQ_STR(callid) && EQ_STR(cseq) )
-                      if ( EQ_REQ_URI_STR )
-                          if ( EQ_VIA_STR(via1) )
-                             if ( EQ_STR(from) && EQ_STR(to) )
-                              { /* WE FOUND THE GOLDEN EGG !!!! */
-                                 goto found;
-                              }
+                        if ( EQ_REQ_URI_STR )
+                           if ( EQ_VIA_STR(via1) )
+                              if ( EQ_STR(from) && EQ_STR(to) )
+                               { /* WE FOUND THE GOLDEN EGG !!!! */
+                                  goto found;
+                               }
       }
       else
       { /* it's a ACK request*/
@@ -134,16 +136,16 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked )
                   if ( EQ_REQ_URI_LEN )
                      if (/*VIA1 len*/ EQ_VIA_LEN(via1) )
                        if ( /*from length*/ EQ_LEN(from) )
-                         //if ( /*to length*/ p_cell->inbound_request->to->body.len == p_msg->to->body.len )
-                            //if ( /*tag length*/ p_cell->tag &&  p_cell->tag->len==p_msg->tag->body.len )
+                         if (get_to(t_msg)->body.len==get_to(p_msg)->body.len)
+                            if (p_cell->tag->len==get_to(p_msg)->tag_value.len )
                             /* so far the lengths are the same -> let's check the contents */
                                 if ( /*callid*/ !memcmp( t_msg->callid->body.s , p_msg->callid->body.s , p_msg->callid->body.len ) )
                                    if ( /*cseq_nr*/ !memcmp( get_cseq(t_msg)->number.s , get_cseq(p_msg)->number.s , get_cseq(p_msg)->number.len ) )
                                       if (/*URI len*/ EQ_REQ_URI_STR )
                                          if (/*VIA1*/ EQ_VIA_STR(via1) )
                                             if ( /*from*/ EQ_STR(from) )
-                                            //if ( /*to*/ !memcmp( p_cell->inbound_request->to->body.s , p_msg->to->body.s , p_msg->to->body.len)  )
-                                              //if ( /*tag*/ !memcmp( p_cell->tag->s , p_msg->tag->body.s , p_msg->tag->body.len ) )
+                                               if (!memcmp(get_to(t_msg)->body.s,get_to(p_msg)->body.s,get_to(t_msg)->body.len))
+                                                 if (!memcmp(p_cell->tag->s,get_to(p_msg)->tag_value.s , p_cell->tag->len))
                                               { /* WE FOUND THE GOLDEN EGG !!!! */
                                                  goto found;
                                               }

+ 39 - 6
msg_parser.c

@@ -167,11 +167,11 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl)
 	*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", 
+	LOG(L_INFO, "ERROR:parse_first_line: bad %s first line\n",
 		(fl->type==SIP_REPLY)?"reply(status)":"request");
 error1:
 	fl->type=SIP_INVALID;
@@ -192,6 +192,7 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
 	char *match;
 	struct via_body *vb;
 	struct cseq_body* cseq_b;
+	struct to_body* to_b;
 
 	if ((*buf)=='\n' || (*buf)=='\r'){
 		/* double crlf or lflf or crcr */
@@ -246,6 +247,24 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
 					hdr->name.s, cseq_b->number.s, cseq_b->method.s);
 			break;
 		case HDR_TO:
+			to_b=pkg_malloc(sizeof(struct to_body));
+			if (to_b==0){
+				LOG(L_ERR, "get_hdr_field: out of memory\n");
+				goto error;
+			}
+			memset(to_b, 0, sizeof(struct to_body));
+			hdr->body.s=tmp;
+			tmp=parse_to(tmp, end,to_b);
+			if (to_b->error==PARSE_ERROR){
+				LOG(L_ERR, "ERROR: get_hdr_field: bad to header\n");
+				pkg_free(to_b);
+				goto error;
+			}
+			hdr->parsed=to_b;
+			hdr->body.len=tmp-hdr->body.s;
+			DBG("get_hdr_field: to <%s>: <%s> %c [%d]\n",
+				hdr->name.s, to_b->body.s,*tmp,hdr->body.len);
+			break;
 		case HDR_FROM:
 		case HDR_CALLID:
 		case HDR_CONTACT:
@@ -256,7 +275,7 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
 			/* just skip over it */
 			hdr->body.s=tmp;
 			/* find end of header */
-			
+
 			/* find lf */
 			do{
 				match=q_memchr(tmp, '\n', end-tmp);
@@ -295,7 +314,7 @@ 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;
@@ -334,7 +353,7 @@ char * parse_cseq(char *buf, char* end, struct cseq_body* cb)
 	*t=0; /*null terminate it*/
 	cb->number.len=t-cb->number.s;
 	DBG("parse_cseq: found number %s\n", cb->number.s);
-	
+
 	if (m_end>=end) goto error;
 	if (m_end==m){
 		/* null method*/
@@ -776,8 +795,19 @@ void free_via_list(struct via_body* vb)
 	}
 }
 
+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, 
+/* frees a hdr_field structure,
  * WARNING: it frees only parsed (and not name.s, body.s)*/
 void clean_hdr_field(struct hdr_field* hf)
 {
@@ -786,6 +816,9 @@ void clean_hdr_field(struct hdr_field* hf)
 			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;

+ 23 - 4
msg_parser.h

@@ -44,8 +44,13 @@ enum{
 		PARAM_ERROR
 };
 
+enum{
+		TAG_PARAM=400, GENERAL_PARAM
+};
+
 /* casting macro for accessing CSEQ body */
-#define get_cseq( p_msg)    ((struct cseq_body*)(p_msg)->cseq->parsed)
+#define get_cseq( p_msg)  ((struct cseq_body*)(p_msg)->cseq->parsed)
+#define get_to( p_msg)      ((struct to_body*)(p_msg)->to->parsed)
 
 
 
@@ -127,13 +132,27 @@ struct via_body{  /* format: name/version/transport host:port;params comment */
 	struct via_param* last_param; /*last via parameter, internal use*/
 	/* shortcuts to "important" params*/
 	struct via_param* branch;
-	
+
 	struct via_body* next; /* pointer to next via body string if
-							  compact via or null */
+         compact via or null */
 };
 
 
 
+struct to_param{
+	int type;
+	str name;
+	str value;
+	struct to_param* next;
+};
+
+struct to_body{
+	int error;
+	str body;
+	str tag_value;
+	struct to_param *param_lst;
+	struct to_param *last_param;
+};
 
 
 struct cseq_body{
@@ -165,7 +184,6 @@ struct sip_msg{
 	struct hdr_field* route;
 	struct hdr_field* record_route;
 	char* eoh; /* pointer to the end of header (if found) or null */
-
 	char* unparsed; /* here we stopped parsing*/
 
 	unsigned int src_ip;
@@ -216,6 +234,7 @@ void free_uri(struct sip_uri* u);
 
 char* parse_hname(char* buf, char* end, struct hdr_field* hdr);
 char* parse_via(char* buffer, char* end, struct via_body *vb);
+char* parse_to(char* buffer, char* end, struct to_body *to_b);
 char* parse_cseq(char* buffer, char* end, struct cseq_body *cb);
 
 void free_via_param_list(struct via_param *vp);

+ 18 - 18
parse_via.c

@@ -1,4 +1,4 @@
-/* 
+/*
  * $Id$ 
  *
  * via parsing automaton
@@ -64,21 +64,21 @@ enum{	L_VALUE=200,   F_VALUE, P_VALUE, P_STRING,
 
 
 
-/* entry state must be F_PARAM, or saved_state=F_PARAM and 
+/* entry state must be F_PARAM, or saved_state=F_PARAM and
  * state=F_{LF,CR,CRLF}!
- * output state = L_PARAM or F_PARAM or END_OF_HEADER 
+ * output state = L_PARAM or F_PARAM or END_OF_HEADER
  * (and saved_state= last state); everything else => error */
-__inline char* parse_via_param(	char* p, char* end, int* pstate, 
+__inline char* parse_via_param(	char* p, char* end, int* pstate,
 								int* psaved_state, struct via_param* param)
 {
 	char* tmp;
 	register int state;
 	int saved_state;
-	
+
 	state=*pstate;
 	saved_state=*psaved_state;
 	param->type=PARAM_ERROR;
-	
+
 	for (tmp=p;tmp<end;tmp++){
 		switch(*tmp){
 			case ' ':
@@ -253,7 +253,7 @@ __inline char* parse_via_param(	char* p, char* end, int* pstate,
 						goto endofparam;
 				}
 				break;
-				
+
 				/* param names */
 			case 'h':
 			case 'H':
@@ -618,7 +618,7 @@ find_value:
 					case P_STRING:
 						saved_state=state;
 						state=F_LF;
-						break; 
+						break;
 					case P_VALUE:
 						*tmp=0;
 						saved_state=L_PARAM;
@@ -645,7 +645,7 @@ find_value:
 					case P_STRING:
 						saved_state=state;
 						state=F_CR;
-						break; 
+						break;
 					case P_VALUE:
 						*tmp=0;
 						param->value.len=tmp-param->value.s;
@@ -775,17 +775,17 @@ endofvalue:
 	param->size=tmp-p;
 	*pstate=state;
 	*psaved_state=saved_state;
-	DBG("Found param type %d, <%s> = <%s>; state=%d\n", param->type, 
+	DBG("Found param type %d, <%s> = <%s>; state=%d\n", param->type,
 			param->name.s, param->value.s, state);
 	return tmp;
-	
+
 end_via:
 	/* if we are here we found an "unexpected" end of via
 	 *  (cr/lf). This is valid only if the param type is GEN_PARAM*/
 	if (param->type==GEN_PARAM) goto endofparam;
 	*pstate=state;
 	*psaved_state=saved_state;
-	DBG("Error on  param type %d, <%s>, state=%d, saved_state=%d\n", 
+	DBG("Error on  param type %d, <%s>, state=%d, saved_state=%d\n",
 		param->type, param->name.s, state, saved_state);
 
 error:
@@ -1587,7 +1587,7 @@ main_via:
 						memset(param,0, sizeof(struct via_param));
 						tmp=parse_via_param(tmp, end, &state, &saved_state,
 											param);
-						
+
 						switch(state){
 							case L_PARAM:
 							case F_PARAM:
@@ -1655,9 +1655,9 @@ main_via:
 							*tmp, state);
 						goto error;
 				}
-				
-					
-		}			
+
+
+		}
 	}
 
 	DBG("end of packet reached, state=%d\n", state);
@@ -1684,7 +1684,7 @@ endofpacket:
 					" state %d\n", state);
 			goto error;
 	}
-	
+
 
 	/*
 	if (proto) printf("<SIP/2.0/%s>\n", proto);
@@ -1695,7 +1695,7 @@ endofpacket:
 	if(next_via) printf("next_via= <%s>\n", next_via);
 	*/
 	/*DBG("parse_via: rest=<%s>\n", tmp);*/
-	
+
 	vb->error=VIA_PARSE_OK;
 	vb->bsize=tmp-buffer;
 	if (vb->port_str.s){

+ 18 - 0
test/th-uri.cfg

@@ -45,6 +45,24 @@ route{
                    mf_add_maxfwd_header( "10" );
              };
 
+             #if (method=="INVITE")
+             #{
+              #  log("SER : runing CPL!! :)\n");
+              #  if ( !cpl_run_script() )
+               # {
+               #    log("SER : Error during running CPL script!\n");
+               # }else{
+                #   if ( cpl_is_response_reject() )
+                  # {
+                    #   t_add_transaction();
+                      # t_send_reply("486","I am not available!");
+                       #drop();
+                 #  }else if ( cpl_is_response_redirect() ) {
+                   #      log("SER : redirect\n");
+                  # };
+               # };
+             #};
+
              #if ( !rewriteFromRoute() )
              #{
                 log( " SER : no route found!\n");