It was possible for the explicit publish destroy function to be called without
the pjsip client ever being initialized. This fix checks to make sure there is
a client to destroy before attempting.
Change-Id: I8eea1bfa3bd472149bfc255310be2a6248688f5c
The app_fax set FAXMODE variable, but res_fax missing this feature.
This patch add FAXMODE variable which is set to either "audio" or "T38".
ASTERISK-25980
Change-Id: Ie3dcbfb72cc681e9e267a60202f7fb8723a51b6b
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
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
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
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
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
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
This change adds the ability to configure outbound publishing of
extension state. Right now stuff is merely set up to store the
configuration and to register a global extension state callback. The
act of constructing the body and sending is not yet complete.
Configurable elements right now are a regex for filtering the context,
a regex for filtering the extension, and the body type to publish.
ASTERISK-25922 #close
Change-Id: Ia7e630136dfc355073c1cadff8ad394a08523d78
The run_agi function is eating control frames when it shouldn't be. This is
causing issues when an AGI is run from CONNECTED_LINE_SEND_SUB in a blond
transfer.
Alice calls Bob. Bob attended transfers to Charlie but hangs up before Charlie
answers.
Alice gets the COLP UPDATE indicating Charlie but Charlie never gets an UPDATE
and is left thinking he's connected to Bob.
In this case, when CONNECTED_LINE_SEND_SUB runs on Alice's channel and it calls
an AGI, the extra eaten frames prevent CONNECTED_LINE_SEND_SUB from running on
Charlie's channel.
The fix was to accumulate deferrable frames in the "forever" loop instead of
dropping them, and re-queue them just before running the actual agi command
or exiting.
ASTERISK-25951 #close
Change-Id: I0f4bbfd72fc1126c2aaba41da3233a33d0433645
We lose the fact that there is a swap channel if there is one. We
currently wind up rejoining the stasis bridge as a normal join after the
swap channel has already been kicked from the bridge.
This patch preserves the swap channel so the AMI/ARI events can note that
the channel joining the bridge is swapping with another channel. Another
benefit to swaqpping in one operation is if there are any channels that
get lonely (MOH, bridge playback, and bridge record channels). The lonely
channels won't leave before the joining channel has a chance to come back
in under stasis if the swap channel is the only reason the lonely channels
are staying in the bridge.
ASTERISK-25947 #close
Reported by: Richard Mudgett
ASTERISK-24649
Reported by: John Bigelow
ASTERISK-24782
Reported by: John Bigelow
Change-Id: If37ea508831d1fed6dbfac2f191c638fc0a850ee
When create_new_id_hdr creates a new RPID or PAI header, it starts by cloning
the From header, then it overwrites the display name and uri from the channel's
connected.id. If the connected.id.name wasn't valid, create_new_id_hdr was
leaving the display name from the From header in the new RPID or PAI header.
On an attended transfer where the originator had a caller id number set but not
a display name, the re-INVITE to the final transferee had the number of the
originator but the display name of the transferer.
Added a check to clear out the display name in the new header if
connected.id.name was invalid.
ASTERISK-25942 #close
Change-Id: I60b4bf7a7ece9b7425eba74151c0b4969cd2738b
The PJSIP parsing functions provide a nice concise way to check the
length of a hostname in a SIP URI. The problem is that in order to use
those parsing functions, it's required to use them from a thread that
has registered with PJLib.
On startup, when parsing AOR configuration, the permanent URI handler
may not be run from a PJLib-registered thread. Specifically, this could
happen when Asterisk was started in daemon mode rather than
console-mode. If PJProject were compiled with assertions enabled, then
this would cause Asterisk to crash on startup.
The solution presented here is to do our own parsing of the contact URI
in order to ensure that the hostname in the URI is not too long. The
parsing does not attempt to perform a full SIP URI parse/validation,
since the hostname in the URI is what is important.
ASTERISK-25928 #close
Reported by Joshua Colp
Change-Id: Ic3d6c20ff3502507c17244a8b7e2ca761dc7fb60
Recent changes to the PJSIP registrar resulted in tests failing due to
missing AOR_CONTACT_ADDED test events. The reason for this was that the
user_agent string had junk values in it, resulting in being unable to
generate the event.
I'm going to be honest here, I have no idea why this was happening. Here
are the steps needed for the user_agent variable to get messed up:
* REGISTER is received
* First contact in the REGISTER results in a contact being removed
* Second contact in the REGISTER results in a contact being added
* The contact, AOR, expiration, and user agent all have to be passed as
format parameters to the creation of a string. Any subset of those
parameters would not be enough to cause the problem.
Looking into what was happening, the thing that struck me as odd was
that the user_agent variable was meant to be set to the value of the
User-Agent SIP header in the incoming REGISTER. However, when removing a
contact, the user_agent variable would be set (via ast_strdupa inside a
loop) to the stored contact's user_agent. This means that the
user_agent's value would be incorrect when attempting to process further
contacts in the incoming REGISTER.
The fix here is to use a different variable for the stored user agent
when removing a contact. Correcting the behavior to be correct also
means the memory usage is less weird, and the issue no longer occurs.
ASTERISK-25929 #close
Reported by Joshua Colp
Change-Id: I7cd24c86a38dec69ebcc94150614bc25f46b8c08
At shutdown it is possible for modules to be unloaded that wouldn't
normally be unloaded. This allows the environment to be cleaned up.
The res_pjsip_transport_management module did not have the unload
logic in it to clean itself up causing the res_pjsip module to not
get unloaded. As a result the res_pjsip monitor thread kept going
processing traffic and timers when it shouldn't.
Change-Id: Ic8cadee131e3b2c436a81d3ae8bb5775999ae00a
The scheduler thread that kills idle TCP connections was not registering
with PJProject properly and causing assertions if PJProject was built in
debug mode.
This change registers the thread with PJProject the first time that the
scheduler callback executes.
AST-2016-005
Change-Id: I5f7a37e2c80726a99afe9dc2a4a69bdedf661283
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
"Idle" here means that someone connects to us and does not send a SIP
request. PJProject will not automatically time out such connections, so
it's up to Asterisk to do it instead.
When we receive an incoming TCP connection, we will start a timer
(equivalent to transaction timer D) waiting to receive an incoming
request. If we do not receive a request in that timeframe, then we will
shut down the TCP connection.
ASTERISK-25796 #close
Reported by George Joseph
AST-2016-005
Change-Id: I7b0d303e5d140d0ccaf2f7af562071e3d1130ac6
Due to some ignored return values, Asterisk could crash if processing an
incoming REGISTER whose contact URI was above a certain length.
ASTERISK-25707 #close
Reported by George Joseph
Patches:
0001-res_pjsip-Validate-that-URIs-don-t-exceed-pjproject-.patch
AST-2016-004
Change-Id: I3ea7cee16f29c8088794de3085ca7523c1c4833d
* Added Useragent and RegExpire headers to AMI Event
ContactStatusDetail with associated documentation.
ASTERISK-25903 #close
Change-Id: If3d121e943e588d016ba51d4eb9c6a421a562239
The first available transport of the appropriate type is used now.
This patch adds new config option 'transport' for outbound-publish.
If transport is set then outbound PUBLISH requests will use this transport.
ASTERISK-25901 #close
Change-Id: Ib389130489b70e36795b0003fa5fd386e2680151
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
BLF pickup isn't working on Cisco SPA and Snom phones
if the direction="recipient" attribute is missing in 'dialog' tag.
This patch adds direction="recipient" if extension state is
Ringing.
ASTERISK-24601 #close
Change-Id: I5b2c097ca29fd59e92ba237ca5d397cb1b0bcd8c
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
When shutting down, the PJSIP sorcery is destroyed. The registrar
expiration module queries the PJSIP sorcery to determine what
to expire. As there was no synchronization between termination
of the expiration thread and the unloading of the module it was
possible for the thread to try to access the PJSIP sorcery after
it had been destroyed.
This change ensures that the thread is shut down before allowing
the module to be considered unloaded.
Change-Id: I69fd239edbaaf160c2d37ae00d3ac06e5596fe8b