diff --git a/modules/mid_registrar/README b/modules/mid_registrar/README index 867a721f072..412155fd596 100644 --- a/modules/mid_registrar/README +++ b/modules/mid_registrar/README @@ -23,11 +23,7 @@ Liviu Chircu 1.2.2. Contact throttling 1.2.3. AOR throttling - 1.3. Insertion modes - - 1.3.1. Insertion by Contact (default) - 1.3.2. Insertion by Path - + 1.3. Auto-Insertion Into Future SIP Flows 1.4. Dependencies 1.4.1. OpenSIPS Modules @@ -36,20 +32,20 @@ Liviu Chircu 1.5. Exported Parameters 1.5.1. mode (integer) - 1.5.2. insertion_mode (integer) - 1.5.3. min_expires (integer) - 1.5.4. default_expires (integer) - 1.5.5. max_expires (integer) - 1.5.6. outgoing_expires (integer) - 1.5.7. contact_match_param (string) - 1.5.8. default_q (integer) - 1.5.9. tcp_persistent_flag (string) - 1.5.10. realm_prefix (string) - 1.5.11. case_sensitive (integer) - 1.5.12. received_avp (string) - 1.5.13. received_param (string) - 1.5.14. max_contacts (integer) - 1.5.15. extra_contact_params_avp (string) + 1.5.2. contact_id_insertion (integer) + 1.5.3. contact_id_param (string) + 1.5.4. outgoing_expires (integer) + 1.5.5. received_avp (string) + 1.5.6. received_param (string) + 1.5.7. extra_contact_params_avp (string) + 1.5.8. min_expires (integer) + 1.5.9. default_expires (integer) + 1.5.10. max_expires (integer) + 1.5.11. default_q (integer) + 1.5.12. tcp_persistent_flag (string) + 1.5.13. realm_prefix (string) + 1.5.14. case_sensitive (integer) + 1.5.15. max_contacts (integer) 1.5.16. retry_after (integer) 1.5.17. disable_gruu (integer) 1.5.18. gruu_secret (string) @@ -65,20 +61,20 @@ Liviu Chircu List of Examples 1.1. Setting the mode module parameter - 1.2. Setting the insertion_mode module parameter - 1.3. Setting the min_expires module parameter - 1.4. Setting the default_expires module parameter - 1.5. Setting the max_expires module parameter - 1.6. Setting the outgoing_expires module parameter - 1.7. Setting the contact_match_param module parameter - 1.8. Setting the default_q module parameter - 1.9. Setting the tcp_persistent_flag module parameter - 1.10. Setting the realm_prefix module parameter - 1.11. Setting the case_sensitive module parameter - 1.12. Setting the received_avp module parameter - 1.13. Setting the received_param module parameter - 1.14. Setting the max_contacts module parameter - 1.15. Setting the extra_contact_params_avp module parameter + 1.2. Setting the contact_id_insertion module parameter + 1.3. Setting the contact_id_param module parameter + 1.4. Setting the outgoing_expires module parameter + 1.5. Setting the received_avp module parameter + 1.6. Setting the received_param module parameter + 1.7. Setting the extra_contact_params_avp module parameter + 1.8. Setting the min_expires module parameter + 1.9. Setting the default_expires module parameter + 1.10. Setting the max_expires module parameter + 1.11. Setting the default_q module parameter + 1.12. Setting the tcp_persistent_flag module parameter + 1.13. Setting the realm_prefix module parameter + 1.14. Setting the case_sensitive module parameter + 1.15. Setting the max_contacts module parameter 1.16. Setting the retry_after module parameter 1.17. Setting the gruu_secret module parameter 1.18. Setting the gruu_secret module parameter @@ -101,9 +97,9 @@ Chapter 1. Admin Guide * convert incoming high-rate registration traffic into a low-rate variant, towards the main registrar layer. With proper configuration, it can absorb over 90% of existing - registration traffic while preserving the back-end's user - location state, effectively reducing resource usage at the - respective layer. + registration traffic while correctly managing the + back-end's user location state, effectively reducing + resource usage at the respective layer. * stay synchronized with the main registrar (from a user location perspective), by properly accepting the contact states and expirations it decides. @@ -114,13 +110,15 @@ Chapter 1. Admin Guide 1.2.1. Contact mirroring (default) - In "contact mirroring" mode, the mid-registrar will insert - itself in the registration flow between end user and main - registrar only as a simple proxy registrar, without any other - contact processing. The incoming REGISTER requests will be - proxied further to the main registrar; the registered contact - will be stored in the mid-registrar only on 2xx replies, - according to the information returned by the main registrar. + In "contact mirroring" mode, the mid-registrar will only insert + itself in the SIP traffic flow between end user and main + registrar by altering the Contact header field values. See + section Section 1.3, “Auto-Insertion Into Future SIP Flows” for + a detailed description of possible Contact-based insertion + modes. The incoming REGISTER requests will be proxied further + to the main registrar; the registered contact will be stored in + the mid-registrar only on 2xx replies, according to the + information returned by the main registrar. A possible usage of this mode, for example, would be to clone registrations on a SIP front-end that extends the main platform @@ -134,8 +132,8 @@ Chapter 1. Admin Guide while coping with a high registration rate on the end-user side (between end-user and mid-registrar). This is useful in scenarios were the end-users are very dynamic and short-lived - (like on mobile devices), but the main registrar cannot cope - with large traffic. + (e.g. mobile devices), but the main registrar cannot cope with + large amounts of registration traffic. Traffic conversion is done in a "per-device" manner, according to each unique SIP Contact header field value. It is achieved @@ -214,39 +212,26 @@ Chapter 1. Admin Guide platform, such as advanced SIP calling features and/or media handling. -1.3. Insertion modes +1.3. Auto-Insertion Into Future SIP Flows A defining feature of the mid-registrar is that it must be easy to integrate, ideally a "plug-and-play" SIP component. It should not impose any "outbound-proxy" configurations on any of the platform's layers and automatically insert itself on the - call flow of successful registrations. - - The script writer can choose between two SIP insertion - mechanisms: either by having the module modify Contact headers - when forwarding registrations, or instruct it to make use of a - Path header (RFC 3327). - -1.3.1. Insertion by Contact (default) + call flows which follow successful registrations. - This insertion mode will mangle the Contact header field values - of all forwarded registration requests, by replacing any - original IP and port of a Contact URI with those of one of the - mid-registrar's listening interfaces. + Regardless of its configured working mode, the mid-registrar + will mangle the Contact header field URIs of all forwarded + REGISTER requests and replace the original "hostname" and + "port" parts of a Contact URI with one of its listening + interfaces. - The mid-registrar will also append a parameter to each Contact - URI ("rid" by default, can be changed through the - contact_match_param module parameter) This URI parameter allows - reply contacts to be matched with request ones. This same - parameter will also be used when routing calls to the users. In - this case, it will be taken from the INVITE's Request-URI. - -1.3.2. Insertion by Path - - Instructs the module to append a "Path" header field to each - forwarded registration request. By recording itself between - each user and the main registrar, the mid-registrar allows - subsequent calls to be properly routed to the called party. + Additionally, in modes "0" and "1", each Contact will be + assigned an unique identifier, which will be utilized in future + contact-based lookup operations. This information will be + included in each forwarded Contact URI. The + contact_id_insertion modparam controls how this information is + included. 1.4. Dependencies @@ -274,10 +259,10 @@ Chapter 1. Admin Guide * when a REGISTER is received, the script writer must call mid_registrar_save() * the mid-registrar will insert itself on the call flow of - all registrations according to the insertion_mode. - * registrations handled by the mid-registrar will - transparently result in a user location update if their - reply status is 2xx. + all registrations according to the contact_id_insertion. + * registrations forwarded by the mid-registrar will + transparently result in a user location update only if the + reply status code from the downstream registrar is 2xx. Each working mode behaves differently, as follows: * 0 (Contact mirroring mode) @@ -296,12 +281,13 @@ Chapter 1. Admin Guide according to outgoing_expires * 2 (AOR throttling mode) AOR throttling is a step beyond "Contact throttling", as - the main registrar is made aware of the network presence of - AORs, rather than Contacts. This behaviour is also made - possible through the outgoing_expires module parameter or - the corresponding parameter to mid_registrar_save(), which - allow the script writer to prolong the life of the - registrations on the way to the main registrar. + the main registrar is only made aware of the network + presence of AORs, rather than Contacts. This behaviour is + also made possible through the outgoing_expires module + parameter or the corresponding parameter to + mid_registrar_save(), which allow the script writer to + prolong the life of the registrations on the way to the + main registrar. In this mode, the mid-registrar will fully replace the Contact set of all forwarded registrations with a single Contact, advertising that the AOR is available to the main @@ -313,19 +299,98 @@ Chapter 1. Admin Guide Example 1.1. Setting the mode module parameter modparam("mid_registrar", "mode", 2) -1.5.2. insertion_mode (integer) +1.5.2. contact_id_insertion (integer) + + Only relevant in a "mirroring" or "contact throttling" mode. + Controls where the additional unique Contact identification + information (64-bit, hex-encoded integer) will be placed within + outgoing Contact header field URIs. Refer to Section 1.3, + “Auto-Insertion Into Future SIP Flows” for more details. + + Possible values are: + * "ct-param" (default) - the contact IDs shall be appended to + outgoing Contact URIs as ";ctid=" parameters. + * "ct-username" - the contact IDs will substitute the + "username" parts of outgoing Contact URIs + + Example 1.2. Setting the contact_id_insertion module parameter +modparam("mid_registrar", "contact_id_insertion", "ct-username") + +1.5.3. contact_id_param (string) + + Only relevant in a "mirroring" or "contact throttling" mode. + Specifies the name of the Contact URI parameter which is used + by the module in order to match contacts and route SIP + requests. + + Default value is “ctid” + + Example 1.3. Setting the contact_id_param module parameter +modparam("mid_registrar", "contact_id_param", "ctid") + +# Example resulting Contact header field: +# Contact: ;expires=18 +0. + +1.5.4. outgoing_expires (integer) + + Only relevant in Contact/AOR throttling modes. Sets a minimal + value for the expiration intervals of egressing contacts. + + Default value is 3600 (seconds) + + Example 1.4. Setting the outgoing_expires module parameter +modparam("mid_registrar", "outgoing_expires", 3600) + +1.5.5. received_avp (string) + + The module will store the value of the AVP configured by this + parameter in the received column of the user location table. It + will leave the column empty if the AVP is empty. The AVP should + contain a SIP URI consisting of the source IP, port, and + protocol of the REGISTER message being processed. + +Note - SIP insertion mode of the module. Refer to Section 1.3, - “Insertion modes” for more details. Possible values are: - * 0 (Insertion by Contact) - * 1 (Insertion by Path) + The value of this parameter should be the same as the value of + corresponding parameter of nathelper module. - Default value is 0 (Insertion by Contact) + Default value is "NULL" (disabled) - Example 1.2. Setting the insertion_mode module parameter -modparam("mid_registrar", "insertion_mode", 1) + Example 1.5. Setting the received_avp module parameter +modparam("mid_registrar", "received_avp", "$avp(rcv)") -1.5.3. min_expires (integer) +1.5.6. received_param (string) + + The name of the parameter that will be appended to Contacts of + 200 OK replies if the received URI is set by nathelper module. + +Note + + The value of this parameter should be the same as the value of + corresponding parameter of nathelper module. + + Default value is "received" + + Example 1.6. Setting the received_param module parameter +modparam("mid_registrar", "received_param", "rcv") + +1.5.7. extra_contact_params_avp (string) + + An AVP specification. This AVP is evaluated during + mid_registrar_save(): if it holds a valid string, its content + be appended to each new Contact URI built by the mid-registrar, + for the outgoing request. + + Default value is None (not used) + + Example 1.7. Setting the extra_contact_params_avp module + parameter +# NB: AVPs are cleared with every new SIP request +modparam("mid_registrar", "extra_contact_params_avp", "$avp(extra_ct_par +ams)") + +1.5.8. min_expires (integer) The minimum expires value of a Contact, values lower than this minimum will be automatically set to the minimum. Value 0 @@ -333,10 +398,10 @@ modparam("mid_registrar", "insertion_mode", 1) Default value is 10 (seconds) - Example 1.3. Setting the min_expires module parameter + Example 1.8. Setting the min_expires module parameter modparam("mid_registrar", "min_expires", 600) -1.5.4. default_expires (integer) +1.5.9. default_expires (integer) If the processed message contains neither Expires HFs nor expires contact parameters, this value will be used as the @@ -344,10 +409,10 @@ modparam("mid_registrar", "min_expires", 600) Default value is 3600 (seconds) - Example 1.4. Setting the default_expires module parameter + Example 1.9. Setting the default_expires module parameter modparam("mid_registrar", "default_expires", 1800) -1.5.5. max_expires (integer) +1.5.10. max_expires (integer) The maximum expires value of a Contact, values higher than this maximum will be automatically set to the maximum. Value 0 @@ -355,31 +420,10 @@ modparam("mid_registrar", "default_expires", 1800) Default value is 3600 (seconds) - Example 1.5. Setting the max_expires module parameter + Example 1.10. Setting the max_expires module parameter modparam("mid_registrar", "max_expires", 7200) -1.5.6. outgoing_expires (integer) - - Only relevant in Contact/AOR throttling modes. Sets a minimal - value for the expiration intervals of egressing contacts. - - Default value is 3600 (seconds) - - Example 1.6. Setting the outgoing_expires module parameter -modparam("mid_registrar", "outgoing_expires", 3600) - -1.5.7. contact_match_param (string) - - Only relevant in "Contact throttling" mode. Specifies the name - of the Contact URI parameter which is used by the module in - order to match contacts and route calls. - - Default value is “rid” - - Example 1.7. Setting the contact_match_param module parameter -modparam("mid_registrar", "contact_match_param", "regid") - -1.5.8. default_q (integer) +1.5.11. default_q (integer) Sets the default "q" value for new contacts. Because OpenSIPS does not support floating point module parameters, the supplied @@ -388,10 +432,10 @@ modparam("mid_registrar", "contact_match_param", "regid") Default value is 0 - Example 1.8. Setting the default_q module parameter + Example 1.11. Setting the default_q module parameter modparam("mid_registrar", "default_q", 380) -1.5.9. tcp_persistent_flag (string) +1.5.12. tcp_persistent_flag (string) Specifies the message flag to be used to control the module behaviour regarding TCP connections. If the flag is set for a @@ -402,11 +446,11 @@ modparam("mid_registrar", "default_q", 380) Default value is -1 (not set) - Example 1.9. Setting the tcp_persistent_flag module parameter + Example 1.12. Setting the tcp_persistent_flag module parameter modparam("mid_registrar", "tcp_persistent_flag", "TCP_PERSIST_REGISTRATI ONS") -1.5.10. realm_prefix (string) +1.5.13. realm_prefix (string) In multi-domain user location scenarios ("use_domain" usrloc module parameter set to "1"), this parameter denotes a prefix @@ -424,10 +468,10 @@ ONS") Default value is NULL (none) - Example 1.10. Setting the realm_prefix module parameter + Example 1.13. Setting the realm_prefix module parameter modparam("mid_registrar", "realm_prefix", "sip.") -1.5.11. case_sensitive (integer) +1.5.14. case_sensitive (integer) If set to 1, then AOR comparison will be case sensitive (as RFC3261 instructs), if set to 0 then AOR comparison will be @@ -435,43 +479,10 @@ modparam("mid_registrar", "realm_prefix", "sip.") Default value is 1 (true) - Example 1.11. Setting the case_sensitive module parameter + Example 1.14. Setting the case_sensitive module parameter modparam("mid_registrar", "case_sensitive", 0) -1.5.12. received_avp (string) - - The module will store the value of the AVP configured by this - parameter in the received column of the user location table. It - will leave the column empty if the AVP is empty. The AVP should - contain a SIP URI consisting of the source IP, port, and - protocol of the REGISTER message being processed. - -Note - - The value of this parameter should be the same as the value of - corresponding parameter of nathelper module. - - Default value is "NULL" (disabled) - - Example 1.12. Setting the received_avp module parameter -modparam("mid_registrar", "received_avp", "$avp(rcv)") - -1.5.13. received_param (string) - - The name of the parameter that will be appended to Contacts of - 200 OK replies if the received URI is set by nathelper module. - -Note - - The value of this parameter should be the same as the value of - corresponding parameter of nathelper module. - - Default value is "received" - - Example 1.13. Setting the received_param module parameter -modparam("mid_registrar", "received_param", "rcv") - -1.5.14. max_contacts (integer) +1.5.15. max_contacts (integer) This parameter can be used to limit the number of contacts per AOR (Address-of-Record) allowed at mid-registrar level. A value @@ -484,24 +495,9 @@ modparam("mid_registrar", "received_param", "rcv") Default value is 0 (disabled) - Example 1.14. Setting the max_contacts module parameter + Example 1.15. Setting the max_contacts module parameter modparam("mid_registrar", "max_contacts", 10) -1.5.15. extra_contact_params_avp (string) - - An AVP specification. This AVP is evaluated during - mid_registrar_save(): if it holds a valid string, its content - be appended to each new Contact URI built by the mid-registrar, - for the outgoing request. - - Default value is None (not used) - - Example 1.15. Setting the extra_contact_params_avp module - parameter -# NB: AVPs are cleared with every new SIP request -modparam("mid_registrar", "extra_contact_params_avp", "$avp(extra_ct_par -ams)") - 1.5.16. retry_after (integer) The mid-registrar can generate 5xx replies to registrations in @@ -560,8 +556,8 @@ modparam("mid_registrar", "gruu_secret", "my_secret") REGISTER request has been answered with 200 OK (absorbed at mid-registrar level). - Depending on the current working mode and insertion_mode, the - function may additionally perform the following series of + Depending on the current working mode and contact_id_insertion, + the function may additionally perform the following series of transformations when relaying REGISTER requests: * in "Contact throttling" mode @@ -576,8 +572,8 @@ modparam("mid_registrar", "gruu_secret", "my_secret") + append a parameter to each Contact URI, which will allow the module to match the reply contacts and also route calls. The name of this URI parameter is - configurable via contact_match_param - + append a "Path" header to the current REGISTER request + configurable via Section 1.5.3, “contact_id_param + (string)” * in "AOR throttling" mode + change the value of the Expires header field to the value of outgoing_expires, if given, otherwise the @@ -586,7 +582,6 @@ modparam("mid_registrar", "gruu_secret", "my_secret") a single Contact header field, which will contain the following SIP URI: "sip:address-of-record@proxy_ip:proxy_port" - + append a "Path" header to the current REGISTER request Meaning of the parameters is as follows: * domain - logical domain within the registrar. If a database @@ -597,21 +592,6 @@ modparam("mid_registrar", "gruu_secret", "my_secret") cache without no DB operation; + 'r' (no Reply) - do not generate a SIP reply to the current REGISTER request. - + 'p0' (Path support - 'off' mode) The Path header is - saved into usrloc, but is never included in the reply. - + 'p1' (Path support - lazy mode) The Path header is - saved into usrloc, but is only included in the reply - if path support is indicated in the registration - request by the “path” option of the “Supported” - header. - + 'p2' (Path support - strict mode) The path header is - only saved into usrloc, if path support is indicated - in the registration request by the “path” option of - the “Supported” header. If no path support is - indicated, the request is rejected with “420 - Bad - Extension” and the header “Unsupported: path” is - included in the reply along with the received “Path” - header. This mode is the one recommended by RFC-3327. + 'v' (path receiVed) if set, the “received” parameter of the first Path URI of a registration is set as received-uri and the NAT branch flag is set for this @@ -684,10 +664,10 @@ if (is_method("REGISTER")) { being optionally created. (depending on the flags parameter) * in "Contact throttling" mode - + extract the contact_match_param from the Request-URI, - derive the actual SIP URI of the destination from it - and set it as the new Request-URI of the INVITE ($ru - variable). + + extract the Section 1.5.3, “contact_id_param (string)” + from the Request-URI, derive the actual SIP URI of the + destination from it and set it as the new Request-URI + of the INVITE ($ru variable). * in "AOR throttling" mode + extract the username (Address-of-Record) from the Request-URI and look up all of its contact bindings diff --git a/modules/mid_registrar/doc/mid_registrar_admin.xml b/modules/mid_registrar/doc/mid_registrar_admin.xml index d4cc28682f3..8ae5d9e5ed2 100644 --- a/modules/mid_registrar/doc/mid_registrar_admin.xml +++ b/modules/mid_registrar/doc/mid_registrar_admin.xml @@ -6,23 +6,25 @@
Overview - The mid_registrar is a mid-component of a SIP platform, - designed to work between end users and the platform's main registration component. + The mid_registrar is a mid-component of a SIP + platform, designed to work between end users and the platform's main + registration component. It opens up new possibilities for leveraging existing infrastructure in order to continue to grow (as subscribers and as registration traffic) while keeping an existing low-resources registrar server. - Acting as a registration front-end to the main SIP registrar, the mid-registrar is able to: + Acting as a registration front-end to the main SIP registrar, the + mid-registrar is able to: - convert incoming high-rate registration traffic into a low-rate variant, - towards the main registrar layer. With proper configuration, it can - absorb over 90% of existing registration traffic while - preserving the back-end's user location state, effectively reducing - resource usage at the respective layer. + convert incoming high-rate registration traffic into a low-rate + variant, towards the main registrar layer. With proper + configuration, it can absorb over 90% of existing registration + traffic while correctly managing the back-end's user location + state, effectively reducing resource usage at the respective layer. @@ -45,12 +47,14 @@
Contact mirroring (default) - In "contact mirroring" mode, the mid-registrar will insert itself - in the registration flow between end user and main registrar only as - a simple proxy registrar, without any other contact processing. The - incoming REGISTER requests will be proxied further to the main - registrar; the registered contact will be stored in the mid-registrar - only on 2xx replies, according to the information returned by the main registrar. + In "contact mirroring" mode, the mid-registrar will only insert itself + in the SIP traffic flow between end user and main registrar by + altering the Contact header field values. See section + for a detailed description of + possible Contact-based insertion modes. The incoming REGISTER requests + will be proxied further to the main registrar; the registered contact + will be stored in the mid-registrar only on 2xx replies, according to + the information returned by the main registrar. A possible usage of this mode, for example, would be to clone @@ -66,33 +70,37 @@ reduce the registration rate on the main registrar side (between mid-registrar and main registrar), while coping with a high registration rate on the end-user side (between end-user and mid-registrar). This - is useful in scenarios were the end-users are very dynamic and short-lived - (like on mobile devices), but the main registrar cannot cope with large traffic. + is useful in scenarios were the end-users are very dynamic and + short-lived (e.g. mobile devices), but the main registrar cannot cope + with large amounts of registration traffic. Traffic conversion is done in a "per-device" - manner, according to each unique SIP Contact header field value. It is achieved by - increasing the "expires" parameter value of each contact, when relaying - registrations to the main registrar. - Once such a registration is completed, subsequent registrations for the same - SIP Contact header field value will be continuously absorbed by the mid-registrar - until, eventually, the lifetime of the remote registration will have decreased - enough that a refresh (i.e. simply forwarding the next REGISTER request) is mandatory. - - - A common occurence is for some SIP User Agents to lose their network connection - (especially when dealing with mobile devices), hence they do not properly de-register - from the mid-registrar. In this case, in order to avoid stale registrations on the - main registrar (which contains SIP contacts with greatly extended lifetimes!), - the mid-registrar will appropriately generate De-REGISTER requests and remove - these contacts from the main registrar's location service as soon as it considers + manner, according to each unique SIP Contact header field value. It is + achieved by increasing the "expires" parameter value of each contact, + when relaying registrations to the main registrar. + Once such a registration is completed, subsequent registrations for the + same SIP Contact header field value will be continuously absorbed by + the mid-registrar until, eventually, the lifetime of the remote + registration will have decreased enough that a refresh (i.e. simply + forwarding the next REGISTER request) is mandatory. + + + A common occurence is for some SIP User Agents to lose their network + connection (especially when dealing with mobile devices), hence they do + not properly de-register from the mid-registrar. In this case, in order + to avoid stale registrations on the main registrar (which contains SIP + contacts with greatly extended lifetimes!), the mid-registrar will + appropriately generate De-REGISTER requests and remove these contacts + from the main registrar's location service as soon as it considers them to have expired. The main practical use for this mode is registration traffic conversion. - By minimizing the strain of processing registrations on the main registrar, - we allow it to dedicate more system resources to critical areas of the - platform, such as advanced SIP calling features and/or media handling. + By minimizing the strain of processing registrations on the main + registrar, we allow it to dedicate more system resources to critical + areas of the platform, such as advanced SIP calling features and/or + media handling.
@@ -148,47 +156,28 @@
-
- Insertion modes +
+ Auto-Insertion Into Future SIP Flows - A defining feature of the mid-registrar is that it must be easy to integrate, - ideally a "plug-and-play" SIP component. It should not impose any - "outbound-proxy" configurations on any of the platform's layers and - automatically insert itself on the call flow of successful registrations. + A defining feature of the mid-registrar is that it must be easy to + integrate, ideally a "plug-and-play" SIP component. It should not + impose any "outbound-proxy" configurations on any of the platform's + layers and automatically insert itself on the call flows which follow + successful registrations. - The script writer can choose between two - SIP insertion mechanisms: either by having the module modify Contact - headers when forwarding registrations, or instruct it to make use - of a Path header (RFC 3327). + Regardless of its configured working , the + mid-registrar will mangle the Contact header field URIs of all + forwarded REGISTER requests and replace the original "hostname" and + "port" parts of a Contact URI with one of its listening interfaces. + + + Additionally, in modes "0" and "1", each Contact will be assigned an + unique identifier, which will be utilized in future contact-based + lookup operations. This information will be included in each forwarded + Contact URI. The modparam + controls how this information is included. -
- Insertion by Contact (default) - - This insertion mode will mangle the Contact header field values - of all forwarded registration requests, by replacing any - original IP and port of a Contact URI with those of one of the - mid-registrar's listening interfaces. - - - The mid-registrar will also append a parameter to each Contact URI - ("rid" by default, can be changed through the - module parameter) - This URI parameter allows reply contacts to be matched with request - ones. This same parameter will also be used when - routing calls to the users. In this case, it will be taken from - the INVITE's Request-URI. - -
-
- Insertion by Path - - Instructs the module to append a "Path" header field to each - forwarded registration request. By recording itself between each - user and the main registrar, the mid-registrar allows subsequent - calls to be properly routed to the called party. - -
@@ -236,7 +225,7 @@
Exported Parameters -
+
<varname>mode</varname> (integer) @@ -258,13 +247,14 @@ the mid-registrar will insert itself on the call flow of all registrations according to the - . + . - registrations handled by the mid-registrar will transparently - result in a user location update if their reply status is 2xx. + registrations forwarded by the mid-registrar will transparently + result in a user location update only if the reply status code from + the downstream registrar is 2xx. @@ -310,8 +300,8 @@ 2 (AOR throttling mode) AOR throttling is a step beyond "Contact throttling", as the main registrar - is made aware of the network presence of AORs, rather than Contacts. This behaviour - is also made possible through the + is only made aware of the network presence of AORs, rather than + Contacts. This behaviour is also made possible through the module parameter or the corresponding parameter to , @@ -340,34 +330,142 @@ modparam("mid_registrar", "mode", 2)
-
- <varname>insertion_mode</varname> (integer) +
+ <varname>contact_id_insertion</varname> (integer) - SIP insertion mode of the module. Refer to - for more details. Possible - values are: + Only relevant in a "mirroring" or "contact throttling" + . Controls where the additional + unique Contact identification information (64-bit, hex-encoded integer) + will be placed within outgoing Contact header field URIs. Refer to + for more details. + + + Possible values are: - - 0 (Insertion by Contact) + "ct-param" (default) - the contact IDs shall + be appended to outgoing Contact URIs as ";ctid=" parameters. - 1 (Insertion by Path) + "ct-username" - the contact IDs will + substitute the "username" parts of outgoing Contact URIs + + Setting the <emphasis>contact_id_insertion</emphasis> module parameter + +modparam("mid_registrar", "contact_id_insertion", "ct-username") + + +
+
+ <varname>contact_id_param</varname> (string) + + Only relevant in a "mirroring" or "contact throttling" + . Specifies the name of the + Contact URI parameter which is used by the module in order to + match contacts and route SIP requests. + + + + Default value is ctid + + + Setting the <emphasis>contact_id_param</emphasis> module parameter + +modparam("mid_registrar", "contact_id_param", "ctid") + +# Example resulting Contact header field: +# Contact: <sip:liviu@10.0.0.10:5060;ctid=619244948763447138>;expires=180. + + +
+
+ <varname>outgoing_expires</varname> (integer) + + Only relevant in Contact/AOR throttling modes. Sets a minimal + value for the expiration intervals of egressing contacts. + - Default value is 0 (Insertion by Contact) + Default value is 3600 (seconds) + + + Setting the <emphasis>outgoing_expires</emphasis> module parameter + +modparam("mid_registrar", "outgoing_expires", 3600) + + +
+
+ <varname>received_avp</varname> (string) + + The module will store the value of the AVP configured by this + parameter in the received column of the user + location table. It will leave the column empty if the AVP is empty. + The AVP should contain a SIP URI consisting of the source IP, port, + and protocol of the REGISTER message being processed. + + + + The value of this parameter should be the same as the value of + corresponding parameter of nathelper module. + + + + Default value is "NULL" (disabled) - Setting the <emphasis>insertion_mode</emphasis> module parameter + Setting the <emphasis>received_avp</emphasis> module parameter + +modparam("mid_registrar", "received_avp", "$avp(rcv)") + + +
+
+ <varname>received_param</varname> (string) + + The name of the parameter that will be appended to Contacts of + 200 OK replies if the received URI is set by nathelper module. + + + + The value of this parameter should be the same as the value of + corresponding parameter of nathelper module. + + + + Default value is "received" + + + Setting the <emphasis>received_param</emphasis> module parameter + +modparam("mid_registrar", "received_param", "rcv") + + +
+
+ <varname>extra_contact_params_avp</varname> (string) + + An AVP specification. This AVP is evaluated during + : + if it holds a valid string, its content be appended to + each new Contact URI built by the mid-registrar, + for the outgoing request. + + + Default value is None (not used) + + + Setting the <emphasis>extra_contact_params_avp</emphasis> module parameter -modparam("mid_registrar", "insertion_mode", 1) +# NB: AVPs are cleared with every new SIP request +modparam("mid_registrar", "extra_contact_params_avp", "$avp(extra_ct_params)")
@@ -417,41 +515,6 @@ modparam("mid_registrar", "default_expires", 1800) Setting the <emphasis>max_expires</emphasis> module parameter modparam("mid_registrar", "max_expires", 7200) - - -
-
- <varname>outgoing_expires</varname> (integer) - - Only relevant in Contact/AOR throttling modes. Sets a minimal - value for the expiration intervals of egressing contacts. - - - - Default value is 3600 (seconds) - - - Setting the <emphasis>outgoing_expires</emphasis> module parameter - -modparam("mid_registrar", "outgoing_expires", 3600) - - -
-
- <varname>contact_match_param</varname> (string) - - Only relevant in "Contact throttling" mode. Specifies the name of the - Contact URI parameter which is used by the module in order to - match contacts and route calls. - - - - Default value is rid - - - Setting the <emphasis>contact_match_param</emphasis> module parameter - -modparam("mid_registrar", "contact_match_param", "regid")
@@ -541,53 +604,6 @@ modparam("mid_registrar", "realm_prefix", "sip.") Setting the <emphasis>case_sensitive</emphasis> module parameter modparam("mid_registrar", "case_sensitive", 0) - - -
-
- <varname>received_avp</varname> (string) - - The module will store the value of the AVP configured by this - parameter in the received column of the user - location table. It will leave the column empty if the AVP is empty. - The AVP should contain a SIP URI consisting of the source IP, port, - and protocol of the REGISTER message being processed. - - - - The value of this parameter should be the same as the value of - corresponding parameter of nathelper module. - - - - Default value is "NULL" (disabled) - - - Setting the <emphasis>received_avp</emphasis> module parameter - -modparam("mid_registrar", "received_avp", "$avp(rcv)") - - -
-
- <varname>received_param</varname> (string) - - The name of the parameter that will be appended to Contacts of - 200 OK replies if the received URI is set by nathelper module. - - - - The value of this parameter should be the same as the value of - corresponding parameter of nathelper module. - - - - Default value is "received" - - - Setting the <emphasis>received_param</emphasis> module parameter - -modparam("mid_registrar", "received_param", "rcv")
@@ -611,26 +627,6 @@ modparam("mid_registrar", "received_param", "rcv") Setting the <emphasis>max_contacts</emphasis> module parameter modparam("mid_registrar", "max_contacts", 10) - - -
-
- <varname>extra_contact_params_avp</varname> (string) - - An AVP specification. This AVP is evaluated during - : - if it holds a valid string, its content be appended to - each new Contact URI built by the mid-registrar, - for the outgoing request. - - - Default value is None (not used) - - - Setting the <emphasis>extra_contact_params_avp</emphasis> module parameter - -# NB: AVPs are cleared with every new SIP request -modparam("mid_registrar", "extra_contact_params_avp", "$avp(extra_ct_params)")
@@ -716,8 +712,8 @@ modparam("mid_registrar", "gruu_secret", "my_secret") Depending on the current working - and - , + and + , the function may additionally perform the following series of transformations when relaying REGISTER requests: @@ -751,12 +747,7 @@ modparam("mid_registrar", "gruu_secret", "my_secret") allow the module to match the reply contacts and also route calls. The name of this URI parameter is configurable via - - - - - - append a "Path" header to the current REGISTER request + @@ -781,11 +772,6 @@ modparam("mid_registrar", "gruu_secret", "my_secret") which will contain the following SIP URI: "sip:address-of-record@proxy_ip:proxy_port" - - - append a "Path" header to the current REGISTER request - - @@ -833,32 +819,6 @@ modparam("mid_registrar", "gruu_secret", "my_secret") !--> - - 'p0' (Path support - 'off' mode) - The Path header is saved into usrloc, but is never - included in the reply. - - - - 'p1' (Path support - lazy mode) - The Path header is saved into usrloc, but is only included - in the reply if path support is indicated in the - registration request by the path option - of the Supported header. - - - - 'p2' (Path support - strict mode) - The path header is only saved into usrloc, if path support - is indicated in the registration request by the - path option of the Supported - header. If no path support is indicated, the request is - rejected with 420 - Bad Extension and the - header Unsupported: path is included in - the reply along with the received Path - header. This mode is the one recommended by RFC-3327. - - 'v' (path receiVed) if set, the received parameter of the first Path @@ -952,7 +912,7 @@ if (is_method("REGISTER")) { Depending on the current working - , + , the function will behave as follows: @@ -978,7 +938,7 @@ if (is_method("REGISTER")) { - extract the + extract the from the Request-URI, derive the actual SIP URI of the destination from it and set it as the new Request-URI of the INVITE ($ru variable). diff --git a/modules/mid_registrar/lookup.c b/modules/mid_registrar/lookup.c index ef074e67e57..426db485c95 100644 --- a/modules/mid_registrar/lookup.c +++ b/modules/mid_registrar/lookup.c @@ -66,48 +66,6 @@ unsigned int nbranches; static char urimem[MAX_BRANCHES-1][MAX_URI_SIZE]; static str branch_uris[MAX_BRANCHES-1]; -int get_match_token(str *uri, str *out_tok, struct sip_uri *out_puri, int *out_idx) -{ - struct sip_uri puri; - int i; - - if (parse_uri(uri->s, uri->len, &puri) < 0) { - LM_ERR("failed to parse contact <%.*s>\n", uri->len, uri->s); - return -1; - } - - if (matching_mode == MATCH_BY_PARAM) { - for (i = 0; i < puri.u_params_no; i++) { - if (!str_strcmp(&puri.u_name[i], &matching_param)) { - *out_tok = puri.u_val[i]; - if (out_idx) - *out_idx = i; - break; - } - } - - if (!out_tok->s || out_tok->len <= 0) { - LM_ERR("a Contact from main registrar (%.*s) is missing the '%.*s'" - " hf parameter\n", uri->len, uri->s, - matching_param.len, matching_param.s); - return -1; - } - } else { - *out_tok = puri.user; - - if (!out_tok->s || out_tok->len <= 0) { - LM_ERR("missing SIP user in Contact from main registrar (%.*s)\n", - uri->len, uri->s); - return -1; - } - } - - if (out_puri) - *out_puri = puri; - - return 0; -} - int mid_reg_lookup(struct sip_msg* req, char* _t, char* _f, char* _s) { unsigned int flags; @@ -228,7 +186,7 @@ int mid_reg_lookup(struct sip_msg* req, char* _t, char* _f, char* _s) *(ua+re_len) = tmp; } - if (reg_mode != MID_REG_THROTTLE_AOR && insertion_mode == INSERT_BY_CONTACT) { + if (reg_mode != MID_REG_THROTTLE_AOR) { if (parse_uri(uri.s, uri.len, &puri) < 0) { LM_ERR("failed to parse R-URI <%.*s>, ci: %.*s\n", uri.len, uri.s, req->callid->body.len, req->callid->body.s); diff --git a/modules/mid_registrar/lookup.h b/modules/mid_registrar/lookup.h index 6a0f6571f05..2879f47e3e8 100644 --- a/modules/mid_registrar/lookup.h +++ b/modules/mid_registrar/lookup.h @@ -36,6 +36,4 @@ int mid_reg_lookup(struct sip_msg* req, char* _t, char* _f, char* _s); -int get_match_token(str *uri, str *out_tok, struct sip_uri *out_puri, int *out_idx); - #endif /* __MID_REG_LOOKUP_ */ diff --git a/modules/mid_registrar/mid_registrar.c b/modules/mid_registrar/mid_registrar.c index 7a2d0454960..ed7cb443fa4 100644 --- a/modules/mid_registrar/mid_registrar.c +++ b/modules/mid_registrar/mid_registrar.c @@ -111,9 +111,6 @@ char* realm_pref = ""; str realm_prefix; int reg_use_domain = 0; -#define is_insertion_mode(v) (v == INSERT_BY_CONTACT || v == INSERT_BY_PATH) -#define insertion_mode_str(v) (v == INSERT_BY_CONTACT ? "by Contact" : "by Path") - static int mod_init(void); static int domain_fixup(void** param); @@ -131,21 +128,10 @@ enum mid_reg_mode reg_mode = MID_REG_MIRROR; unsigned int outgoing_expires = 3600; -#define is_matching_mode(v) (v == MATCH_BY_PARAM || v == MATCH_BY_USER) -#define matching_mode_str(v) (v == MATCH_BY_PARAM ? "by uri param" : "by user") - -enum mid_reg_insertion_mode insertion_mode = INSERT_BY_CONTACT; - -//TODO: remove the Path-based mid-registrar logic starting with OpenSIPS 2.4 -enum mid_reg_matching_mode matching_mode = MATCH_BY_PARAM; +enum mid_reg_insertion_mode ctid_insertion = MR_REPLACE_USER; +char *mp_ctid_insertion = "ct-param"; -/* - * TODO: get rid of this (no pun intended) - * Only used in INSERT_BY_CONTACT insertion mode - * Allows us to match the request contact set with the reply contact set, - * which contains rewritten Contact header field domains - */ -str matching_param = str_init("rid"); +str ctid_param = str_init("ctid"); static cmd_export_t cmds[] = { { "mid_registrar_save", (cmd_function)mid_reg_save, 1, @@ -182,8 +168,8 @@ static param_export_t mod_params[] = { { "gruu_secret", STR_PARAM, &gruu_secret.s }, { "disable_gruu", INT_PARAM, &disable_gruu }, { "outgoing_expires", INT_PARAM, &outgoing_expires }, - { "insertion_mode", INT_PARAM, &insertion_mode }, - { "contact_match_param", STR_PARAM, &matching_param.s }, + { "contact_id_insertion", STR_PARAM, &mp_ctid_insertion }, + { "contact_id_param", STR_PARAM, &ctid_param.s }, { "extra_contact_params_avp", STR_PARAM, &extra_ct_params_str.s }, { 0,0,0 } }; @@ -294,20 +280,14 @@ static int mod_init(void) return -1; } - if (!is_insertion_mode(insertion_mode)) { - insertion_mode = INSERT_BY_PATH; - LM_WARN("bad \"insertion_mode\" (%d) - using '%s' as a default\n", - insertion_mode, insertion_mode_str(insertion_mode)); + if (!strncasecmp(mp_ctid_insertion, STR_L("ct-param"))) { + ctid_insertion = MR_APPEND_PARAM; + } else if (!strncasecmp(mp_ctid_insertion, STR_L("ct-user"))) { + ctid_insertion = MR_REPLACE_USER; } else { - LM_DBG("insertion mode: '%s'\n", insertion_mode_str(insertion_mode)); - } - - if (!is_matching_mode(matching_mode)) { - matching_mode = MATCH_BY_PARAM; - LM_WARN("bad \"matching_mode\" (%d) - using '%s' as a default\n", - matching_mode, matching_mode_str(matching_mode)); - } else { - LM_DBG("contact matching mode: '%s'\n", matching_mode_str(matching_mode)); + LM_WARN("bad 'contact_id_insertion' (%s) - using 'ct-param' as a " + "default\n", mp_ctid_insertion); + ctid_insertion = MR_APPEND_PARAM; } if (min_expires > default_expires) { @@ -356,7 +336,7 @@ static int mod_init(void) tcp_persistent_flag = get_flag_id_by_name(FLAG_TYPE_MSG, tcp_persistent_flag_s); tcp_persistent_flag = (tcp_persistent_flag != -1) ? (1 << tcp_persistent_flag) : 0; - matching_param.len = strlen(matching_param.s); + ctid_param.len = strlen(ctid_param.s); if (reg_mode != MID_REG_MIRROR) { if (ul_api.register_ulcb( @@ -497,12 +477,6 @@ void mri_free(struct mid_reg_info *mri) if (mri->user_agent.s) shm_free(mri->user_agent.s); - if (mri->path.s) - shm_free(mri->path.s); - - if (mri->path_received.s) - shm_free(mri->path_received.s); - free_ct_mappings(&mri->ct_mappings); #ifdef EXTRA_DEBUG diff --git a/modules/mid_registrar/mid_registrar.h b/modules/mid_registrar/mid_registrar.h index 76d5cf1284a..76068dc44e2 100644 --- a/modules/mid_registrar/mid_registrar.h +++ b/modules/mid_registrar/mid_registrar.h @@ -52,14 +52,8 @@ enum mid_reg_mode { }; enum mid_reg_insertion_mode { - INSERT_BY_CONTACT, - INSERT_BY_PATH, -}; - -//TODO: remove the Path-based mid-registrar logic starting with OpenSIPS 2.4 -enum mid_reg_matching_mode { - MATCH_BY_PARAM, - MATCH_BY_USER, + MR_REPLACE_USER, + MR_APPEND_PARAM, }; struct ct_mapping { @@ -116,8 +110,6 @@ struct mid_reg_info { /* ucontact_info dup'ed fields */ str user_agent; - str path_received; - str path; unsigned int ul_flags; unsigned int cflags; diff --git a/modules/mid_registrar/save.c b/modules/mid_registrar/save.c index cd3b975f07b..cf28b5841a2 100644 --- a/modules/mid_registrar/save.c +++ b/modules/mid_registrar/save.c @@ -50,12 +50,10 @@ #include "../../data_lump.h" #include "../../data_lump_rpl.h" -#include "../../lib/path.h" #include "../../lib/reg/ci.h" #include "../../lib/reg/sip_msg.h" #include "../../lib/reg/rerrno.h" #include "../../lib/reg/regtime.h" -#include "../../lib/reg/path.h" #include "../../trim.h" @@ -508,7 +506,6 @@ int dup_req_info(struct sip_msg *req, struct mid_reg_info *mri) struct ct_mapping *ctmap; unsigned int allowed; str *ua, no_ua = str_init("n/a"); - str path, path_received = {NULL, 0}; if (parse_headers(req, HDR_USERAGENT_F, 0) != -1 && req->user_agent && req->user_agent->body.len > 0 && @@ -525,31 +522,6 @@ int dup_req_info(struct sip_msg *req, struct mid_reg_info *mri) mri->cflags = getb0flags(req); - shm_str_clean(&mri->path); - shm_str_clean(&mri->path_received); - - if (mri->reg_flags & REG_SAVE_PATH_FLAG) { - if (build_path_vector(req, &path, &path_received, mri->reg_flags) < 0) { - rerrno = R_PARSE_PATH; - return -1; - } - - if (path.len && path.s) { - if (shm_str_dup(&mri->path, &path) != 0) { - LM_ERR("oom\n"); - return -1; - } - } - - if (path_received.len && path_received.s) { - mri->cflags |= ul_api.nat_flag; - if (shm_str_dup(&mri->path_received, &path_received) != 0) { - LM_ERR("oom\n"); - return -1; - } - } - } - if (req && parse_allow(req) != -1) allowed = get_allow_methods(req); else @@ -621,7 +593,6 @@ void mid_reg_req_fwded(struct cell *t, int type, struct tmcb_params *params) { struct sip_msg *req = params->req; struct mid_reg_info *mri = *(struct mid_reg_info **)(params->param); - str user = {NULL, 0}; str *next_hop = NULL; if (mri->sip_state == SIP_REQ_OUT) { @@ -682,17 +653,11 @@ void mid_reg_req_fwded(struct cell *t, int type, struct tmcb_params *params) return; } - if (insertion_mode == INSERT_BY_PATH) { - if (prepend_path(req, &user, 0, 0)) - LM_ERR("failed to append Path header for aor '%.*s'!\n", - mri->aor.len, mri->aor.s); - } else { - if (reg_mode == MID_REG_MIRROR || reg_mode == MID_REG_THROTTLE_CT) { - LM_DBG("fixing Contact URI ...\n"); - if (overwrite_req_contacts(req, mri)) { - LM_ERR("failed to overwrite Contact URIs\n"); - return; - } + if (reg_mode == MID_REG_MIRROR || reg_mode == MID_REG_THROTTLE_CT) { + LM_DBG("fixing Contact URI ...\n"); + if (overwrite_req_contacts(req, mri)) { + LM_ERR("failed to overwrite Contact URIs\n"); + return; } } @@ -933,52 +898,6 @@ static contact_t *match_contact(str *username, struct sip_msg *msg) return NULL; } -/** - * TODO: remove the Path-based mid-registrar logic starting with OpenSIPS 2.4 - */ -static int _match_contact_path_mode(struct sip_uri *ct, struct sip_msg *msg, contact_t **out) -{ - contact_t *c; - struct sip_uri uri, match_uri; - str match_tok, dec_uri; - int i; - - for (c = get_first_contact2(msg); c; c = get_next_contact2(c)) { - LM_DBG("it='%.*s'\n", c->uri.len, c->uri.s); - - if (insertion_mode == INSERT_BY_PATH) { - dec_uri = c->uri; - } else { - if (get_match_token(&c->uri, &match_tok, &uri, &i) != 0) { - LM_ERR("failed to get match token\n"); - return -1; - } - - if (decrypt_str(&match_tok, &dec_uri)) { - LM_ERR("failed to decrypt matching Contact param (%.*s=%.*s)\n", - matching_param.len, matching_param.s, - match_tok.len, match_tok.s); - return -1; - } - } - - if (parse_uri(dec_uri.s, dec_uri.len, &match_uri) < 0) { - pkg_free(dec_uri.s); - LM_ERR("failed to parse decrypted uri <%.*s>\n", - dec_uri.len, dec_uri.s); - return -1; - } - - /* try to match the request Contact with a Contact from the reply */ - if (compare_uris(NULL, &match_uri, NULL, ct) == 0) { - *out = c; - return 0; - } - } - - return -1; -} - /** * Ensures that a given @msg includes all registering contact usernames from * the @ct_mappings list. @@ -998,234 +917,6 @@ static int validate_msg_contacts(struct sip_msg *msg, return 0; } - -/** - * TODO: remove the Path-based mid-registrar logic starting with OpenSIPS 2.4 - */ -int _replace_response_expires_path_mode(struct sip_msg *msg, contact_t *ct, int expires) -{ - struct lump *lump; - int len; - char *p; - - if (!ct->expires) { - LM_DBG("adding expires, ct '%.*s' with %d, %p -> %p\n", - ct->uri.len, ct->uri.s, expires, msg->buf, msg->buf+msg->len); - - lump = anchor_lump(msg, ct->name.s + ct->len - msg->buf, HDR_OTHER_T); - if (!lump) { - LM_ERR("oom\n"); - return -1; - } - - p = pkg_malloc(20); - if (!p) - return -1; - - len = sprintf(p, ";expires=%d", expires); - } else { - LM_DBG("replacing expires, ct '%.*s' '%.*s' with %d, %p -> %p (%p)\n", - ct->uri.len, ct->uri.s, ct->expires->body.len, - ct->expires->body.s, expires, msg->buf, msg->buf+msg->len, - ct->expires->body.s); - - lump = del_lump(msg, ct->expires->body.s - msg->buf, ct->expires->body.len, - HDR_EXPIRES_T); - if (!lump) { - LM_ERR("oom\n"); - return -1; - } - - p = pkg_malloc(11); - if (!p) - return -1; - - len = sprintf(p, "%d", expires); - } - - if (!insert_new_lump_after(lump, p, len, HDR_OTHER_T)) { - LM_ERR("insert_new_lump_after() failed!\n"); - return -1; - } - - return 0; -} - -/** - * TODO: remove the Path-based mid-registrar logic starting with OpenSIPS 2.4 - */ -static inline int _save_rpl_contacts_path_mode(struct sip_msg *req, struct sip_msg* rpl, - struct mid_reg_info *mri, str* _a) -{ - struct mid_reg_info *cti; - ucontact_info_t* ci = NULL; - ucontact_t* c; - urecord_t *r; - contact_t *_c = NULL, *__c; - unsigned int cflags; - int e, e_out; - int e_max = 0; - int tcp_check = 0; - int remove_exp_hf = 1; - struct sip_uri uri; - str ct_uri; - - cflags = (mri->reg_flags®_SAVE_MEMORY_FLAG)?FL_MEM:FL_NONE; - if (is_tcp_based_proto(req->rcv.proto) && (req->flags & tcp_persistent_flag)) { - tcp_check = 1; - } - - ul_api.lock_udomain(mri->dom, &mri->aor); - ul_api.get_urecord(mri->dom, &mri->aor, &r); - - if (!r) { - if (ul_api.insert_urecord(mri->dom, _a, &r, 0) < 0) { - rerrno = R_UL_NEW_R; - LM_ERR("failed to insert new record structure\n"); - goto error; - } - } - - LM_DBG("running\n"); - - for (__c = get_first_contact(req); __c; __c = get_next_contact(__c)) { - /* calculate expires */ - calc_contact_expires(req, __c->expires, &e, 1); - - if (parse_uri(__c->uri.s, __c->uri.len, &uri) < 0) { - LM_ERR("failed to parse contact <%.*s>\n", - __c->uri.len, __c->uri.s); - goto out; - } - - LM_DBG("REQ ct: [name='%.*s', uri='%.*s']\n", - uri.user.len, uri.user.s, __c->uri.len, __c->uri.s); - - if (_match_contact_path_mode(&uri, rpl, &_c) != 0) { - if (e != 0) { - LM_ERR("Contact '%.*s' not found in reply from main registrar!\n", - __c->uri.len, __c->uri.s); - goto out; - } - - /* Contact deleted on main registrar! We can also delete it now! */ - goto update_usrloc; - } - - calc_contact_expires(rpl, _c->expires, &e_out, 1); - if (!_c->expires) - remove_exp_hf = 0; - - LM_DBG(" >> REGISTER %ds ------- %ds 200 OK <reg_flags); - if (ci == NULL) { - LM_ERR("failed to extract contact info\n"); - goto error; - } - ci->expires_out = e_out; - - if ((r->contacts==0 || - ul_api.get_ucontact(r, &__c->uri, ci->callid, ci->cseq+1, &c)!=0) && e > 0) { - LM_DBG("INSERTING .....\n"); - LM_DBG(":: inserting contact with expires %lu\n", ci->expires); - - if (reg_mode != MID_REG_MIRROR) { - cti = mri_dup(mri); - ct_uri.len = _c->uri.len; - ct_uri.s = _c->uri.s; - - shm_str_dup(&cti->ct_uri, &ct_uri); - - cti->expires = e; - cti->expires_out = e_out; - cti->last_reg_ts = get_act_time(); - set_ct(cti); - } - - if (ul_api.insert_ucontact( r, &__c->uri, ci, &c, 0) < 0) { - rerrno = R_UL_INS_C; - LM_ERR("failed to insert contact\n"); - goto error; - } - - set_ct(NULL); - - } else if (c != NULL) { - if (e == 0) { - if (ul_api.delete_ucontact(r, c, 0) < 0) { - rerrno = R_UL_UPD_C; - LM_ERR("failed to update contact\n"); - goto error; - } - continue; - } - - LM_DBG("UPDATING .....\n"); - if (reg_mode != MID_REG_MIRROR) { - mri->expires_out = e_out; - set_ct(mri); - } - - if (ul_api.update_ucontact( r, c, ci, 0) < 0) { - rerrno = R_UL_UPD_C; - LM_ERR("failed to update contact\n"); - goto error; - } - - set_ct(NULL); - } - - if (tcp_check) { - /* parse contact uri to see if transport is TCP */ - if (parse_uri( __c->uri.s, __c->uri.len, &uri)<0) { - LM_ERR("failed to parse contact <%.*s>\n", - __c->uri.len, __c->uri.s); - } else if ( is_tcp_based_proto(uri.proto) ) { - if (e_max) { - LM_WARN("multiple TCP contacts on single REGISTER\n"); - if (e_out>e_max) e_max = e_out; - } else { - e_max = e_out; - } - } - } - } - - if (r) { - ul_api.release_urecord(r, 0); - } - - if (remove_exp_hf) - remove_expires_hf(rpl); - - if ( tcp_check && e_max>0 ) { - e_max -= get_act_time(); - trans_set_dst_attr( &req->rcv, DST_FCNTL_SET_LIFETIME, - (void*)(long)(e_max + 10) ); - } - - ul_api.unlock_udomain(mri->dom, &mri->aor); - return 0; -error: - if (r) - ul_api.delete_urecord(mri->dom, _a, r, 0); -out: - ul_api.unlock_udomain(mri->dom, &mri->aor); - return -1; -} - int append_contacts(ucontact_t *contacts, struct sip_msg *msg) { struct lump *anchor; @@ -1288,11 +979,9 @@ struct ucontact_info *mid_reg_pack_ci(struct sip_msg *req, struct sip_msg *rpl, ci.sock = req->rcv.bind_address; ci.user_agent = &mri->user_agent; - ci.path = &mri->path; ci.last_modified = get_act_time(); ci.flags = mri->ul_flags; ci.cflags = mri->cflags; - ci.received = mri->path_received; ci.expires = ctmap->expires + get_act_time(); ci.q = ctmap->q; @@ -1775,13 +1464,6 @@ void mid_reg_resp_in(struct cell *t, int type, struct tmcb_params *params) update_act_time(); - /* TODO: the Path code / SHM req parsing is broken, leaky and deprecated, - * delete starting with 2.4! */ - //if (parse_reg_headers(req) != 0) { - // LM_ERR("failed to parse req headers\n"); - // goto out_free; - //} - if (parse_reg_headers(rpl) != 0) { LM_ERR("failed to parse rpl headers\n"); goto out; @@ -1793,17 +1475,9 @@ void mid_reg_resp_in(struct cell *t, int type, struct tmcb_params *params) } if (reg_mode == MID_REG_MIRROR || reg_mode == MID_REG_THROTTLE_CT) { - /* TODO: the Path code is deprecated, delete starting with 2.4! */ - if (insertion_mode == INSERT_BY_PATH) { - if (_save_rpl_contacts_path_mode(req, rpl, mri, &mri->aor)) { - LM_ERR("failed to process rpl contacts for AoR '%.*s'\n", - mri->aor.len, mri->aor.s); - } - } else { - if (save_restore_rpl_contacts(req, rpl, mri, &mri->aor)) { - LM_ERR("failed to process rpl contacts for AoR '%.*s'\n", - mri->aor.len, mri->aor.s); - } + if (save_restore_rpl_contacts(req, rpl, mri, &mri->aor)) { + LM_ERR("failed to process rpl contacts for AoR '%.*s'\n", + mri->aor.len, mri->aor.s); } } else if (reg_mode == MID_REG_THROTTLE_AOR) { if (save_restore_req_contacts(req, rpl, mri, &mri->aor)) { @@ -1927,7 +1601,6 @@ static int add_retry_after(struct sip_msg* _m) #define PATH "Path: " #define PATH_LEN (sizeof(PATH) - 1) - static int add_path(struct sip_msg* _m, str* _p) { char* buf; diff --git a/str.h b/str.h index 04bca47c531..62cb89f5d9c 100644 --- a/str.h +++ b/str.h @@ -78,4 +78,6 @@ static inline str *str_cpy(str *dest, const str *src) return dest; } +#define STR_L(s) s, strlen(s) + #endif