mod_enum
About
ENUM (Electronic Number Mapping System) is a system that uses standard phone numbers as a key to lookup addressing and identification information that can potentially let Freeswitch servers communicate directly, thus bypassing the PSTN, reducing cost, and improving audio quality. It is based on the E.164 standard and uses standard DNS systems to translate telephone numbers into a special DNS record type called a NAPTR record (NamingAuthority PoinTer Resource Record) that might contain information for 1-(800)-555-1234 such as:
$ORIGIN 4.3.2.1.5.5.5.0.0.8.1.e164.arpa. IN NAPTR 100 10 "U" "E2U+sip" "!^.$!sip:customer-service@example.com!" . IN NAPTR 102 10 "U" "E2U+email" "!^.$!<mailto:information@example.com>!" .
Click here to expand Table of Contents
- 1 Configuration
- 1.1 Options
- 2 Dialplan interface
- 3 Dialplan apps
- 3.1 enum
- 4 API
- 5 ENUM providers
Configuration
The main file for configuring ENUM functionality (assuming you've done "make samples" and are working with the provided sample configuration files) is: conf/autoload_configs/enum.conf.xml
The contents of this file are as of such:
<configuration name="enum.conf" description="ENUM Module"> <settings> <param name="default-root" value="e164.org"/> <param name="default-isn-root" value="freenum.org"/> <param name="query-timeout" value="10"/> <param name="auto-reload" value="true"/> </settings> <routes> <route service="E2U+SIP" regex="sip:(.)" replace="sofia/$${sip_profile}/$1"/> <route service="E2U+IAX2" regex="iax2:(.)" replace="iax/$1"/> <route service="E2U+XMPP" regex="XMPP:(.*)" replace="dingaling/$${xmpp_server_profile}/$1"/> </routes> </configuration>
Note the above configuration uses global variables $${sip_profile} and $${xmpp_server_profile}}, these must be set in vars.conf.xml. Or use static values. The above is only an example.
Options
Name | Description | Example |
---|---|---|
auto-reload | Whether to reload the XML configuration when reloadxml is run | true |
default-root | Default root to use when not specified. | e164.org |
default-isn-root | Default root to use when not specified. | freenum.org |
query-timeout | How long before ENUM DNS query times out (seconds) | 10 |
ToDo: The difference between default-isn-root and default-root needs to be documented.
Dialplan interface
The enum module provides a dialplan interface which allows you only to dial a number and an ENUM lookup will be done. If results are found, the ones supported will be called in order of priority and weight of the DNS records. The results are mapped to dialstrings using the routes options from the configuration file.
The ENUM dialplan can be set from one of the Endpoints configuration XML as follows:
<param name="dialplan" value="enum"/>
It is also possible to transfer to the enum dialplan from another dialplan such as the XML one.
Dialplan apps
enum
The ENUM application can be called from the dialplan by executing it from within your condition as follows:
<action application="enum" data="$1 e164.org"/>
You can specify a custom root domain as the second parameter, above it is "e164.org" the parameter $1 contains what has been dialed.
The lookup generates dialstrings for bridge using the routes set in the configuration file, for example:
enum_route_1: sofia/internal/18005551212@tf.voipmich.com enum_route_2: sofia/internal/16416418005551212@sip.tollfreegateway.com enum_route_3: sofia/internal/18005551212@tollfree.sip-happens.com enum_route_count: 3 enum_auto_route: sofia/internal/18005551212@tf.voipmich.com,sofia/internal/16416418005551212@sip.tollfreegateway.com,sofia/internal/18005551212@tollfree.sip-happens.com
The last variable enum_auto_route is convenient to pass directly to bridge. If the enum lookup fails it will be empty, one way to handle this would be to set continue_on_fail=true and fallback to another bridge, for example:
<extension name="Outbound to US PSTN 11 Digits"> <condition field="destination_number" expression="^(1[2-9][0-9][0-9][2-9][0-9][0-9][0-9][0-9][0-9][0-9])$"> <action application="set" data="continue_on_fail=true"/> <action application="enum" data="$1 e164.org"/> <action application="bridge" data="${enum_auto_route}"/> <action application="bridge" data="sofia/gateway/myVoIPGateWay/$1|sofia/gateway/myVoIPGateWay-backup/$1|sofia/gateway/LastVoIPGateWayAttempt/$1"/> </condition> </extension>
API
enum
enum < reload | number [root] >
From the CLI issue something similar to the following to see a readable output of the ENUM lookup results:
enum 18002255288 enum 18002255288 e164.org
Example output:
Offered Routes:
Order Pref Service Route
100 10 E2U+SIP sofia/internal/16416418002255288@sip.tollfreegateway.com;transport=udp 100 10 E2U+SIP sofia/internal/16416418002255288@tollfree.sip-happens.com;transport=udp
Supported Routes:
Order Pref Service Route
100 10 E2U+SIP sofia/internal/16416418002255288@sip.tollfreegateway.com;transport=udp 100 10 E2U+SIP sofia/internal/16416418002255288@tollfree.sip-happens.com;transport=udp
It can also be used to reload the XML configuration:
enum reload
enum_auto
This API can be used to generate a dialstring compatible with bridge:
enum_auto 18002255288
gives
sofia/internal/16416418002255288@sip.tollfreegateway.com;transport=udp,sofia/internal/16416418002255288@tollfree.sip-happens.com;transport=udp
ENUM providers
Public E164
There are several popular ENUM providers for E164 numbers, including:
e164.org e164.arpa
Hence, one could try:
<action application="set" data="continue_on_fail=true"/> <action application="enum" data="$1 e164.org"/> <action application="bridge" data="${enum_auto_route}"/> <action application="enum" data="$1 e164.arpa"/> <action application="bridge" data="${enum_auto_route}"/>
And there are numerous others spanned across the globe, but please research them fully before using them lest calls be "hijacked" to somewhere else. You could in fact institute your own dialplan within your own DNS domain by using ENUM lookups for particular extensions, however it has been reported that it might be possible to have your DOMAIN hijacked and in the process your telephone traffic may also be exploited. So do your own research into the security of such a deployment.
Registering your number with e164.org
E164.org is a free service (supported by donations) that verifies your number by placing a phone call and reading a 6-digit PIN. However, the digits are read only once, rather fast, and it can't dial through an IVR, which makes it difficult to register a number on an operational system. One way to work with this problem is to place in your public dialplan an extension that routes a call from e164.org directly to your extension, using their caller-ID number (+12243336164) as a condition:
<condition field="caller_id_number" expression="^+?(12243336164)$"> <action application="transfer" data="1023 XML default"/> </condition>
After entering your number at e164.org, wait a few minutes at that extension, pick it up immediately, and get ready to write down the 6-digit PIN.
Incidentally, although this PIN method ensures that only the owner of a phone number can register it, it is not clear how or if they can detect numbers that have been "changed" or "disconnected", etc... Hence, they rely on the individual that "owns" the record to delete the record for their old number. Hence, over time it is possible that if enough people "forget" to delete their old numbers that a call could get improperly routed to the wrong (old) destination and not arrive to the person/organization that presently owns that PSTN number.
In short, use at your own risk.
Custom ENUM Server
You can use enum to store your internal phone number to user/phone mapping (often called carrier-enum), this python code use the twisted matrix DNS library ( apt-get install python-twisted-names ) to create a custom enum DNS server to that end.
Use different sofia profiles when using Enum
Should you want to use different profiles for with your enum entries, it is possible thanks to RFC 3761 section 2.4.2
In your enum.conf configuration, setup multiple services giving them names after the comma and then use those name as the NAPTR service name in DNS.
<routes> <route service="E2U+SIP:MEDIA" regex="sip:(.)" replace="sofia/media/$1"/> <route service="E2U+SIP:TRUNK" regex="sip:(.)" replace="sofia/pstn/$1"/> </route>
$ cat ienum #!/bin/sh
should stip here + or 00 from $1
echo host -t naptr $(echo $1 | rev | sed -e 's/[0-9]/&./g')my-enum-domain.com host -t naptr $(echo $1 | rev | sed -e 's/[0-9]/&./g')my-enum-domain.com
replace my-enum-domain.com with your enum root.
Example output :
$ ienum 123456789 host -t naptr 9.8.7.6.5.4.3.2.1.enum.domain.com 9.8.7.6.5.4.3.2.1.enum.domain.com has NAPTR record 10 100 "U" "E2U+sip:MEDIA" "!^.*$!sip:unallocated-123456789@127.0.0.1!" .