bool RegisterDialog::decodeUsername(const string& encoded_user, AmUriParser& uri) { DBG("trying to decode hidden contact variables from '%s'\n", encoded_user.c_str()); AmArg vars; if (!username2arg(encoded_user, vars)) { DBG("decoding failed!\n"); return false; } DBG("decoded variables: '%s'\n", AmArg::print(vars).c_str()); if(!vars.hasMember("u") || !isArgCStr(vars["u"]) || !vars.hasMember("h") || !isArgCStr(vars["h"]) || !vars.hasMember("p") || !isArgCStr(vars["p"]) ) { DBG("missing variables or type mismatch!\n"); return false; } uri.uri_user = vars["u"].asCStr(); uri.uri_host = vars["h"].asCStr(); uri.uri_port = vars["p"].asCStr(); return true; }
bool retarget(const string& r_uri, const AmArg& values, SBCCallProfile* call_profile) { bool nat_handling = true; // default bool sticky_iface = true; // default if (values.hasMember("nat_handling") && string(values["nat_handling"].asCStr())=="no") { nat_handling = false; } if (values.hasMember("sticky_iface") && string(values["sticky_iface"].asCStr())=="no") { sticky_iface = false; } DBG("Registrar handling message to R-URI '%s'\n", r_uri.c_str()); DBG("nat_handling: %sabled, sticky_iface: %sabled\n", nat_handling?"en":"dis", sticky_iface?"en":"dis"); // should we check if the R-URI has already been changed? string aor = RegisterCache::canonicalize_aor(r_uri); RegisterCache* reg_cache = RegisterCache::instance(); map<string,string> alias_map; if(!aor.empty() && reg_cache->getAorAliasMap(aor,alias_map) && !alias_map.empty()) { AliasEntry alias_entry; const string& alias = alias_map.begin()->first; // no forking if(!alias.empty() && reg_cache->findAliasEntry(alias,alias_entry)) { call_profile->ruri = alias_entry.contact_uri; DBG("R-URI from location DB: '%s'\n", alias_entry.contact_uri.c_str()); if (nat_handling) { call_profile->next_hop = alias_entry.source_ip; if(alias_entry.source_port != 5060) call_profile->next_hop += ":" + int2str(alias_entry.source_port); call_profile->next_hop += "/" + alias_entry.trsp; } if (sticky_iface) { string out_if = AmConfig::SIP_Ifs[alias_entry.local_if].name; DBG("out_if = '%s'",out_if.c_str()); call_profile->outbound_interface = out_if; DBG("setting from registration cache: outbound_interface='%s'\n", call_profile->outbound_interface.c_str()); } return true; } } DBG("No registration found for r-ruri '%s'/ aor '%s' in location database.\n", r_uri.c_str(), aor.c_str()); return false; }
static RestParams::Format getFormat(const AmArg &values, RestParams::Format _default) { if (!values.hasMember("format")) return _default; const AmArg &a = values["format"]; if (!isArgCStr(a)) throw string("configuration error: wrong arg type\n"); const char *str = a.asCStr(); if (str) { if (strcmp(str, "text") == 0) return RestParams::TEXT; if (strcmp(str, "json") == 0) return RestParams::JSON; if (strcmp(str, "xml") == 0) return RestParams::XML; } throw string("invalid format parameter value\n"); return _default; }
void CCBLRedis::start(const string& cc_name, const string& ltag, SBCCallProfile* call_profile, int start_ts_sec, int start_ts_usec, const AmArg& values, int timer_id, AmArg& res) { // start code here res.push(AmArg()); AmArg& res_cmd = res[0]; #define MAX_ARGV_ITEMS 20 const char* argv[MAX_ARGV_ITEMS]; size_t argvlen[MAX_ARGV_ITEMS]; unsigned int argv_max = 0; if (!values.hasMember("argc") || str2i(values["argc"].asCStr(), argv_max) || (!argv_max)) { ERROR("deciphering argc\n"); res_cmd[SBC_CC_ACTION] = SBC_CC_REFUSE_ACTION; res_cmd[SBC_CC_REFUSE_CODE] = 500; res_cmd[SBC_CC_REFUSE_REASON] = SIP_REPLY_SERVER_INTERNAL_ERROR; return; } unsigned int argv_index=0; string query; for (; argv_index<argv_max;argv_index++) { argv[argv_index] = values["argv_"+int2str(argv_index)].asCStr(); argvlen[argv_index] = strlen(argv[argv_index]); if (query.length()) query+=" "; query+=string(argv[argv_index], argvlen[argv_index]); } DBG("query to REDIS: '%s'\n", query.c_str()); bool hit = false; unsigned int retries = 0; for (;retries<max_retries;retries++) { redisContext* redis_context = connection_pool.getActiveConnection(); if (NULL == redis_context) { INFO("no connection to REDIS\n"); if (!pass_on_bl_unavailable) { res_cmd[SBC_CC_ACTION] = SBC_CC_REFUSE_ACTION; res_cmd[SBC_CC_REFUSE_CODE] = 500; res_cmd[SBC_CC_REFUSE_REASON] = SIP_REPLY_SERVER_INTERNAL_ERROR; } return; } DBG("using redis connection [%p]\n", redis_context); redisReply* reply = (redisReply *) redisCommandArgv(redis_context, argv_index, argv, argvlen); int ret = handle_redis_reply(redis_context, reply, hit); if (ret == RWT_E_CONNECTION) { WARN("connection [%p] failed - retrying\n", redis_context); connection_pool.returnFailedConnection(redis_context); continue; } connection_pool.returnConnection(redis_context); break; } if (retries == max_retries) { if (!pass_on_bl_unavailable) { res_cmd[SBC_CC_ACTION] = SBC_CC_REFUSE_ACTION; res_cmd[SBC_CC_REFUSE_CODE] = 500; res_cmd[SBC_CC_REFUSE_REASON] = SIP_REPLY_SERVER_INTERNAL_ERROR; } return; } if (hit) { if (values.hasMember("action") && isArgCStr(values["action"]) && values["action"] == "drop") { DBG("Blacklist: Dropping call\n"); res_cmd[SBC_CC_ACTION] = SBC_CC_DROP_ACTION; } else { DBG("Blacklist: Refusing call\n"); res_cmd[SBC_CC_ACTION] = SBC_CC_REFUSE_ACTION; res_cmd[SBC_CC_REFUSE_CODE] = 403; res_cmd[SBC_CC_REFUSE_REASON] = "Unauthorized"; } } }
void RestModule::start(const string& cc_name, const string& ltag, SBCCallProfile* call_profile, int start_ts_sec, int start_ts_usec, const AmArg& values, int timer_id, AmArg& res) { res.push(AmArg()); AmArg& res_cmd = res[0]; try { string url; if (!values.hasMember("url")) throw string("configuration error: url must be configured for REST queries\n"); if (!isArgCStr(values["url"]) || !strlen(values["url"].asCStr())) { throw string("configuration error: invalid value of url\n"); } url = values["url"].asCStr(); RestParams params; if (params.retrieve(url, getFormat(values, RestParams::TEXT))) { // parameters successfully read from server params.getIfSet("ruri", call_profile->ruri); params.getIfSet("from", call_profile->from); params.getIfSet("to", call_profile->to); //TODO: params.getIfSet("contact", call_profile->contact); params.getIfSet("call-id", call_profile->callid); params.getIfSet("outbound_proxy", call_profile->outbound_proxy); params.getIfSet("force_outbound_proxy", call_profile->force_outbound_proxy); params.getIfSet("next_hop", call_profile->next_hop); string hf_type, hf_list; params.getIfSet("header_filter", hf_type); params.getIfSet("header_list", hf_list); if ( (!hf_type.empty()) || (!hf_list.empty())) setHeaderFilter(call_profile, hf_type, hf_list); //messagefilter // sdpfilter, anonymize_sdp params.getIfSet("sst_enabled", call_profile->sst_enabled); //doesn't work:params.getIfSet("sst_aleg_enabled", call_profile->sst_aleg_enabled); // TODO: autho, auth_aleg, reply translations params.getIfSet("append_headers", call_profile->append_headers); // CRLF is handled in SBC //doesn't work: params.getIfSet("refuse_with", call_profile->refuse_with); // TODO: rtprelay, symmetric_rtp, ... params.getIfSet("rtprelay_interface", call_profile->rtprelay_interface); params.getIfSet("aleg_rtprelay_interface", call_profile->aleg_rtprelay_interface); params.getIfSet("outbound_interface", call_profile->outbound_interface); } } catch (string &err) { ERROR("%s", err.c_str()); res_cmd[SBC_CC_ACTION] = SBC_CC_REFUSE_ACTION; res_cmd[SBC_CC_REFUSE_CODE] = 500; res_cmd[SBC_CC_REFUSE_REASON] = "REST configuration error"; } }