Asterisk
Asterisk Asterisk
Contents

Asterisk - The Open Source VoIP PBX

Previous Page Next Page
 
Asterisk: The Future of Telephony
Table of Contents
Copyright
Foreword
Preface
Audience
Organization
Software
Conventions Used in This Book
Using Code Examples
Safari® Enabled
How to Contact Us
Acknowledgments
Chapter 1.  A Telephony Revolution
Section 1.1.  VoIP: Bridging the Gap Between Traditional Telephony and Network Telephony
Section 1.2.  Massive Change Requires Flexible Technology
Section 1.3.  Asterisk: The Hacker's PBX
Section 1.4.  Asterisk: The Professional's PBX
Section 1.5.  The Asterisk Community
Section 1.6.  The Business Case
Section 1.7.  This Book
Chapter 2.  Preparing a System for Asterisk
Section 2.1.  Server Hardware Selection
Section 2.2.  Environment
Section 2.3.  Telephony Hardware
Section 2.4.  Types of Phone
Section 2.5.  Linux Considerations
Section 2.6.  Conclusion
Chapter 3.  Installing Asterisk
Section 3.1.  What Packages Do I Need?
Section 3.2.  Obtaining the Source Code
Section 3.3.  Compiling Zaptel
Section 3.4.  Compiling libpri
Section 3.5.  Compiling Asterisk
Section 3.6.  Installing Additional Prompts
Section 3.7.  Updating Your Source Code
Section 3.8.  Common Compiling Issues
Section 3.9.  Loading Zaptel Modules
Section 3.10.  Loading libpri
Section 3.11.  Loading Asterisk
Section 3.12.  Directories Used by Asterisk
Section 3.13.  Conclusion
Chapter 4.  Initial Configuration of Asterisk
Section 4.1.  What Do I Really Need?
Section 4.2.  Working with Interface Configuration Files
Section 4.3.  FXO and FXS Channels
Section 4.4.  Configuring an FXO Channel
Section 4.5.  Configuring an FXS Channel
Section 4.6.  Configuring SIP
Section 4.7.  Configuring Inbound IAX Connections
Section 4.8.  Configuring Outbound IAX Connections
Section 4.9.  Debugging
Section 4.10.  Conclusion
Chapter 5.  Dialplan Basics
Section 5.1.  Dialplan Syntax
Section 5.2.  A Simple Dialplan
Section 5.3.  Adding Logic to the Dialplan
Section 5.4.  Conclusion
Chapter 6.  More Dialplan Concepts
Section 6.1.  Expressions and Variable Manipulation
Section 6.2.  Dialplan Functions
Section 6.3.  Conditional Branching
Section 6.4.  Voicemail
Section 6.5.  Macros
Section 6.6.  Using the Asterisk Database (AstDB)
Section 6.7.  Handy Asterisk Features
Section 6.8.  Conclusion
Chapter 7.  Understanding Telephony
Section 7.1.  Analog Telephony
Section 7.2.  Digital Telephony
Section 7.3.  The Digital Circuit-Switched Telephone Network
Section 7.4.  Packet-Switched Networks
Section 7.5.  Conclusion
Chapter 8.  Protocols for VoIP
Section 8.1.  The Need for VoIP Protocols
Section 8.2.  VoIP Protocols
Section 8.3.  Codecs
Section 8.4.  Quality of Service
Section 8.5.  Echo
Section 8.6.  Asterisk and VoIP
Section 8.7.  Conclusion
Chapter 9.  The Asterisk Gateway Interface (AGI)
Section 9.1.  Fundamentals of AGI Communication
Section 9.2.  Writing AGI Scripts in Perl
Section 9.3.  Creating AGI Scripts in PHP
Section 9.4.  Writing AGI Scripts in Python
Section 9.5.  Debugging in AGI
Section 9.6.  Conclusion
Chapter 10.  Asterisk for the Über-Geek
Section 10.1.  Festival
Section 10.2.  Call Detail Recording
Section 10.3.  Customizing System Prompts
Section 10.4.  Manager
Section 10.5.  Call Files
Section 10.6.  DUNDi
Section 10.7.  Conclusion
Chapter 11.  Asterisk: The Future of Telephony
Section 11.1.  The Problems with Traditional Telephony
Section 11.2.  Paradigm Shift
Section 11.3.  The Promise of Open Source Telephony
Section 11.4.  The Future of Asterisk
Appendix A.  VoIP Channels
Section A.1.  IAX
Section A.2.  SIP
Appendix B.  Application Reference
AbsoluteTimeout( )
AddQueueMember( )
ADSIProg( )
AgentCallbackLogin( )
AgentLogin( )
AgentMonitorOutgoing( )
AGI( )
AlarmReceiver( )
Answer( )
AppendCDRUserField( )
Authenticate( )
Background( )
BackgroundDetect( )
Busy( )
CallingPres( )
ChangeMonitor( )
ChanIsAvail( )
CheckGroup( )
Congestion( )
ControlPlayback( )
Curl( )
Cut( )
DateTime( )
DBdel( )
DBdeltree( )
DBget( )
DBput( )
DeadAGI( )
Dial( )
DigitTimeout( )
Directory( )
DISA( )
DumpChan( )
DUNDiLookup( )
EAGI( )
Echo( )
EndWhile( )
ENUMLookup( )
Eval( )
Exec( )
ExecIf( )
FastAGI( )
Festival( )
Flash( )
ForkCDR( )
GetCPEID( )
GetGroupCount( )
GetGroupMatchCount( )
Goto( )
GotoIf( )
GotoIfTime( )
Hangup( )
HasNewVoicemail( )
HasVoicemail( )
IAX2Provision( )
ImportVar( )
LookupBlacklist( )
LookupCIDName( )
Macro( )
MailboxExists( )
Math( )
MeetMe( )
MeetMeAdmin( )
MeetMeCount( )
Milliwatt( )
Monitor( )
MP3Player( )
MusicOnHold( )
NBScat( )
NoCDR( )
NoOp( )
Park( )
ParkAndAnnounce( )
ParkedCall( )
PauseQueueMember( )
Playback( )
Playtones( )
Prefix( )
PrivacyManager( )
Progress( )
Queue( )
Random( )
Read( )
RealTime
RealTimeUpdate( )
Record( )
RemoveQueueMember( )
ResetCDR( )
ResponseTimeout( )
RetryDial( )
Ringing( )
SayAlpha( )
SayDigits( )
SayNumber( )
SayPhonetic( )
SayUnixTime( )
SendDTMF( )
SendImage( )
SendText( )
SendURL( )
Set( )
SetAccount( )
SetAMAFlags( )
SetCallerID( )
SetCallerPres( )
SetCDRUserField( )
SetCIDName( )
SetCIDNum( )
SetGlobalVar( )
SetGroup( )
SetLanguage( )
SetMusicOnHold( )
SetRDNIS( )
SetVar( )
SIPAddHeader( )
SIPDtmfMode( )
SIPGetHeader( )
SoftHangup( )
StopMonitor( )
StopPlaytones( )
StripLSD( )
StripMSD( )
SubString( )
Suffix( )
System( )
Transfer( )
TrySystem( )
TXTCIDName( )
UnpauseQueueMember( )
UserEvent( )
Verbose( )
VMAuthenticate( )
VoiceMail( )
VoiceMailMain( )
Wait( )
WaitExten( )
WaitForRing( )
WaitForSilence( )
WaitMusicOnHold( )
While( )
Zapateller( )
ZapBarge( )
ZapRAS( )
ZapScan( )
Appendix C.  AGI Reference
ANSWER
CHANNEL STATUS
DATABASE DEL
DATABASE DELTREE
DATABASE GET
DATABASE PUT
EXEC
GET DATA
GET FULL VARIABLE
GET OPTION
GET VARIABLE
HANGUP
NOOP
RECEIVE CHAR
RECORD FILE
SAY ALPHA
SAY DATE
SAY DATETIME
SAY DIGITS
SAY NUMBER
SAY PHONETIC
SAY TIME
SEND IMAGE
SEND TEXT
SET AUTOHANGUP
SET CALLERID
SET CONTEXT
SET EXTENSION
SET MUSIC ON
SET PRIORITY
SET VARIABLE
STREAM FILE
TDD MODE
VERBOSE
WAIT FOR DIGIT
Appendix D.  Configuration Files
Section D.1.  modules.conf
Section D.2.  adsi.conf
Section D.3.  adtranvofr.conf
Section D.4.  agents.conf
Section D.5.  alarmreceiver.conf
Section D.6.  alsa.conf
Section D.7.  asterisk.conf
Section D.8.  cdr.conf
Section D.9.  cdr_manager.conf
Section D.10.  cdr_odbc.conf
Section D.11.  cdr_pgsql.conf
Section D.12.  cdr_tds.conf
Section D.13.  codecs.conf
Section D.14.  dnsmgr.conf
Section D.15.  dundi.conf
Section D.16.  enum.conf
Section D.17.  extconfig.conf
Section D.18.  extensions.conf
Section D.19.  features.conf
Section D.20.  festival.conf
Section D.21.  iax.conf
Section D.22.  iaxprov.conf
Section D.23.  indications.conf
Section D.24.  logger.conf
Section D.25.  manager.conf
Section D.26.  meetme.conf
Section D.27.  mgcp.conf
Section D.28.  modem.conf
Section D.29.  musiconhold.conf
Section D.30.  osp.conf
Section D.31.  oss.conf
Section D.32.  phone.conf
Section D.33.  privacy.conf
Section D.34.  queues.conf
Section D.35.  res_odbc.conf
Section D.36.  rpt.conf
Section D.37.  rtp.conf
Section D.38.  sip.conf
Section D.39.  sip_notify.conf
Section D.40.  skinny.conf
Section D.41.  voicemail.conf
Section D.42.  vpb.conf
Section D.43.  zapata.conf
Section D.44.  zaptel.conf
Appendix E.  Asterisk Command-Line Interface Reference
!
abort halt
Section E.1.  add
Section E.2.  agi
Section E.3.  database
Section E.4.  iax2
Section E.5.  indication
Section E.6.  logger
Section E.7.  meetme
Section E.8.  pri
Section E.9.  remove
Section E.10.  restart
Section E.11.  set
Section E.12.  show
Section E.13.  sip
Section E.14.  stop
Section E.15.  zap
Colophon
About the Authors
Colophon
Index
SYMBOL
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
Previous Page
Next Page

10.6. DUNDi

If there were any concerns that Mark Spencer was in danger of running out of good ideas, Distributed Universal Number Discovery (DUNDi) ought to lay such thoughts to rest. DUNDi is poised to be as revolutionary as Asterisk. The DUNDi web site (http://www.dundi.com) says it best: "DUNDiTM is a peer to peer system for locating Internet gateways to telephony services. Unlike traditional centralized services (such as the remarkably simple and concise ENUM[*] standard), DUNDi is fully distributed with no centralized authority whatsoever."

[*] http://www.faqs.org/rfc/rfc2916.txt.

10.6.1. How Does DUNDi Work?

Think of DUNDi as a large phone book that allows you to ask peers if they know of an alternative VoIP route to an extension number or PSTN telephone number.

For example, assume you are connected to the DUNDi-test network (a free and open network that terminates calls to traditional PSTN numbers). You ask your friend Bob if he knows how to reach 1-800-555-1212, a number for which you have no direct access. Bob replies, "I don't know how to reach that number, but let me ask my peer Sally."

Bob asks Sally if she knows how to reach the requested number, and she responds with, "You can reach that number at IAX2/dundi:very_long_password@hostname/extension." Bob then stores the address in his database and passes on to you the information about how to reach 1-800-555-1212 via VoIP, allowing you an alternative method of reaching the same destination through a different network.

Because Bob has stored the information he found, he'll be able to provide it to any peers who later request the same number from him, so the lookup won't have to go any further. This helps reduce the load on the network and increases response times for numbers that are looked up often. (However, it should be noted that DUNDi creates a rotating key, and thus stored information is valid for a limited period of time.)

DUNDi performs lookups dynamically, either with a switch => statement in your extensions.conf file or with the use of the DUNDiLookup( ) application. DUNDi is available only in Asterisk Version 1.2 or higher.

You can use the DUNDi protocol in a private network as well. Say you're the Asterisk administrator of a very large enterprise installation and you wish to simplify the administration of extension numbers. You could use DUNDi in this situation, allowing multiple Asterisk boxes (presumably located at each of the company's locations and peered with one another) to perform dynamic lookups for the VoIP addresses of extensions on the network.

10.6.2. Configuring Asterisk for Use with DUNDi

There are three files that need to be configured for DUNDi: dundi.conf, extensions.conf, and iax.conf.[*] The dundi.conf file controls the authentication of peers who we allow to perform lookups through our system. This file also manages the list of peers to whom we might submit our own lookup requests. Since it is possible to run several different networks on the same box, it is necessary to define a different section for each peer, and then configure the networks in which that peer is allowed to perform lookups. Additionally, we need to define which peers we wish to use to perform lookups.

[*] The dundi.conf and extensions.conf files must be configured. We have chosen to configure iax.conf for our address advertisement on the network, but DUNDi is protocol-agnosticthus sip.conf, h323.conf, or mgcp.conf could be used instead.

10.6.2.1. The General Peering Agreement

The General Peering Agreement (GPA) is a legally binding license agreement that is designed to prevent abuse of the DUNDi protocol. Before connecting to the DUNDi-test group, you are required to sign a GPA. The GPA is used to protect the members of the group and to create a "trust" between the members. It is a requirement of the DUNDi-test group that your complete and accurate contact information be configured in dundi.conf, so that members of your peer group can contact you. The GPA can be found in the doc/ subdirectory of the Asterisk source.

10.6.2.2. General configuration

The [general] section of dundi.conf contains parameters relating to the overall operation of the DUNDi client and server:

    ; DUNDi configuration file
    ;
    [general]
    ;
    department=IT
    organization= toronto.example.com
    locality=Toronto
    stateprov=ON
    country=CA
    email=support@toronto.example.com
    phone=+19055551212
    ;
    ; Specify bind address and port number.  Default is 4520
    ;bindaddr=0.0.0.0
    port=4520
    entityid=FF:FF:FF:FF:FF:FF
    ttl=32
    autokill=yes
    ;secretpath=dundi

The entity identifier defined by entityid should generally be the Media Access Control (MAC) address of an interface in the machine. The entity ID defaults to the first Ethernet address of the server, but you can override this with entityid, as long as it is set to the MAC address of something you own. The MAC address of the primary external interface is recommended. This is the address that other peers will use to identify you.

The Time To Live (ttl) field defines how many peers away we wish to receive replies from and is used to break loops. Each time a request is passed on down the line because the requested number is not known, the value in the TTL field is decreased by one, much like the TTL field of an ICMP packet. The TTL field also defines the maximum number of seconds we are willing to wait for a reply.

When you request a number lookup, an initial query (called a DPDISCOVER) is sent to your peers requesting that number. If you do not receive an acknowledgment (ACK) of your query (DPDISCOVER) within 2,000 ms (enough time for a single transmission only), and autokill is equal to yes, Asterisk will send a CANCEL to the peers. (Note that an acknowledgment is not necessarily a reply to the query; it is just an acknowledgment that the peer has received the request.) The purpose of autokill is to keep the lookup from stalling due to hosts with high latency. In addition to the yes and no options, you may also specify the number of milliseconds to wait.

The pbx_dundi module creates a rotating key and stores it in the local Asterisk database (AstDB). The key name secret is stored in the dundi family. The value of the key can be viewed with the database show command at the Asterisk console. The database family can be overridden with the secretpath option.

10.6.2.3. Creating mapping contexts

The dundi.conf file defines DUNDi contexts that are mapped to dialplan contexts in your extensions.conf file. DUNDi contexts are a way of defining distinct and separate directory service groups. The contexts in the mapping section point to contexts in the extensions.conf file, which control the numbers that you advertise. When you create a peer, you need to define which mapping contexts you will allow this peer to search. You do this with the permit statement (each peer may contain multiple permit statements). Mapping contexts are related to dialplan contexts in the sense that they are a security boundary for your peers.

Phone numbers must be advertised in the following format:

     <country_code><area_code><prefix><number>

For example, a complete North American number could be advertised as 14165551212.

All DUNDi mapping contexts take the form of:

    dundi_context => local_context,weight,technology,destination[,options]]

The following configuration creates a DUNDi mapping context that we will use to advertise our local phone numbers to the DUNDi-test group. Note that this should all appear on one line:

    dundi-test => dundi-local,0,IAX2,dundi:${SECRET}@toronto.example.com/
    ${NUMBER}, nounsolicited,nocomunsolicit,nopartial

In this example, the mapping context is dundi-test, which points to the dundi-local context within extensions.conf (providing a listing of phone numbers to reply to). Numbers that resolve to the PBX should be advertised with a weight of zero (directly connected). Numbers higher than 0 indicate an increased number of hops or paths to reach the final destination. This is useful when multiple replies for the same lookup are received at the end that initially requested the numbera weight with a lower number will be the preferred path.

If we can reply to a lookup, our response will contain the method by which the other end can connect to the system. This includes the technology to use (such as IAX2, SIP, H323, and so on), the username and password with which to authenticate, which host to send the authentication to, and finally the extension number.

Asterisk provides some shortcuts to allow us to create a "template" with which we can build our responses. The following channel variables can be used to construct the template:



${SECRET}

Replaced with the password stored in the local AstDB



${NUMBER}

The number being requested



${IPADDR}

The IP address to connect to

It is generally safest to statically configure the hostname, rather than making use of the ${IPADDR} variable. The ${IPADDR} variable will sometimes reply with an address in the private IP space, which is unreachable from the Internet.


10.6.2.4. Defining DUNDi peers

DUNDi peers are defined in the dundi.conf file. Peers are identified by the unique layer-two MAC address of an interface on the remote system. The dundi.conf file is where we define what context to search for peers requesting a lookup and which peers we want to use when doing a lookup for a particular network.

    [00:00:00:00:00:00] ; Remote Office
    model = symmetric
    host = montreal.example.com
    inkey = montreal
    outkey = toronto
    include = dundi-test
    permit = dundi-test
    qualify = yes
    dynamic=yes

The remote peer's identifier (MAC address) is enclosed in square brackets ([]). The inkey and outkey are the public/private key pairs that we use for authentication. Key pairs are generated with the astgenkey script, located in the ./asterisk/contrib/scripts/ source directory. Be sure to use the -n flag so that you don't have to initialize passwords every time you start Asterisk:

    # cd /var/lib/asterisk/keys
    # /usr/src/asterisk/contrib/scripts/astgenkey -n toronto

The resulting keys, toronto.pub and toronto.key, will be placed in your /var/lib/asterisk/keys/ directory. The toronto.pub file is the public key, which you should post to a web server so that it is easily accessible for anyone with whom you wish to peer. When you peer, you can give your peers the HTTP-accessible public key, which they can then place in their /var/lib/asterisk/keys/ directories.

After you have downloaded the keys, you must reload the res_crypto.so and pbx_dundi.so modules in Asterisk:

    *CLI> reload res_crypto.so
        -- Reloading module 'res_crypto.so' (Cryptographic Digital Signatures)
        -- Loaded PRIVATE key 'toronto'
        -- Loaded PUBLIC key 'toronto'

    *CLI> reload pbx_dundi.so
        -- Reloading module 'pbx_dundi.so' (Distributed Universal Number 
           Discovery
    (DUNDi)) 
 
      == Parsing '/etc/asterisk/dundi.conf': Found

Then, create the dundi user in the iax.conf file to allow connections into your Asterisk system. When a call is authenticated, the extension number being requested is passed to the dundi-local context in the extensions.conf file, where the call is then handled by Asterisk.

10.6.2.5. Allowing remote connections

Here is the user definition for the dundi user:

    [dundi]
    type=user
    dbsecret=dundi/secret
    context=dundi-local
    disallow=all
    allow=ulaw
    allow=g726

Instead of using a static password, Asterisk regenerates passwords every 3,600 seconds (1 hour). The value is stored in /dundi/secret of the Asterisk database and advertised using the ${SECRET} variable defined within the mapping context lines in dundi.conf. You can see the current keys for all peers, including your local public and private keys, by performing a show keys at the Asterisk CLI.

The context entry dundi-local is where authorized callers are sent in extensions.conf. From there, we can manipulate the call just as we would in the dialplan of any other incoming connection.

10.6.2.6. Configuring the dialplan

The extensions.conf file handles what numbers you advertise and what you do with the calls that connect to them. The dundi-local context performs double duty:

  • It controls the numbers we advertise, referenced by the dundi mapping context in dundi.conf.

  • It controls what to do with the call, referenced by the dundi user in iax.conf.

You have the power of dialplan pattern matching to advertise ranges of numbers and to control the incoming calls. In the following dialplan, we are only advertising the number +1-416-555-1212, but pattern matching could just as easily have been employed to advertise a range of numbers or extensions:

    [dundi-local]
    exten => 14165551212,1,NoOp(dundi-local: Number advertisement and incoming)
    exten => 14165551212,n,Answer( )
    exten => 14165551212,n(call),Dial(SIP/1000)
    exten => 14165551212,n,Voicemail(u1000)
    exten => 14165551212,n,Hangup( )
    exten => 14165551212,n(call)+101,Voicemail(b1000)
    exten => 14165551212,n,Hangup( )


Previous Page
Next Page
Asterisk