Good afternoon gentlemen (and ladies). A costumer of mine has many servers and each one maps their SIP extensions to the others via DUNDi. It works like a charm. SIP extensions can only register at one server, the one they "belong" to. In case one extension wants to call other that is registered in another server, DUNDi takes care of that by calling the other server using IAX2 and G.729 codec. It's important to clarify that each server today works as a completely independent PBX, talking to each other using IAX2 that is routed via a MPLS network. Also, the servers are very distant from each other physically. Today the extensions are being mapped in DUNDi like this: [dundi-internal] exten => _70XX,1,Noop() And all extensions configurations are done in sip.conf. No realtime is being used, yet. Now the customer wants to take a step further and make it possible that *every* SIP extension could be able to register in *every* server. That would make possible for them to use DNS to automatically "find" the closest PBX and make the extension register on that one. So far I considered the following for this project: - Moving all SIP extensions from individual sip.confs to one MySQL database, and point all servers to that one - Configure sip.conf on each machine like this: regcontext=dundi-internal rtcachefriends=yes rtsavesysname=yes rtupdate=no rtautoclear=yes ignoreregexpire=no That way each time an extension registers, Asterisk would add an extension to the dundi-internal context, which as you guessed, is the one being mapped to the other servers. So instead of mapping extensions using wildcards, the extensions will be mapped individually. extensions.conf would be something like this: [internal] ;Tries to make the call using SIP, in the case ;the extension is registered in this server ;If it's not, switches to DUNDi exten => _XXXX,1,Dial(SIP/${EXTEN},60) exten => _XXXX,n,NoOp(DIALSTATUS = ${DIALSTATUS}) exten => _XXXX,n,NoOp(FROM_DUNDI = ${FROM_DUNDI}) exten => _XXXX,n,GotoIf($["${FROM_DUNDI}" = "1"]?end:start) exten => _XXXX,n(start),Answer() exten => _XXXX,n,Playback(vm-dialout) exten => _XXXX,n,Goto(dundi-internal-helper,${EXTEN},1) exten => _XXXX,n(end),Noop(Loop detected. Hanging up.) exten => _XXXX,n,Hangup() [dundi-internal-helper] switch => DUNDi/dundi_internal [from-dundi] exten => _XXXX,1,Set(FROM_DUNDI=1) exten => _XXXX,n,Dial(SIP/${EXTEN},60) So far it's working fine in a test lab with 2 servers running Asterisk 1.6.0.15. For the gurus out there: is there something that I'm doing terribly wrong, that would break everything and make the universe collapse into itself when I apply the same principle on production? I'll be happy to provide more details in case there are any doubts. I really appreciate your feedback, no matter what is it. :) Vin?cius Fontes www.asteriskforum.com.br - Informa??es e discuss?o sobre Asterisk e telefonia IP
> Good afternoon gentlemen (and ladies). > > A costumer of mine has many servers and each one maps their SIP extensions > to the others via DUNDi. It works like a charm. SIP extensions can only > register at one server, the one they "belong" to. In case one extension > wants to call other that is registered in another server, DUNDi takes care > of that by calling the other server using IAX2 and G.729 codec. It's > important to clarify that each server today works as a completely > independent PBX, talking to each other using IAX2 that is routed via a > MPLS network. Also, the servers are very distant from each other > physically. > > Today the extensions are being mapped in DUNDi like this: > > [dundi-internal] > exten => _70XX,1,Noop() > > And all extensions configurations are done in sip.conf. No realtime is > being used, yet. > > > > > Now the customer wants to take a step further and make it possible that > *every* SIP extension could be able to register in *every* server. That > would make possible for them to use DNS to automatically "find" the > closest PBX and make the extension register on that one. > > So far I considered the following for this project: > > - Moving all SIP extensions from individual sip.confs to one MySQL > database, and point all servers to that one > - Configure sip.conf on each machine like this: > > regcontext=dundi-internal > rtcachefriends=yes > rtsavesysname=yes > rtupdate=no > rtautoclear=yes > ignoreregexpire=no > > That way each time an extension registers, Asterisk would add an extension > to the dundi-internal context, which as you guessed, is the one being > mapped to the other servers. So instead of mapping extensions using > wildcards, the extensions will be mapped individually. > > extensions.conf would be something like this: > > [internal] > ;Tries to make the call using SIP, in the case > ;the extension is registered in this server > ;If it's not, switches to DUNDi > exten => _XXXX,1,Dial(SIP/${EXTEN},60) > exten => _XXXX,n,NoOp(DIALSTATUS = ${DIALSTATUS}) > exten => _XXXX,n,NoOp(FROM_DUNDI = ${FROM_DUNDI}) > exten => _XXXX,n,GotoIf($["${FROM_DUNDI}" = "1"]?end:start) > exten => _XXXX,n(start),Answer() > exten => _XXXX,n,Playback(vm-dialout) > exten => _XXXX,n,Goto(dundi-internal-helper,${EXTEN},1) > exten => _XXXX,n(end),Noop(Loop detected. Hanging up.) > exten => _XXXX,n,Hangup() > > [dundi-internal-helper] > switch => DUNDi/dundi_internal > > [from-dundi] > exten => _XXXX,1,Set(FROM_DUNDI=1) > exten => _XXXX,n,Dial(SIP/${EXTEN},60) > > > So far it's working fine in a test lab with 2 servers running Asterisk > 1.6.0.15. > > For the gurus out there: is there something that I'm doing terribly wrong, > that would break everything and make the universe collapse into itself > when I apply the same principle on production? > > I'll be happy to provide more details in case there are any doubts. I > really appreciate your feedback, no matter what is it. :) > > > > Vin?cius Fontes > www.asteriskforum.com.br - Informa??es e discuss?o sobre Asterisk e > telefonia IP >[JR Richardson] I used to do this exact thing a few years ago, wrote a couple of papers about it. Realtime + DINDi works great for this, I would add in MySQL replication to the mix so each server writes the SIP cache info to a Master database that is replicated out to all the servers. Each server will have a copy of the same database and be able to contact the phones if DUNDi queries become unavailable. The tricky problem you may run into, if you haven't figured it out yet, is what to do about voicemail and where the storage will be, distributed voicemail will be problematic in a dynamic sip ua registration environment across multiple servers. Centralize voicemail using DUNDi can help this out as well. I'll send you some papers off line Hope this helps. JR ---- Engineering for the Masses
----- "JR Richardson" <jmr.richardson at gmail.com> escreveu:> > Good afternoon gentlemen (and ladies). > > > > A costumer of mine has many servers and each one maps their SIP > extensions > > to the others via DUNDi. It works like a charm. SIP extensions can > only > > register at one server, the one they "belong" to. In case one > extension > > wants to call other that is registered in another server, DUNDi > takes care > > of that by calling the other server using IAX2 and G.729 codec. > It's > > important to clarify that each server today works as a completely > > independent PBX, talking to each other using IAX2 that is routed via > a > > MPLS network. Also, the servers are very distant from each other > > physically. > > > > Today the extensions are being mapped in DUNDi like this: > > > > [dundi-internal] > > exten => _70XX,1,Noop() > > > > And all extensions configurations are done in sip.conf. No realtime > is > > being used, yet. > > > > > > > > > > Now the customer wants to take a step further and make it possible > that > > *every* SIP extension could be able to register in *every* server. > That > > would make possible for them to use DNS to automatically "find" the > > closest PBX and make the extension register on that one. > > > > So far I considered the following for this project: > > > > - Moving all SIP extensions from individual sip.confs to one MySQL > > database, and point all servers to that one > > - Configure sip.conf on each machine like this: > > > > regcontext=dundi-internal > > rtcachefriends=yes > > rtsavesysname=yes > > rtupdate=no > > rtautoclear=yes > > ignoreregexpire=no > > > > That way each time an extension registers, Asterisk would add an > extension > > to the dundi-internal context, which as you guessed, is the one > being > > mapped to the other servers. So instead of mapping extensions using > > wildcards, the extensions will be mapped individually. > > > > extensions.conf would be something like this: > > > > [internal] > > ;Tries to make the call using SIP, in the case > > ;the extension is registered in this server > > ;If it's not, switches to DUNDi > > exten => _XXXX,1,Dial(SIP/${EXTEN},60) > > exten => _XXXX,n,NoOp(DIALSTATUS = ${DIALSTATUS}) > > exten => _XXXX,n,NoOp(FROM_DUNDI = ${FROM_DUNDI}) > > exten => _XXXX,n,GotoIf($["${FROM_DUNDI}" = "1"]?end:start) > > exten => _XXXX,n(start),Answer() > > exten => _XXXX,n,Playback(vm-dialout) > > exten => _XXXX,n,Goto(dundi-internal-helper,${EXTEN},1) > > exten => _XXXX,n(end),Noop(Loop detected. Hanging up.) > > exten => _XXXX,n,Hangup() > > > > [dundi-internal-helper] > > switch => DUNDi/dundi_internal > > > > [from-dundi] > > exten => _XXXX,1,Set(FROM_DUNDI=1) > > exten => _XXXX,n,Dial(SIP/${EXTEN},60) > > > > > > So far it's working fine in a test lab with 2 servers running > Asterisk > > 1.6.0.15. > > > > For the gurus out there: is there something that I'm doing terribly > wrong, > > that would break everything and make the universe collapse into > itself > > when I apply the same principle on production? > > > > I'll be happy to provide more details in case there are any doubts. > I > > really appreciate your feedback, no matter what is it. :) > > > > > > > > Vin?cius Fontes > > www.asteriskforum.com.br - Informa??es e discuss?o sobre Asterisk e > > telefonia IP > > > [JR Richardson] > I used to do this exact thing a few years ago, wrote a couple of > papers > about it. Realtime + DINDi works great for this, I would add in > MySQL > replication to the mix so each server writes the SIP cache info to a > Master > database that is replicated out to all the servers. Each server will > have a > copy of the same database and be able to contact the phones if DUNDi > queries > become unavailable. > > The tricky problem you may run into, if you haven't figured it out > yet, is > what to do about voicemail and where the storage will be, distributed > voicemail will be problematic in a dynamic sip ua registration > environment > across multiple servers. Centralize voicemail using DUNDi can help > this out > as well. > > I'll send you some papers off line > > Hope this helps. > > JR > ---- > Engineering for the Masses > > > _______________________________________________ > -- Bandwidth and Colocation Provided by http://www.api-digital.com -- > > AstriCon 2009 - October 13 - 15 Phoenix, Arizona > Register Now: http://www.astricon.net > > asterisk-users mailing list > To UNSUBSCRIBE or update options visit: > http://lists.digium.com/mailman/listinfo/asterisk-usersThank you so much for your answers. I really wasn't aware of the problem with voicemail, but storing it on IMAP or even MySQL will certainly help. Your case is really close to my own, with a few differences. The main objective in my case is not redundancy, but saving bandwidth. That because if a user of pbxA is physically in the same network of pbxB, it will register directly to pbxA. And as the dialplan uses the options tT on Dial(), if this user calls an extension registered at pbxB, the audio needs to go to pbxA and come back to pbxB. To make things worst, in this case the codec used is alaw. So my idea is to force all inter-server communication to be done via DUNDi and IAX, because all IAX users/peers have trunk=yes, and use g729. In no circunstances a call should be routed directly to a different server without passing by DUNDi first. As you could see on the dialplan I attached, I first tried dialing the extension and in case of ${DIALSTATUS}=CHANUNAVAIL direct it to DUNDi, but your approach using ChanIsAvail() is much more elegant. You mentioned there is a caveat because of the registration time of the phones, that ChanIsAvail() would report a phone as available even if it's not anymore. Do you recommend lowering the registration time to one minute in order to minimize this problem? Other thing that concerns me is the CDR. I'm thinking of centralizing CDR as well, storing it in a MySQL database and setting up the accountcode on the SIP extensions to make it easy to retrieve all extensions on the same PBX for example. If you see any other problem with my toughts on this, any feedback would be much appreciated. Vin?cius Fontes www.asteriskforum.com.br - Informa??es e discuss?o sobre Asterisk e telefonia IP
JR - couldn't find your whitepaper from astricon06 online, links are broken would it be possible for you to email it to me? I have not tried setting up DUNDi yet, but from the sound of it, seems like it would be pretty handy. I have sip phones registering to two asterisk servers [primary and backup] and have a macro setup where incoming call checks if sip phone is available via ${SIPPEER}(${EXTEN}:status and if it is not on the primary server, then sends the call to the backup server in a separate context which attempts to dial the sip phone once, and if the phone is offline / unavailable there as well, then to send it to voicemail or followme as the case may be. However, DUNDi sounds better in terms of scalability as I'm fast outgrowing two servers. :) Thanks, Neeraj