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