1UID Domain Module 2 3Juha Heinanen 4 5 <jh@tutpro.com> 6 7 Copyright © 2002-2010 Juha Heinanen 8 __________________________________________________________________ 9 10 Table of Contents 11 12 1. Admin Guide 13 14 1. Overview 15 16 1.1. Virtual Domains 17 1.2. Domain-level Configuration Attributes 18 1.3. Caching 19 20 2. Dependencies 21 3. Known Limitations 22 4. Parameters 23 24 4.1. db_url (string) 25 4.2. db_mode (integer) 26 4.3. domain_table (string) 27 4.4. did_col (string) 28 4.5. domain_col (string) 29 4.6. flags_col (string) 30 4.7. domattr_table (string) 31 4.8. domattr_did (string) 32 4.9. domattr_name (string) 33 4.10. domattr_type (string) 34 4.11. domattr_value (string) 35 4.12. domattr_flags (string) 36 4.13. load_domain_attrs (integer) 37 38 5. Functions 39 40 5.1. is_local(domain) 41 5.2. lookup_domain(attr_group, domain) 42 43 6. FIFO Interface 44 45 6.1. domain.reload 46 6.2. domain.dump 47 48 7. Internal API 49 50 List of Examples 51 52 1.1. Virtual Domain iptel.org 53 1.2. Database Representation of Virtual Domain 54 1.3. Table domain_attrs 55 1.4. Setting db_url parameter 56 1.5. Setting db_mode parameter 57 1.6. Setting domain_table parameter 58 1.7. Setting did_col parameter 59 1.8. Setting domain_col parameter 60 1.9. Setting flags_col parameter 61 1.10. Setting domattrs_table parameter 62 1.11. Setting domattrs_did parameter 63 1.12. Setting domattrs_name parameter 64 1.13. Setting domattrs_type parameter 65 1.14. Setting domattrs_value parameter 66 1.15. Setting domattrs_flags parameter 67 1.16. Setting load_domain_attrs parameter 68 1.17. is_uri_host_local_local usage 69 1.18. lookup_domain usage 70 1.19. Calling load_domain_api 71 72Chapter 1. Admin Guide 73 74 Table of Contents 75 76 1. Overview 77 78 1.1. Virtual Domains 79 1.2. Domain-level Configuration Attributes 80 1.3. Caching 81 82 2. Dependencies 83 3. Known Limitations 84 4. Parameters 85 86 4.1. db_url (string) 87 4.2. db_mode (integer) 88 4.3. domain_table (string) 89 4.4. did_col (string) 90 4.5. domain_col (string) 91 4.6. flags_col (string) 92 4.7. domattr_table (string) 93 4.8. domattr_did (string) 94 4.9. domattr_name (string) 95 4.10. domattr_type (string) 96 4.11. domattr_value (string) 97 4.12. domattr_flags (string) 98 4.13. load_domain_attrs (integer) 99 100 5. Functions 101 102 5.1. is_local(domain) 103 5.2. lookup_domain(attr_group, domain) 104 105 6. FIFO Interface 106 107 6.1. domain.reload 108 6.2. domain.dump 109 110 7. Internal API 111 1121. Overview 113 114 1.1. Virtual Domains 115 1.2. Domain-level Configuration Attributes 116 1.3. Caching 117 118 Domain modules, as the name suggests, implements support for multiple 119 independent virtual domains hosted on one SIP server. This is often 120 useful if you have multiple domain names and you want to make them all 121 work and appear as one. Alternatively you might find the module useful 122 if you want to run a shared SIP service for multiple independent 123 customers. The module stores all supported domains and associated 124 configuration in a database table. Most of the information can be 125 cached in memory for performance reasons. 126 1271.1. Virtual Domains 128 129 The domain module adds support for so-called virtual domains. A virtual 130 domain is just a collection of domain names and associated 131 configuration information identified by a unique identifier. We refer 132 to the domain identifier as DID elsewhere in the documentation. DID 133 stands for "Domain IDentifier". In traditional POST world the term DID 134 has a different meaning though. Please be aware that this is just pure 135 coincidence. 136 137 All domain names that belong to one virtual domain are interchangeable. 138 From SIP server's perspective there is no difference between them. They 139 can be used in SIP URIs interchangeably and the behavior of the SIP 140 server will not be affected. This is called "domain name normalization" 141 and it is one of the steps performed early during SIP message 142 processing. 143 144 The DID identifier can be anything. To the SIP server DIDs are just 145 opaque strings and what format you choose depends on your requirements 146 and the type of the setup. You can use numbers in smaller setups if the 147 size of the data is a concern. You can set the DID to the canonical 148 domain name of the domain. You can use RFC 4122 style UUIDs if your 149 setup is large and distributed. You can use anything as long as it can 150 be represented as string. The only requirement is that the identifier 151 of each virtual domain must be unique. 152 153 The following example illustrates how one virtual domain can be 154 represented. The iptel.org domain runs a public SIP service. The users 155 of the service can use SIP URIs of form sip:username@iptel.org. The SIP 156 service is distributed, there is a number of SIP servers. The SIP 157 servers are also available through a number of other domain names, such 158 as sip.iptel.org, proxy.iptel.org and so on. We created one virtual 159 domain in the domain module and added all such domain names to the 160 virtual domain: 161 162 Example 1.1. Virtual Domain iptel.org 163iptel 164 | 165 +---iptel.org 166 +---sip.iptel.org 167 +---proxy.iptel.org 168 +---213.192.59.75 169 170 In the example above, we chose "iptel" as the unique identifier for the 171 virtual domain. This identifier is permanent. It never changes. Over 172 time we may change domain names assigned to this virtual domain, but 173 this identifier never changes. The main reason why virtual domain 174 identifiers must never change is that because they are referenced from 175 other tables, for example the accounting table. The data in the 176 accounting table is long-lived, usually archived, and this ensures that 177 the data will still reference correct virtual domain, no matter what 178 domain names are assigned to it. 179 180 The virtual domain described above will be stored in the domain table 181 in the database: 182 183 Example 1.2. Database Representation of Virtual Domain 184+-------+-----------------+-------+ 185| did | domain | flags | 186+-------+-----------------+-------+ 187| iptel | iptel.org | 33 | 188| iptel | sip.iptel.org | 33 | 189| iptel | proxy.iptel.org | 33 | 190| iptel | 213.192.59.75 | 33 | 191+-------+-----------------+-------+ 192 193 Because all domain names that belong to one particular virtual domain 194 are equal, it does not matter which domain name is used in the host 195 part of the SIP URI. Thus an imaginary user joe with SIP URI 196 sip:joe@iptel.org will also be reachable as sip:joe@sip.iptel.org, 197 sip:joe@proxy.iptel.org, and sip:joe@213.192.59.75. If we add a new 198 domain name to this virtual domain then joe will also be able to use 199 the new domain name in his SIP URI, without the need to change 200 anything. 201 2021.2. Domain-level Configuration Attributes 203 204 In addition to a number of domain names, each virtual domain can also 205 have extra configuration information associated with it. The 206 possibility to configure the SIP server sightly differently in each 207 virtual domain is, in fact, the main reason why we introduced the 208 concept of virtual domains. We wanted to have one SIP server which will 209 provide SIP service to multiple different customers and each of the 210 customers may have slightly different configuration requirements. 211 That's how domain-level configuration attributes were born. 212 213 Because the administrator of the SIP server seldom knows configuration 214 requirements in advance, we decided to implement a generic solution and 215 store all configuration options in named attributes. Named attributes 216 are just like variables, they have a name and they have a value. 217 Attributes are accessible from the configuration script of the SIP 218 server. Domain-level attributes are attributes that are associated with 219 a particular virtual domain. They can be used to store additional 220 configuration for the entire virtual domain, that is all users that 221 belong (or have SIP URI) in that particular virtual domain. 222 Domain-level attributes can be overridden be user-level attributes with 223 the same name configured for a particular user. In other words a domain 224 level attribute will only be effective if no user-level attribute with 225 the same name exists. 226 227 Domain-level attributes are stored in a separate table. The name of the 228 table is domain_attrs and it is defined as follows: 229 230 Example 1.3. Table domain_attrs 231+-------+------------------+------+-----+---------+-------+ 232| Field | Type | Null | Key | Default | Extra | 233+-------+------------------+------+-----+---------+-------+ 234| did | varchar(64) | YES | MUL | NULL | | 235| name | varchar(32) | NO | | NULL | | 236| type | int(11) | NO | | 0 | | 237| value | varchar(255) | YES | | NULL | | 238| flags | int(10) unsigned | NO | | 0 | | 239+-------+------------------+------+-----+---------+-------+ 240 241 Each attribute has name, type and value. A single attribute can have 242 multiple values and in that case it will occupy more rows in the table. 243 Each attribute is associated with a particular virtual domain using the 244 DID identifier. Domain-level attributes can contain just about 245 anything. It is a generic configuration mechanism and it is up to you 246 to define a list of attribute that are meaningful in your setup and use 247 those attributes in the routing part of the configuration file. 248 249 Attributes for a particular virtual-domain are made available to script 250 function by the lookup_domain function. This is the function that is 251 used to map domain names to DIDs. One of the side-effects of the 252 function is that it makes domain-level attributes available to script 253 function if a matching virtual domain is found. 254 255 When caching is enabled, all attributes from domain_attrs table are 256 cached in memory, just like virtual domain themselves. If you disable 257 caching then the domain module will attempt to load attributes from the 258 database each time you call lookup_domain. Attributes cached in memory 259 can be reloaded with the domain.reload management function. 260 2611.3. Caching 262 263 Domain module operates in caching or non-caching mode depending on 264 value of module parameter db_mode. In caching mode domain module reads 265 the contents of domain table into cache memory when the module is 266 loaded. After that domain table is re-read only when module is given 267 domain_reload fifo command. Any changes in domain table must thus be 268 followed by domain_reload command in order to reflect them in module 269 behavior. In non-caching mode domain module always queries domain table 270 in the database. 271 272 Caching is implemented using a hash table. The size of the hash table 273 is given by HASH_SIZE constant defined in domain_mod.h. Its "factory 274 default" value is 128. Caching mode is highly recommended if you want 275 to use domain-level attributes. 276 2772. Dependencies 278 279 The module depends on the following modules (in the other words the 280 listed modules must be loaded before this module): 281 * database - Any database module 282 2833. Known Limitations 284 285 There is an unlikely race condition on domain list update. If a process 286 uses a table, which is reloaded at the same time twice through FIFO, 287 the second reload will delete the original table still in use by the 288 process. 289 2904. Parameters 291 292 4.1. db_url (string) 293 4.2. db_mode (integer) 294 4.3. domain_table (string) 295 4.4. did_col (string) 296 4.5. domain_col (string) 297 4.6. flags_col (string) 298 4.7. domattr_table (string) 299 4.8. domattr_did (string) 300 4.9. domattr_name (string) 301 4.10. domattr_type (string) 302 4.11. domattr_value (string) 303 4.12. domattr_flags (string) 304 4.13. load_domain_attrs (integer) 305 3064.1. db_url (string) 307 308 This is URL of the database to be used. 309 310 Default value is "mysql://serro:47serro11@localhost/ser" 311 312 Example 1.4. Setting db_url parameter 313modparam("domain", "db_url", "mysql://ser:pass@db_host/ser") 314 3154.2. db_mode (integer) 316 317 Database mode. Value 0 means non-caching, 1 means caching is enabled. 318 It is highly recommended to enable caching if you want to use 319 domain-level attributes. 320 321 Default value is 1 (caching). 322 323 Example 1.5. Setting db_mode parameter 324modparam("domain", "db_mode", 0) # Do not use caching 325 3264.3. domain_table (string) 327 328 Name of table containing names of local domains that the proxy is 329 responsible for. Local users must have in their SIP URI a host part 330 that is equal to one of the domains stored in this table. 331 332 Default value is "domain". 333 334 Example 1.6. Setting domain_table parameter 335modparam("domain", "domain_table", "new_name") 336 3374.4. did_col (string) 338 339 This is the name of the column in domain table that contains the unique 340 identifiers of virtual domains. Domains names found in this table are 341 arranged into virtual domains. Each virtual domain must have a unique 342 identifier and it can contain one or more domain names. 343 344 Default value is "did". 345 346 Example 1.7. Setting did_col parameter 347modparam("domain", "did_col", "did") 348 3494.5. domain_col (string) 350 351 Name of column containing domain names in the domain table. 352 353 Default value is "domain". 354 355 Example 1.8. Setting domain_col parameter 356modparam("domain", "domain_col", "domain") 357 3584.6. flags_col (string) 359 360 This is the name of the column in domain table which stores various 361 flags. Each row in the table has a bunch of generic flags that can be 362 used mark the row disabled, deleted, etc. The flags allow for more 363 flexible administration of the data in the database and they are 364 present in several other tables too. 365 366 Default value is "flags". 367 368 Example 1.9. Setting flags_col parameter 369modparam("domain", "flags_col", "domain") 370 3714.7. domattr_table (string) 372 373 This parameter can be used to configure the name of the table that is 374 used to store domain-level attributes. Domain level attributes are 375 attributes that are associated with a particular virtual domain. They 376 are typically used to store additional domain-wide settings that should 377 apply to all users who belong to the domain. 378 379 Default value is "domain_attrs". 380 381 Example 1.10. Setting domattrs_table parameter 382modparam("domain", "domattr_table", "domain_attrs") 383 3844.8. domattr_did (string) 385 386 Use this parameter to configure the name of the column in domain_attrs 387 table that is used to store the did of the virtual domain the attribute 388 belongs to. Normally there is no need to configure this parameter, 389 unless you want adapt to module to a different database schema. 390 391 Default value is "did". 392 393 Example 1.11. Setting domattrs_did parameter 394modparam("domain", "domattr_did", "did") 395 3964.9. domattr_name (string) 397 398 Use this parameter to configure the name of the column in domain_attrs 399 table that is used to store the name of the attribute. Normally there 400 is no need to configure this parameter, unless you want adapt to module 401 to a different database schema. 402 403 Default value is "name". 404 405 Example 1.12. Setting domattrs_name parameter 406modparam("domain", "domattr_name", "name") 407 4084.10. domattr_type (string) 409 410 Use this parameter to configure the name of the column in domain_attrs 411 table that is used to store the type of the attribute. Normally there 412 is no need to configure this parameter, unless you want adapt to module 413 to a different database schema. 414 415 Default value is "type". 416 417 Example 1.13. Setting domattrs_type parameter 418modparam("domain", "domattr_type", "type") 419 4204.11. domattr_value (string) 421 422 Use this parameter to configure the name of the column in domain_attrs 423 table that is used to store the value of the attribute. Normally there 424 is no need to configure this parameter, unless you want adapt to module 425 to a different database schema. 426 427 Default value is "value". 428 429 Example 1.14. Setting domattrs_value parameter 430modparam("domain", "domattr_value", "value") 431 4324.12. domattr_flags (string) 433 434 This is the name of the column in domain_attrs table which stores 435 various flags. Each row in the table has a bunch of generic flags that 436 can be used mark the row disabled, deleted, etc. The flags allow for 437 more flexible administration of the data in the database and they are 438 present in several other tables too. You do not have to touch this 439 parameter under normal circumstances. 440 441 Default value is "flags". 442 443 Example 1.15. Setting domattrs_flags parameter 444modparam("domain", "domattr_flags", "flags") 445 4464.13. load_domain_attrs (integer) 447 448 This parameter can be used to enable/disable user of domain-level 449 attributes. Domain-level attributes are variables that can be used to 450 store additional configuration that applies to the whole virtual domain 451 and all users within the virtual domain. Domain-level attributes are 452 stored in domain_attrs. If you set this parameter to a non-zero value 453 then the server will make domain-level attributes available to the 454 script every time you call function lookup_domain. If you set the 455 parameter to 0 then domain-level attributes will be ignored, the domain 456 module will not load them from the database and the lookup function 457 will not make them available to the script. 458 459 Default value is 0. 460 461 Example 1.16. Setting load_domain_attrs parameter 462modparam("domain", "load_domain_attrs", 1) 463 4645. Functions 465 466 5.1. is_local(domain) 467 5.2. lookup_domain(attr_group, domain) 468 4695.1. is_local(domain) 470 471 This function can be used to test whether a given domain name in 472 parameter belongs to one of the virtual domains defined in the domain 473 table. Such domain name is said to be local. The function returns 1 if 474 the domain name is found in the domain table and -1 otherwise. 475 476 The first parameter of the function can be anything that returns a 477 string with domain name. In its simplest form it can be a string with 478 domain name: is_local("iptel.org"). You can also test a domain name 479 stored in an attribute: is_local("$my_domain"). And finally you can 480 test a domain name present in the SIP message with selects: 481 is_local("@ruri.host"). 482 483 Note: Unlike function lookup_domain, this function does not make domain 484 attributes of the virtual domain available to the script. Domain 485 attributes are simply ignored by this function. 486 487 Example 1.17. is_uri_host_local_local usage 488... 489if (is_local("@ruri.host")) { 490 /* Domain part of Request-URI is local */ 491} 492... 493 4945.2. lookup_domain(attr_group, domain) 495 496 This is the main function of the domain module. It can be used to 497 implement support for virtual domains in the SIP server. Each virtual 498 domain is identified by a unique identifier (opaque string) and it can 499 have one or more associated domain names. Given a domain name in the 500 second parameter, this function finds the associated virtual domain 501 identifier (known as DID) and stores it in an attribute for later user. 502 In addition to that the function also loads all domain-level attributes 503 for the virtual domain and makes them available to the configuration 504 script. 505 506 The first parameter of the function identifies the group of attributes 507 where the DID and domain-level attributes shall be stored. The value of 508 the first parameter can be either "$fd" for the domain-level attribute 509 group that belongs to the calling party (From), or "$td" for the 510 domain-level attribute group that belongs to the called party 511 (Request-URI). 512 513 The value of the second parameter can be a simple string, an attribute 514 name, or a select. See the documentation of function is_local for more 515 details. 516 517 If a match is found then the DID of the virtual domain will be stored 518 either in $fd.did or in $td.did, depending on the value of the first 519 parameter. In addition to that domain-level attributes, if any, will be 520 available as either $fd.<name> or $td.</name>. 521 522 The function returns 1 when a matching virtual domain for the given 523 domain name was found and -1 otherwise. 524 525 The following example shows a typical use of the function. In a multi 526 domain setup, one has to typically figure out where the both the 527 calling and the called domains are local (i.e. configured on the server 528 as the domains the server is responsible for). This is typically done 529 by calling function lookup_domain twice, once with the hostname part of 530 the From header as parameter and secondly with the hostname part of the 531 Request-URI as parameter. 532 533 The type of the situation can be then determined from the value of 534 corresponding attributes ($td.did and $fd.did). A non-existing 535 attribute value indicates that the domain name is not local (it does 536 not belong to any virtual domain configured in the domain table). 537 538 Example 1.18. lookup_domain usage 539lookup_domain("$fd", "@from.uri.host"); 540lookup_domain("$td", "@ruri.host"); 541 542if (strempty($fd.did) && strempty($td.did)) { 543 # Neither the calling nor the called domain is local 544 # This is a relaying attempt which should be forbidden 545 sl_reply("403", "Relaying Forbidden"); 546 drop; 547} 548if (strempty($fd.did) && $td.did) { 549 # The calling domain is not local and the called domain 550 # is local, this is an inbound call from a 3rd party 551 # user to one of local users 552} 553if ($fd.did && strempty($td.did)) { 554 # The calling domain is local and the called domain 555 # is not local, this is an outbound call from one of 556 # our users to a 3rd party user 557} 558if ($fd.did && $td.did) { 559 # Both the calling and the called domains are local, 560 # one of our local users calls another local user, 561 # either in the same virtual domain or in another 562 # virtual domain hosted on the same server 563} 564 5656. FIFO Interface 566 567 6.1. domain.reload 568 6.2. domain.dump 569 5706.1. domain.reload 571 572 Causes domain module to re-read the contents of domain table into cache 573 memory. If domain-level attributes are used then it will also re-load 574 the contents of the domain_attrs table in the memory cache. 575 5766.2. domain.dump 577 578 Causes domain module to dump hash indexes and domain names in its cache 579 memory. 580 5817. Internal API 582 583 The domain module has an internal API which can be used to access 584 additional functions of the module (i.e. functions that are normally 585 not available from the routing script). Currently the API exports only 586 the function is_domain_local. That function can be used to determine 587 whether a given domain name is on the list of locally configured domain 588 names. 589 590 If you want to use the internal API of domain module from your module 591 then you need to include the header file domain_api.h and call 592 load_domain_api first. 593 594 Example 1.19. Calling load_domain_api 595#include "../domain/domain_api.h" 596 597domain_api_t dom_api; 598 599if (load_domain_api(&dom_api) != 0) { 600 /* error */ 601} 602 603 After that you can call function is_domain_local whose pointer is 604 stored in the initialized data structure: 605str tmp = STR_STATIC_INIT("mydomain.com"); 606 607if (dom_api.is_domain_local(&tmp) == 1) { 608 /* Domain is local */ 609} else { 610 /* Domain is not local or an error was encountered */ 611} 612