summaryrefslogtreecommitdiff
path: root/include
AgeCommit message (Collapse)Author
2016-05-03res_pjsip/AMI: add contact.updated eventAlexei Gradinari
With the old SIP module AMI sends PeerStatus event on every successfully REGISTER requests, ie, on start registration, update registration and stop registration. With PJSIP AMI sends ContactStatus only when status is changed. Regarding registration: on start registration - Created on stop registration - Removed but on update registration nothing This patch added contact.updated event. ASTERISK-25904 Change-Id: I8fad8aae9305481469c38d2146e1ba3a56d3108f
2016-05-03Merge "pjsip: Added "reg_server" to contacts."zuul
2016-05-02pjsip: Added "reg_server" to contacts.Alexei Gradinari
If the Asterisk system name is set in asterisk.conf, it will be stored into the "reg_server" field in the ps_contacts table to facilitate multi-server setups. ASTERISK-25931 Change-Id: Ia8f6bd2267809c78753b52bcf21835b9b59f4cb8
2016-04-29res_pjsip_exten_state: Create PUBLISH messages.Richard Mudgett
Create PUBLISH messages to update a third party when an extension state changes because of either a device or presence state change. A configuration example: [exten-state-publisher] type=outbound-publish server_uri=sip:instance1@172.16.10.2 event=presence ; Optional regex for context filtering, if specified only extension state ; for contexts matching the regex will cause a PUBLISH to be sent. @context=^users ; Optional regex for extension filtering, if specified only extension ; state for extensions matching the regex will cause a PUBLISH to be sent. @exten=^[0-9]* ; Required body type for the PUBLISH message. ; ; Supported values are: ; application/pidf+xml ; application/xpidf+xml ; application/cpim-pidf+xml ; application/dialog-info+xml (Planned support but not yet) @body=application/pidf+xml The '@' extended variables are used because the implementation can't extend the outbound publish type as it is provided by the outbound publish module. That means you either have to use extended variables, or implement some sort of custom extended variable thing in the outbound publish module. Another option would be to refactor that stuff to have an option which specifies the use of an alternate implementation's configuration and then have that passed to the implementation. JColp opted for the extended variables method originally. ASTERISK-25972 #close Change-Id: Ic0dab4022f5cf59302129483ed38398764ee3cca
2016-04-29Merge "res_pjsip_exten_state: Check if body generator is available."Joshua Colp
2016-04-28Merge "res_pjsip_pubsub.h: Fix doxygen association."zuul
2016-04-28res_pjsip_exten_state: Check if body generator is available.Richard Mudgett
When starting the extension state publishers, check if the requested message body generator is available. If not available give error message and skip starting that publisher. * res_pjsip_pubsub.c: Create new API if type/subtype generator registered. * res_pjsip_exten_state.c: Use new body generator API for validation. ASTERISK-25922 Change-Id: I4ad69200666e3cc909d4619e3c81042d7f9db25c
2016-04-28res_pjsip_pubsub.h: Fix doxygen association.Richard Mudgett
Change-Id: I110d3e3572598289fcd4215d966cf0c858f98632
2016-04-27res_pjsip: Add ability to identify by Authorization usernameGeorge Joseph
A feature of chan_sip that service providers relied upon was the ability to identify by the Authorization username. This is most often used when customers have a PBX that needs to register rather than identify by IP address. From my own experiance, this is pretty common with small businesses who otherwise don't need a static IP. In this scenario, a register from the customer's PBX may succeed because From will usually contain the PBXs account id but an INVITE will contain the caller id. With nothing recognizable in From, the service provider's Asterisk can never match to an endpoint and the INVITE just stays unauthorized. The fixes: A new value "auth_username" has been added to endpoint/identify_by that will use the username and digest fields in the Authorization header instead of username and domain in the the From header to match an endpoint, or the To header to match an aor. This code as added to res_pjsip_endpoint_identifier_user rather than creating a new module. Although identify_by was always a comma-separated list, there was only 1 choice so order wasn't preserved. So to keep the order, a vector was added to the end of ast_sip_endpoint. This is only used by res_pjsip_registrar to find the aor. The res_pjsip_endpoint_identifier_* modules are called in globals/endpoint_identifier_order. Along the way, the logic in res_pjsip_registrar was corrected to match most-specific to least-specific as res_pjsip_endpoint_identifier_user does. The order is: username@domain username@domain_alias username Auth by username does present 1 problem however, the first INVITE won't have an Authorization header so the distributor, not finding a match on anything, sends a securty_alert. It still sends a 401 with a challenge so the next INVITE will have the Authorization header and presumably succeed. As a result though, that first security alert is actually a false alarm. To address this, a new feature has been added to pjsip_distributor that keeps track of unidentified requests and only sends the security alert if a configurable number of unidentified requests come from the same IP in a configurable amout of time. Those configuration options have been added to the global config object. This feature is only used when auth_username is enabled. Finally, default_realm was added to the globals object to replace the hard coded "asterisk" used when an endpoint is not yet identified. The testsuite tests all pass but new tests are forthcoming for this new feature. ASTERISK-25835 #close Reported-by: Ross Beer Change-Id: I30ba62d208e6f63439600916fcd1c08a365ed69d
2016-04-27Merge "res_pjsip: disable multi domain to improve realtime performace"Joshua Colp
2016-04-27Merge "res_pjsip: Add serialized scheduler (res_pjsip/pjsip_scheduler.c)"zuul
2016-04-27res_pjsip: disable multi domain to improve realtime performaceAlexei Gradinari
This patch added new global pjsip option 'disable_multi_domain'. Disabling Multi Domain can improve Realtime performance by reducing number of database requests. ASTERISK-25930 #close Change-Id: I2e7160f3aae68475d52742107949a799aa2c7dc7
2016-04-26Merge changes from topic 'system_stress_patches'Joshua Colp
* changes: test_message.c: Wait longer in case dialplan also processes the test message. Manager: Short circuit AMI message processing. manager.c: Eliminate most RAII_VAR usage.
2016-04-25Merge "Bridge system: Fix memory leaks and double frees on impart failure."zuul
2016-04-25Merge "bridge_softmix.c: Fix crash if channel fails to join mixing tech."zuul
2016-04-22Merge "bridge: Hold off more than one imparting channel at a time."zuul
2016-04-22Bridge system: Fix memory leaks and double frees on impart failure.Richard Mudgett
You cannot reference the passed in features struct after calling ast_bridge_impart(). Even if the call fails. Change-Id: I902b88ba0d5d39520e670fb635078a367268ea21
2016-04-22bridge_softmix.c: Fix crash if channel fails to join mixing tech.Richard Mudgett
softmix_bridge_join() failed because of an allocation failure. To address this, the softmix bridge technology now checks if the channel failed to join softmix successfully. In addition, the bridge now begins the process of kicking the channel out of the bridge so we don't have channels partially in the bridge for very long. * Fix the test_channel_feature_hooks.c unit tests. The test channel must have a valid codec to join the simple_bridge technology. This patch makes joining a bridge more strict by not allowing partially joined channels to remain in the bridge. Change-Id: I97e2ade6a2bcd1214f24fb839fda948825b61a2b
2016-04-22Manager: Short circuit AMI message processing.Richard Mudgett
Improve AMI message processing performance if there are no consumers listening for the messages. We now skip creating the AMI event message text strings. Change-Id: I7b22fc5ec4e500d00635c1a467aa8ea68a1bb2b3
2016-04-20bridge: Hold off more than one imparting channel at a time.Richard Mudgett
An earlier patch blocked the ast_bridge_impart() call until the channel either entered the target bridge or it failed. Unfortuantely, if the target bridge is stasis and the imprted channel is not a stasis channel, stasis bounces the channel out of the bridge to come back into the bridge as a proper stasis channel. When the channel is bounced out, that released the block on ast_bridge_impart() to continue. If the impart was a result of a transfer, then it became a race to see if the swap channel would get hung up before the imparted channel could come back into the stasis bridge. If the imparted channel won then everything is fine. If the swap channel gets hung up first then the transfer will fail because the swap channel is leaving the bridge. * Allow a chain of ast_bridge_impart()'s to happen before any are unblocked to prevent the race condition described above. When the channel finally joins the bridge or completely fails to join the bridge then the ast_bridge_impart() instances are unblocked. ASTERISK-25947 Reported by: Richard Mudgett ASTERISK-24649 Reported by: John Bigelow ASTERISK-24782 Reported by: John Bigelow Change-Id: I8fef369171f295f580024ab4971e95c799d0dde1
2016-04-14res_pjsip: Add serialized scheduler (res_pjsip/pjsip_scheduler.c)George Joseph
There are several places that do scheduled tasks or periodic housecleaning, each with its own implementation: * res_pjsip_keepalive has a thread that sends keepalives. * pjsip_distributor has a thread that cleans up expired unidentified requests. * res_pjsip_registrar_expire has a thread that cleans up expired contacts. * res_pjsip_pubsub uses ast_sched directly and then calls ast_sip_push_task. * res_pjsip_sdp_rtp also uses ast_sched to send keepalives. There are also places where we should be doing scheduled work but aren't. A good example are the places we have sorcery observers to start registration or qualify. These don't work when changes are made to a backend database without a pjsip reload. We need to check periodically. As a first step to solving these issues, a new ast_sip_sched facility has been created. ast_sip_sched wraps ast_sched but only uses ast_sched as a scheduled queue. When a task is ready to run, ast_sip_task_pusk is called for it. This ensures that the task is executed in a PJLIB registered thread and doesn't hold up the ast_sched thread so it can immediately continue processing the queue. The serializer used by ast_sip_sched is one of your choosing or a random one from the res_pjsip pool if you don't choose one. Another feature is the ability to automatically clean up the task_data when the task expires (if ever). If it's an ao2 object, it will be dereferenced, if it's a malloc'd object it will be freed. This is selectable when the task is scheduled. Even if you choose to not auto dereference an ao2 task data object, the scheduler itself maintains a reference to it while the task is under it's control. This prevents the data from disappearing out from under the task. There are two scheduling models. AST_SIP_SCHED_TASK_PERIODIC specifies that the invocations of the task occur at the specific interval. That is, every "interval" milliseconds, regardless of how long the task takes. If the task takes longer than the interval, it will be scheduled at the next available multiple of interval. For exmaple: If the task has an interval of 60 secs and the task takes 70 secs (it better not), the next invocation will happen at 120 seconds. AST_SIP_SCHED_TASK_DELAY specifies that the next invocation of the task should start "interval" milliseconds after the current invocation has finished. Also, the same ast_sched facility for fixed or variable intervals exists. The task's return code in conjunction with the AST_SIP_SCHED_TASK_FIXED or AST_SIP_SCHED_TASK_VARIABLE flags controls the next invocation start time. One res_pjsip.h housekeeping change was made. The pjsip header files were added to the top. There have been a few cases lately where I've needed res_pjsip.h just for ast_sip calls and had compiles fail spectacularly because I didn't add the pjsip header files to my source even though I never referenced any pjsip calls. Finally, a few new convenience APIs were added to astobj2 to make things a little easier in the scheduler. ao2_ref_and_lock() calls ao2_ref() and ao2_lock() in one go. ao2_unlock_and_unref() does the reverse. A few macros were also copied from res_phoneprov because I got tired of having to duplicate the same hash, sort and compare functions over and over again. The AO2_STRING_FIELD_(HASH|SORT|CMP)_FN macros will insert functions suitable for aor_container_alloc into your source. This facility can be used immediately for the situations where we already have a thread that wakes up periodically or do some scheduled work. For the registration and qualify issues, additional sorcery and schema changes would need to be made so that we can easily detect changed objects on a periodic basis without having to pull the entire database back to check. I'm thinking of a last-updated timestamp on the rows but more on this later. Change-Id: I7af6ad2b2d896ea68e478aa1ae201d6dd016ba1c
2016-04-13stringfields: Update extended string fields for master only.George Joseph
In 13, the new ast_string_field_header structure had to be dynamically allocated and assigned to a pointer in ast_string_field_mgr to preserve ABI compatability. In master, it can be converted to being a structure-in-place in ast_string_field_mgr to eliminate the extra alloc and free calls. Change-Id: Ia97c5345eec68717a15dc16fe2e6746ff2a926f4
2016-04-11res_pjsip contact: Lock expiration/addition of contactsGeorge Joseph
Contact expiration can occur in several places: res_pjsip_registrar, res_pjsip_registrar_expire, and automatically when anyone calls ast_sip_location_retrieve_aor_contact. At the same time, res_pjsip_registrar may also be attempting to renew or add a contact. Since none of this was locked it was possible for one thread to be renewing a contact and another thread to expire it immediately because it was working off of stale data. This was the casue of intermittent registration/inbound/nominal/multiple_contacts test failures. Now, the new named lock functionality is used to lock the aor during contact expire and add operations and res_pjsip_registrar_expire now checks the expiration with the lock held before deleting the contact. ASTERISK-25885 #close Reported-by: Josh Colp Change-Id: I83d413c46a47796f3ab052ca3b349f21cca47059
2016-04-11Merge "lock: Add named lock capability"Joshua Colp
2016-04-08Merge "pbx.h: Make ast_state_cb_type take more const."Joshua Colp
2016-04-08lock: Add named lock capabilityGeorge Joseph
Locking some objects like sorcery objects can be tricky because the underlying ao2 object may not be the same for all callers. For instance, two threads that call ast_sorcery_retrieve_by_id on the same aor name might actually get 2 different ao2 objects if the underlying wizard had to rehydrate the aor from a database. Locking one ao2 object doesn't have any effect on the other even if those objects had locks in the first place. Named locks allow access control by keyspace and key strings. Now an "aor" named "1000" can be locked and any other thread attempting to lock "aor" "1000" will wait regardless of whether the underlying ao2 object is the same or not. Mutex and rwlocks are supported. This capability will initially be used to lock an aor when multiple threads may be attempting to prune expired contacts from it. Change-Id: If258c0b7f92b02d07243ce70e535821a1ea7fb45
2016-04-07pbx.h: Make ast_state_cb_type take more const.Richard Mudgett
This eliminates some casts that I made a note saying v10 and above would no longer need them. Better late than never :) Change-Id: I346cdb3032b6478ceb40eb6fe732978b54035572
2016-04-07pbx: Update doxygen for extension state watchers.Richard Mudgett
Change-Id: Id1403b12136de62a272c01bb355aef65fd2c2d1e
2016-04-07Merge "pbx: Add support for autohints."Joshua Colp
2016-04-06Merge "ARI: Add method to Dial a created channel."Joshua Colp
2016-04-05ARI: Add method to Dial a created channel.Mark Michelson
This adds a new ARI method that allows for you to dial a channel that you previously created in ARI. By combining this with the create method for channels, it allows for a workflow where a channel can be created, manipulated, and then dialed. The channel is under control of the ARI application during all stages of the Dial and can even be manipulated based on channel state changes observed within an ARI application. The overarching goal for this is to eventually be able to add a dialed channel to a Stasis bridge earlier than the "Up" state. However, at the moment more work is needed in the Dial and Bridge APIs in order to facilitate that. ASTERISK-25889 #close Change-Id: Ic6c399c791e66c4aa52454222fe4f8b02483a205
2016-04-05Merge "Dial: Add function to append already-created channel."Joshua Colp
2016-04-05pbx: Add support for autohints.Joshua Colp
This change introduces the concept of autohints. These are hints which are created as a result of device state changes occurring within the core. When this happens a hint will be created (if it does not exist already) using the device name as the extension. For example if a device state change is received for "PJSIP/bob" and autohints are enabled on a context then a hint will exist in that context for "bob" with a device of "PJSIP/bob". For virtual or custom device states the name after the type will be used. For example if the device state of "Custom:bob" changes then a hint will exist in that context for "bob" with a device of "Custom:bob". This functionality can be enabled in extensions.conf by placing "autohints=yes" in a context. ASTERISK-25881 #close Change-Id: I7e444c7da41b7b7d33374420fec658beeb18584e
2016-04-05Dial: Add function to append already-created channel.Mark Michelson
The Dial API takes responsiblity for creating an outbound channel when calling ast_dial_append(). This commit adds a new function, ast_dial_append_channel(), which allows us to create the channel outside the Dial API and then to append the channel to the ast_dial structure. This is useful for situations where the channel's creation and dialing are distinct operations. Upcoming ARI early bridge work will illustrate its usage. ASTERISK-25889 Change-Id: Id8179f64f8f99132f80dead8d5db2030fd2c0509
2016-04-05Merge "stringfields: Refactor to allow fields to be added to the end of ↵Joshua Colp
structures"
2016-04-05Merge "res_rtp_asterisk: Use separate SRTP session for RTCP with DTLS"Joshua Colp
2016-04-04stringfields: Refactor to allow fields to be added to the end of structuresGeorge Joseph
String fields are great, except that you can't add new ones without breaking ABI compatibility because it shifts down everything else in the structure. The only alternative is to add your own char * field to the end of the structure and manage the memory yourself which isn't ideal, especially since you then can't use the OPT_STRINGFIELD_T type. Background: The reason string fields had to be declared inside the AST_DECLARE_STRING_FIELDS block was to facilitate iteration over all declared fields for initialization, compare and copy. Since AST_DECLARE_STRING_FIELDS declared the pool, then the fields, then the manager, you could use the offsets of the pool and manager and iterate over the sequential addresses in between to access the fields. The actual pool, field allocation and field set operations don't actually care where the field is. It's just iteration over the fields that was the problem. Solution: Extended String Fields An extended string field is one that is declared outside the AST_DECLARE_STRING_FIELDS block but still (anywhere) inside the parent structure. Other than using AST_STRING_FIELD_EXTENDED instead of AST_STRING_FIELD, it looks the same as other string fields. It's storage comes from the pool and it participates in string field compare and copy operations peformed on the parent structure. It's also a valid target for the OPT_STRINGFIELD_T aco option type. Implementation: To keep track of the extended fields and make sure that ABI isn't broken, the existing embedded_pool pointer in the manager structure was repurposed to be a pointer to a separate header structure that contains the embedded_pool pointer plus a vector of fields. The length of the manager structure didn't change and the embedded_pool pointer isn't used in the macros, only the stringfields C code. A side benefit of this is that changing the header structure in the future won't break ABI. ast_string_fields_init initializes the normal string fields and appends them to the vector, and subsequent calls to ast_string_field_init_extended initialize and append the extended fields. Cleanup, ast_string_fields_cmp, and ast_string_fields_copy can now work on the vector instead of sequentially traversing the addresses between the pool and manager. The total size of a structure using string fields didn't change, whether using extended fields or not, nor have the offsets of any structure members, either inside the original block or outside. Adding an extended field to the end of a structure is the same as adding a char *. Details: The stringfield C code was pulled out from utils.c and into stringfields.c. It just made sense. Additional work was done in ast_string_field_init and ast_calloc_with_stringfields to handle the allocation of the new header structure and the vector, and the associated cleanup. In the process some additional NULL pointer checking was added. A lot of work was done in stringfields.h since the logic for compare and copy is there. Documentation was added as well as somne additional NULL checking. The ability to call ast_calloc_with_stringfields with a number of structures greater than 1 never really worked. Well, the calloc worked but there was no way to access the additional structures or clean them up. It was agreed that there was no use case for requesting more than 1 structure so an ast_assert was added to prevent it and the iteration code removed. Testing: The stringfield unit tests were updated to test both normal and extended fields. Tests for ast_string_field_ptr_set_by_fields and ast_calloc_with_stringfields were also added. As an ABI test, 13 was compiled from git and the res_pjsip_* modules, except res_pjsip itself, saved off. The patch was then added and a full compile and install was performed. Then the older res_pjsip_* moduled were copied over the installed versions so res_pjsip was new and the rest were old. No issues. contact->aor, which is a char * at the end of contact, was then changed to an extended string field and a recompile and reinstall was performed, again leaving stock versions of the the res_pjsip_* modules. Again, no issues with the res_pjsip_* modules using the old stringfield implementation and with contact->aor as a char *, and res_pjsip itself using the new stringfield implementation and contact->aor being an extended string field. Finally, several existing string fields were converted to extended string fields to test OPT_STRINGFIELD_T. Again, no issues. Change-Id: I235db338c5b178f5a13b7946afbaa5d4a0f91d61
2016-04-04Merge "res_pjsip_mwi: Add voicemail extension and ↵Joshua Colp
mwi_subscribe_replaces_unsolicited"
2016-03-30res_stasis: Add control ref to playback and recording structs.Richard Mudgett
The stasis_app_playback and stasis_app_recording structs need to have a struct stasis_app_control ref. Other threads can get a reference to the playback and recording structs from their respective global container. These other threads can then use the control pointer they contain after the control struct has gone. * Add control ref to stasis_app_playback and stasis_app_recording structs. With the refs added, the control command queue can now have a circular control reference which will cause the control struct to never get released if the control's command queue is not flushed when the channel leaves the Stasis application. Also the command queue needs better protection from adding commands if the control->is_done flag is set. * Flush the control command queue on exit. ASTERISK-25882 #close Change-Id: I3cf1fb59cbe6f50f20d9e35a2c07ac07d7f4320d
2016-03-30res_pjsip_mwi: Add voicemail extension and mwi_subscribe_replaces_unsolicitedGeorge Joseph
res_pjsip_mwi was missing the chan_sip "vmexten" functionality which adds the Message-Account header to the MWI NOTIFY. Also, specifying mailboxes on endpoints for unsolicited mwi and on aors for subscriptions required that the admin know in advance which the client wanted. If you specified mailboxes on the endpoint, subscriptions were rejected even if you also specified mailboxes on the aor. Voicemail extension: * Added a global default_voicemail_extension which defaults to "". * Added voicemail_extension to both endpoint and aor. * Added ast_sip_subscription_get_dialog for support. * Added ast_sip_subscription_get_sip_uri for support. When an unsolicited NOTIFY is constructed, the From header is parsed, the voicemail extension from the endpoint is substituted for the user, and the result placed in the Message-Account field in the body. When a subscribed NOTIFY is constructed, the subscription dialog local uri is parsed, the voicemail_extension from the aor (looked up from the subscription resource name) is substituted for the user, and the result placed in the Message-Account field in the body. If no voicemail extension was defined, the Message-Account field is not added to the NOTIFY body. mwi_subscribe_replaces_unsolicited: * Added mwi_subscribe_replaces_unsolicited to endpoint. The previous behavior was to reject a subscribe if a previous internal subscription for unsolicited MWI was found for the mailbox. That remains the default. However, if there are mailboxes also set on the aor and the client subscribes and mwi_subscribe_replaces_unsolicited is set, the existing internal subscription is removed and replaced with the external subscription. This allows an admin to configure mailboxes on both the endpoint and aor and allows the client to select which to use. ASTERISK-25865 #close Reported-by: Ross Beer Change-Id: Ic15a9415091760539c7134a5ba3dc4a6a1217cea
2016-03-29Merge "res_rtp_asterisk: Fix packet stats on bridged connection"Joshua Colp
2016-03-29res_rtp_asterisk: Use separate SRTP session for RTCP with DTLSJacek Konieczny
Asterisk uses separate UDP ports for RTP and RTCP traffic and RFC 5764 explicitly states: There MUST be a separate DTLS-SRTP session for each distinct pair of source and destination ports used by a media session This means RTP keying material cannot be used for DTLS RTCP, which was the reason why RTCP encryption would fail. ASTERISK-25642 Change-Id: I7e8779d8b63e371088081bb113131361b2847e3a
2016-03-28res_rtp_asterisk: Fix packet stats on bridged connectionGeorge Joseph
rxcount, txcount, rxoctetcount and txoctetcount weren't being calculated for bridged streams because the calulations were being done after the bridged short-circuit. Actually, rxoctetcount wasn't ever being calculated. Moved the calculations so they occur for all valid received packets and all transmitted packets. Also added rxoctetcount and txoctetcount to ast_rtp_instance_stat. Change-Id: I08fb06011a82d38c3b4068867a615068fbe59cbb
2016-03-27sorcery/res_pjsip: Refactor for realtime performanceGeorge Joseph
There were a number of places in the res_pjsip stack that were getting all endpoints or all aors, and then filtering them locally. A good example is pjsip_options which, on startup, retrieves all endpoints, then the aors for those endpoints, then tests the aors to see if the qualify_frequency is > 0. One issue was that it never did anything with the endpoints other than retrieve the aors so we probably could have skipped a step and just retrieved all aors. But nevermind. This worked reasonably well with local config files but with a realtime backend and thousands of objects, this was a nightmare. The issue really boiled down to the fact that while realtime supports predicates that are passed to the database engine, the non-realtime sorcery backends didn't. They do now. The realtime engines have a scheme for doing simple comparisons. They take in an ast_variable (or list) for matching, and the name of each variable can contain an operator. For instance, a name of "qualify_frequency >" and a value of "0" would create a SQL predicate that looks like "where qualify_frequency > '0'". If there's no operator after the name, the engines add an '=' so a simple name of "qualify_frequency" and a value of "10" would return exact matches. The non-realtime backends decide whether to include an object in a result set by calling ast_sorcery_changeset_create on every object in the internal container. However, ast_sorcery_changeset_create only does exact string matches though so a name of "qualify_frequency >" and a value of "0" returns nothing because the literal "qualify_frequency >" doesn't match any name in the objset set. So, the real task was to create a generic string matcher that can take a left value, operator and a right value and perform the match. To that end, strings.c has a new ast_strings_match(left, operator, right) function. Left and right are the strings to operate on and the operator can be a string containing any of the following: = (or NULL or ""), !=, >, >=, <, <=, like or regex. If the operator is like or regex, the right string should be a %-pattern or a regex expression. If both left and right can be converted to float, then a numeric comparison is performed, otherwise a string comparison is performed. To use this new function on ast_variables, 2 new functions were added to config.c. One that compares 2 ast_variables, and one that compares 2 ast_variable lists. The former is useful when you want to compare 2 ast_variables that happen to be in a list but don't want to traverse the list. The latter will traverse the right list and return true if all the variables in it match the left list. Now, the backends' fields_cmp functions call ast_variable_lists_match instead of ast_sorcery_changeset_create and they can now process the same syntax as the realtime engines. The realtime backend just passes the variable list unaltered to the engine. The only gotcha is that there's no common realtime engine support for regex so that's been noted in the api docs for ast_sorcery_retrieve_by_fields. Only one more change to sorcery was done... A new config flag "allow_unqualified_fetch" was added to reg_sorcery_realtime. "no": ignore fetches if no predicate fields were supplied. "error": same as no but emit an error. (good for testing) "yes": allow (the default); "warn": allow but emit a warning. (good for testing) Now on to res_pjsip... pjsip_options was modified to retrieve aors with qualify_frequency > 0 rather than all endpoints then all aors. Not only was this a big improvement in realtime retrieval but even for config files there's an improvement because we're not going through endpoints anymore. res_pjsip_mwi was modified to retieve only endpoints with something in the mailboxes field instead of all endpoints then testing mailboxes. res_pjsip_registrar_expire was completely refactored. It was retrieving all contacts then setting up scheduler entries to check for expiration. Now, it's a single thread (like keepalive) that periodically retrieves only contacts whose expiration time is < now and deletes them. A new contact_expiration_check_interval was added to global with a default of 30 seconds. Ross Beer reports that with this patch, his Asterisk startup time dropped from around an hour to under 30 seconds. There are still objects that can't be filtered at the database like identifies, transports, and registrations. These are not going to be anywhere near as numerous as endpoints, aors, auths, contacts however. Back to allow_unqualified_fetch. If this is set to yes and you have a very large number of objects in the database, the pjsip CLI commands will attempt to retrive ALL of them if not qualified with a LIKE. Worse, if you type "pjsip show endpoint <tab>" guess what's going to happen? :) Having a cache helps but all the objects will have to be retrieved at least once to fill the cache. Setting allow_unqualified_fetch=no prevents the mass retrieve and should be used on endpoints, auths, aors, and contacts. It should NOT be used for identifies, registrations and transports since these MUST be retrieved in bulk. Example sorcery.conf: [res_pjsip] endpoint=config,pjsip.conf,criteria=type=endpoint endpoint=realtime,ps_endpoints,allow_unqualified_fetch=error ASTERISK-25826 #close Reported-by: Ross Beer Tested-by: Ross Beer Change-Id: Id2691e447db90892890036e663aaf907b2dc1c67
2016-03-24Restrict CLI/AMI commands on shutdown.Mark Michelson
During stress testing, we have frequently seen crashes occur because a CLI or AMI command attempts to access information that is in the process of being destroyed. When addressing how to fix this issue, we initially considered fixing individual crashes we observed. However, the changes required to fix those problems would introduce considerable overhead to the nominal case. This is not reasonable in order to prevent a crash from occurring while Asterisk is already shutting down. Instead, this change makes it so AMI and CLI commands cannot be executed if Asterisk is being shut down. For AMI, this is absolute. For CLI, though, certain commands can be registered so that they may be run during Asterisk shutdown. ASTERISK-25825 #close Change-Id: I8887e215ac352fadf7f4c1e082da9089b1421990
2016-03-15Merge "build: Add configure check for proto field of PJSIP TLS transport ↵zuul
setting."
2016-03-14build: Add configure check for proto field of PJSIP TLS transport setting.Joshua Colp
Older versions of PJSIP do not have the proto field on the TLS transport setting structure. This change adds a configure check so even if it is not present we will still be able to build. Change-Id: Ibf3f47befb91ed1b8194bf63888baa6fee05aba9
2016-03-11app_chanspy: Fix occasional deadlock with ChanSpy and Local channels.Walter Doekes
Channel masquerading had a conflict with autochannel locking. When locking autochannel->channel, the channel is fetched from the autochannel and then locked. During the fetch, the autochannel -- which has no locks itself -- can be modified by someone who owns the channel lock. That means that the value of autochan->channel cannot be trusted until you hold the lock. In practice, this caused problems with Local channels getting masqueraded away while the ChanSpy attempted to get info from that channel. The old channel which was about to get removed got locked, but the new (replaced) channel got unlocked (no-op). Because the replaced channel was now locked (and would never get unlocked), it couldn't get removed from the channel list in a timely manner, and would now cause deadlocks when iterating over the channel list. This change checks the autochannel after locking the channel for changes to the autochannel. If the channel had been changed, the lock is reobtained on the new channel. In theory it seems possible that after this fix, the lock attempt on the old (wrong) channel can be on an already destroyed lock, maybe causing a crash. But that hasn't been observed in the wild and is harder induce than the current deadlock. Thanks go to Filip Frank for suggesting a fix similar to this and especially to IRC user hexanol for pointing out why this deadlock was possible and testing this fix. And to Richard for catching my rookie while loop mistake ;) ASTERISK-25321 #close Change-Id: I293ae0014e531cd0e675c3f02d1d118a98683def
2016-03-08Merge "res_pjsip_caller_id: Anonymize 'From' when caller id presentation is ↵zuul
prohibited"
2016-03-08Merge "res_pjsip: Strip spaces from items parsed from comma-separated lists"zuul