From f7735ad6623d8564065ca46594f9df2dd9a79c7a Mon Sep 17 00:00:00 2001 From: Kirill Solomko Date: Mon, 12 Sep 2016 13:19:15 +0200 Subject: [PATCH] MT#19113 CallRoutingVerify adjustments, Peering lookup - use the caller domain part in subscriber and peering lookups - allowed_cli is checked after inbound rewrite rules - peering lookup also requires a 3rd argument "prefix" that matches the number and caller and callee are expected to be uri. Change-Id: I57e3ca01fc1bfa7dcddda90ed4176176713f6d2d --- lib/NGCP/Panel/Controller/CallRouting.pm | 156 ++++++++++++----------- lib/NGCP/Panel/Utils/Peering.pm | 6 +- 2 files changed, 88 insertions(+), 74 deletions(-) diff --git a/lib/NGCP/Panel/Controller/CallRouting.pm b/lib/NGCP/Panel/Controller/CallRouting.pm index 111bac6472..26466ee581 100644 --- a/lib/NGCP/Panel/Controller/CallRouting.pm +++ b/lib/NGCP/Panel/Controller/CallRouting.pm @@ -50,9 +50,13 @@ sub callroutingverify :Chained('/') :PathPart('callroutingverify') :Args(0) { # caller/callee general parsing # remove leading/trailing spaces + # save the domain part foreach my $type (qw(caller callee)) { $data->{$type} =~ s/(^\s+|\s+$)//g; $data->{$type} =~ s/^sip://; + if ($data->{$type} =~ s/\@(.+)$//) { + $data->{$type.'_domain'} = $1; + } } # caller lookup @@ -83,12 +87,15 @@ sub callroutingverify :Chained('/') :PathPart('callroutingverify') :Args(0) { } $data->{caller_peer_host} = $data->{caller_peer}->voip_peer_hosts->first; } else { + my $caller_uri = $data->{caller_domain} + ? $data->{caller}.'@'.$data->{caller_domain} + : $data->{caller}; push @log, sprintf "no caller subscriber/peer was specified, using subscriber lookup based on caller %s", - $data->{caller}; + $caller_uri; $data->{caller_subscriber} = NGCP::Panel::Utils::Subscriber::lookup( c => $c, - lookup => $data->{caller}, + lookup => $caller_uri ); if ($data->{caller_subscriber}) { $data->{caller_subscriber_id} = $data->{caller_subscriber}->id; @@ -121,71 +128,6 @@ sub callroutingverify :Chained('/') :PathPart('callroutingverify') :Args(0) { $data->{caller_peer_host}->id; } - # subscriber allowed_cli checks - if ($data->{caller_subscriber}) { - my %usr_prefs; - foreach my $pref (qw(allowed_clis allowed_clis_reject_policy cli user_cli)) { - my $rs = NGCP::Panel::Utils::Preferences::get_usr_preference_rs( - c => $c, attribute => $pref, - prov_subscriber => - $data->{caller_subscriber}->provisioning_voip_subscriber, - ); - if ($rs->first) { - @{$usr_prefs{$pref}} = map { $_->value } $rs->all; - } else { - $rs = NGCP::Panel::Utils::Preferences::get_dom_preference_rs( - c => $c, attribute => $pref, - prov_domain => - $data->{caller_subscriber}->provisioning_voip_subscriber->domain, - ); - if ($rs->first) { - @{$usr_prefs{$pref}} = map { $_->value } $rs->all; - } - } - } - my $match = map { $_ =~ s/\*/.*/g; - $data->{caller} =~ /^$_$/; - } @{$usr_prefs{allowed_clis}}; - if ($match) { - push @log, sprintf - "caller %s is accepted as it matches subscriber's 'allowed_clis'", - $data->{caller}; - } else { - push @log, sprintf - "caller %s is rejected as it does not match subscriber's 'allowed_clis'", - $data->{caller}; - if (defined $usr_prefs{allowed_clis_reject_policy}) { - SWITCH: for ($usr_prefs{allowed_clis_reject_policy}[0]) { - /^override_by_clir$/ && do { - push @log, - "'allowed_cli' reject policy is 'override_by_clir', anonymising caller"; - $data->{caller} = 'anonymous'; - last SWITCH; - }; - /^override_by_usernpn$/ && do { - push @log, - "'allowed_cli' reject policy is 'override_by_usernpn'"; - foreach my $cli (qw(user_cli cli)) { - if (defined $usr_prefs{$cli}) { - $data->{caller} = $usr_prefs{$cli}[0]; - $log[-1] .= sprintf ", taken from '$cli' %s", - $usr_prefs{$cli}[0]; - last; - } - } - last SWITCH; - }; - /^reject$/ && do { - push @log, - "'allowed_cli' reject policy is 'reject', terminating the call"; - goto RESULT; - last SWITCH; - }; - } - } - } - } - # caller inbound rewrite rules lookup if ($data->{caller_rewrite_id}) { my $rs = $c->model('DB')->resultset('voip_rewrite_rule_sets')->search({ @@ -284,6 +226,71 @@ sub callroutingverify :Chained('/') :PathPart('callroutingverify') :Args(0) { $data->{$type.'_in'} = $new || $data->{$type}; } + # subscriber allowed_cli checks + if ($data->{caller_subscriber}) { + my %usr_prefs; + foreach my $pref (qw(allowed_clis allowed_clis_reject_policy cli user_cli)) { + my $rs = NGCP::Panel::Utils::Preferences::get_usr_preference_rs( + c => $c, attribute => $pref, + prov_subscriber => + $data->{caller_subscriber}->provisioning_voip_subscriber, + ); + if ($rs->first) { + @{$usr_prefs{$pref}} = map { $_->value } $rs->all; + } else { + $rs = NGCP::Panel::Utils::Preferences::get_dom_preference_rs( + c => $c, attribute => $pref, + prov_domain => + $data->{caller_subscriber}->provisioning_voip_subscriber->domain, + ); + if ($rs->first) { + @{$usr_prefs{$pref}} = map { $_->value } $rs->all; + } + } + } + my $match = map { $_ =~ s/\*/.*/g; + $data->{caller} =~ /^$_$/; + } @{$usr_prefs{allowed_clis}}; + if ($match) { + push @log, sprintf + "caller %s is accepted as it matches subscriber's 'allowed_clis'", + $data->{caller}; + } else { + push @log, sprintf + "caller %s is rejected as it does not match subscriber's 'allowed_clis'", + $data->{caller}; + if (defined $usr_prefs{allowed_clis_reject_policy}) { + SWITCH: for ($usr_prefs{allowed_clis_reject_policy}[0]) { + /^override_by_clir$/ && do { + push @log, + "'allowed_cli' reject policy is 'override_by_clir', anonymising caller"; + $data->{caller} = 'anonymous'; + last SWITCH; + }; + /^override_by_usernpn$/ && do { + push @log, + "'allowed_cli' reject policy is 'override_by_usernpn'"; + foreach my $cli (qw(user_cli cli)) { + if (defined $usr_prefs{$cli}) { + $data->{caller} = $usr_prefs{$cli}[0]; + $log[-1] .= sprintf ", taken from '$cli' %s", + $usr_prefs{$cli}[0]; + last; + } + } + last SWITCH; + }; + /^reject$/ && do { + push @log, + "'allowed_cli' reject policy is 'reject', terminating the call"; + goto RESULT; + last SWITCH; + }; + } + } + } + } + # callee lookup if ($data->{callee_peer_id}) { my $rs = $c->model('DB')->resultset('voip_peer_groups')->search({ @@ -317,14 +324,21 @@ sub callroutingverify :Chained('/') :PathPart('callroutingverify') :Args(0) { push @log, sprintf "found callee subscriber '%s' with id %d", $sub, $data->{callee_subscriber_id}; } else { + foreach my $type (qw(caller callee)) { + $data->{$type.'_uri'} = $data->{$type}; + if ($data->{$type.'_domain'}) { + $data->{$type.'_uri'} .= '@' . $data->{$type.'_domain'}; + } + } push @log, - sprintf "no callee subscriber found, performing a peer lookup with caller %s and callee %s", - @{$data}{qw(caller_in callee_in)}; + sprintf "no callee subscriber found, performing a peer lookup with caller uri %s and callee uri %s and callee %s", + @{$data}{qw(caller_uri callee_uri callee_in)}; $data->{callee_peers} = NGCP::Panel::Utils::Peering::lookup( c => $c, - caller => $data->{caller_in}, - callee => $data->{callee_in}, + prefix => $data->{callee_in}, + caller => $data->{caller_uri}, + callee => $data->{callee_uri}, ); unless ($data->{callee_peers} && scalar @{$data->{callee_peers}}) { push @log, sprintf "no callee peers found"; diff --git a/lib/NGCP/Panel/Utils/Peering.pm b/lib/NGCP/Panel/Utils/Peering.pm index 634a2af21f..cedf245825 100644 --- a/lib/NGCP/Panel/Utils/Peering.pm +++ b/lib/NGCP/Panel/Utils/Peering.pm @@ -103,16 +103,16 @@ sub apply_rewrite { sub lookup { my (%params) = @_; - my ($c, $caller, $callee) = @{params}{qw(c caller callee)}; + my ($c, $caller, $callee, $prefix) = @{params}{qw(c caller callee prefix)}; - return unless $caller && $callee; + return unless $caller && $callee && $prefix; my $rs = $c->model('DB')->resultset('voip_peer_rules')->search({ enabled => 1, },{ '+columns' => { rule_match => \do { - "'$callee' LIKE CONCAT(callee_prefix,'%') as rule_match" + "'$prefix' LIKE CONCAT(callee_prefix,'%') as rule_match" }, }, having => { rule_match => 1 },