This time WITH patch ;-)
-Raphael.
On 20.04.10 18:00, Raphael Coeffic wrote:
Gentlemen,
here is a patch implementing the outbound proxy (with "force" flag) at
the AmSipDialog level following the "guidance of the bible" (RFC3261).
Though it is not tested, please have a close look at it (especially
the code for AmSipDialog::send_request()) and tell me if this could
satisfy your needs.
-Raphael.
PS: I haven't ported the code for the SIPRegistrarClient yet... please
forgive me!
On 20.04.10 15:32, Juha Heinanen wrote:
Raphael Coeffic writes:
> This means that the intended behavior is:
> 1. send the first request to the outbound proxy (if existing).
> 2. send subsequent requests using the route-set and standard
behavior
> (means: no outbound proxy there).
>
> Forcing the proxy is an option, but should definitely not be the
default
> behavior. At least not if we claim to have some level of
compliance with
> standards ;-)
raphael,
i agree that standard behavior is to follow route set, but for security
reasons, it makes sense to have an option for force ob also for inbound
requests.
-- juha
Index: apps/conference/Conference.cpp
===================================================================
--- apps/conference/Conference.cpp (revision 1811)
+++ apps/conference/Conference.cpp (working copy)
@@ -839,13 +839,13 @@
// 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.route = get_header_keyvalue(iptel_app_param,"Transfer-RR");
//dlg.next_hop = get_header_keyvalue(iptel_app_param,"Transfer-NH");
} 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.route = getHeader(req.hdrs,"P-Transfer-RR");
//dlg.next_hop = getHeader(req.hdrs,"P-Transfer-NH");
}
Index: core/AmSipDialog.h
===================================================================
--- core/AmSipDialog.h (revision 1811)
+++ core/AmSipDialog.h (working copy)
@@ -100,7 +100,6 @@
TransMap uac_trans;
AmSipDialogEventHandler* hdl;
- std::vector<string> route; // record routing
int updateStatusReply(const AmSipRequest& req,
unsigned int code);
@@ -133,16 +132,12 @@
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; // Local CSeq for next request
- int cseq; // CSeq for next request
-
- char serKey[MAX_SER_KEY_LEN]; // opaque string returned by SER, when
staring a T
- unsigned int serKeyLen;
-
AmSipDialog(AmSipDialogEventHandler* h=0);
~AmSipDialog();
Index: core/AmSipDialog.cpp
===================================================================
--- core/AmSipDialog.cpp (revision 1811)
+++ core/AmSipDialog.cpp (working copy)
@@ -41,7 +41,9 @@
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 @@
void AmSipDialog::updateStatus(const AmSipRequest& req)
{
- if (req.method == "ACK") {
- // || (req.method == "CANCEL")
+ if ((req.method == "ACK") || (req.method == "CANCEL")) {
return;
}
@@ -103,7 +104,9 @@
remote_party = req.from;
local_party = req.to;
- setRoute(req.route);
+ //setRoute(req.route);
+ route = req.route;
+
//next_hop = req.next_hop;
}
}
@@ -217,7 +220,8 @@
if(status < Connected) {
if(!reply.route.empty())
- setRoute(reply.route);
+ //setRoute(reply.route);
+ route = reply.route;
//next_hop = reply.next_hop;
}
@@ -491,7 +495,7 @@
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 +503,7 @@
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 +524,12 @@
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 +553,6 @@
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 +576,22 @@
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 + ", ";
+ }
+ req.route += route + CRLF;
+ }
+ else if (!local_tag.empty() && !remote_tag.empty() &&
!outbound_proxy.empty()) {
+ req.route = "Route: " + outbound_proxy + CRLF;
+ }
+
if(!body.empty()) {
req.content_type = content_type;
req.body = body;
@@ -613,17 +608,6 @@
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 +618,6 @@
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 +673,7 @@
}
if(!route.empty())
- req.route = getRoute();
+ req.route = route; //getRoute();
if(!body.empty()) {
req.content_type = content_type;
Index: core/sip/trans_layer.h
===================================================================
--- core/sip/trans_layer.h (revision 1811)
+++ core/sip/trans_layer.h (working copy)
@@ -97,12 +97,12 @@
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 @@
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
@@ -180,14 +188,6 @@
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
* please be quick.
Index: core/sip/parse_header.cpp
===================================================================
--- core/sip/parse_header.cpp (revision 1811)
+++ core/sip/parse_header.cpp (working copy)
@@ -282,8 +282,6 @@
int saved_st = 0;
char* begin = *c;
- //bool cr = false;
-
auto_ptr<sip_header> hdr(new sip_header());
for(;**c;(*c)++){
Index: core/sip/trans_layer.cpp
===================================================================
--- core/sip/trans_layer.cpp (revision 1811)
+++ core/sip/trans_layer.cpp (working copy)
@@ -535,7 +535,7 @@
//
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;
@@ -644,7 +644,7 @@
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;
@@ -665,7 +665,8 @@
}
}
- 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){
@@ -726,17 +727,26 @@
// 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);
@@ -1032,7 +1042,7 @@
}
else {
DBG("Found retransmission\n");
- retransmit(t);
+ retransmit(t); // retransmit reply
}
}
else {
Index: core/AmSipMsg.h
===================================================================
--- core/AmSipMsg.h (revision 1811)
+++ core/AmSipMsg.h (working copy)
@@ -11,7 +11,6 @@
{
public:
string method;
- //string next_hop; // URI
string route;
string contact;
Index: core/AmConfig.h
===================================================================
--- core/AmConfig.h (revision 1811)
+++ core/AmConfig.h (working copy)
@@ -87,6 +87,8 @@
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 */
Index: core/SipCtrlInterface.h
===================================================================
--- core/SipCtrlInterface.h (revision 1811)
+++ core/SipCtrlInterface.h (working copy)
@@ -38,17 +38,16 @@
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 @@
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);
/**
Index: core/AmConfig.cpp
===================================================================
--- core/AmConfig.cpp (revision 1811)
+++ core/AmConfig.cpp (working copy)
@@ -57,6 +57,7 @@
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 @@
// 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");
Index: core/SipCtrlInterface.cpp
===================================================================
--- core/SipCtrlInterface.cpp (revision 1811)
+++ core/SipCtrlInterface.cpp (working copy)
@@ -127,16 +127,15 @@
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 @@
// CSeq
// Contact
// Max-Forwards
-
char* c = (char*)req.from.c_str();
int err = parse_headers(msg,&c);
@@ -175,7 +173,6 @@
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,37 +186,20 @@
if(!req.route.empty()){
- char *c = (char*)req.route.c_str();
+ c = (char*)req.route.c_str();
+ err = parse_headers(msg,&c);
- err = parse_headers(msg,&c);
-
if(err){
ERROR("Route headers parsing failed\n");
ERROR("Faulty headers were: <%s>\n",req.route.c_str());
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 @@
}
}
- 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;
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev