The Mk-III Safety Net for SfB Gateway AD-Lookups

It’s been a long while between visits to the subject of Sonus (now Ribbon) AD-based routing in the SBC1k, 2k & SWe Lite, but my colleague Tristan recently pointed out a new feature that I wasn’t previously aware of.

In my 2012 Mk-II Safety Net I showed how you could do a second AD lookup against an incoming call so as to ensure the transformation table passed regardless of whether their LineURI contained an “ext=” suffix or not.

Now it seems that’s been superseded by the addition of wildcard handling in AD lookups! [Reference]. And so here’s the Mk-III!

The Mk-III AD Lookup

For context, here’s what the Mk-II looked like:

Capture-MkII-TransformationTable-4

Here’s what the AD Lookup Transformation Table looks like now:

Mk-III-ADLookup-TransformationTable

The new and critical piece here is the “*” at the end of the reformatted E.164 called number.

  • Entry 1 reformats the called number into E.164 – with a wildcard “*” on the end – and saves it to a variable
  • Entry 2 tests to see if anyone’s msRTCSIPLine starts with the called number now in the variable, and if that test passes it initialises another variable
  • Entry 3 tests to see if the user matched in the previous line is enabled for EV. If so then it updates the Called number with the user’s Line URI. (The purpose of this latter exercise is to strip the “*” we added at the start)

If ALL the above tests pass – you’ll see their “Match Type” is Mandatory – then this table will be $true and its relevant entry will be followed in the routing table.

(The Optional entries 4 & 5 simply reformat the calling number. Customise as appropriate to suit your environment).

The Safety Net

The Safety Net incorporates the same wildcard test, although in this one I re-used the “Called Address/Number” instead of “User Value 1”. Either approach is valid – the use of the variable might be seen by a purist as code inefficient, but a little clearer in what’s going on:

Mk-III-ADLookup-SafetyNet-TransformationTable

The point of the Safety Net is that it traps a call to a user who’s had their Line URI set correctly, but hasn’t been enabled for Enterprise Voice. Without EV enabled SfB will reject any call the SBC sends to it, and so the Safety Net instead redirects those calls to a safe harbour, perhaps Reception or the HelpDesk.

You’ll notice there’s no test here for the msRTCSIP-OptionFlags because we want to test for a “not” or “false” condition, and Transformation Tables don’t allow for negation or “else” handling. Instead we achieve this by implication, a process of elimination. As the routing table executes in sequence from top to bottom, the only way a call will reach Entry 2 (the Safety Net) is if Entry 1 (the AD Lookup) fails one or both of the AD tests. If we re-test in the Safety Net for the LineURI and it passes, then the failure in the AD Lookup *must* have been the OptionFlags, thus confirming the user is not enabled for EV.

The Routing Table

So this is the final table:

Mk-III-ADLookup-RoutingTable

  • Entry 1 sends a call to an SfB user who’s setup correctly
  • If they’re not setup correctly, Entry 2 routes the call to the HelpDesk or whatever Safety Net destination you chose
  • Assuming there’s a PABX, then Entry 3 routes all remaining calls to that…

AD Setup

Prior to any of the above working you’ll need to create a user account in AD that the SBC will use to perform these tests, and create a Domain Controller in the SBC under “Auth and Directory Services / Active Directory”. Here are the settings I’m using.

Configuration

Mk-III-ADLookup-ADConfig

telephoneNumber and displayName aren’t used in the example presented here. I always add displayName to help me debugging – see “Debugging / Test the AD Cache”, below.

If you find you can’t get to the Configuration page to show, it might be that you’re running AdBlock Plus on Chrome, and in all recent builds (up to the current 7.0.1 b483) ABP won’t let you get there. Disable it for this site and all will be revealed.

Domain Controllers

Mk-III-ADLookup-AD-DCs

Critical to the DC setup is your search scope – you don’t want it to be too high so as to overflow the Cache, and you don’t want to burrow too low and miss users that might be in a remote OU. Also make sure your LDAP Query looks like the above. Don’t just put a “*” there – that won’t work.

Call Traces

Here are some sample call traces to show the Mk-III in operation.

Valid SfB user – with extension

Here’s a call to my number, where my line ID is (the fake) “+61270001223;ext=1223”:

- Using table From Carrier (5) to route call.
- Rule AD Lookup test (5.1(1)) being tested for selection.
- Performing MANDATORY transformation using entry Reformat called number for E.164 (9.1(1)).
- Successful regex match of "tfCalledNumber" field for "(\d{8})" (updated "(\d{8})") with input of "70001223"
- Regex replacement output of "tfUserValue1" field is "+61270001223*"
- Doing AD lookup for field 'msRTCSIP-Line' with value '+61270001223*'
- Transformation table(New AD Lookup test:9) is a AD Lookup
- Got AD lookup response with 4 field/value pairs.
- Using AD lookup response in request.
- Using table From Carrier (5) to route call.
- Rule AD Lookup test (5.1(1)) being tested for selection.
- Performing MANDATORY transformation using entry Test for msRTCSIP-Line match (9.2(2)).
- detect wildcard AD matching, swap AD rule and input string for proper regex
- Successful regex match of "tfUserValue1" field for "=msRTCSIP-Line=" (updated "\+61270001223.*") with input of "+61270001223;ext=1223"
- Regex replacement output of "tfUserValue2" field is "385"
- Performing MANDATORY transformation using entry Test for OptionFlags (9.3(3)).
- non wildcard AD, proceed as normal
- Successful regex match of "tfUserValue2" field for "=msRTCSIP-OptionFlags=" (updated "385") with input of "385"
- Regex replacement output of "tfCalledNumber" field is "+61270001223;ext=1223"
- Rule Format calling # (9.4(4)) skipped due to transformation entry disabled.
- Performing OPTIONAL transformation using entry Format calling # (9.5(5)).
- Failed regex match of "tfCallingNumber" field for "(\d{9})" (updated "(\d{9})") with input of "+61400000000"
- Performing OPTIONAL transformation using entry Format calling # (9.6(6)).
- Successful regex match of "tfCallingNumber" field for "(.*)" (updated "(.*)") with input of "+61400000000"
- Regex replacement output of "tfCallingNumber" field is "+61400000000"
- Transformation table(New AD Lookup test:9) is a SUCCESS
- Successful route request with entry AD Lookup test (5.1(1))

Valid SfB user – without extension

Here’s a call to Chode, signed in to the cockroach-infested Tanjay on top of the fridge. His line URI is “tel:+61270001263”:

- Using table From Carrier (5) to route call.
- Rule AD Lookup test (5.1(1)) being tested for selection.
- Performing MANDATORY transformation using entry Reformat called number for E.164 (9.1(1)).
- Successful regex match of "tfCalledNumber" field for "(\d{8})" (updated "(\d{8})") with input of "70001263"
- Regex replacement output of "tfUserValue1" field is "+61270001263*"
- Doing AD lookup for field 'msRTCSIP-Line' with value '+61270001263*'
- Transformation table(New AD Lookup test:9) is a AD Lookup
- Got AD lookup response with 4 field/value pairs.
- Using AD lookup response in request.
- Using table From Carrier (5) to route call.
- Rule AD Lookup test (5.1(1)) being tested for selection.
- Performing MANDATORY transformation using entry Test for msRTCSIP-Line match (9.2(2)).
- detect wildcard AD matching, swap AD rule and input string for proper regex
- Successful regex match of "tfUserValue1" field for "=msRTCSIP-Line=" (updated "\+61270001263.*") with input of "+61270001263"
- Regex replacement output of "tfUserValue2" field is "385"
- Performing MANDATORY transformation using entry Test for OptionFlags (9.3(3)).
- non wildcard AD, proceed as normal
- Successful regex match of "tfUserValue2" field for "=msRTCSIP-OptionFlags=" (updated "385") with input of "385"
- Regex replacement output of "tfCalledNumber" field is "+61270001263"
- Performing OPTIONAL transformation using entry Format calling # (9.4(4)).
- Failed regex match of "tfCallingNumber" field for "(\d{9})" (updated "(\d{9})") with input of "+61400000000"
- Performing OPTIONAL transformation using entry Format calling # (9.5(5)).
- Successful regex match of "tfCallingNumber" field for "(.*)" (updated "(.*)") with input of "+61400000000"
- Regex replacement output of "tfCallingNumber" field is "+61400000000"
- Transformation table(New AD Lookup test:9) is a SUCCESS
- Successful route request with entry AD Lookup test (5.1(1))

Invalid SfB user – not EV-enabled

This user has a valid line URI (“tel:+61270001208;ext=1208”) but is EV-disabled:

- Using table From Carrier (5) to route call.
- Rule AD Lookup test (5.1(1)) being tested for selection.
- Performing MANDATORY transformation using entry Reformat called number for E.164 (9.1(1)).
- Successful regex match of "tfCalledNumber" field for "(\d{8})" (updated "(\d{8})") with input of "70001208"
- Regex replacement output of "tfUserValue1" field is "+61270001208*"
- Doing AD lookup for field 'msRTCSIP-Line' with value '+61270001208*'
- Transformation table(New AD Lookup test:9) is a AD Lookup
- Got AD lookup response with 3 field/value pairs.
- Using AD lookup response in request.
- Using table From Carrier (5) to route call.
- Rule AD Lookup test (5.1(1)) being tested for selection.
- Performing MANDATORY transformation using entry Test for msRTCSIP-Line match (9.2(2)).
- detect wildcard AD matching, swap AD rule and input string for proper regex
- Successful regex match of "tfUserValue1" field for "=msRTCSIP-Line=" (updated "\+61270001208.*") with input of "+61270001208;ext=1208"
- Regex replacement output of "tfUserValue2" field is "385"
- Performing MANDATORY transformation using entry Test for OptionFlags (9.3(3)).
- non wildcard AD, proceed as normal
- Failed regex match of "tfUserValue2" field for "=msRTCSIP-OptionFlags=" (updated "2305") with input of "385"
- Transformation table(New AD Lookup test:9) is a FAILURE
- Rule Safety Net (5.2(2)) being tested for selection.
- Performing MANDATORY transformation using entry Reformat called number for E.164 (10.1(1)).
- Successful regex match of "tfCalledNumber" field for "(\d{8})" (updated "(\d{8})") with input of "70001208"
- Regex replacement output of "tfCalledNumber" field is "+61270001208*"
- Doing AD lookup for field 'msRTCSIP-Line' with value '+61270001208*'
- Transformation table(AD Lookup Safety Net:10) is a AD Lookup
- Got AD lookup response with 3 field/value pairs.
- Using AD lookup response in request.
- Using table From Carrier (5) to route call.
- Rule Safety Net (5.2(2)) being tested for selection.
- Performing MANDATORY transformation using entry Test for msRTCSIP-Line match (10.2(2)).
- detect wildcard AD matching, swap AD rule and input string for proper regex
- Successful regex match of "tfCalledNumber" field for "=msRTCSIP-Line=" (updated "\+61270001208.*") with input of "+61270001208;ext=1208"
- Regex replacement output of "tfCalledNumber" field is "+61270001277"    <--- THIS IS MY SAFETY NET VALUE
- Performing OPTIONAL transformation using entry Format calling # (10.3(3)).
- Failed regex match of "tfCallingNumber" field for "(\d{9})" (updated "(\d{9})") with input of "+61400000000"
- Performing OPTIONAL transformation using entry Format calling # (10.4(4)).
- Successful regex match of "tfCallingNumber" field for "(.*)" (updated "(.*)") with input of "+61400000000"
- Regex replacement output of "tfCallingNumber" field is "+61400000000"
- Transformation table(AD Lookup Safety Net:10) is a SUCCESS
- Successful route request with entry Safety Net (5.2(2))

PABX user

If you don’t have a Line URI then it’s off to the PABX with you:

- Using table From Carrier (5) to route call.
- Rule AD Lookup test (5.1(1)) being tested for selection.
- Performing MANDATORY transformation using entry Reformat called number for E.164 (9.1(1)).
- Successful regex match of "tfCalledNumber" field for "(\d{8})" (updated "(\d{8})") with input of "70001238"
- Regex replacement output of "tfUserValue1" field is "+61270001238*"
- Doing AD lookup for field 'msRTCSIP-Line' with value '+61270001238*'
- Transformation table(New AD Lookup test:9) is a AD Lookup
- Got AD lookup response with 1 field/value pairs.
- Using AD lookup response in request.
- Using table From Carrier (5) to route call.
- Rule AD Lookup test (5.1(1)) being tested for selection.
- Performing MANDATORY transformation using entry Test for msRTCSIP-Line match (9.2(2)).
- detect wildcard AD matching, swap AD rule and input string for proper regex
- Failed regex match of "tfUserValue1" field for "=msRTCSIP-Line=" (updated "\+61270001238.*") with input of ""
- Transformation table(New AD Lookup test:9) is a FAILURE
- Rule Safety Net (5.2(2)) being tested for selection.
- Performing MANDATORY transformation using entry Reformat called number for E.164 (10.1(1)).
- Successful regex match of "tfCalledNumber" field for "(\d{8})" (updated "(\d{8})") with input of "70001238"
- Regex replacement output of "tfCalledNumber" field is "+61270001238*"
- Doing AD lookup for field 'msRTCSIP-Line' with value '+61270001238*'
- Using table From Carrier (5) to route call.
- Rule Safety Net (5.2(2)) being tested for selection.
- Performing MANDATORY transformation using entry Test for msRTCSIP-Line match (10.2(2)).
- detect wildcard AD matching, swap AD rule and input string for proper regex
- Failed regex match of "tfCalledNumber" field for "=msRTCSIP-Line=" (updated "\+61270001238.*") with input of ""
- Transformation table(AD Lookup Safety Net:10) is a FAILURE
- Rule Route everything else to the PABX (5.3(3)) being tested for selection.
- Performing MANDATORY transformation using entry  (1.1(1)).
- Successful regex match of "tfCalledNumber" field for "(.*)" (updated "(.*)") with input of "70001238"
- Regex replacement output of "tfCalledNumber" field is "70001238"
- Transformation table(Passthrough Untouched:1) is a SUCCESS
- Successful route request with entry Route everything else to the PABX (5.3(3))

Caveats

The above assumes:

  • You have Active Directory / Configuration / Cache Settings / Normalize Cache set True. This strips “tel:” from the start of the Line URI from AD and means we don’t need to cater for them in the table. If yours is False then the tables above won’t work unless you change the first rule in each of them to turn the called number into (in my example) “tel:+612\1*”.
  • Your users all have a dedicated indial number each. You’re not “piggy-backing” multiple users with a different extension suffix under the same indial, like “tel:=61270001000;ext=1234” & “tel:=61270001000;ext=5678”. If you are, then the first user found by the AD search will receive all the calls to that number. How else is it going to work??

Debugging

Test the AD Cache

Before you venture into attempting phone calls and potentially risk disruption to a working system, test the AD cache first. Head to the Diagnostics tab and “Tools / Query AD Cache”. In this example I needed to enter the “*” at the end of my phone number before it would match, but with that present the cache revealed all the stored details. Here is where I get the payoff from adding the displayName to the cached attributes, as I know for sure I’m matching on the expected user.

Mk-III-ADLookup-QueryADCache

Note in the above that it’s showing my LineURI has a value of “+61270001223;ext=1223”, which I know to be wrong, because in AD (and in SfB) it has a “tel:” prefix. This is a result of setting Active Directory / Configuration / Cache Settings / Normalize Cache to True, and it means you only have to test for the “+” and the digits in the transformation tables.

AD Cache Overflow

If you have a VAST Active Directory and you set the Search Scope too high up you run the risk of filling or overflowing the cache (especially in the 1k). If this happens it will log an alarm to let you know, and you’ll probably start to see some intermittent call failures (or calls being routed incorrectly).

To mitigate this in a 1k, any of the below will help:

  • Cache fewer attributes
  • Query lower down the AD tree
  • Add a USB memory stick
  • As a last resort, set “Normalize Cache” to False and handle the “tel:” in your Transformation Tables

See the reference below for more reading on this one.

AD Cache Update

A common problem I see in the field with AD-based routing is that someone has been enabled for SfB EV, but their calls still route to the PABX. The issue here is that either the cache hasn’t updated or AD hasn’t replicated. To address the former issue you can either manually reset the cache (in the header of the “Configuration” menu option) or reduce the cache “Update Frequency” timer. Obviously the larger your AD the less inclined you will be to this, so perhaps a manual reset is the best approach – or simply set a policy of not enabling new users until late in the day for the next morning.

Case-Sensitivity

The SBC’s AD-lookup is NOT case-sensitive, which is a relief because Skype for Business will accept the alpha characters in a LineURI in any combination of case.

How I Test

As you will have seen in my Call Traces above, I’m using different test accounts, each configured with a different combination of LineURI and EnterpriseVoiceEnabled, rather than just changing one and watching the outcome. If you take the latter approach, you’ll have to wait for the “Lync Lag” with every user change, and also manually refresh the SBC’s AD cache (which you’ll find in the header of the “Configuration” menu option). Throw in delays associated with AD replication and you might start to see the value in this approach.

References

Revision history

28th April 2018: this is the original post

 

– G.

Leave a Reply

Your email address will not be published.

... and please just confirm for me that you're not a bot first: Time limit is exhausted. Please reload the CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.