- simplified some code in the SIP stack

- introduced outbound_proxy+force_outbound_proxy at the SIP dialog level (AmSipDialog)
- outbound_proxy+force_outbound_proxy is configurable in the sems.conf


git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@1818 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Raphael Coeffic 16 years ago
parent 1a0d15d310
commit b24f51ef5b

@ -839,14 +839,12 @@ void ConferenceDialog::onSipRequest(const AmSipRequest& req)
// get route set and next hop
string iptel_app_param = getHeader(req.hdrs, PARAM_HDR);
if (iptel_app_param.length()) {
dlg.setRoute(get_header_keyvalue(iptel_app_param,"Transfer-RR"));
//dlg.next_hop = get_header_keyvalue(iptel_app_param,"Transfer-NH");
dlg.route = get_header_keyvalue(iptel_app_param,"Transfer-RR");
} else {
INFO("Use of P-Transfer-RR/P-Transfer-NH is deprecated. "
"Use '%s: Transfer-RR=<rr>;Transfer-NH=<nh>' instead.\n",PARAM_HDR);
dlg.setRoute(getHeader(req.hdrs,"P-Transfer-RR"));
//dlg.next_hop = getHeader(req.hdrs,"P-Transfer-NH");
dlg.route = getHeader(req.hdrs,"P-Transfer-RR");
}
DBG("ConferenceDialog::onSipRequest: local_party = %s\n",dlg.local_party.c_str());

@ -57,6 +57,7 @@ int AmConfig::SIPServerThreads = NUM_SIP_SERVERS;
int AmConfig::LocalSIPPort = 5060;
string AmConfig::LocalSIPIP = "";
string AmConfig::OutboundProxy = "";
bool AmConfig::ForceOutboundProxy = false;
string AmConfig::Signature = "";
bool AmConfig::SingleCodecInOK = false;
unsigned int AmConfig::DeadRtpTime = DEAD_RTP_TIME;
@ -218,6 +219,11 @@ int AmConfig::readConfiguration()
// outbound_proxy
OutboundProxy = cfg.getParameter("outbound_proxy");
// force_outbound_proxy
if(cfg.hasParameter("force_outbound_proxy")) {
ForceOutboundProxy = (cfg.getParameter("force_outbound_proxy") == "yes");
}
// plugin_path
PlugInPath = cfg.getParameter("plugin_path");

@ -87,6 +87,8 @@ struct AmConfig
static int LocalSIPPort;
/** Outbound Proxy (optional, outgoing calls only) */
static string OutboundProxy;
/** force Outbound Proxy to be used for in dialog requests */
static bool ForceOutboundProxy;
/** Server/User-Agent header (optional) */
static string Signature;
/** If 200 OK reply should be limited to preferred codec only */

@ -41,7 +41,9 @@ const char* AmSipDialog::status2str[4] = {
AmSipDialog::AmSipDialog(AmSipDialogEventHandler* h)
: status(Disconnected),cseq(10),hdl(h), serKeyLen(0)
: status(Disconnected),cseq(10),hdl(h),
outbound_proxy(AmConfig::OutboundProxy),
force_outbound_proxy(AmConfig::ForceOutboundProxy)
{
}
@ -69,8 +71,7 @@ AmSipDialog::~AmSipDialog()
void AmSipDialog::updateStatus(const AmSipRequest& req)
{
if (req.method == "ACK") {
// || (req.method == "CANCEL")
if ((req.method == "ACK") || (req.method == "CANCEL")) {
return;
}
@ -102,9 +103,7 @@ void AmSipDialog::updateStatus(const AmSipRequest& req)
local_uri = req.r_uri;
remote_party = req.from;
local_party = req.to;
setRoute(req.route);
//next_hop = req.next_hop;
route = req.route;
}
}
@ -145,8 +144,6 @@ int AmSipDialog::updateStatusReply(const AmSipRequest& req, unsigned int code)
DBG("reply: transaction found!\n");
AmSipTransaction& t = t_it->second;
//t->reply_code = code;
switch(status){
case Disconnected:
@ -202,24 +199,21 @@ void AmSipDialog::updateStatus(const AmSipReply& reply, bool do_200_ack)
AmSipTransaction& t = t_it->second;
// rfc3261 12.1
// && method==INVITE
// Dialog established only by 101-199 or 2xx
// responses to INVITE
if ((reply.code >= 101) && (reply.code < 300) &&
(remote_tag.empty() && !reply.remote_tag.empty()))
remote_tag = reply.remote_tag;
if ((reply.code >= 200) && (reply.code < 300) &&
(status != Connected && !reply.remote_tag.empty()))
if ( (reply.code > 100)
&& (reply.code < 300)
&& !reply.remote_tag.empty()
&& (remote_tag.empty() ||
((status < Connected) && (reply.code >= 200))) ) {
remote_tag = reply.remote_tag;
}
// allow route overwritting
if(status < Connected) {
if(!reply.route.empty())
setRoute(reply.route);
//next_hop = reply.next_hop;
if ((status < Connected) && !reply.route.empty()) {
route = reply.route;
}
if (reply.next_request_uri.length())
@ -491,7 +485,7 @@ int AmSipDialog::transfer(const string& target)
string hdrs = "";
AmSipDialog tmp_d(*this);
tmp_d.setRoute("");
tmp_d.route = "";
tmp_d.contact_uri = SIP_HDR_COLSP(SIP_HDR_CONTACT)
"<" + tmp_d.remote_uri + ">" CRLF;
tmp_d.remote_uri = target;
@ -499,14 +493,7 @@ int AmSipDialog::transfer(const string& target)
string r_set;
if(!route.empty()){
vector<string>::iterator it = route.begin();
r_set ="Transfer-RR=\"" + *it;
for(it++; it != route.end(); it++)
r_set += "," + *it;
r_set += "\"";
hdrs = PARAM_HDR ": " + r_set;
hdrs = PARAM_HDR ": " "Transfer-RR=\"" + route + "\"";
}
int ret = tmp_d.sendRequest("REFER","","",hdrs);
@ -527,22 +514,12 @@ int AmSipDialog::transfer(const string& target)
int AmSipDialog::cancel()
{
for(TransMap::reverse_iterator t = uac_trans.rbegin();
t != uac_trans.rend(); t++) {
if(t->second.method == "INVITE"){
AmSipRequest req;
req.method = "CANCEL";
req.callid = callid;
req.cseq = t->second.cseq;
req.tt = t->second.tt;
return SipCtrlInterface::send(req) ? 0 : -1;
return SipCtrlInterface::cancel(&t->second.tt);
}
}
@ -566,7 +543,6 @@ int AmSipDialog::sendRequest(const string& method,
req.method = method;
req.r_uri = remote_uri;
//req.next_hop = next_hop;
req.from = SIP_HDR_COLSP(SIP_HDR_FROM) + local_party;
if(!local_tag.empty())
@ -590,13 +566,22 @@ int AmSipDialog::sendRequest(const string& method,
if (AmConfig::Signature.length())
req.hdrs += SIP_HDR_COLSP(SIP_HDR_USER_AGENT) + AmConfig::Signature + CRLF;
req.hdrs += SIP_HDR_COLSP(SIP_HDR_MAX_FORWARDS) /*TODO: configurable?!*/MAX_FORWARDS CRLF;
req.hdrs += SIP_HDR_COLSP(SIP_HDR_MAX_FORWARDS) /*TODO: configurable?!*/ MAX_FORWARDS CRLF;
}
if(!route.empty())
req.route = getRoute();
if(!route.empty()) {
req.route = "Route: ";
if(force_outbound_proxy){
req.route += "<" + outbound_proxy + ";lr>, ";
}
req.route += route + CRLF;
}
else if (remote_tag.empty() && !outbound_proxy.empty()) {
req.route = "Route: <" + outbound_proxy + ";lr>" CRLF;
}
if(!body.empty()) {
req.content_type = content_type;
req.body = body;
@ -613,17 +598,6 @@ int AmSipDialog::sendRequest(const string& method,
return 0;
}
// bool AmSipDialog::match_cancel(const AmSipRequest& cancel_req)
// {
// TransMap::iterator t = uas_trans.find(cancel_req.cseq);
// if((t != uas_trans.end()) && (t->second.method == "INVITE"))
// return true;
// return false;
// }
string AmSipDialog::get_uac_trans_method(unsigned int cseq)
{
TransMap::iterator t = uac_trans.find(cseq);
@ -634,39 +608,6 @@ string AmSipDialog::get_uac_trans_method(unsigned int cseq)
return "";
}
string AmSipDialog::getRoute()
{
string r_set("");
for(vector<string>::iterator it = route.begin();
it != route.end(); it++) {
r_set += SIP_HDR_COLSP(SIP_HDR_ROUTE) + *it + CRLF;
}
return r_set;
}
void AmSipDialog::setRoute(const string& n_route)
{
string m_route = n_route;
if(!m_route.empty() && (m_route.find("Route: ")!=string::npos))
m_route = m_route.substr(7/*sizeof("Route: ")*/);
route.clear();
while(!m_route.empty()){
string::size_type comma_pos;
comma_pos = m_route.find(',');
//route += "Route: " + m_route.substr(0,comma_pos) + "\r\n";
route.push_back(m_route.substr(0,comma_pos));
if(comma_pos != string::npos)
m_route = m_route.substr(comma_pos+1);
else
m_route = "";
}
}
int AmSipDialog::drop()
{
status = Disconnected;
@ -722,7 +663,7 @@ int AmSipDialog::send_200_ack(const AmSipTransaction& t,
}
if(!route.empty())
req.route = getRoute();
req.route = route; //getRoute();
if(!body.empty()) {
req.content_type = content_type;

@ -100,7 +100,6 @@ class AmSipDialog
TransMap uac_trans;
AmSipDialogEventHandler* hdl;
std::vector<string> route; // record routing
int updateStatusReply(const AmSipRequest& req,
unsigned int code);
@ -133,15 +132,11 @@ class AmSipDialog
string remote_party; // To/From
string local_party; // To/From
string getRoute(); // record routing
void setRoute(const string& n_route);
string route;
string outbound_proxy;
bool force_outbound_proxy;
//string next_hop; // next_hop for t_uac_dlg
int cseq; // CSeq for next request
char serKey[MAX_SER_KEY_LEN]; // opaque string returned by SER, when staring a T
unsigned int serKeyLen;
int cseq; // Local CSeq for next request
AmSipDialog(AmSipDialogEventHandler* h=0);
~AmSipDialog();
@ -152,10 +147,11 @@ class AmSipDialog
void updateStatus(const AmSipRequest& req);
void updateStatus(const AmSipReply& reply, bool do_200_ack=true);
/** update Status from locally originated request (e.g. INVITE) */
void updateStatusFromLocalRequest(const AmSipRequest& req);
int reply(const AmSipRequest& req, // Ser's transaction key
int reply(const AmSipRequest& req,
unsigned int code,
const string& reason,
const string& content_type = "",
@ -189,12 +185,6 @@ class AmSipDialog
int transfer(const string& target);
int drop();
/**
* @return true if a transaction could be found that
* matches the CANCEL's one.
*/
//bool match_cancel(const AmSipRequest& cancel_req);
/**
* @return the method of the corresponding uac request
*/

@ -11,7 +11,6 @@ class _AmSipMsgInDlg
{
public:
string method;
//string next_hop; // URI
string route;
string contact;

@ -127,16 +127,15 @@ SipCtrlInterface::SipCtrlInterface()
trans_layer::instance()->register_ua(this);
}
int SipCtrlInterface::cancel(AmSipRequest& req)
int SipCtrlInterface::cancel(trans_ticket* tt)
{
return trans_layer::instance()->cancel(&req.tt);
return trans_layer::instance()->cancel(tt);
}
int SipCtrlInterface::send(AmSipRequest &req)
{
if(req.method == "CANCEL")
return cancel(req);
return cancel(&req.tt);
sip_msg* msg = new sip_msg();
@ -152,7 +151,6 @@ int SipCtrlInterface::send(AmSipRequest &req)
// CSeq
// Contact
// Max-Forwards
char* c = (char*)req.from.c_str();
int err = parse_headers(msg,&c);
@ -175,7 +173,6 @@ int SipCtrlInterface::send(AmSipRequest &req)
msg->callid = new sip_header(0,"Call-ID",stl2cstr(req.callid));
msg->hdrs.push_back(msg->callid);
if(!req.contact.empty()){
c = (char*)req.contact.c_str();
@ -189,9 +186,8 @@ int SipCtrlInterface::send(AmSipRequest &req)
if(!req.route.empty()){
char *c = (char*)req.route.c_str();
err = parse_headers(msg,&c);
c = (char*)req.route.c_str();
err = parse_headers(msg,&c);
if(err){
ERROR("Route headers parsing failed\n");
@ -199,27 +195,11 @@ int SipCtrlInterface::send(AmSipRequest &req)
delete msg;
return -1;
}
//
// parse_headers() appends our route headers
// to msg->hdrs and msg->route. But we want
// only msg->route(), so we just remove the
// route headers at the end of msg->hdrs.
//
for(sip_header* h_rr = msg->hdrs.back();
!msg->hdrs.empty(); h_rr = msg->hdrs.back()) {
if(h_rr->type != sip_header::H_ROUTE){
break;
}
msg->hdrs.pop_back();
}
}
if(!req.hdrs.empty()) {
char *c = (char*)req.hdrs.c_str();
c = (char*)req.hdrs.c_str();
err = parse_headers(msg,&c);
@ -244,41 +224,6 @@ int SipCtrlInterface::send(AmSipRequest &req)
}
}
string next_hop;
unsigned int next_port_i = 0;
// if(!req.next_hop.empty()){
// string next_port;
// sip_uri parsed_uri;
// if (parse_uri(&parsed_uri, (char *)req.next_hop.c_str(),
// req.next_hop.length()) < 0) {
// ERROR("invalid next hop URI '%s'\n", req.next_hop.c_str());
// ERROR("Using default outbound proxy");
// next_hop = SipCtrlInterface::outbound_host;
// next_port_i = SipCtrlInterface::outbound_port;
// } else {
// next_hop = c2stlstr(parsed_uri.host);
// if (parsed_uri.port) {
// next_port_i= parsed_uri.port; }
// next_hop += *(c++);
// }
// }
// else
if(!SipCtrlInterface::outbound_host.empty()){
next_hop = SipCtrlInterface::outbound_host;
next_port_i = SipCtrlInterface::outbound_port;
}
cstring c_next_hop = stl2cstr(next_hop);
if(trans_layer::instance()->set_next_hop(msg->route,msg->u.request->ruri_str,
c_next_hop,(unsigned short)next_port_i,
&msg->remote_ip) < 0){
DBG("set_next_hop failed\n");
delete msg;
return -1;
}
int res = trans_layer::instance()->send_request(msg,&req.tt);
delete msg;

@ -38,17 +38,16 @@ using std::list;
class AmSipRequest;
class AmSipReply;
class trans_layer;
class trans_bucket;
struct sip_msg;
struct sip_header;
class trans_ticket;
class SipCtrlInterface:
public sip_ua
{
void prepare_routes_uac(const list<sip_header*>& routes, string& route_field);
void prepare_routes_uas(const list<sip_header*>& routes, string& route_field);
static int cancel(AmSipRequest& req);
friend class udp_trsp;
@ -68,10 +67,9 @@ public:
void run(const string& bind_addr, unsigned short bind_port);
/**
* From AmCtrlInterface
*/
static int send(AmSipRequest &req);
static int cancel(trans_ticket* tt);
static int send(const AmSipReply &rep);
/**

@ -282,8 +282,6 @@ int parse_headers(sip_msg* msg, char** c)
int saved_st = 0;
char* begin = *c;
//bool cr = false;
auto_ptr<sip_header> hdr(new sip_header());
for(;**c;(*c)++){

@ -539,7 +539,7 @@ int trans_layer::send_sl_reply(sip_msg* req, int reply_code,
//
int trans_layer::set_next_hop(list<sip_header*>& route_hdrs,
cstring& r_uri, cstring& next_hop,
unsigned short next_port,
unsigned short& next_port,
sockaddr_storage* remote_ip)
{
int err=0;
@ -648,7 +648,7 @@ int trans_layer::set_next_hop(list<sip_header*>& route_hdrs,
case RR_PARAMS:
// remove current route header from message
DBG("delete (fr=0x%p)\n",fr);
delete fr; // route_hdrs.front();
delete fr;
route_hdrs.pop_front();
DBG("route_hdrs.length() = %i\n",(int)route_hdrs.size());
break;
@ -669,7 +669,8 @@ int trans_layer::set_next_hop(list<sip_header*>& route_hdrs,
}
}
else if (next_hop.len == 0) {
else {
sip_uri parsed_r_uri;
err = parse_uri(&parsed_r_uri,r_uri.s,r_uri.len);
if(err < 0){
@ -730,17 +731,26 @@ int trans_layer::send_request(sip_msg* msg, trans_ticket* tt)
// Contact
// Supported / Require
// Content-Length / Content-Type
assert(transport);
assert(msg);
assert(tt);
cstring next_hop;
unsigned short next_port = 0;
tt->_bucket = 0;
tt->_t = 0;
// assume that msg->route headers are not in msg->hdrs
msg->hdrs.insert(msg->hdrs.begin(),msg->route.begin(),msg->route.end());
if(trans_layer::instance()->set_next_hop(msg->route,msg->u.request->ruri_str,
next_hop,next_port,
&msg->remote_ip) < 0){
DBG("set_next_hop failed\n");
delete msg;
return -1;
}
int request_len = request_line_len(msg->u.request->method_str,
msg->u.request->ruri_str);
@ -1036,7 +1046,7 @@ void trans_layer::received_msg(sip_msg* msg)
}
else {
DBG("Found retransmission\n");
retransmit(t);
retransmit(t); // retransmit reply
}
}
else {

@ -97,12 +97,12 @@ class trans_layer
int update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply_code);
/**
* Retransmits reply / non-200 ACK (if possible).
* Retransmits the content of the retry buffer (replies or non-200 ACK).
*/
void retransmit(sip_trans* t);
/**
* Retransmits a message (mostly the first UAC request).
* Retransmits a message (UAC requests).
*/
void retransmit(sip_msg* msg);
@ -120,6 +120,14 @@ class trans_layer
int send_sl_reply(sip_msg* req, int reply_code,
const cstring& reason,
const cstring& hdrs, const cstring& body);
/**
* Fills the address structure passed and modifies
* R-URI and Route headers as needed.
*/
int set_next_hop(list<sip_header*>& route_hdrs, cstring& r_uri,
cstring& next_hop, unsigned short& next_port,
sockaddr_storage* remote_ip);
/**
* Transaction timeout
@ -179,14 +187,6 @@ class trans_layer
*/
void received_msg(sip_msg* msg);
/**
* Fills the address structure passed and modifies
* R-URI and Route headers as needed.
*/
int set_next_hop(list<sip_header*>& route_hdrs, cstring& r_uri,
cstring& next_hop, unsigned short next_port,
sockaddr_storage* remote_ip);
/**
* This is called by the transaction timer callback.
* At this place, the bucket is already locked, so

Loading…
Cancel
Save