Hello anonymous!

does this patch fix the issue?

-Raphael.


Anonymous (JIRA) wrote:
Multiple Contact headers are not returned by sipctrl in 200 to REGISTER
-----------------------------------------------------------------------

                 Key: SEMS-44
                 URL: http://tracker.iptel.org/browse/SEMS-44
             Project: SEMS
          Issue Type: Bug
    Affects Versions: 1.0
         Assigned To: Raphael Coeffic


Contact entries may be in multiple headers in 200 Replies to REGISTER. sipctrl 
only passes the last header up to the application layer, the previous ones are 
overwritten (parse_header.cpp:212). Therefore to SEMS SIP registrations do seem 
to not work if the server returns registered contacts like this:

Contact: sip:[EMAIL PROTECTED];expires=1000
Contact: sip:[EMAIL PROTECTED];expires=550

This problem occurs only with sipctrl. SER as SIP stack collapses multiple 
contact lines into the contact field of the parsed request.


Index: sip_parser.h
===================================================================
--- sip_parser.h        (revision 1117)
+++ sip_parser.h        (working copy)
@@ -111,7 +111,8 @@
     sip_via_parm*      via_p1;
 
     sip_header*        callid;
-    sip_header*        contact;
+
+    list<sip_header*>  contacts;
     list<sip_header*>  route;
     list<sip_header*>  record_route;
     sip_header*        content_type;
@@ -130,6 +131,8 @@
 int parse_method(int* method, const char* beg, int len);
 int parse_sip_msg(sip_msg* msg);
 
+#define get_contact(msg) (msg->contacts.empty() ? NULL : 
(*msg->contacts.begin()))
+
 #endif
 
 /** EMACS **
Index: SipCtrlInterface.cpp
===================================================================
--- SipCtrlInterface.cpp        (revision 1117)
+++ SipCtrlInterface.cpp        (working copy)
@@ -496,13 +496,13 @@
     req.port     = int2str(ntohs(((sockaddr_in*)(&msg->local_ip))->sin_port));
     req.r_uri    = c2stlstr(msg->u.request->ruri_str);
 
-    if(msg->contact){
+    if(get_contact(msg)){
 
        sip_nameaddr na;
-       const char* c = msg->contact->value.s;
-       if(parse_nameaddr(&na,&c,msg->contact->value.len) < 0){
+       const char* c = get_contact(msg)->value.s;
+       if(parse_nameaddr(&na,&c,get_contact(msg)->value.len) < 0){
            WARN("Contact parsing failed\n");
-           WARN("\tcontact = 
'%.*s'\n",msg->contact->value.len,msg->contact->value.s);
+           WARN("\tcontact = 
'%.*s'\n",get_contact(msg)->value.len,get_contact(msg)->value.s);
            WARN("\trequest = '%.*s'\n",msg->len,msg->buf);
        }
        else {
@@ -514,7 +514,7 @@
            }
 
            req.from_uri = c2stlstr(na.addr);
-           req.contact  = c2stlstr(msg->contact->value);
+           req.contact  = c2stlstr(get_contact(msg)->value);
        }
     }
     else {
@@ -571,12 +571,13 @@
     reply.code   = msg->u.reply->code;
     reply.reason = c2stlstr(msg->u.reply->reason);
 
-    if(msg->contact){
+    if(get_contact(msg)){
 
-       const char* c = msg->contact->value.s;
+       // parse the first contact
+       const char* c = get_contact(msg)->value.s;
        sip_nameaddr na;
        
-       int err = parse_nameaddr(&na,&c,msg->contact->value.len);
+       int err = parse_nameaddr(&na,&c,get_contact(msg)->value.len);
        if(err < 0) {
            
            ERROR("Contact nameaddr parsing failed\n");
@@ -584,8 +585,13 @@
        }
        
        // 'Contact' header?
-       reply.next_request_uri = c2stlstr(na.addr); 
-       reply.contact = c2stlstr(msg->contact->value);
+       reply.next_request_uri = c2stlstr(na.addr);
+       
+       list<sip_header*>::iterator c_it = msg->contacts.begin();
+       reply.contact = c2stlstr((*c_it)->value);
+       for(;c_it!=msg->contacts.end(); ++c_it){
+           reply.contact += "," + c2stlstr((*c_it)->value);
+       }
     }
 
     reply.callid = c2stlstr(msg->callid->value);
@@ -596,12 +602,6 @@
     reply.dstip = get_addr_str(((sockaddr_in*)(&msg->local_ip))->sin_addr); 
//FIXME: IPv6
     reply.port  = int2str(ntohs(((sockaddr_in*)(&msg->local_ip))->sin_port));
 
-    //if( (get_cseq(msg)->method == sip_request::INVITE) 
-    //         && (msg->u.reply->code >= 200) 
-    //         && (msg->u.reply->code < 300) ){
-    //         tl->send_200_ack(msg);
-    //}
-
     prepare_routes_uac(msg->record_route, reply.route);
 
     for (list<sip_header*>::iterator it = msg->hdrs.begin(); 
Index: sip_parser.cpp
===================================================================
--- sip_parser.cpp      (revision 1117)
+++ sip_parser.cpp      (working copy)
@@ -46,7 +46,7 @@
       cseq(NULL),
       via1(NULL),via_p1(NULL),
       callid(NULL),
-      contact(NULL),
+      contacts(),
       route(),
       record_route(),
       content_type(NULL),
@@ -73,7 +73,7 @@
       cseq(NULL),
       via1(NULL),via_p1(NULL),
       callid(NULL),
-      contact(NULL),
+      contacts(),
       route(),
       record_route(),
       content_type(NULL),
Index: parse_header.cpp
===================================================================
--- parse_header.cpp    (revision 1117)
+++ parse_header.cpp    (working copy)
@@ -112,7 +112,7 @@
       } break;
       case 'm': { // Contact      
        h->type = sip_header::H_CONTACT;
-       msg->contact = h;
+       msg->contacts.push_back(h);
       } break;
        //       case 'e': // Content-Encoding
        //      {} break;
@@ -209,7 +209,7 @@
            case 'O':
                if(!lower_cmp(h->name.s+2,CONTACT_lc+2,CONTACT_len-2)){
                    h->type = sip_header::H_CONTACT;
-                   msg->contact = h;
+                   msg->contacts.push_back(h);
                }
                break;
 
Index: trans_layer.cpp
===================================================================
--- trans_layer.cpp     (revision 1117)
+++ trans_layer.cpp     (working copy)
@@ -653,7 +653,7 @@
        + copy_hdr_len(req->callid)
        + cseq_len(get_cseq(req)->num_str,cancel_str)
        + copy_hdrs_len(req->route)
-       + copy_hdr_len(req->contact);
+       + copy_hdrs_len(req->contacts);
 
     request_len += 2/* CRLF end-of-headers*/;
 
@@ -673,7 +673,7 @@
     copy_hdr_wr(&c,req->callid);
     cseq_wr(&c,get_cseq(req)->num_str,cancel_str);
     copy_hdrs_wr(&c,req->route);
-    copy_hdr_wr(&c,req->contact);
+    copy_hdrs_wr(&c,req->contacts);
 
     *c++ = CR;
     *c++ = LF;
@@ -1156,14 +1156,14 @@
 {
     // Set request URI
     // TODO: use correct R-URI instead of just 'Contact'
-    if(!reply->contact) {
+    if(!get_contact(reply)) {
        DBG("Sorry, reply has no Contact header: could not send ACK\n");
        return;
     }
     
     sip_nameaddr na;
-    const char* c = reply->contact->value.s;
-    if(parse_nameaddr(&na,&c,reply->contact->value.len) < 0){
+    const char* c = get_contact(reply)->value.s;
+    if(parse_nameaddr(&na,&c,get_contact(reply)->value.len) < 0){
        DBG("Sorry, reply's Contact parsing failed: could not send ACK\n");
        return;
     }
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to