1 /*
2  * $Id: SipCtrlInterface.cpp 1648 2010-03-03 19:35:22Z sayer $
3  *
4  * Copyright (C) 2007 Raphael Coeffic
5  *
6  * This file is part of SEMS, a free SIP media server.
7  *
8  * SEMS is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version. This program is released under
12  * the GPL with the additional exemption that compiling, linking,
13  * and/or using OpenSSL is allowed.
14  *
15  * For a license to use the SEMS software under conditions
16  * other than those described here, or to purchase support for this
17  * software, please contact iptel.org by e-mail at the following addresses:
18  *    info@iptel.org
19  *
20  * SEMS is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29 #include "SipCtrlInterface.h"
30 
31 #include "AmUtils.h"
32 #include "AmSipMsg.h"
33 #include "AmMimeBody.h"
34 #include "AmSipHeaders.h"
35 
36 #include "sip/trans_layer.h"
37 #include "sip/sip_parser.h"
38 #include "sip/parse_header.h"
39 #include "sip/parse_from_to.h"
40 #include "sip/parse_cseq.h"
41 #include "sip/parse_100rel.h"
42 #include "sip/parse_route.h"
43 #include "sip/trans_table.h"
44 #include "sip/sip_trans.h"
45 #include "sip/wheeltimer.h"
46 #include "sip/msg_hdrs.h"
47 #include "sip/udp_trsp.h"
48 #include "sip/ip_util.h"
49 #include "sip/tcp_trsp.h"
50 
51 #include "log.h"
52 
53 #include <assert.h>
54 
55 #include "AmApi.h"
56 #include "AmConfigReader.h"
57 #include "AmSipDispatcher.h"
58 #include "AmEventDispatcher.h"
59 #include "AmSipEvent.h"
60 
61 bool _SipCtrlInterface::log_parsed_messages = true;
62 int _SipCtrlInterface::udp_rcvbuf = -1;
63 
alloc_udp_structs()64 int _SipCtrlInterface::alloc_udp_structs()
65 {
66     udp_sockets = new udp_trsp_socket*[ AmConfig::SIP_Ifs.size() ];
67     udp_servers = new udp_trsp* [ AmConfig::SIPServerThreads
68 				  * AmConfig::SIP_Ifs.size() ];
69 
70     if(udp_sockets && udp_servers)
71 	return 0;
72 
73     return -1;
74 }
75 
init_udp_servers(int if_num)76 int _SipCtrlInterface::init_udp_servers(int if_num)
77 {
78     udp_trsp_socket* udp_socket =
79 	new udp_trsp_socket(if_num,AmConfig::SIP_Ifs[if_num].SigSockOpts
80 			    | (AmConfig::ForceOutboundIf ?
81 			       trsp_socket::force_outbound_if : 0)
82 			    | (AmConfig::UseRawSockets ?
83 			       trsp_socket::use_raw_sockets : 0),
84 			    AmConfig::SIP_Ifs[if_num].NetIfIdx);
85 
86     if(!AmConfig::SIP_Ifs[if_num].PublicIP.empty()) {
87 	udp_socket->set_public_ip(AmConfig::SIP_Ifs[if_num].PublicIP);
88     }
89 
90     if(udp_socket->bind(AmConfig::SIP_Ifs[if_num].LocalIP,
91 			AmConfig::SIP_Ifs[if_num].LocalPort) < 0){
92 
93 	ERROR("Could not bind SIP/UDP socket to %s:%i",
94 	      AmConfig::SIP_Ifs[if_num].LocalIP.c_str(),
95 	      AmConfig::SIP_Ifs[if_num].LocalPort);
96 
97 	delete udp_socket;
98 	return -1;
99     }
100 
101     if(udp_rcvbuf > 0) {
102 	udp_socket->set_recvbuf_size(udp_rcvbuf);
103     }
104 
105     trans_layer::instance()->register_transport(udp_socket);
106     udp_sockets[if_num] = udp_socket;
107     inc_ref(udp_socket);
108     nr_udp_sockets++;
109 
110     for(int j=0; j<AmConfig::SIPServerThreads;j++){
111 	udp_servers[if_num * AmConfig::SIPServerThreads + j] =
112 	    new udp_trsp(udp_socket);
113 	nr_udp_servers++;
114     }
115 
116     return 0;
117 }
118 
alloc_tcp_structs()119 int _SipCtrlInterface::alloc_tcp_structs()
120 {
121     tcp_sockets = new tcp_server_socket*[ AmConfig::SIP_Ifs.size() ];
122     tcp_servers = new tcp_trsp* [ AmConfig::SIP_Ifs.size() ];
123 
124     if(tcp_sockets && tcp_servers)
125 	return 0;
126 
127     return -1;
128 }
129 
init_tcp_servers(int if_num)130 int _SipCtrlInterface::init_tcp_servers(int if_num)
131 {
132     tcp_server_socket* tcp_socket = new tcp_server_socket(if_num);
133 
134     if(!AmConfig::SIP_Ifs[if_num].PublicIP.empty()) {
135      	tcp_socket->set_public_ip(AmConfig::SIP_Ifs[if_num].PublicIP);
136     }
137 
138     tcp_socket->set_connect_timeout(AmConfig::SIP_Ifs[if_num].tcp_connect_timeout);
139     tcp_socket->set_idle_timeout(AmConfig::SIP_Ifs[if_num].tcp_idle_timeout);
140 
141     if(tcp_socket->bind(AmConfig::SIP_Ifs[if_num].LocalIP,
142 			AmConfig::SIP_Ifs[if_num].LocalPort) < 0){
143 
144 	ERROR("Could not bind SIP/TCP socket to %s:%i",
145 	      AmConfig::SIP_Ifs[if_num].LocalIP.c_str(),
146 	      AmConfig::SIP_Ifs[if_num].LocalPort);
147 
148 	delete tcp_socket;
149 	return -1;
150     }
151 
152     //TODO: add some more threads
153     tcp_socket->add_threads(AmConfig::SIPServerThreads);
154 
155     trans_layer::instance()->register_transport(tcp_socket);
156     tcp_sockets[if_num] = tcp_socket;
157     inc_ref(tcp_socket);
158     nr_tcp_sockets++;
159 
160     tcp_servers[if_num] = new tcp_trsp(tcp_socket);
161     nr_tcp_servers++;
162 
163     return 0;
164 }
165 
load()166 int _SipCtrlInterface::load()
167 {
168     if (!AmConfig::OutboundProxy.empty()) {
169 	sip_uri parsed_uri;
170 	if (parse_uri(&parsed_uri, (char *)AmConfig::OutboundProxy.c_str(),
171 		      AmConfig::OutboundProxy.length()) < 0) {
172 	    ERROR("invalid outbound_proxy specified\n");
173 	    return -1;
174 	}
175     }
176 
177     AmConfigReader cfg;
178     string cfgfile = AmConfig::ConfigurationFile.c_str();
179     if (file_exists(cfgfile) && !cfg.loadFile(cfgfile)) {
180 	if (cfg.hasParameter("accept_fr_without_totag")) {
181 	    trans_layer::accept_fr_without_totag =
182 		cfg.getParameter("accept_fr_without_totag") == "yes";
183 	}
184 	DBG("accept_fr_without_totag = %s\n",
185 	    trans_layer::accept_fr_without_totag?"yes":"no");
186 
187 	if (cfg.hasParameter("default_bl_ttl")) {
188 	    trans_layer::default_bl_ttl =
189 		cfg.getParameterInt("default_bl_ttl",
190 				    trans_layer::default_bl_ttl);
191 	}
192 	DBG("default_bl_ttl = %u\n",trans_layer::default_bl_ttl);
193 
194 	if (cfg.hasParameter("log_raw_messages")) {
195 	    string msglog = cfg.getParameter("log_raw_messages");
196 	    if (msglog == "no") trsp_socket::log_level_raw_msgs = -1;
197 	    else if (msglog == "error") trsp_socket::log_level_raw_msgs = L_ERR;
198 	    else if (msglog == "warn")  trsp_socket::log_level_raw_msgs = L_WARN;
199 	    else if (msglog == "info")  trsp_socket::log_level_raw_msgs = L_INFO;
200 	    else if (msglog == "debug") trsp_socket::log_level_raw_msgs = L_DBG;
201 	}
202 	DBG("log_raw_messages level = %d\n",
203 	    trsp_socket::log_level_raw_msgs);
204 
205 	if (cfg.hasParameter("log_parsed_messages")) {
206 	    log_parsed_messages = cfg.getParameter("log_parsed_messages")=="yes";
207 	}
208 	DBG("log_parsed_messages = %s\n",
209 	    log_parsed_messages?"yes":"no");
210 
211 	if (cfg.hasParameter("udp_rcvbuf")) {
212 	    unsigned int config_udp_rcvbuf = -1;
213 	    if (str2i(cfg.getParameter("udp_rcvbuf"), config_udp_rcvbuf)) {
214 		ERROR("invalid value specified for udp_rcvbuf\n");
215 		return false;
216 	    }
217 	    udp_rcvbuf = config_udp_rcvbuf;
218 	    DBG("udp_rcvbuf = %d\n", udp_rcvbuf);
219 	}
220 
221     } else {
222 	DBG("assuming SIP default settings.\n");
223     }
224 
225     if(alloc_udp_structs() < 0) {
226 	ERROR("no enough memory to alloc UDP structs");
227 	return -1;
228     }
229 
230     // Init UDP transport instances
231     for(unsigned int i=0; i<AmConfig::SIP_Ifs.size();i++) {
232 	if(init_udp_servers(i) < 0) {
233 	    return -1;
234 	}
235     }
236 
237     if(alloc_tcp_structs() < 0) {
238 	ERROR("no enough memory to alloc TCP structs");
239 	return -1;
240     }
241 
242     // Init TCP transport instances
243     for(unsigned int i=0; i<AmConfig::SIP_Ifs.size();i++) {
244 	if(init_tcp_servers(i) < 0) {
245 	    return -1;
246 	}
247     }
248 
249     return 0;
250 }
251 
_SipCtrlInterface()252 _SipCtrlInterface::_SipCtrlInterface()
253     : stopped(false),
254       nr_udp_sockets(0), udp_sockets(NULL),
255       nr_udp_servers(0), udp_servers(NULL),
256       nr_tcp_sockets(0), tcp_sockets(NULL),
257       nr_tcp_servers(0), tcp_servers(NULL)
258 {
259     trans_layer::instance()->register_ua(this);
260 }
261 
cancel(trans_ticket * tt,const string & dialog_id,unsigned int inv_cseq,const string & hdrs)262 int _SipCtrlInterface::cancel(trans_ticket* tt, const string& dialog_id,
263 			      unsigned int inv_cseq, const string& hdrs)
264 {
265     return trans_layer::instance()->cancel(tt,stl2cstr(dialog_id),
266 					   inv_cseq,stl2cstr(hdrs));
267 }
268 
send(AmSipRequest & req,const string & dialog_id,const string & next_hop,int out_interface,unsigned int flags,msg_logger * logger)269 int _SipCtrlInterface::send(AmSipRequest &req, const string& dialog_id,
270 			    const string& next_hop, int out_interface,
271 			    unsigned int flags, msg_logger* logger)
272 {
273     if(req.method == "CANCEL")
274 	return cancel(&req.tt, dialog_id, req.cseq, req.hdrs);
275 
276     sip_msg* msg = new sip_msg();
277 
278     msg->type = SIP_REQUEST;
279     msg->u.request = new sip_request();
280 
281     msg->u.request->method_str = stl2cstr(req.method);
282     msg->u.request->ruri_str = stl2cstr(req.r_uri);
283 
284     // To
285     // From
286     // Call-ID
287     // CSeq
288     // Contact
289     // Max-Forwards
290 
291     char* c = (char*)req.from.c_str();
292     int err = parse_headers(msg,&c,c+req.from.length());
293 
294     c = (char*)req.to.c_str();
295     err = err || parse_headers(msg,&c,c+req.to.length());
296 
297     if(err){
298 	ERROR("Malformed To or From header\n");
299 	delete msg;
300 	return -1;
301     }
302 
303     string cseq = int2str(req.cseq)
304 	+ " " + req.method;
305 
306     msg->cseq = new sip_header(0,SIP_HDR_CSEQ,stl2cstr(cseq));
307     msg->hdrs.push_back(msg->cseq);
308 
309     msg->callid = new sip_header(0,SIP_HDR_CALL_ID,stl2cstr(req.callid));
310     msg->hdrs.push_back(msg->callid);
311 
312     if(!req.contact.empty()){
313 
314 	c = (char*)req.contact.c_str();
315 	err = parse_headers(msg,&c,c+req.contact.length());
316 	if(err){
317 	    ERROR("Malformed Contact header\n");
318 	    delete msg;
319 	    return -1;
320 	}
321     }
322 
323     if(!req.route.empty()){
324 
325  	c = (char*)req.route.c_str();
326 	err = parse_headers(msg,&c,c+req.route.length());
327 
328 	if(err){
329 	    ERROR("Route headers parsing failed\n");
330 	    ERROR("Faulty headers were: <%s>\n",req.route.c_str());
331 	    delete msg;
332 	    return -1;
333 	}
334     }
335 
336     if(req.max_forwards < 0) {
337 	req.max_forwards = AmConfig::MaxForwards;
338     }
339 
340     string mf = int2str(req.max_forwards);
341     msg->hdrs.push_back(new sip_header(0,SIP_HDR_MAX_FORWARDS,stl2cstr(mf)));
342 
343     if(!req.hdrs.empty()) {
344 
345  	c = (char*)req.hdrs.c_str();
346 
347  	err = parse_headers(msg,&c,c+req.hdrs.length());
348 
349 	if(err){
350 	    ERROR("Additional headers parsing failed\n");
351 	    ERROR("Faulty headers were: <%s>\n",req.hdrs.c_str());
352 	    delete msg;
353 	    return -1;
354 	}
355     }
356 
357     string body;
358     string content_type;
359 
360     if(!req.body.empty()){
361 	content_type = req.body.getCTHdr();
362 	msg->content_type = new sip_header(0,SIP_HDR_CONTENT_TYPE,
363 					   stl2cstr(content_type));
364 	msg->hdrs.push_back(msg->content_type);
365 	req.body.print(body);
366 	msg->body = stl2cstr(body);
367     }
368 
369     int res = trans_layer::instance()->send_request(msg,&req.tt,
370 						    stl2cstr(dialog_id),
371 						    stl2cstr(next_hop),
372 						    out_interface,
373 						    flags,logger);
374     delete msg;
375 
376     return res;
377 }
378 
run()379 int _SipCtrlInterface::run()
380 {
381     DBG("Starting SIP control interface\n");
382     wheeltimer::instance()->start();
383 
384     if (NULL != udp_servers) {
385 	for(int i=0; i<nr_udp_servers;i++){
386 	    udp_servers[i]->start();
387 	}
388     }
389 
390     if (NULL != tcp_servers) {
391 	for(int i=0; i<nr_tcp_servers;i++){
392 	    tcp_servers[i]->start();
393 	}
394     }
395 
396     while (!stopped.get()) {
397         stopped.wait_for();
398     }
399 
400     DBG("SIP control interface ending\n");
401     return 0;
402 }
403 
stop()404 void _SipCtrlInterface::stop()
405 {
406     stopped.set(true);
407 }
408 
cleanup()409 void _SipCtrlInterface::cleanup()
410 {
411     DBG("Stopping SIP control interface threads\n");
412 
413     if (NULL != udp_servers) {
414 	for(int i=0; i<nr_udp_servers;i++){
415 	    udp_servers[i]->stop();
416 	    udp_servers[i]->join();
417 	    delete udp_servers[i];
418 	}
419 
420 	delete [] udp_servers;
421 	udp_servers = NULL;
422 	nr_udp_servers = 0;
423     }
424 
425     if (NULL != tcp_servers) {
426 	for(int i=0; i<nr_tcp_servers;i++){
427 	    tcp_servers[i]->stop();
428 	    tcp_servers[i]->join();
429 	    delete tcp_servers[i];
430 	}
431 
432 	delete [] tcp_servers;
433 	tcp_servers = NULL;
434 	nr_tcp_servers = 0;
435     }
436 
437     trans_layer::instance()->clear_transports();
438 
439     if (NULL != udp_sockets) {
440 	for(int i=0; i<nr_udp_sockets;i++){
441 	    DBG("dec_ref(%p)",udp_sockets[i]);
442 	    dec_ref(udp_sockets[i]);
443 	}
444 
445 	delete [] udp_sockets;
446 	udp_sockets = NULL;
447 	nr_udp_sockets = 0;
448     }
449 
450     if (NULL != tcp_sockets) {
451 	for(int i=0; i<nr_tcp_sockets;i++){
452 	    DBG("dec_ref(%p)",tcp_sockets[i]);
453 	    dec_ref(tcp_sockets[i]);
454 	}
455 
456 	delete [] tcp_sockets;
457 	tcp_sockets = NULL;
458 	nr_tcp_sockets = 0;
459     }
460 }
461 
send(const AmSipReply & rep,const string & dialog_id,msg_logger * logger)462 int _SipCtrlInterface::send(const AmSipReply &rep, const string& dialog_id,
463 			   msg_logger* logger)
464 {
465     sip_msg msg;
466 
467     if(!rep.hdrs.empty()) {
468 
469 	char* c = (char*)rep.hdrs.c_str();
470 	int err = parse_headers(&msg,&c,c+rep.hdrs.length());
471 	if(err){
472 	    ERROR("Malformed additional header\n");
473 	    return -1;
474 	}
475     }
476 
477     if(!rep.contact.empty()){
478 
479 	char* c = (char*)rep.contact.c_str();
480 	int err = parse_headers(&msg,&c,c+rep.contact.length());
481 	if(err){
482 	    ERROR("Malformed Contact header\n");
483 	    return -1;
484 	}
485     }
486 
487     string body;
488     string content_type;
489     if(!rep.body.empty()) {
490 	content_type = rep.body.getCTHdr();
491 	rep.body.print(body);
492     	if(content_type.empty()){
493     	    ERROR("Reply does not contain a Content-Type whereby body is not empty\n");
494     	    return -1;
495     	}
496 	msg.body = stl2cstr(body);
497 	msg.hdrs.push_back(new sip_header(sip_header::H_CONTENT_TYPE,
498 					  SIP_HDR_CONTENT_TYPE,
499 					  stl2cstr(content_type)));
500     }
501 
502     msg.type = SIP_REPLY;
503     msg.u.reply = new sip_reply(rep.code,stl2cstr(rep.reason));
504 
505     return
506 	trans_layer::instance()->send_reply(&msg,(trans_ticket*)&rep.tt,
507 					    stl2cstr(dialog_id),
508 					    stl2cstr(rep.to_tag),logger);
509 }
510 
511 
sip_msg2am_request(const sip_msg * msg,const trans_ticket & tt,AmSipRequest & req)512 inline bool _SipCtrlInterface::sip_msg2am_request(const sip_msg *msg,
513 						 const trans_ticket& tt,
514 						 AmSipRequest &req)
515 {
516     assert(msg);
517     assert(msg->from && msg->from->p);
518     assert(msg->to && msg->to->p);
519 
520     req.method   = c2stlstr(msg->u.request->method_str);
521     req.user     = c2stlstr(msg->u.request->ruri.user);
522     req.domain   = c2stlstr(msg->u.request->ruri.host);
523     req.r_uri    = c2stlstr(msg->u.request->ruri_str);
524     req.tt       = tt;
525 
526     if(get_contact(msg) && get_contact(msg)->value.len){
527 
528 	sip_nameaddr na;
529 	cstring contact = get_contact(msg)->value;
530 	if(parse_first_nameaddr(&na,contact.s,contact.len) < 0) {
531 	    WARN("Contact parsing failed\n");
532 	    WARN("\tcontact = '%.*s'\n",contact.len,contact.s);
533 	    WARN("\trequest = '%.*s'\n",msg->len,msg->buf);
534 
535 	    trans_layer::instance()->send_sf_error_reply(&tt, msg, 400,
536 							 "Bad Contact");
537 	    return false;
538 	}
539 
540 	const char* c = na.addr.s;
541 	if((na.addr.len != 1) || (*c != '*')) {
542 	    sip_uri u;
543 	    if(parse_uri(&u,na.addr.s,na.addr.len)){
544 		DBG("'Contact' in new request contains a malformed URI\n");
545 		DBG("\tcontact uri = '%.*s'\n",na.addr.len,na.addr.s);
546 		DBG("\trequest = '%.*s'\n",msg->len,msg->buf);
547 
548 		trans_layer::instance()->
549 		    send_sf_error_reply(&tt, msg, 400, "Malformed Contact URI");
550 		return false;
551 	    }
552 
553 	    req.from_uri = c2stlstr(na.addr);
554 	}
555 
556 	list<sip_header*>::const_iterator c_it = msg->contacts.begin();
557 	req.contact = c2stlstr((*c_it)->value);
558 	++c_it;
559 
560 	for(;c_it!=msg->contacts.end(); ++c_it){
561 	    req.contact += ", " + c2stlstr((*c_it)->value);
562 	}
563     }
564     else {
565 	if (req.method == SIP_METH_INVITE) {
566 	    DBG("Request has no contact header\n");
567 	    DBG("\trequest = '%.*s'\n",msg->len,msg->buf);
568 	    trans_layer::instance()->
569 		send_sf_error_reply(&tt, msg, 400, "Missing Contact-HF");
570 	    return false;
571 	}
572     }
573 
574     if(req.from_uri.empty()) {
575 	req.from_uri = c2stlstr(get_from(msg)->nameaddr.addr);
576     }
577 
578     if(get_from(msg)->nameaddr.name.len){
579 	req.from += c2stlstr(get_from(msg)->nameaddr.name) + ' ';
580     }
581 
582     req.from += '<' + c2stlstr(get_from(msg)->nameaddr.addr) + '>';
583 
584     req.to       = c2stlstr(msg->to->value);
585     req.callid   = c2stlstr(msg->callid->value);
586     req.from_tag = c2stlstr(((sip_from_to*)msg->from->p)->tag);
587     req.to_tag   = c2stlstr(((sip_from_to*)msg->to->p)->tag);
588     req.cseq     = get_cseq(msg)->num;
589     req.cseq_method = c2stlstr(get_cseq(msg)->method_str);
590     req.via_branch = c2stlstr(msg->via_p1->branch);
591 
592     if (msg->rack) {
593         req.rseq = get_rack(msg)->rseq;
594 	req.rack_method = c2stlstr(get_rack(msg)->method_str);
595 	req.rack_cseq = get_rack(msg)->cseq;
596     }
597 
598     if (msg->content_type) {
599 
600 	if(req.body.parse(c2stlstr(msg->content_type->value),
601 			  (unsigned char*)msg->body.s,
602 			  msg->body.len) < 0) {
603 	    DBG("could not parse MIME body\n");
604 	}
605 	else {
606 	    DBG("MIME body successfully parsed\n");
607 	    // some debug infos?
608 	}
609     }
610 
611     prepare_routes_uas(msg->record_route, req.route);
612 
613     for (list<sip_header *>::const_iterator it = msg->hdrs.begin();
614 	 it != msg->hdrs.end(); ++it) {
615 
616 	switch((*it)->type) {
617 	case sip_header::H_OTHER:
618 	case sip_header::H_REQUIRE:
619 	    req.hdrs += c2stlstr((*it)->name) + ": "
620 		+ c2stlstr((*it)->value) + CRLF;
621 	    break;
622 	case sip_header::H_VIA:
623 	    req.vias += c2stlstr((*it)->name) + ": "
624 		+ c2stlstr((*it)->value) + CRLF;
625 	    break;
626 	case sip_header::H_MAX_FORWARDS:
627 	    if(!str2int(c2stlstr((*it)->value),req.max_forwards) ||
628 	       (req.max_forwards < 0) ||
629 	       (req.max_forwards > 255)) {
630 		trans_layer::instance()->
631 		    send_sf_error_reply(&tt, msg, 400, "Incorrect Max-Forwards");
632 		return false;
633 	    }
634 	    break;
635 	}
636     }
637 
638     if(req.max_forwards < 0)
639 	req.max_forwards = AmConfig::MaxForwards;
640 
641     req.remote_ip = get_addr_str(&msg->remote_ip);
642     req.remote_port = am_get_port(&msg->remote_ip);
643 
644     req.local_ip = get_addr_str(&msg->local_ip);
645     req.local_port = am_get_port(&msg->local_ip);
646 
647     req.trsp = msg->local_socket->get_transport();
648     req.local_if = msg->local_socket->get_if();
649 
650     req.via1 = c2stlstr(msg->via1->value);
651     if(msg->vias.size() > 1) {
652 	req.first_hop = false;
653     }
654     else {
655 	sip_via* via1 = (sip_via*)msg->via1->p;
656 	assert(via1); // gets parsed in parse_sip_msg()
657 	req.first_hop = (via1->parms.size() == 1);
658     }
659 
660     return true;
661 }
662 
sip_msg2am_reply(sip_msg * msg,AmSipReply & reply)663 inline bool _SipCtrlInterface::sip_msg2am_reply(sip_msg *msg, AmSipReply &reply)
664 {
665     if (msg->content_type) {
666 
667 	if(reply.body.parse(c2stlstr(msg->content_type->value),
668 			    (unsigned char*)msg->body.s,
669 			    msg->body.len) < 0) {
670 	    DBG("could not parse MIME body\n");
671 	}
672 	else {
673 	    DBG("MIME body successfully parsed\n");
674 	    // some debug infos?
675 	}
676     }
677 
678     reply.cseq = get_cseq(msg)->num;
679     reply.cseq_method = c2stlstr(get_cseq(msg)->method_str);
680 
681     reply.code   = msg->u.reply->code;
682     reply.reason = c2stlstr(msg->u.reply->reason);
683 
684     if(get_contact(msg) && get_contact(msg)->value.len){
685 
686 	// parse the first contact
687 	sip_nameaddr na;
688 	cstring contact = get_contact(msg)->value;
689 	if(parse_first_nameaddr(&na,contact.s,contact.len) < 0) {
690 
691 	    ERROR("Contact nameaddr parsing failed ('%.*s')\n",
692 		  contact.len,contact.s);
693 	}
694 	else {
695 	    reply.to_uri = c2stlstr(na.addr);
696 	}
697 
698 	list<sip_header*>::iterator c_it = msg->contacts.begin();
699 	reply.contact = c2stlstr((*c_it)->value);
700 	++c_it;
701 
702 	for(;c_it!=msg->contacts.end(); ++c_it){
703 	    reply.contact += "," + c2stlstr((*c_it)->value);
704 	}
705     }
706 
707     reply.callid = c2stlstr(msg->callid->value);
708 
709     reply.to_tag = c2stlstr(((sip_from_to*)msg->to->p)->tag);
710     reply.from_tag  = c2stlstr(((sip_from_to*)msg->from->p)->tag);
711 
712 
713     prepare_routes_uac(msg->record_route, reply.route);
714 
715     unsigned rseq;
716     for (list<sip_header*>::iterator it = msg->hdrs.begin();
717 	 it != msg->hdrs.end(); ++it) {
718 #ifdef PROPAGATE_UNPARSED_REPLY_HEADERS
719         reply.unparsed_headers.push_back(AmSipHeader((*it)->name, (*it)->value));
720 #endif
721         switch ((*it)->type) {
722           case sip_header::H_OTHER:
723           case sip_header::H_REQUIRE:
724 	      reply.hdrs += c2stlstr((*it)->name) + ": "
725                   + c2stlstr((*it)->value) + CRLF;
726               break;
727           case sip_header::H_RSEQ:
728               if (! parse_rseq(&rseq, (*it)->value.s, (*it)->value.len)) {
729                   ERROR("failed to parse (rcvd) '" SIP_HDR_RSEQ "' hdr.\n");
730               } else {
731                   reply.rseq = rseq;
732               }
733               break;
734         }
735     }
736 
737     reply.remote_ip = get_addr_str(&msg->remote_ip);
738     reply.remote_port = am_get_port(&msg->remote_ip);
739 
740     reply.local_ip = get_addr_str(&msg->local_ip);
741     reply.local_port = am_get_port(&msg->local_ip);
742 
743     if(msg->local_socket)
744 	reply.trsp = msg->local_socket->get_transport();
745 
746     return true;
747 }
748 
749 
750 #define DBG_PARAM(p)\
751     DBG("%s = <%s>\n",#p,p.c_str());
752 
handle_sip_request(const trans_ticket & tt,sip_msg * msg)753 void _SipCtrlInterface::handle_sip_request(const trans_ticket& tt, sip_msg* msg)
754 {
755     assert(msg);
756     assert(msg->from && msg->from->p);
757     assert(msg->to && msg->to->p);
758 
759     AmSipRequest req;
760 
761     if(!sip_msg2am_request(msg, tt, req))
762 	return;
763 
764     DBG("Received new request from <%s:%i/%s> on intf #%i\n",
765 	req.remote_ip.c_str(),req.remote_port,req.trsp.c_str(),req.local_if);
766 
767     if (_SipCtrlInterface::log_parsed_messages) {
768 	//     DBG_PARAM(req.cmd);
769 	DBG_PARAM(req.method);
770 	//     DBG_PARAM(req.user);
771 	//     DBG_PARAM(req.domain);
772 	DBG_PARAM(req.r_uri);
773 	DBG_PARAM(req.from_uri);
774 	DBG_PARAM(req.from);
775 	DBG_PARAM(req.to);
776 	DBG_PARAM(req.callid);
777 	DBG_PARAM(req.from_tag);
778 	DBG_PARAM(req.to_tag);
779 	DBG("cseq = <%i>\n",req.cseq);
780 	DBG("max_forwards = <%i>\n",req.max_forwards);
781 	DBG_PARAM(req.route);
782 	DBG("hdrs = <%s>\n",req.hdrs.c_str());
783 	DBG("body-ct = <%s>\n",req.body.getCTStr().c_str());
784     }
785 
786     AmSipDispatcher::instance()->handleSipMsg(req);
787 
788     DBG("^^ M [%s|%s] Ru SIP request %s handled ^^\n",
789 	req.callid.c_str(), req.to_tag.c_str(), req.method.c_str());
790 }
791 
handle_sip_reply(const string & dialog_id,sip_msg * msg)792 void _SipCtrlInterface::handle_sip_reply(const string& dialog_id, sip_msg* msg)
793 {
794     assert(msg->from && msg->from->p);
795     assert(msg->to && msg->to->p);
796 
797     AmSipReply   reply;
798 
799 
800     if (! sip_msg2am_reply(msg, reply)) {
801       ERROR("failed to convert sip_msg to AmSipReply\n");
802       // trans_bucket::match_reply only uses via_branch & cseq
803       reply.cseq = get_cseq(msg)->num;
804       reply.cseq_method = c2stlstr(get_cseq(msg)->method_str);
805       reply.code = 500;
806       reply.reason = "Internal Server Error";
807       reply.callid = c2stlstr(msg->callid->value);
808       reply.to_tag = c2stlstr(((sip_from_to*)msg->to->p)->tag);
809       reply.from_tag  = c2stlstr(((sip_from_to*)msg->from->p)->tag);
810       AmSipDispatcher::instance()->handleSipMsg(dialog_id, reply);
811       return;
812     }
813 
814     DBG("Received reply: %i %s\n",reply.code,reply.reason.c_str());
815     DBG_PARAM(reply.callid);
816     DBG_PARAM(reply.from_tag);
817     DBG_PARAM(reply.to_tag);
818     DBG_PARAM(reply.contact);
819     DBG_PARAM(reply.to_uri);
820     DBG("cseq = <%i>\n",reply.cseq);
821     DBG_PARAM(reply.route);
822     DBG("hdrs = <%s>\n",reply.hdrs.c_str());
823     DBG("body-ct = <%s>\n",reply.body.getCTStr().c_str());
824 
825     AmSipDispatcher::instance()->handleSipMsg(dialog_id, reply);
826 
827     DBG("^^ M [%s|%s] ru SIP reply %u %s handled ^^\n",
828 	reply.callid.c_str(), reply.from_tag.c_str(),
829 	reply.code, reply.reason.c_str());
830 }
831 
handle_reply_timeout(AmSipTimeoutEvent::EvType evt,sip_trans * tr,trans_bucket * buk)832 void _SipCtrlInterface::handle_reply_timeout(AmSipTimeoutEvent::EvType evt,
833     sip_trans *tr, trans_bucket *buk)
834 {
835   AmSipTimeoutEvent *tmo_evt;
836 
837   switch (evt) {
838   case AmSipTimeoutEvent::noACK: {
839       sip_cseq* cseq = dynamic_cast<sip_cseq*>(tr->msg->cseq->p);
840 
841       if(!cseq){
842           ERROR("missing CSeq\n");
843           return;
844       }
845     tmo_evt = new AmSipTimeoutEvent(evt, cseq->num);
846     }
847     break;
848 
849   case AmSipTimeoutEvent::noPRACK: {
850       sip_msg msg(tr->retr_buf, tr->retr_len);
851 
852       char* err_msg=0;
853       int err = parse_sip_msg(&msg, err_msg);
854       if (err) {
855           ERROR("failed to parse (own) reply[%d]: %s.\n", err,
856               err_msg ? err_msg : "???");
857           return;
858       }
859 
860       AmSipReply reply;
861       if (! sip_msg2am_reply(&msg, reply)) {
862           ERROR("failed to convert sip_msg to AmSipReply.\n");
863           return;
864       }
865 
866       AmSipRequest request;
867       sip_msg2am_request(tr->msg, trans_ticket(tr, buk), request);
868 
869       DBG("Reply timed out: %i %s\n",reply.code,reply.reason.c_str());
870       DBG_PARAM(reply.callid);
871       DBG_PARAM(reply.to_tag);
872       DBG_PARAM(reply.from_tag);
873       DBG("cseq = <%i>\n",reply.cseq);
874 
875       tmo_evt = new AmSipTimeoutEvent(evt, request, reply);
876     }
877     break;
878 
879   default:
880     ERROR("BUG: unexpected timout event type '%d'.\n", evt);
881     return;
882   }
883 
884   cstring dlg_id = tr->to_tag;
885   if(tr->dialog_id.len) {
886       dlg_id = tr->dialog_id;
887   }
888 
889   if(!AmEventDispatcher::instance()->post(c2stlstr(dlg_id), tmo_evt)){
890       DBG("Could not post timeout event (sess. id: %.*s)\n",dlg_id.len,dlg_id.s);
891       delete tmo_evt;
892   }
893 }
894 
895 #undef DBG_PARAM
896 
prepare_routes_uac(const list<sip_header * > & routes,string & route_field)897 void _SipCtrlInterface::prepare_routes_uac(const list<sip_header*>& routes, string& route_field)
898 {
899     if(routes.empty())
900 	return;
901 
902     list<sip_header*>::const_reverse_iterator it_rh = routes.rbegin();
903     if(parse_route(*it_rh) < 0){
904 	DBG("Could not parse route header [%.*s]\n",
905 	    (*it_rh)->value.len,(*it_rh)->value.s);
906 	return;
907     }
908     sip_route* route = (sip_route*)(*it_rh)->p;
909 
910     list<route_elmt*>::const_reverse_iterator it_re = route->elmts.rbegin();
911     route_field = c2stlstr((*it_re)->route);
912 
913     while(true) {
914 
915 	if(++it_re == route->elmts.rend()) {
916 	    if(++it_rh == routes.rend()){
917 		DBG("route_field = [%s]\n",route_field.c_str());
918 		return;
919 	    }
920 
921 	    if(parse_route(*it_rh) < 0){
922 		DBG("Could not parse route header [%.*s]\n",
923 		    (*it_rh)->value.len,(*it_rh)->value.s);
924 		return;
925 	    }
926 	    route = (sip_route*)(*it_rh)->p;
927 	    if(route->elmts.empty())
928 		return;
929 	    it_re = route->elmts.rbegin();
930 	}
931 
932 	route_field += ", " + c2stlstr((*it_re)->route);
933     }
934 
935 }
936 
prepare_routes_uas(const list<sip_header * > & routes,string & route_field)937 void _SipCtrlInterface::prepare_routes_uas(const list<sip_header*>& routes, string& route_field)
938 {
939     if(!routes.empty()){
940 
941 	list<sip_header*>::const_iterator it = routes.begin();
942 
943 	route_field = c2stlstr((*it)->value);
944 	++it;
945 
946 	for(; it != routes.end(); ++it) {
947 
948 	    route_field += ", " + c2stlstr((*it)->value);
949 	}
950     }
951 }
952 
953 /** EMACS **
954  * Local variables:
955  * mode: c++
956  * c-basic-offset: 4
957  * End:
958  */
959