FreeSWITCH          




Page tree
Skip to end of metadata
Go to start of metadata

About

Set a limit on number of calls to/from a resource.Limit is designed to provide limit management on resources. This is useful if you want to limit the number of calls to or from an arbitrary resource.

When the limit is reached, the call is automatically transferred to "limit_exceeded" in the same context or the specified context.

Note that a limit is active within a given context - if you transfer an inbound call from the public dialplan to an extension in the default dialplan - any limit you just set in the public dialplan will be reset.

NB: if the limit is on the destination number, and then the call is transferred to another extension even in same context, limit will be decreased

Also note that a limit is not decreased if you transfer the call using the "REFER" method, eg using the TRANSFER button on the phone.

 Click to expand Table of Contents

Dialplan Apps

The limit dialplan apps are implemented by mod_dptools.

limit

limit <backend> <realm> <resource> <max[/interval]> [<transfer_destination_number> [<dialplan> [<context>]]

backend

The backend to use.

realm

Arbitrary name

resource

The resource on which to limit the number of calls.

max

The maximum number of concurrent calls allowed to pass or a call rate in calls/sec. If not set or set to a negative value the limit application only acts as a counter.

Note: limit is not decreased if you transfer the call using the "REFER" method, eg using the TRANSFER button on the phone.
NB: if the limit is on the destination number, and then the call is transferred to another extension even in same context, limit will be decreased

The interval argument is ONLY supported by the hash and hiredis backend.

transfer_destination_number

Transfer to this extension in the dialplan. It's optional. If you don't give it, limit transfers to 'limit_exceeded' extension in the current dialplan and context.

limit_execute

Execute requested APP only if resource has not reached its limit

Note: limit is not decreased if you transfer the call using the "REFER" method, eg using the TRANSFER button on the phone.
NB: if the limit is on the destination number, and then the call is transferred to another extension even in same context, limit will be decreased

limit_execute <backend> <realm> <resource> <max[/interval]> <application> [application arguments]

backend

The backend to use.

realm

Arbitrary name

resource

The resource on which to limit application execution

max

The maximum number of concurrent executions or an interval in executions/sec. If set to a negative value then there is no limit; the limit system simply acts as a counter. Setting the value to zero will set a limit of zero, meaning no concurrent executions.

Note: limit is not decreased if you transfer the call using the "REFER" method, eg using the TRANSFER button on the phone.
NB: if the limit is on the destination number, and then the call is transferred to another extension even in same context, limit will be decreased

application

The application to execute

application arguments

The optional application arguments

 

API

The limit APIs are implemented by mod_commands. You can also use them via the dialplan like so:

limit_reset

Resets a given limit backend.

  • DB: deletes ALL entries for that hostname.
  • Hiredis: not implemented. 

    • to reset the resource, use the command: 

    • hiredis_raw set <resource_name> 0
  • Hash: not implemented.
API: limit_reset <backend>

limit_status

Retrieve current status of a given backend. Only supported in DB, not hash or hiredis.

API: limit_status <backend>

limit_usage

Retrieve current usage for a given resource, all backends.

Note: limit is not decreased if you transfer the call using the "REFER" method, eg using the TRANSFER button on the phone.
NB: if the limit is on the destination number, and then the call is transferred to another extension even in same context, limit will be decreased

limit_usage <backend> <realm> <id>

uuid_limit_release

Manually decrease the usage by one by removing the "usage" entry for that UUID.

If realm/resource is specified, it removes only that limit. Otherwise, it removes all limits held by the given UUID.

API: uuid_limit_release <uuid> <backend> [realm] [resource]

limit_interval_reset

Manually reset the interval counter to zero prior to the next interval starting: Only implemented in Hash, not DB or hiredis.

API: limit_interval_reset <backend> <realm> <resource>

hash_remote

You can access data from other FreeSWITCH systems with the hash_remote API. The hash_remote API uses the event socket. Configure your server names and credentials in conf/autoload_configs/hash.conf.xml.

It seems it queries each remote hash endpoint every 5 seconds for the entire hash list. It hen adds that to normal hash usage on the current server.

hash_remote <list>|<kill> [name]|<rescan>

Channel Variables

Variables Set by Limit

The following channel variables are set when limit is called.

  • "limit_realm"
  • "limit_id"
  • "limit_max"

These channel variables are used at hang up to remove the record. More specifically, the delete is limited by uuid, hostname, realm and id.

Variables That Affect Limit

limit_ignore_transfer=true - causes the current call count to not be reset when the call is transferred. This is useful where calls that come into a gateway are transferred to an extension, but you want to preserve the call count.

limit_ignore_transfer=false - calls that are transferred cause the call count for that realm_id to decrement

Note: limit is not decreased if you transfer the call using the "REFER" method, eg using the TRANSFER button on the phone.

NB: if the limit is on the destination number, and then the call is transferred to another extension even in same context, limit will be decreased

Backends

db

You may choose to take advantage of the db backend mod_db to allow multiple servers to limit the number of calls and stay aware of how many calls <resource> has in session across all participating servers.

hash

mod_hash provides a hashtable backend for limit. It uses a hashtable as data structure (faster) and has some additional features. Here is the syntax for the main application:

<action application="limit" data="hash <realm> <id> [<max>[/<interval>] [number [dialplan [context]]]" />

Note that you can also do rate-limiting with this application by specifying an interval, 5/1 will limit the resource to 5 calls per second. The application will transfer the call to the specified number/dialplan/context if the resource is currently over-limit. You can also use tell limit_hash to automatically hangup the call when its over-limit, use a ! before the number to indicate that it is a hangup cause.

<action application="limit" data="hash inbound 15142223333 2 !USER_BUSY" />

If the maximum isn't specified, limit will count the number of active calls but won't limit anything.

hiredis

mod_hiredis provides a redis backend for limit.

Which Backend Do I Use?

BackendSpeedPersistenceCluster-abilityInterval Support
Hashfastestnosee hash_remoteyes
DBslowyespossibleno
Hiredisfastyes, configurableyesyes

Examples

Limit Access To an Application

It is sometimes required to limit access to a single application, such as when trying outbound carriers, the following will do so:

Example: this will try 2 carriers, not sending more than 5 calls per carrier.

Limit a User's Concurrent Calls

The following is a simple example of limiting a user in your domain to 1 call. Here, max_calls is set to 1 in the dialplan, but you could use a global variable (vars.xml) or a user variable (directory.conf).

Note that limit_exceeded comes before the limit extension as limit() uses transfer(), which will search from the beginning of the dialplan. You must do this or add regex to check the destination to avoid a transfer loop.

 

Rate Limiting Calls, Anti-SPIT

Limit the calls per second by source ip + destination number:

Limit calls to 5 calls every 10 minutes:

User Busy

This checks the current usage a limit counter before dialing a user, conditionally returning user_busy or putting the call through under a specific condition over the value of this counter. This can be useful if you wish to check against a counter managed by an external application or incremented by other events.

Note: The above action will not increment the limit counter.

Note: In recent versions, in order for this function to return a non-zero value you must call the limit application before. It should set some limit for this resource (even -1 which is unlimited) in order to enable counting.

Using Limit With Per-Gateway or Per-User Channel Limits

If you wish to set a limit bound to the b-leg part of a call (ex: outgoing counter), it is only possible using loopback channels. The following will do so:

And inside the corresponding context:

The result of this example is that if the first gateway has too many channels open, then it cleans up the limit data for the first gateway before trying the next gateway.

If this was done within an extension as a series of limit and bridge apps, then the limit data wouldn't be cleaned up until the a-leg returned to the CS_ROUTING state. That would mean calls would continue holding a channel open on a gateway they had tried while they were still connected to another gateway.

Using Limit With an Outbound Gateway

Example below, things to note:

  • auto_hunt=true so that you can jump directly to extensions without going through the entire dialplan
  • Replace PROVIDER1..3 with the relevant gateways
  • Replace PROVIDER1..3_CHANNEL_LIMIT with the relevant channel limit
  • transfer is done after the bridge so that failover works between the providers, ie, PROVIDER1 may be down
  • This example is only for 10 digit US phone numbers, please adapt as needed to other dialplans

 

Using Limit to Monitor Each Gateway IP Address

To get the number of concurrent calls per gateway ip address, you may issue a command as follows:

To monitor "inbound"
# fs_cli -x 'limit_usage db inbound 1.2.3.4'
To monitor "outbound
# fs_cli -x 'limit_usage db outbound 5.6.7.8'

Example Dialplan:

Using Limit to Handle Outbound Calls

If you have the default configs then locate the Local_Extension in conf/dialplan/default.xml. Add this line right after the condition:

Then add this new file as "limits.xml" in conf/dialplan/ :

Now when you call a local extension it won't allow more than one call. Note that you can change the value in the limit's data argument. For example, this would cause a limit of 4 concurrent calls, sending the 5th call into "oops, too many calls" extension:

Here is another example that when this person makes a call to a 7-digit number or does 1+ 7 or more digits, it will add to his limit totals. However, if he just calls another 4-digit extension on the system then it won't add to his limit. Put it right after the "global" extension in default.xml:

More Examples

Some examples of using limit to protect against toll fraud is here.

Here are some Dialplan Recipes using limit.