Previous chan_sip behavior:
Before this patch chan_sip would always strip any quotes from an incoming
reason and pass that value up as the REDIRECTING(reason). For an outgoing
reason value, chan_sip would check the value against known values and
quote any it didn't recognize. Incoming 480 response message reason text
was just assigned to the REDIRECTING(reason).
Previous chan_pjsip behavior:
Before this patch chan_pjsip would always pass the incoming reason value
up as the REDIRECTING(reason). For an outgoing reason value, chan_pjsip
would send the reason value as passed down.
With this patch:
Both channel drivers match incoming reason values with values documented
by REDIRECTING(reason) and values documented by RFC5806 regardless of
whether they are quoted or not. RFC5806 values are mapped to the
equivalent REDIRECTING(reason) documented value and is set in
REDIRECTING(reason). e.g., an incoming RFC5806 'unconditional' value or a
quoted string version ('"unconditional"') is converted to
REDIRECTING(reason)'s 'cfu' value. The user's dialplan only needs to deal
with 'cfu' instead of any of the aliases.
The incoming 480 response reason text supported by chan_sip checks for
known reason values and if not matched then puts quotes around the reason
string and assigns that to REDIRECTING(reason).
Both channel drivers send outgoing known REDIRECTING(reason) values as the
unquoted RFC5806 equivalent. User custom values are either sent as is or
with added quotes if SIP doesn't allow a character within the value as
part of a RFC3261 Section 25.1 token. Note that there are still
limitations on what characters can be put in a custom user value. e.g.,
embedding quotes in the middle of the reason string is silly and just
going to cause you grief.
* Setting a REDIRECTING(reason) value now recognizes RFC5806 aliases.
e.g., Setting REDIRECTING(reason) to 'unconditional' is converted to the
'cfu' value.
* Added missing malloc() NULL return check in res_pjsip_diversion.c
set_redirecting_reason().
* Fixed potential read from a stale pointer in res_pjsip_diversion.c
add_diversion_header(). The reason string needed to be copied into the
tdata memory pool to ensure that the string would always be available.
Otherwise, if the reason string returned by reason_code_to_str() was a
user's reason string then the string could be freed later by another
thread.
Change-Id: Ifba83d23a195a9f64d55b9c681d2e62476b68a87
chan_sip could not handle AST_T38_TERMINATED frames being sent to it when
the channel left the bridge. The action resulted in overlapping outgoing
reINVITEs. The testsuite tests/fax/sip/directmedia_reinvite_t38 was not
happy.
* Force T.38 to be remembered as locally bridged. Now when the channel
leaves the native RTP bridge after T.38, the channel remembers that it has
already reINVITEed the media back to Asterisk. It just needs to terminate
T.38 when the AST_T38_TERMINATED arrives.
* Prevent redundant AST_T38_TERMINATED from causing problems. Redundant
AST_T38_TERMINATED frames could cause overlapping outgoing reINVITEs if
they happen before the T.38 state changes to disabled. Now the T.38 state
is set to disabled before the reINVITE is sent.
ASTERISK-25582 #close
Change-Id: I53f5c6ce7d90b3f322a942af1a9bcab6d967b7ce
Use the correct comparison function since we only care if the address
without the port is the same.
Change-Id: Ibf6c485f843a1be6dee58a47b33d81a7a8cbe3b0
Setting the sip.conf timert1 value to a value higher than 1245 can cause
an integer overflow and result in large retransmit timeout times. These
large timeout times hold system file descriptors hostage and can cause the
system to run out of file descriptors.
NOTE: The default sip.conf timert1 value is 500 which does not expose the
vulnerability.
* The overflow is now detected and the previous timeout time is
calculated.
ASTERISK-25397 #close
Reported by: Alexander Traud
Change-Id: Ia7231f2f415af1cbf90b923e001b9219cff46290
When I ask asterisk to send a SIP NOTIFY message to a sip peer using either a)
AMI action: SIPnotify or b) cli command: sip notify <cmd> <peer>, I expect
asterisk to include the same value for its own ip in both cases a) and b),
but it seems a) produces a contact header like Contact:
<sip:asterisk@192.168.1.227:8060> whereas b) produces a contact header like
<sip:asterisk@127.0.0.1:8060>. 0.0.0.0:8060 is my udpbindaddr in sip.conf
My guess is that manager_sipnotify should call
ast_sip_ouraddrfor(&p->sa, &p->ourip, p) the same way sip_cli_notify does,
because after applying this patch, both cases a) and b) produce
the contact header that I expect: <sip:asterisk@192.168.1.227:8060>
Reported by: Stefan Engström
Tested by: Stefan Engström
Change-Id: I86af5e209db64aab82c25417de6c768fb645f476
sip_sipredirect uses sscanf to copy up to 256 characters to a stacked buffer
of 256 characters. This patch reduces the copy to 255 characters to leave
room for the string null terminator.
ASTERISK-25722 #close
Change-Id: Id6c3a629a609e94153287512c59aa1923e8a03ab
websocket_write_timeout was not being set to its default value
during sip config reload, which meant that prior to this commit,
1) the default value of 100 was not used, unless an invalid value
(or 1) was specified in sip.conf for websocket_write_timeout, and
2) if the websocket_write_timeout directive was removed from sip.conf
without a full restart of asterisk, then the previous value would
continue to be used indefinitely.
This essentially lead to a 0ms write timeout (the first write attempt
in ast_careful_fwrite must have succeeded) in websocket write requests
from chan_sip, unless websocket_write_timeout was explicitely set in sip.conf.
Changes to websocket_write_timeout still only apply to new websocket
sessions, after the sip reload -- timeouts on existing sessions are
not adjusted during sip reload.
Change-Id: Ibed3816ed29cc354af6564c5ab3e75eab72cb953
Per the documentation the WebSocket support in chan_sip is
supposed to be enabled by default but is not. This change
corrects that.
Change-Id: Icb02bbcad47b11a795c14ce20a9bf29649a54423
Adds the TCP Keep Alive option to TCP and TLS server sockets. Previously
this option was only being set on session sockets.
http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/
According to the link above, the SO_KEEPALIVE option is useful for knowing
when a TCP connected endpoint has severed communication without indicating
it or has become unreachable for some reason. Without this patch, keep
alive is not set on the socket listening for incoming TCP sessions and
in Komatsu's report this resulted in the thread listening for TCP becoming
stuck in a waiting state.
ASTERISK-25364 #close
Reported by: Hiroaki Komatsu
Change-Id: I7ed7bcfa982b367dc64b4b73fbd962da49b9af36
Asterisk may crash when calling ast_channel_get_t38_state(c)
on a locked channel which is being hung up.
ASTERISK-25609 #close
Change-Id: Ifaa707c04b865a290ffab719bd2e5c48ff667c7b
The current logic for ICE negotiation starts it
when receiving an SDP with ICE candidates. This is
incorrect as ICE negotiation can only start when each
call party have at least one pair of local and remote
candidate. Starting ICE negotiation early would result
in negotiation failure and ultimately no audio.
This change makes it so ICE negotiation is only started
when a response with SDP is received or when a response
with SDP is sent.
ASTERISK-24146
Change-Id: I55a632bde9e9827871b09141d82747e08379a8ca
A crash happens sometimes when performing a CLI "sip reload". The bogus
peer gets refreshed while it is in use by a new call which can cause the
crash.
* Protected the global bogus peer object with an ao2 global object
container.
ASTERISK-25610 #close
Change-Id: I5b528c742195681abcf713c6e1011ea65354eeed
chan_sip.c:
* Initialize mwi subscription scheduler ids earlier because of ASTOBJ to
ao2 conversion.
* Initialize register scheduler ids earlier because of ASTOBJ to ao2
conversion.
chan_skinny.c:
* Fix more scheduler usage for the valid 0 id value.
ASTERISK-25476
Change-Id: If9f0e5d99638b2f9d102d1ebc9c5a14b2d706e95
channels/chan_iax2.c:
* Initialize struct chan_iax2_pvt scheduler ids earlier because of
iax2_destroy_helper().
channels/chan_sip.c:
channels/sip/config_parser.c:
* Fix initialization of scheduler id struct members. Some off nominal
paths had 0 as a scheduler id to be destroyed when it was never started.
chan_skinny.c:
* Fix some scheduler id comparisons that excluded the valid 0 id.
channel.c:
* Fix channel initialization of the video stream scheduler id.
pbx_dundi.c:
* Fix channel initialization of the packet retransmission scheduler id.
ASTERISK-25476
Change-Id: I07a3449f728f671d326a22fcbd071f150ba2e8c8
When a channel is in a direct media bridge, a re-INVITE may arrive that forces
Asterisk to re-negotiate the media to a T.38 fax. When this occurs, the bridge
must change its technology to a simple bridge, and re-INVITE the media back
to Asterisk.
Generally, this logic mostly already exists in Asterisk. However, prior to this
patch, there were a few bugs:
(1) The T.38 framehook currently prevents a channel capable of T.38 faxes from
ever entering into a direct media bridge. This applies even when the only
media being passed over the channel is audio. This patch fixes this bug
by having the framehook specify that it defers caring about any frame type.
This allows the channels to enter into a direct media bridge, which will
be broken when a re-INVITE is received.
(2) When a re-INVITE is received, nothing instructed the bridging layer to
re-inspect the allowed bridging technology. This now occurs when either
a re-INVITE is received from a peer, or when a response is received from
the far end (that is, when the T.38 state changes to either
T38_PEER_REINVITE or T38_LOCAL_REINVITE).
(3) chan_pjsip needs to do a small amount of work to prevent a direct media
bridge from being chosen when a T.38 session is in progress. When a T.38
session supplement has a t38 datastore - which is added when we detect
we should start thinking about T.38 on a channel - we now refuse a native
RTP bridge.
(4) When a BYE request is received, we don't terminate the T.38 session. If
the other side of a T.38 fax survives the hangup (due to the 'g' flag
in Dial, for example), we don't currently re-INVITE the media on the
other channel back to audio. This patch now has res_pjsip_t38 intercept
BYE requests and inform the far side that the T.38 session is terminated.
This naturally causes the correct re-INVITEs to be sent.
ASTERISK-25582
Change-Id: Iabd6aa578e633d16e6b9f342091264e4324a79eb
When ASTERISK-25449 was closed, a number of scheduler issues mentioned in
the comments were missed. These have since beed raised in ASTERISK-25476
and elsewhere.
This patch attempts to collect all of the scheduler issues discovered so
far and address them sensibly.
ASTERISK-25476 #close
Change-Id: I87a77d581e2e0d91d33b4b2fbff80f64a566d05b
This patch adds a new setting "websockets_enabled" to sip.conf.
Setting this to false allows chan_sip to be used without causing
conflicts with res_pjsip_transport_websocket.
ASTERISK-24106 #close
Reported by: Andrew Nagy
Change-Id: I04fe8c4f2d57b2d7375e0e25826c91a72e93bea7
Since version 13, Asterisk sent all allowed codecs as callee, even when the
caller did not request/support them. In case of dynamic RTP payloads, this led
to the same ID for different codecs, which is not allowed by SIP/SDP. Now, the
intersection between the requested and the supported codecs is send again.
ASTERISK-24543 #close
Change-Id: Ie90cb8bf893b0895f8d505e77343de3ba152a287
Fixed 1 issue in each of the affected files.
ASTERISK-25494 #close
Reported-by: George Joseph
Tested-by: George Joseph
Change-Id: I818f149cd66a93b062df421e1c73c7942f5a4a77
With Asterisk 13, the structures ast_format and ast_codec changed. Because of
that, the paketization timing (framing) of the RTP channel moved away from the
formats/codecs. In the course of that change, the ptime of the callee was not
honored anymore, when the optional autoframing was enabled.
ASTERISK-25484 #close
Change-Id: Ic600ccaa125e705922f89c72212c698215d239b4
To quote Olle:
"When issuing a hangup due to RTP timeouts the cause code is not set. I have
selected 44 based on Cisco's implementation..."
ASTERISK-25135 #close
Reported by: Olle Johansson
patches:
rtp-timeout-cause-1.8.diff uploaded by Olle Johansson (License 5267)
Change-Id: Ia62100c55077d77901caee0bcae299f8dc7375fc
If a Via header containes an IPv6 address and a port number is ommitted,
as it is the standard port, we now leave the port empty and to not set it
to the value after the first colon of the IPv6 address.
ASTERISK-25443 #close
Change-Id: Ie3c2f05471cd006bf04ed15598589c09577b1e70
Apparently some endpoints attempt to send a reINVITE before completing the
initial INVITE transaction. In this case PJSIP responds appropriately to
the reINVITE with a 491 INVITE request pending. Unfortunately chan_pjsip
is using the initial INVITE transaction state to determine if an INVITE is
the initial INVITE or a reINVITE. Since the initial INVITE transaction
has not been confirmed yet chan_pjsip thinks the reINVITE is an initial
INVITE and starts another PBX thread on the channel. The extra PBX thread
ensures that hilarity ensues.
* Fix checks for a reINVITE on incoming requests to look for the presence
of a to-tag instead of the initial INVITE transaction state.
* Made caller_id_incoming_request() determine what to do if there is a
channel on the session or not. After a channel is created it is too late
to just store the new party id on the session because the session's party
id has already been copied to the channel's caller id.
ASTERISK-25404 #close
Reported by: Chet Stevens
Change-Id: Ie78201c304a2b13226f3a4ce59908beecc2c68be
When 5c713fdf18 was merged, it allowed for scheduled items to have an ID of
'0' returned. While this was valid per the documentation for the API, it was
apparently never returned previously. As a result, several users of the
scheduler API viewed the result as being invalid, causing them to reschedule
already scheduled items or otherwise fail in interesting ways.
This patch corrects the users such that they view '0' as valid, and a returned
ID of -1 as being invalid.
Note that the failing HEP RTCP tests now pass with this patch. These tests
failed due to a duplicate scheduling of the RTCP transmissions.
ASTERISK-25449 #close
Change-Id: I019a9aa8b6997584f66876331675981ac9e07e39
Some systems require the REFER packet to include a Referred-By header.
If the channel variable SIPREFERREDBYHDR is set, it passes that value as the
Referred-By header value. Otherwise, it adds the current dialog’s local info.
Reported by: Dan Cropp
Tested by: Dan Cropp
Change-Id: I3d17912ce548667edf53cb549e88a25475eda245
The CALLERID(num) and CALLERID(name) and other info are placed into the
`char from[256]` in initreqprep. If the name was too long, the addr-spec
and params wouldn't fit.
Code is moved around so the addr-spec with params is placed there first,
and then fitting in as much of the display-name as possible.
ASTERISK-25396 #close
Change-Id: I33632baf024f01b6a00f8c7f35c91e5f68c40260
Although unlikely, if the tech private is returned as
a NULL, chan_pjsip_get_rtp_peer() would crash.
ASTERISK-25323
Change-Id: Ie231369bfa7da926fb2b9fdaac228261a3152e6a
Change validation on reload module because now used the cli function for
reload. The sip_reload() function never fail and ever return NULL for this
reason on reload() now use the call the sip_reload() and return
AST_MODULE_LOAD_SUCCESS.
This problem is dectected on reload by PUT method on ARI, getting always
404 http code when the module is reloaded.
ASTERISK-25325 #close
Reporte by: Rodrigo Ramírez Norambuena
Change-Id: I41215877fb2cfc589e0d4d464000cf6825f4d7fb
This patch adds a new option to the CHANNEL function that allows for the
extraction of the SIP call-id. It is used in conjunction with the 'pjsip'
option, and will return the Call-ID of the INVITE request that established
the PJSIP channel.
ASTERISK-25352
Change-Id: I278d1f8bcfe3a53c5aa1dadebc14e92b0abd476a
In chan_pjsip_new, if allocation of the pvt
structure fails, ast_hangup is called. But
it was written to assume pvt was valid, and
this change corrects that.
ASTERISK-25323
Reported by: Scott Griepentrog
Change-Id: I5f47860fe9cee4cd56abd3f79b108678ab72cc87
The call pickup implementation in chan_sip currently sets the channel
hangup cause to "normal clearing" if call pickup is successfully
performed. This action overwrites the "answered elsewhere" hangup cause
set by the call pickup code and can result in the SIP device in
question showing a missed call when it should not.
This change sets the hangup cause to "normal clearing" as a
default initially but allows the call pickup to change it as
needed.
ASTERISK-25346 #close
Change-Id: I00ac2c269cee9e29586ee2c65e83c70e52a02cff
In chan_sip, after handling an incoming invite a security event is raised
describing authorization (success, failure, etc...). However, it was doing
a lookup of the peer by extension. This is fine for register messages, but
in the case of an invite it may search and find the wrong peer, or a non
existent one (for instance, in the case of call pickup). Also, if the peers
are configured through realtime this may cause an unnecessary database lookup
when caching is enabled.
This patch makes it so that sip_report_security_event searches by IP address
when looking for a peer instead of by extension after an invite is processed.
ASTERISK-25320 #close
Change-Id: I9b3f11549efb475b6561c64f0e6da1a481d98bc4
Pressing DTMF digits on a phone to go out on a DAHDI channel can result in
the digit not being recognized or even heard by the peer.
Phone -> Asterisk -> DAHDI/channel
Turns out the DAHDI behavior with DTMF generation (and any other generated
tones) is exposed by the "buffers=" setting in chan_dahdi.conf. When
Asterisk requests to start sending DTMF then DAHDI waits until its write
buffer is empty before generating any samples for the DTMF tones. When
Asterisk subsequently requests DAHDI to stop sending DTMF then DAHDI
immediately stops generating the DTMF samples. As a result, the more
samples there are in the DAHDI write buffer the shorter the time DTMF
actually gets sent on the wire. If there are more samples in the write
buffer than the time DTMF is supposed to be sent then no DTMF gets sent on
the wire. With the "buffers=12,half" setting and each buffer representing
20 ms of samples then the DAHDI write buffer is going to contain around
120 ms of samples. For DTMF to be recognized by the peer the actual sent
DTMF duration needs to be a minimum of 40 ms. Therefore, the intended
duration needs to be a minimum of 160 ms for the peer to receive the
minimum DTMF digit duration to recognize it.
A simple and effective solution to work around the DAHDI behavior is for
Asterisk to flush the DAHDI write buffer when sending DTMF so the full
duration of DTMF is actually sent on the wire. When someone is going to
send DTMF they are not likely to be talking before sending the tones so
the flushed write samples are expected to just contain silence.
* Made dahdi_digit_begin() flush the DAHDI write buffer after requesting
to send a DTMF digit.
ASTERISK-25315 #close
Reported by John Hardin
Change-Id: Ib56262c708cb7858082156bfc70ebd0a220efa6a
There is a window of opportunity for DTMF to not go out if an audio frame
is in the process of being written to DAHDI while another thread starts
sending DTMF. The thread sending the audio frame could be past the
currently dialing check before being preempted by another thread starting
a DTMF generation request. When the thread sending the audio frame
resumes it will then cause DAHDI to stop the DTMF tone generation. The
result is no DTMF goes out.
* Made dahdi_write() lock the private struct before writing to the DAHDI
file descriptor.
ASTERISK-25315
Reported by John Hardin
Change-Id: Ib4e0264cf63305ed5da701188447668e72ec9abb
iLBC 20 was advertised in a SIP/SDP negotiation. However, only iLBC 30 is
supported. Removes "a=fmtp:x mode=y" from SDP. Because of RFC 3952 section 5,
only iLBC 30 is negotiated now.
ASTERISK-25309 #close
Change-Id: I92d724600a183eec3114da0ac607b994b1a793da
We have seen a rash of test failures on a 32-bit build agent. Commit
48698a5e21 solved an obvious problem where
we were not encoding a 64-bit value correctly over the wire. This
commit, however, did not solve the test failures.
In the failing tests, ARI is attempting to send a 537 byte text frame
over a websocket. When sending a frame this small, 16 bits are all that
is required in order to encode the payload length on the websocket
frame. However, ast_websocket_write() thinks that the payload length is
greater than 65535 and therefore writes out a 64 bit payload length.
Inspecting this payload length, the lower 32 bits are exactly what we
would expect it to be, 537 in hex. The upper 32 bits, are junk values
that are not expected to be there.
In the failure, we are passing the result of strlen() to a function that
expects a uint64_t parameter to be passed in. strlen() returns a size_t,
which on this 32-bit machine is 32 bits wide. Normally, passing a 32-bit
unsigned value to somewhere where a 64-bit unsigned value is expected
would cause no problems. In fact, in manual runs of failing tests, this
works just fine. However, ast_websocket_write() uses the Asterisk
optional API, which means that rather than a simple function call, there
are a series of macros that are used for its declaration and
implementation. These macros may be causing some sort of error to occur
when converting from a 32 bit quantity to a 64 bit quantity.
This commit changes the logic by making existing ast_websocket_write()
calls use ast_websocket_write_string() instead. Within
ast_websocket_write_string(), the 64-bit converted strlen is saved in a
local variable, and that variable is passed to ast_websocket_write()
instead.
Note that this commit message is full of speculation rather than
certainty. This is because the observed test failures, while always
present in automated test runs, never occur when tests are manually
attempted on the same test agent. The idea behind this commit is to fix
a theoretical issue by performing changes that should, at the least,
cause no harm. If it turns out that this change does not fix the failing
tests, then this commit should be reverted.
Change-Id: I4458dd87d785ca322b89c152b223a540a3d23e67
This change adds support for the 'rtp_timeout' and 'rtp_timeout_hold'
endpoint options. These allow the channel to be hung up if RTP
is not received from the remote endpoint for a specified number of
seconds.
ASTERISK-25259 #close
Change-Id: I3f39daaa7da2596b5022737b77799d16204175b9
Receipt of an RTP packet currently causes the formats on an PJSIP channel to
change to the format of the RTP packet. In some off-nominal cases it's possible
for this to be a format that has not been configured or negotiated. This change
makes it so only formats explicitly configured on the endpoint are allowed.
ASTERISK-25258 #close
Change-Id: If93d641fb6418a285928839300d7854cab8c1020