mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
615 lines
23 KiB
615 lines
23 KiB
|
|
UID Domain Module
|
|
|
|
Juha Heinanen
|
|
|
|
<jh@tutpro.com>
|
|
|
|
Copyright © 2002-2010 Juha Heinanen
|
|
_________________________________________________________________
|
|
|
|
Table of Contents
|
|
|
|
1. Admin Guide
|
|
|
|
1. Overview
|
|
|
|
1.1. Virtual Domains
|
|
1.2. Domain-level Configuration Attributes
|
|
1.3. Caching
|
|
|
|
2. Dependencies
|
|
3. Known Limitations
|
|
4. Parameters
|
|
|
|
4.1. db_url (string)
|
|
4.2. db_mode (integer)
|
|
4.3. domain_table (string)
|
|
4.4. did_col (string)
|
|
4.5. domain_col (string)
|
|
4.6. flags_col (string)
|
|
4.7. domattr_table (string)
|
|
4.8. domattr_did (string)
|
|
4.9. domattr_name (string)
|
|
4.10. domattr_type (string)
|
|
4.11. domattr_value (string)
|
|
4.12. domattr_flags (string)
|
|
4.13. load_domain_attrs (integer)
|
|
|
|
5. Functions
|
|
|
|
5.1. is_local(domain)
|
|
5.2. lookup_domain(attr_group, domain)
|
|
|
|
6. FIFO Interface
|
|
|
|
6.1. domain.reload
|
|
6.2. domain.dump
|
|
|
|
7. Internal API
|
|
|
|
List of Examples
|
|
|
|
1.1. Virtual Domain iptel.org
|
|
1.2. Database Representation of Virtual Domain
|
|
1.3. Table domain_attrs
|
|
1.4. Setting db_url parameter
|
|
1.5. Setting db_mode parameter
|
|
1.6. Setting domain_table parameter
|
|
1.7. Setting did_col parameter
|
|
1.8. Setting domain_col parameter
|
|
1.9. Setting flags_col parameter
|
|
1.10. Setting domattrs_table parameter
|
|
1.11. Setting domattrs_did parameter
|
|
1.12. Setting domattrs_name parameter
|
|
1.13. Setting domattrs_type parameter
|
|
1.14. Setting domattrs_value parameter
|
|
1.15. Setting domattrs_flags parameter
|
|
1.16. Setting load_domain_attrs parameter
|
|
1.17. is_uri_host_local_local usage
|
|
1.18. lookup_domain usage
|
|
1.19. Calling load_domain_api
|
|
|
|
Chapter 1. Admin Guide
|
|
|
|
Table of Contents
|
|
|
|
1. Overview
|
|
|
|
1.1. Virtual Domains
|
|
1.2. Domain-level Configuration Attributes
|
|
1.3. Caching
|
|
|
|
2. Dependencies
|
|
3. Known Limitations
|
|
4. Parameters
|
|
|
|
4.1. db_url (string)
|
|
4.2. db_mode (integer)
|
|
4.3. domain_table (string)
|
|
4.4. did_col (string)
|
|
4.5. domain_col (string)
|
|
4.6. flags_col (string)
|
|
4.7. domattr_table (string)
|
|
4.8. domattr_did (string)
|
|
4.9. domattr_name (string)
|
|
4.10. domattr_type (string)
|
|
4.11. domattr_value (string)
|
|
4.12. domattr_flags (string)
|
|
4.13. load_domain_attrs (integer)
|
|
|
|
5. Functions
|
|
|
|
5.1. is_local(domain)
|
|
5.2. lookup_domain(attr_group, domain)
|
|
|
|
6. FIFO Interface
|
|
|
|
6.1. domain.reload
|
|
6.2. domain.dump
|
|
|
|
7. Internal API
|
|
|
|
1. Overview
|
|
|
|
1.1. Virtual Domains
|
|
1.2. Domain-level Configuration Attributes
|
|
1.3. Caching
|
|
|
|
Domain modules, as the name suggests, implements support for multiple
|
|
independent virtual domains hosted on one SIP server. This is often
|
|
useful if you have multiple domain names and you want to make them all
|
|
work and appear as one. Alternatively you might find the module useful
|
|
if you want to run a shared SIP service for multiple independent
|
|
customers. The module stores all supported domains and associated
|
|
configuration in a database table. Most of the information can be
|
|
cached in memory for performance reasons.
|
|
|
|
1.1. Virtual Domains
|
|
|
|
The domain module adds support for so-called virtual domains. A
|
|
virtual domain is just a collection of domain names and associated
|
|
configuration information identified by a unique identifier. We refer
|
|
to the domain identifier as DID elsewhere in the documentation. DID
|
|
stands for "Domain IDentifier". In traditional POST world the term DID
|
|
has a different meaning though. Please be aware that this is just pure
|
|
coincidence.
|
|
|
|
All domain names that belong to one virtual domain are
|
|
interchangeable. From SIP server's perspective there is no difference
|
|
between them. They can be used in SIP URIs interchangeably and the
|
|
behavior of the SIP server will not be affected. This is called
|
|
"domain name normalization" and it is one of the steps performed early
|
|
during SIP message processing.
|
|
|
|
The DID identifier can be anything. To the SIP server DIDs are just
|
|
opaque strings and what format you choose depends on your requirements
|
|
and the type of the setup. You can use numbers in smaller setups if
|
|
the size of the data is a concern. You can set the DID to the
|
|
canonical domain name of the domain. You can use RFC 4122 style UUIDs
|
|
if your setup is large and distributed. You can use anything as long
|
|
as it can be represented as string. The only requirement is that the
|
|
identifier of each virtual domain must be unique.
|
|
|
|
The following example illustrates how one virtual domain can be
|
|
represented. The iptel.org domain runs a public SIP service. The users
|
|
of the service can use SIP URIs of form sip:username@iptel.org. The
|
|
SIP service is distributed, there is a number of SIP servers. The SIP
|
|
servers are also available through a number of other domain names,
|
|
such as sip.iptel.org, proxy.iptel.org and so on. We created one
|
|
virtual domain in the domain module and added all such domain names to
|
|
the virtual domain:
|
|
|
|
Example 1.1. Virtual Domain iptel.org
|
|
iptel
|
|
|
|
|
+---iptel.org
|
|
+---sip.iptel.org
|
|
+---proxy.iptel.org
|
|
+---213.192.59.75
|
|
|
|
In the example above, we chose "iptel" as the unique identifier for
|
|
the virtual domain. This identifier is permanent. It never changes.
|
|
Over time we may change domain names assigned to this virtual domain,
|
|
but this identifier never changes. The main reason why virtual domain
|
|
identifiers must never change is that because they are referenced from
|
|
other tables, for example the accounting table. The data in the
|
|
accounting table is long-lived, usually archived, and this ensures
|
|
that the data will still reference correct virtual domain, no matter
|
|
what domain names are assigned to it.
|
|
|
|
The virtual domain described above will be stored in the domain table
|
|
in the database:
|
|
|
|
Example 1.2. Database Representation of Virtual Domain
|
|
+-------+-----------------+-------+
|
|
| did | domain | flags |
|
|
+-------+-----------------+-------+
|
|
| iptel | iptel.org | 33 |
|
|
| iptel | sip.iptel.org | 33 |
|
|
| iptel | proxy.iptel.org | 33 |
|
|
| iptel | 213.192.59.75 | 33 |
|
|
+-------+-----------------+-------+
|
|
|
|
Because all domain names that belong to one particular virtual domain
|
|
are equal, it does not matter which domain name is used in the host
|
|
part of the SIP URI. Thus an imaginary user joe with SIP URI
|
|
sip:joe@iptel.org will also be reachable as sip:joe@sip.iptel.org,
|
|
sip:joe@proxy.iptel.org, and sip:joe@213.192.59.75. If we add a new
|
|
domain name to this virtual domain then joe will also be able to use
|
|
the new domain name in his SIP URI, without the need to change
|
|
anything.
|
|
|
|
1.2. Domain-level Configuration Attributes
|
|
|
|
In addition to a number of domain names, each virtual domain can also
|
|
have extra configuration information associated with it. The
|
|
possibility to configure the SIP server sightly differently in each
|
|
virtual domain is, in fact, the main reason why we introduced the
|
|
concept of virtual domains. We wanted to have one SIP server which
|
|
will provide SIP service to multiple different customers and each of
|
|
the customers may have slightly different configuration requirements.
|
|
That's how domain-level configuration attributes were born.
|
|
|
|
Because the administrator of the SIP server seldom knows configuration
|
|
requirements in advance, we decided to implement a generic solution
|
|
and store all configuration options in named attributes. Named
|
|
attributes are just like variables, they have a name and they have a
|
|
value. Attributes are accessible from the configuration script of the
|
|
SIP server. Domain-level attributes are attributes that are associated
|
|
with a particular virtual domain. They can be used to store additional
|
|
configuration for the entire virtual domain, that is all users that
|
|
belong (or have SIP URI) in that particular virtual domain.
|
|
Domain-level attributes can be overridden be user-level attributes
|
|
with the same name configured for a particular user. In other words a
|
|
domain level attribute will only be effective if no user-level
|
|
attribute with the same name exists.
|
|
|
|
Domain-level attributes are stored in a separate table. The name of
|
|
the table is domain_attrs and it is defined as follows:
|
|
|
|
Example 1.3. Table domain_attrs
|
|
+-------+------------------+------+-----+---------+-------+
|
|
| Field | Type | Null | Key | Default | Extra |
|
|
+-------+------------------+------+-----+---------+-------+
|
|
| did | varchar(64) | YES | MUL | NULL | |
|
|
| name | varchar(32) | NO | | NULL | |
|
|
| type | int(11) | NO | | 0 | |
|
|
| value | varchar(255) | YES | | NULL | |
|
|
| flags | int(10) unsigned | NO | | 0 | |
|
|
+-------+------------------+------+-----+---------+-------+
|
|
|
|
Each attribute has name, type and value. A single attribute can have
|
|
multiple values and in that case it will occupy more rows in the
|
|
table. Each attribute is associated with a particular virtual domain
|
|
using the DID identifier. Domain-level attributes can contain just
|
|
about anything. It is a generic configuration mechanism and it is up
|
|
to you to define a list of attribute that are meaningful in your setup
|
|
and use those attributes in the routing part of the configuration
|
|
file.
|
|
|
|
Attributes for a particular virtual-domain are made available to
|
|
script function by the lookup_domain function. This is the function
|
|
that is used to map domain names to DIDs. One of the side-effects of
|
|
the function is that it makes domain-level attributes available to
|
|
script function if a matching virtual domain is found.
|
|
|
|
When caching is enabled, all attributes from domain_attrs table are
|
|
cached in memory, just like virtual domain themselves. If you disable
|
|
caching then the domain module will attempt to load attributes from
|
|
the database each time you call lookup_domain. Attributes cached in
|
|
memory can be realoaded with the domain.reload management function.
|
|
|
|
1.3. Caching
|
|
|
|
Domain module operates in caching or non-caching mode depending on
|
|
value of module parameter db_mode. In caching mode domain module reads
|
|
the contents of domain table into cache memory when the module is
|
|
loaded. After that domain table is re-read only when module is given
|
|
domain_reload fifo command. Any changes in domain table must thus be
|
|
followed by domain_reload command in order to reflect them in module
|
|
behavior. In non-caching mode domain module always queries domain
|
|
table in the database.
|
|
|
|
Caching is implemented using a hash table. The size of the hash table
|
|
is given by HASH_SIZE constant defined in domain_mod.h. Its "factory
|
|
default" value is 128. Caching mode is highly recommended if you want
|
|
to use domain-level attributes.
|
|
|
|
2. Dependencies
|
|
|
|
The module depends on the following modules (in the other words the
|
|
listed modules must be loaded before this module):
|
|
* database - Any database module
|
|
|
|
3. Known Limitations
|
|
|
|
There is an unlikely race condition on domain list update. If a
|
|
process uses a table, which is reloaded at the same time twice through
|
|
FIFO, the second reload will delete the original table still in use by
|
|
the process.
|
|
|
|
4. Parameters
|
|
|
|
4.1. db_url (string)
|
|
4.2. db_mode (integer)
|
|
4.3. domain_table (string)
|
|
4.4. did_col (string)
|
|
4.5. domain_col (string)
|
|
4.6. flags_col (string)
|
|
4.7. domattr_table (string)
|
|
4.8. domattr_did (string)
|
|
4.9. domattr_name (string)
|
|
4.10. domattr_type (string)
|
|
4.11. domattr_value (string)
|
|
4.12. domattr_flags (string)
|
|
4.13. load_domain_attrs (integer)
|
|
|
|
4.1. db_url (string)
|
|
|
|
This is URL of the database to be used.
|
|
|
|
Default value is "mysql://serro:47serro11@localhost/ser"
|
|
|
|
Example 1.4. Setting db_url parameter
|
|
modparam("domain", "db_url", "mysql://ser:pass@db_host/ser")
|
|
|
|
4.2. db_mode (integer)
|
|
|
|
Database mode. Value 0 means non-caching, 1 means caching is enabled.
|
|
It is highly recommended to enable caching if you want to use
|
|
domain-level attributes.
|
|
|
|
Default value is 1 (caching).
|
|
|
|
Example 1.5. Setting db_mode parameter
|
|
modparam("domain", "db_mode", 0) # Do not use caching
|
|
|
|
4.3. domain_table (string)
|
|
|
|
Name of table containing names of local domains that the proxy is
|
|
responsible for. Local users must have in their SIP URI a host part
|
|
that is equal to one of the domains stored in this table.
|
|
|
|
Default value is "domain".
|
|
|
|
Example 1.6. Setting domain_table parameter
|
|
modparam("domain", "domain_table", "new_name")
|
|
|
|
4.4. did_col (string)
|
|
|
|
This is the name of the column in domain table that contains the
|
|
unique identifiers of virtual domains. Domains names found in this
|
|
table are arranged into virtual domains. Each virtual domain must have
|
|
a unique identifier and it can contain one or more domain names.
|
|
|
|
Default value is "did".
|
|
|
|
Example 1.7. Setting did_col parameter
|
|
modparam("domain", "did_col", "did")
|
|
|
|
4.5. domain_col (string)
|
|
|
|
Name of column containing domain names in the domain table.
|
|
|
|
Default value is "domain".
|
|
|
|
Example 1.8. Setting domain_col parameter
|
|
modparam("domain", "domain_col", "domain")
|
|
|
|
4.6. flags_col (string)
|
|
|
|
This is the name of the column in domain table which stores various
|
|
flags. Each row in the table has a bunch of generic flags that can be
|
|
used mark the row disabled, deleted, etc. The flags allow for more
|
|
flexible administration of the data in the database and they are
|
|
present in several other tables too.
|
|
|
|
Default value is "flags".
|
|
|
|
Example 1.9. Setting flags_col parameter
|
|
modparam("domain", "flags_col", "domain")
|
|
|
|
4.7. domattr_table (string)
|
|
|
|
This parameter can be used to configure the name of the table that is
|
|
used to store domain-level attributes. Domain level attributes are
|
|
attributes that are associated with a particular virtual domain. They
|
|
are typically used to store additional domain-wide settings that
|
|
should apply to all users who belong to the domain.
|
|
|
|
Default value is "domain_attrs".
|
|
|
|
Example 1.10. Setting domattrs_table parameter
|
|
modparam("domain", "domattr_table", "domain_attrs")
|
|
|
|
4.8. domattr_did (string)
|
|
|
|
Use this parameter to configure the name of the column in domain_attrs
|
|
table that is used to store the did of the virtual domain the
|
|
attribute belongs to. Normally there is no need to configure this
|
|
parameter, unless you want adapt to module to a different database
|
|
schema.
|
|
|
|
Default value is "did".
|
|
|
|
Example 1.11. Setting domattrs_did parameter
|
|
modparam("domain", "domattr_did", "did")
|
|
|
|
4.9. domattr_name (string)
|
|
|
|
Use this parameter to configure the name of the column in domain_attrs
|
|
table that is used to store the name of the attribute. Normally there
|
|
is no need to configure this parameter, unless you want adapt to
|
|
module to a different database schema.
|
|
|
|
Default value is "name".
|
|
|
|
Example 1.12. Setting domattrs_name parameter
|
|
modparam("domain", "domattr_name", "name")
|
|
|
|
4.10. domattr_type (string)
|
|
|
|
Use this parameter to configure the name of the column in domain_attrs
|
|
table that is used to store the type of the attribute. Normally there
|
|
is no need to configure this parameter, unless you want adapt to
|
|
module to a different database schema.
|
|
|
|
Default value is "type".
|
|
|
|
Example 1.13. Setting domattrs_type parameter
|
|
modparam("domain", "domattr_type", "type")
|
|
|
|
4.11. domattr_value (string)
|
|
|
|
Use this parameter to configure the name of the column in domain_attrs
|
|
table that is used to store the value of the attribute. Normally there
|
|
is no need to configure this parameter, unless you want adapt to
|
|
module to a different database schema.
|
|
|
|
Default value is "value".
|
|
|
|
Example 1.14. Setting domattrs_value parameter
|
|
modparam("domain", "domattr_value", "value")
|
|
|
|
4.12. domattr_flags (string)
|
|
|
|
This is the name of the column in domain_attrs table which stores
|
|
various flags. Each row in the table has a bunch of generic flags that
|
|
can be used mark the row disabled, deleted, etc. The flags allow for
|
|
more flexible administration of the data in the database and they are
|
|
present in several other tables too. You do not have to touch this
|
|
parameter under normal circumstances.
|
|
|
|
Default value is "flags".
|
|
|
|
Example 1.15. Setting domattrs_flags parameter
|
|
modparam("domain", "domattr_flags", "flags")
|
|
|
|
4.13. load_domain_attrs (integer)
|
|
|
|
This parameter can be used to enable/disable user of domain-level
|
|
attributes. Domain-level attributes are variables that can be used to
|
|
store additional configuration that applies to the whole virtual
|
|
domain and all users within the virtual domain. Domain-level
|
|
attributes are stored in domain_attrs. If you set this parameter to a
|
|
non-zero value then the server will make domain-level attributes
|
|
available to the script every time you call function lookup_domain. If
|
|
you set the parameter to 0 then domain-level attributes will be
|
|
ignored, the domain module will not load them from the database and
|
|
the lookup function will not make them available to the script.
|
|
|
|
Default value is 0.
|
|
|
|
Example 1.16. Setting load_domain_attrs parameter
|
|
modparam("domain", "load_domain_attrs", 1)
|
|
|
|
5. Functions
|
|
|
|
5.1. is_local(domain)
|
|
5.2. lookup_domain(attr_group, domain)
|
|
|
|
5.1. is_local(domain)
|
|
|
|
This function can be used to test whether a given domain name in
|
|
parameter belongs to one of the virtual domains defined in the domain
|
|
table. Such domain name is said to be local. The function returns 1 if
|
|
the domain name is found in the domain table and -1 otherwise.
|
|
|
|
The first parameter of the function can be anything that returns a
|
|
string with domain name. In its simplest form it can be a string with
|
|
domain name: is_local("iptel.org"). You can also test a domain name
|
|
stored in an attribute: is_local("$my_domain"). And finally you can
|
|
test a domain name present in the SIP message with selects:
|
|
is_local("@ruri.host").
|
|
|
|
Note: Unlike function lookup_domain, this function does not make
|
|
domain attributes of the virtual domain available to the script.
|
|
Domain attributes are simply ignored by this function.
|
|
|
|
Example 1.17. is_uri_host_local_local usage
|
|
...
|
|
if (is_local("@ruri.host")) {
|
|
/* Domain part of Request-URI is local */
|
|
}
|
|
...
|
|
|
|
5.2. lookup_domain(attr_group, domain)
|
|
|
|
This is the main function of the domain module. It can be used to
|
|
implement support for virtual domains in the SIP server. Each virtual
|
|
domain is identified by a unique identifier (opaque string) and it can
|
|
have one or more associated domain names. Given a domain name in the
|
|
second parameter, this function finds the associated virtual domain
|
|
identifier (known as DID) and stores it in an attribute for later
|
|
user. In addition to that the function also loads all domain-level
|
|
attributes for the virtual domain and makes them available to the
|
|
configuration script.
|
|
|
|
The first parameter of the function identifies the group of attributes
|
|
where the DID and domain-level attributes shall be stored. The value
|
|
of the first parameter can be either "$fd" for the domain-level
|
|
attribute group that belongs to the calling party (From), or "$td" for
|
|
the domain-level attribute group that belongs to the called party
|
|
(Request-URI).
|
|
|
|
The value of the second parameter can be a simple string, an attribute
|
|
name, or a select. See the documentation of function is_local for more
|
|
details.
|
|
|
|
If a match is found then the DID of the virtual domain will be stored
|
|
either in $fd.did or in $td.did, depending on the value of the first
|
|
parameter. In addition to that domain-level attributes, if any, will
|
|
be available as either $fd.<name> or $td.</name>.
|
|
|
|
The function returns 1 when a matching virtual domain for the given
|
|
domain name was found and -1 otherwise.
|
|
|
|
The following example shows a typical use of the function. In a multi
|
|
domain setup, one has to typically figure out where the both the
|
|
calling and the called domains are local (i.e. configured on the
|
|
server as the domains the server is responsible for). This is
|
|
typically done by calling function lookup_domain twice, once with the
|
|
hostname part of the From header as parameter and secondly with the
|
|
hostname part of the Request-URI as parameter.
|
|
|
|
The type of the situation can be then determined from the value of
|
|
corresponding attributes ($td.did and $fd.did). A non-existing
|
|
attribute value indicates that the domain name is not local (it does
|
|
not belong to any virtual domain configured in the domain table).
|
|
|
|
Example 1.18. lookup_domain usage
|
|
lookup_domain("$fd", "@from.uri.host");
|
|
lookup_domain("$td", "@ruri.host");
|
|
|
|
if (strempty($fd.did) && strempty($td.did)) {
|
|
# Neither the calling nor the called domain is local
|
|
# This is a relaying attempt which should be forbidden
|
|
sl_reply("403", "Relaying Forbidden");
|
|
drop;
|
|
}
|
|
if (strempty($fd.did) && $td.did) {
|
|
# The calling domain is not local and the called domain
|
|
# is local, this is an inbound call from a 3rd party
|
|
# user to one of local users
|
|
}
|
|
if ($fd.did && strempty($td.did)) {
|
|
# The calling domain is local and the called domain
|
|
# is not local, this is an outbound call from one of
|
|
# our users to a 3rd party user
|
|
}
|
|
if ($fd.did && $td.did) {
|
|
# Both the calling and the called domains are local,
|
|
# one of our local users calls another local user,
|
|
# either in the same virtual domain or in another
|
|
# virtual domain hosted on the same server
|
|
}
|
|
|
|
6. FIFO Interface
|
|
|
|
6.1. domain.reload
|
|
6.2. domain.dump
|
|
|
|
6.1. domain.reload
|
|
|
|
Causes domain module to re-read the contents of domain table into
|
|
cache memory. If domain-level attributes are used then it will also
|
|
re-load the contents of the domain_attrs table in the memory cache.
|
|
|
|
6.2. domain.dump
|
|
|
|
Causes domain module to dump hash indexes and domain names in its
|
|
cache memory.
|
|
|
|
7. Internal API
|
|
|
|
The domain module has an internal API which can be used to access
|
|
additional functions of the module (i.e. functions that are normally
|
|
not available from the routing script). Currently the API exports only
|
|
the function is_domain_local. That function can be used to determine
|
|
whether a given domain name is on the list of locally configured
|
|
domain names.
|
|
|
|
If you want to use the internal API of domain module from your module
|
|
then you need to include the header file domain_api.h and call
|
|
load_domain_api first.
|
|
|
|
Example 1.19. Calling load_domain_api
|
|
#include "../domain/domain_api.h"
|
|
|
|
domain_api_t dom_api;
|
|
|
|
if (load_domain_api(&dom_api) != 0) {
|
|
/* error */
|
|
}
|
|
|
|
After that you can call function is_domain_local whose pointer is
|
|
stored in the initialized data structure:
|
|
str tmp = STR_STATIC_INIT("mydomain.com");
|
|
|
|
if (dom_api.is_domain_local(&tmp) == 1) {
|
|
/* Domain is local */
|
|
} else {
|
|
/* Domain is not local or an error was encountered */
|
|
}
|