Browse code

sbc: added reg-cache based retargeting

please use "enable_reg_caching = yes" in the profile to activate the feature.

Raphael Coeffic authored on 17/07/2013 10:11:06
Showing 4 changed files
... ...
@@ -807,8 +807,14 @@ void SBCCallLeg::onInvite(const AmSipRequest& req)
807 807
     throw AmSession::Exception(400,"Failed to parse R-URI");
808 808
   }
809 809
 
810
-  if(RegisterDialog::decodeUsername(req.user,uac_ruri)) {
811
-    uac_req.r_uri = uac_ruri.uri_str();
810
+  if(call_profile.contact_hiding) { 
811
+    if(RegisterDialog::decodeUsername(req.user,uac_ruri)) {
812
+      uac_req.r_uri = uac_ruri.uri_str();
813
+    }
814
+  }
815
+  else if(call_profile.reg_caching) {
816
+    // REG-Cache lookup
817
+    uac_req.r_uri = call_profile.retarget(req.user,*dlg);
812 818
   }
813 819
 
814 820
   ruri = call_profile.ruri.empty() ? uac_req.r_uri : call_profile.ruri;
... ...
@@ -35,6 +35,7 @@
35 35
 #include "SBCCallControlAPI.h"
36 36
 #include "RTPParameters.h"
37 37
 #include "SDPFilter.h"
38
+#include "RegisterCache.h"
38 39
 
39 40
 typedef vector<SdpPayload>::iterator PayloadIterator;
40 41
 static string payload2str(const SdpPayload &p);
... ...
@@ -1174,6 +1175,32 @@ void SBCCallProfile::fix_reg_contact(ParamReplacerCtx& ctx,
1174 1175
   }
1175 1176
 }
1176 1177
 
1178
+string SBCCallProfile::retarget(const string& alias, AmBasicSipDialog& dlg) const
1179
+{
1180
+    // REG-Cache lookup
1181
+    AliasEntry alias_entry;
1182
+    if(!RegisterCache::instance()->findAliasEntry(alias, alias_entry)) {
1183
+      throw AmSession::Exception(404,"User not found");
1184
+    }
1185
+    string new_r_uri = alias_entry.contact_uri;
1186
+    DBG("setting from registration cache: r_uri='%s'\n",new_r_uri.c_str());
1187
+
1188
+    // fix NAT
1189
+    string nh = alias_entry.source_ip;
1190
+    if(alias_entry.source_port != 5060)
1191
+      nh += ":" + int2str(alias_entry.source_port);
1192
+
1193
+    DBG("setting from registration cache: next_hop='%s'\n", nh.c_str());
1194
+    dlg.setNextHop(nh);
1195
+
1196
+    // sticky interface
1197
+    DBG("setting from registration cache: outbound_interface='%s'\n",
1198
+	AmConfig::SIP_Ifs[alias_entry.local_if].name.c_str());
1199
+    dlg.setOutboundInterface(alias_entry.local_if);
1200
+
1201
+    return new_r_uri;
1202
+}
1203
+
1177 1204
 static bool readPayloadList(std::vector<PayloadDesc> &dst, const std::string &src)
1178 1205
 {
1179 1206
   dst.clear();
... ...
@@ -319,6 +319,14 @@ struct SBCCallProfile
319 319
 
320 320
   void fix_reg_contact(ParamReplacerCtx& ctx, const AmSipRequest& req,
321 321
 		       AmUriParser& contact) const;
322
+
323
+  /**
324
+   * Reg-cache lookup:
325
+   * - searches for alias in the reg-cache.
326
+   * - sets next-hop & outbound_interface
327
+   * @return retargeted R-URI
328
+   */
329
+  string retarget(const string& alias, AmBasicSipDialog& dlg) const;
322 330
 };
323 331
 
324 332
 #endif // _SBCCallProfile_h
... ...
@@ -325,8 +325,19 @@ int SimpleRelayDialog::initUAC(const AmSipRequest& req,
325 325
       reply_error(req,400,"Failed to parse R-URI");
326 326
     }
327 327
 
328
-    if(RegisterDialog::decodeUsername(req.user,ruri)) {
329
-      n_req.r_uri = ruri.uri_str();
328
+    if(cp.contact_hiding) {
329
+      if(RegisterDialog::decodeUsername(req.user,ruri)) {
330
+	n_req.r_uri = ruri.uri_str();
331
+      }
332
+    }
333
+    else if(cp.reg_caching) {
334
+      try {
335
+	n_req.r_uri = cp.retarget(req.user,*this);
336
+      }
337
+      catch(AmSession::Exception& e) {
338
+	reply_error(req,e.code,e.reason);
339
+	return -1;
340
+      }
330 341
     }
331 342
   }
332 343