Commit Graph

32822 Commits

Author SHA1 Message Date
Asterisk Development Team
77ea4d0b26 Update for 16.17.0 16.17.0 2021-03-25 12:30:04 -05:00
Asterisk Development Team
7022e06955 Update for 16.17.0-rc2 16.17.0-rc2 2021-03-22 10:38:50 -05:00
George Joseph
6a31b988e7 res_pjsip_session: Make reschedule_reinvite check for NULL topologies
When the check for equal topologies was added to reschedule_reinvite()
it was assumed that both the pending and active media states would
actually have non-NULL topologies.  We since discovered this isn't
the case.

We now only test for equal topologies if both media states have
non-NULL topologies.  The logic had to be rearranged a bit to make
sure that we cloned the media states if their topologies were
non-NULL but weren't equal.

ASTERISK-29215

Change-Id: I61313cca7fc571144338aac826091791b87b6e17
2021-03-22 09:39:53 -05:00
Joshua C. Colp
093a4444d5 core_unreal: Fix deadlock with T.38 control frames.
When using the ast_unreal_lock_all function no channel
locks can be held before calling it.

This change unlocks the channel that indicate was
called on before doing so and then relocks it afterwards.

ASTERISK-29035

Change-Id: Id65016201b5f9c9519a216e250f9101c629e19e9
2021-03-19 09:02:38 -06:00
Asterisk Development Team
e3b0ea02ca Update for 16.17.0-rc1 16.17.0-rc1 2021-03-11 12:01:16 -05:00
Kevin Harwell
ec8b030bd7 manager: Increase the non breaking AMI version number
ASTERISK~29244 added three new AMI events, so bump the version number.

Change-Id: I0e77fa36d38fb27dec3481d4ef08131330da0632
2021-03-11 10:54:49 -06:00
Asterisk Development Team
fb17a41641 Update CHANGES and UPGRADE.txt for 16.17.0 2021-03-11 11:38:54 -05:00
Joshua C. Colp
ceb8404667 channel: Fix crash in suppress API.
There exists an inconsistency with framehook usage
such that it is only on reads that the frame should
be freed, not on writes as well.

ASTERISK-29071

Change-Id: I5ef918ebe4debac8a469e8d43bf9d6b673e8e472
2021-03-10 11:07:42 -06:00
Jaco Kroon
59129bfab8 func_callerid+res_agi: Fix compile errors related to -Werror=zero-length-bounds
Change-Id: I75152cece8a00b7523d542e5ac22796f9595692b
Signed-off-by: Jaco Kroon <jaco@uls.co.za>
2021-03-10 08:57:01 -06:00
Jaco Kroon
fce875cf46 app.h: Fix -Werror=zero-length-bounds compile errors in dev mode.
Change-Id: I5c104dc1f8417ccd3d01faf86e84ccbf89bc3b31
Signed-off-by: Jaco Kroon <jaco@uls.co.za>
2021-03-10 04:24:40 -06:00
Sean Bright
dcfcf7d70a app_dial.c: Only send DTMF on first progress event.
ASTERISK-29329 #close

Change-Id: Ic58e7a17f1ff3f785a5b21dced88682581149601
2021-03-10 04:22:53 -06:00
Alexander Traud
f875175815 res_format_attr_*: Parameter Names are Case-Insensitive.
see RFC 4855:
parameter names are case-insensitive both in media type strings and
in the default mapping to the SDP a=fmtp attribute.

This change is required for H.263+ because some implementations are
known to use even mixed-case. This does not fix ASTERISK~29268 because
H.264 was not fixed. This approach here lowers/uppers both parameter
names and parameter values. H.264 needs a different approach because
one of its parameter values is not case-insensitive:
sprop-parameter-sets is Base64.

Change-Id: Idf2a73457be231647aed3c87b1da197afba86892
2021-03-10 04:22:27 -06:00
Alexander Traud
10c0d9e711 chan_iax2: System Header strings is included via asterisk.h/compat.h.
The system header strings was included mistakenly with commit 3de0204.
That header is included via asterisk.h and there via the compat.h.

Change-Id: I3dc49060e275295f785670c87cc65fd3c3abd24a
2021-03-10 04:21:09 -06:00
Sean Bright
526917bf61 modules.conf: Fix differing usage of assignment operators.
ASTERISK-24434 #close

Change-Id: I0144e8d65d878128da59dcf3df12ca8cee47d6db
2021-03-10 04:19:10 -06:00
Sean Bright
08b94d5837 strings.h: ast_str_to_upper() and _to_lower() are not pure.
Because they modify their argument they are not pure functions and
should not be marked as such, otherwise the compiler may optimize
them away.

ASTERISK-29306 #close

Change-Id: Ibec03a08522dd39e8a137ece9bc6a3059dfaad5f
2021-03-10 04:18:14 -06:00
Sean Bright
1fc4ab38b8 res_musiconhold.c: Plug ref leak caused by ao2_replace() misuse.
ao2_replace() bumps the reference count of the object that is doing the
replacing, which is not what we want. We just want to drop the old ref
on the old object and update the pointer to point to the new object.

Pointed out by George Joseph in #asterisk-dev

Change-Id: Ie8167ed3d4b52b9d1ea2d785f885e8c27206743d
2021-03-08 18:19:40 -05:00
Torrey Searle
b90ecc6b31 res/res_rtp_asterisk: generate new SSRC on native bridge end
For RTCP to work, we update the ssrc to be the one corresponding to
the native bridge while active.  However when the bridge ends we
should generate a new SSRC as the sequence numbers will not continue
from the native bridge left off.

ASTERISK-29300 #close

Change-Id: I23334b6934d2bf6490bda4bbf6414d96b8d17d10
2021-03-08 08:14:10 -06:00
Joshua C. Colp
11b53aecc8 sorcery: Add support for more intelligent reloading.
Some sorcery objects actually contain dynamic content
that can change despite the underlying configuration
itself not changing. A good example of this is the
res_pjsip_endpoint_identifier_ip module which allows
specifying hostnames. While the configuration may not
change between reloads the DNS information of the
hostnames can.

This change adds the ability for a sorcery object to be
marked as having dynamic contents which is then taken
into account when reloading by the sorcery file based
config module. If there is an object with dynamic content
then a reload will be forced while if there are none
then the existing behavior of not reloading occurs.

ASTERISK-29321

Change-Id: I9342dc55be46cc00204533c266a68d972760a0b1
2021-03-05 10:32:59 -06:00
George Joseph
90a456e6d2 res_pjsip_refer: Move the progress dlg release to a serializer
Although the dlg session count was incremented in a pjsip servant
thread, there's no guarantee that the last thread to unref this
progress object was one.  Before we decrement, we need to make
sure that this is either a servant thread or that we push the
decrement to a serializer that is one.

Because pjsip_dlg_dec_session requires the dialog lock, we don't
want to wait on the task to complete if we had to push it to a
serializer.

Change-Id: I8ff2d5d94be3ff04298394070434e22a7d3cbc41
2021-03-05 08:18:43 -06:00
Joshua C. Colp
13b1ee8aa5 res_pjsip_registrar: Include source IP and port in log messages.
When registering it can be useful to see the source IP address and
port in cases where multiple devices are using the same endpoint
or when anonymous is in use.

ASTERISK-29325

Change-Id: Ie178a6f55f53f8473035854c411bc3d056e0a2e0
2021-03-05 08:13:43 -06:00
Joshua C. Colp
4083aa6546 asterisk: Update copyright.
ASTERISK-29326

Change-Id: Ia95dbfb66e2d11ac4d1228444283bb2e4d77396a
2021-03-04 13:48:14 -06:00
Ben Ford
b409fa1fff AST-2021-006 - res_pjsip_t38.c: Check for session_media on reinvite.
When Asterisk sends a reinvite negotiating T38 faxing, it's possible a
crash can occur if the response contains a m=image and zero port. The
reinvite callback code now checks session_media to see if it is null or
not before trying to access the udptl variable on it.

ASTERISK-29305

Change-Id: I1dfc51c5fa586e38579ede4bc228edee213ccaa9
2021-03-04 07:50:15 -07:00
Alexander Traud
fcf1bec363 res_format_attr_h263: Generate valid SDP fmtp for H.263+.
Fixed:
* RFC 4629 does not allow the value "0" for MPI, K, and N.
* Allow value "0" for PAR.
* BPP is printed only when specified because "0" has a meaning.

New:
* Added CPCF and MaxBR.
* Some implementations provide CIF without MPI: a=fmtp:xx CIF;F=1
  Although a violation of RFC 3555 section 3, we can support that.

Changed:
* Resorts the CIFs from large to small which partly fixes ASTERISK~29267.

Change-Id: I95a650c715007b8dde11a77cb37d9c6c123a441e
2021-03-03 12:27:47 -06:00
Joshua C. Colp
d65041ebea res_pjsip_nat: Don't rewrite Contact on REGISTER responses.
When sending a SIP response to an incoming REGISTER request
we don't want to change the Contact header as it will
contain the Contacts registered to the AOR and not our own
Contact URI.

ASTERISK-29235

Change-Id: I35a0723545281dd01fcd5cae497baab58720478c
2021-03-03 12:08:30 -06:00
Joshua C. Colp
c81c4f3ae2 channel: Fix memory leak in suppress API.
A frame suppression API exists as part of channels
which allows audio frames to or from a channel to
be dropped. The MuteAudio AMI action uses this
API to perform its job.

This API uses a framehook to intercept flowing
audio and drop it when appropriate. It is the
responsibility of the framehook to free the
frame it is given if it changes the frame. The
suppression API failed to do this resulting in
a leak of audio frames.

This change adds the freeing of these frames.

ASTERISK-29071

Change-Id: Ie50acd454d672d36af914050c327d2e120d8ba7b
2021-03-03 10:15:10 -06:00
Salah Ahmed
6c065088be res_rtp_asterisk: Check remote ICE reset and reset local ice attrb
This change will check is the remote ICE session got reset or not by
checking the offered ufrag and password with session. If the remote ICE
reset session then Asterisk reset its local ufrag and password to reject
binding request with Old ufrag and Password.

ASTERISK-29266

Change-Id: I9c55e79a7af98a8fbb497d336b828ba41bc34eeb
2021-03-03 09:54:24 -06:00
Holger Hans Peter Freyther
4ceb07434c pjsip: Generate progress (once) when receiving a 180 with a SDP
ASTERISK-29105

Change-Id: If1615fe7115fe544ef974b044d3cea5c48b94a38
2021-03-02 11:22:23 -06:00
Nico Kooijman
980cc0d364 main: With Dutch language year after 2020 is not spoken in say.c
Implemented the english way of saying the year in ast_say_date_with_format_nl.
Currently the numbers are spoken correctly until 2020 and stopped working
this year.

ASTERISK-29297 #close
Reported-by: Jacek Konieczny

Change-Id: If5918eed5ab05df31df4dd23f08a909a60f6aba4
2021-03-02 11:20:05 -06:00
Alexei Gradinari
d7eaf44501 res_fax: validate the remote/local Station ID for UTF-8 format
If the remote Station ID contains invalid UTF-8 characters
the asterisk fails to publish the Stasis and ReceiveFax status messages.

json.c: Error building JSON from '{s: s, s: s}': Invalid UTF-8 string.
0: /usr/sbin/asterisk(ast_json_vpack+0x98) [0x4f3f28]
1: /usr/sbin/asterisk(ast_json_pack+0x8c) [0x4f3fcc]
2: /usr/sbin/asterisk(ast_channel_publish_varset+0x2b) [0x57aa0b]
3: /usr/sbin/asterisk(pbx_builtin_setvar_helper+0x121) [0x530641]
4: /usr/lib64/asterisk/modules/res_fax.so(+0x44fe) [0x7f27f4bff4fe]
...
stasis_channels.c: Error creating message

json.c: Error building JSON from '{s: s, s: s, s: s, s: s, s: s, s: s, s: o}': Invalid UTF-8 string.
0: /usr/sbin/asterisk(ast_json_vpack+0x98) [0x4f3f28]
1: /usr/sbin/asterisk(ast_json_pack+0x8c) [0x4f3fcc]
2: /usr/lib64/asterisk/modules/res_fax.so(+0x5acd) [0x7f27f4c00acd]
...
res_fax.c: Error publishing ReceiveFax status message

This patch replaces the invalid UTF-8 Station IDs with an empty string.

ASTERISK-29312 #close

Change-Id: Ieb00b6ecf67db3bfca787649caa8517f29d987db
2021-03-02 11:17:14 -06:00
Sean Bright
8604867857 app_page.c: Don't fail to Page if beep sound file is missing
ASTERISK-16799 #close

Change-Id: I40367b0d6dbf66a39721bde060c8b2d734a61cf4
2021-02-26 09:35:48 -06:00
George Joseph
1c1d4b2c68 res_pjsip_refer: Refactor progress locking and serialization
Although refer_progress_notify() always runs in the progress
serializer, the pjproject evsub module itself can cause the
subscription to be destroyed which then triggers
refer_progress_on_evsub_state() to clean it up.  In this case,
it's possible that refer_progress_notify() could get the
subscription pulled out from under it while it's trying to use
it.

At one point we tried to have refer_progress_on_evsub_state()
push the cleanup to the serializer and wait for its return before
returning to pjproject but since pjproject calls its state
callbacks with the dialog locked, this required us to unlock the
dialog while waiting for the serialized cleanup, then lock it
again before returning to pjproject. There were also still some
cases where other callers of refer_progress_notify() weren't
using the serializer and crashes were resulting.

Although all callers of refer_progress_notify() now use the
progress serializer, we decided to simplify the locking so we
didn't have to unlock and relock the dialog in
refer_progress_on_evsub_state().

Now, refer_progress_notify() holds the dialog lock for its
duration and since pjproject also holds the dialog lock while
calling refer_progress_on_evsub_state() (which does the cleanup),
there should be no more chances for the subscription to be
cleaned up while still being used to send NOTIFYs.

To be extra safe, we also now increment the session count on
the dialog when we create a progress object and decrement
the count when the progress is destroyed.

ASTERISK-29313

Change-Id: I97a8bb01771a3c85345649b8124507f7622a8480
2021-02-26 08:12:37 -06:00
Kevin Harwell
11fa7f6e0c res_rtp_asterisk: Add packet subtype during RTCP debug when relevant
For some RTCP packet types the report count is actually the packet's subtype.
This was not being reflected in the packet debug output.

This patch makes it so for some RTCP packet types a "Packet Subtype" is
now output in the debug replacing the "Reception reports" (i.e count).

Change-Id: Id4f4b77bb37077a4c4f039abd6a069287bfefcb8
2021-02-26 08:05:56 -06:00
Joshua C. Colp
7acb6e2194 res_pjsip_session: Always produce offer on re-INVITE without SDP.
When PJSIP receives a re-INVITE without an SDP offer the INVITE
session library will first call the on_create_offer callback and
if unavailable then use the active negotiated SDP as the offer.

In some cases this would result in a different SDP then was
previously used without an incremented SDP version number. The two
known cases are:

1. Sending an initial INVITE with a set of codecs and having the
remote side answer with a subset. The active negotiated SDP would
have the pruned list but would not have an incremented SDP version
number.

2. Using re-INVITE for unhold. We would modify the active negotiated
SDP but would not increment the SDP version.

To solve these, and potential other unknown cases, the on_create_offer
callback has now been implemented which produces a fresh offer with
incremented SDP version number. This better fits within the model
provided by the INVITE session library.

ASTERISK-28452

Change-Id: I2d81048d54edcb80fe38fdbb954a86f0a58281a1
2021-02-25 08:50:44 -06:00
Ben Ford
88461a23bb res_pjsip_session.c: Check topology on re-invite.
Removes an unnecessary check for the conditional that compares the
stream topologies to see if they are equal to suppress re-invites. This
was a problem when a Digium phone received an INVITE that offered codecs
different than what it supported, causing Asterisk to send the
re-invite.

ASTERISK-29303

Change-Id: I04dc91befb2387904e28a9aaeaa3bcdbcaa7fa63
2021-02-25 08:44:29 -06:00
Boris P. Korzun
3096dcee15 res_config_pgsql: Limit realtime_pgsql() to return one (no more) record.
Added a SELECT 'LIMIT' clause to realtime_pgsql() and refactored the function.

ASTERISK-29293 #close

Change-Id: If5a6d4b1072ea2e6e89059b21139d554a74b34f5
2021-02-25 07:53:49 -06:00
Jaco Kroon
9a1cf7fb77 res_odbc_transaction: correctly initialise forcecommit value from DSN.
Also improve the in-process documentation to clarify that the value is
initialised from the DSN and not default false, but that the DSN's value
is default false if unset.

ASTERISK-29311 #close

Change-Id: I46e2379f7b0656034442bce77cb37ccd4e61098d
Signed-off-by: Jaco Kroon <jaco@uls.co.za>
2021-02-23 14:52:56 -06:00
Ivan Poddubnyi
c63ab5580c app_queue: Fix conversion of complex extension states into device states
Queue members using dialplan hints as a state interface must handle
INUSE+RINGING hint as RINGINUSE devstate, and INUSE + ONHOLD as INUSE.

ASTERISK-28369

Change-Id: I127e06943d4b4f1afc518f9e396de77449992b9f
2021-02-23 13:37:51 -06:00
Jaco Kroon
a63c7883b4 app.h: Restore C++ compatibility for macro AST_DECLARE_APP_ARGS
This partially reverts commit 3d1bf3c537,
specifically for app.h.

This works with both gcc 9.3.0 and 10.2.0 now, both for C and C++ (as
tested with external modules).

ASTERISK-29287

Change-Id: I5b9f02a9b290675682a1d13f1788fdda597c9fca
Signed-off-by: Jaco Kroon <jaco@uls.co.za>
2021-02-23 13:01:54 -06:00
Alexander Traud
99666117be chan_sip: Filter pass-through audio/video formats away, again.
Instead of looking for pass-through formats in the list of transcodable
formats (which is going to find nothing), go through the result which
is going to be the jointcaps of the tech_pvt of the channel. Finally,
only with that list, ast_format_cap_remove(.) is going to succeed.

This restores the behaviour of Asterisk 1.8. However, it does not fix
ASTERISK_29282 because that issue report is about chan_sip and PJSIP.
Here, only chan_sip is fixed because PJSIP does not even call
ast_rtp_instance_available_formats -> ast_translate_available_format.

Change-Id: Icade2366ac2b82935b95a9981678c987da2e8c34
2021-02-23 12:41:56 -06:00
Jaco Kroon
d847f7e8f8 func_odbc: Introduce minargs config and expose ARGC in addition to ARGn.
minargs enables enforcing of minimum count of arguments to pass to
func_odbc, so if you're unconditionally using ARG1 through ARG4 then
this should be set to 4.  func_odbc will generate an error in this case,
so for example

[FOO]
minargs = 4

and ODBC_FOO(a,b,c) in dialplan will now error out instead of using a
potentially leaked ARG4 from Gosub().

ARGC is needed if you're using optional argument, to verify whether or
not an argument has been passed, else it's possible to use a leaked ARGn
from Gosub (app_stack).  So now you can safely do
${IF($[${ARGC}>3]?${ARGV}:default value)} kind of thing.

Change-Id: I6ca0b137d90b03f6aa9c496991f6cbf1518f6c24
Signed-off-by: Jaco Kroon <jaco@uls.co.za>
2021-02-23 12:18:00 -06:00
Sebastien Duthil
435d68be97 app_mixmonitor: Add AMI events MixMonitorStart, -Stop and -Mute.
ASTERISK-29244

Change-Id: I1862d58264c2c8b5d8983272cb29734b184d67c5
2021-02-18 17:17:00 -06:00
Kevin Harwell
5699eb7b0f AST-2021-002: Remote crash possible when negotiating T.38
When an endpoint requests to re-negotiate for fax and the incoming
re-invite is received prior to Asterisk sending out the 200 OK for
the initial invite the re-invite gets delayed. When Asterisk does
finally send the re-inivite the SDP includes streams for both audio
and T.38.

This happens because when the pending topology and active topologies
differ (pending stream is not in the active) in the delayed scenario
the pending stream is appended to the active topology. However, in
the fax case the pending stream should replace the active.

This patch makes it so when a delay occurs during fax negotiation,
to or from, the audio stream is replaced by the T.38 stream, or vice
versa instead of being appended.

Further when Asterisk sent the re-invite with both audio and T.38,
and the endpoint responded with a declined T.38 stream then Asterisk
would crash when attempting to change the T.38 state.

This patch also puts in a check that ensures the media state has a
valid fax session (associated udptl object) before changing the
T.38 state internally.

ASTERISK-29203 #close

Change-Id: I407f4fa58651255b6a9030d34fd6578cf65ccf09
2021-02-18 10:38:09 -06:00
Alexander Traud
c98de279b2 rtp: Enable srtp replay protection
Add option "srtpreplayprotection" rtp.conf to enable srtp
replay protection.

ASTERISK-29260
Reported by: Alexander Traud

Change-Id: I5cd346e3c6b6812039d1901aa4b7be688173b458
2021-02-18 10:36:25 -06:00
Ivan Poddubnyi
872c1786e6 res_pjsip_diversion: Fix adding more than one histinfo to Supported
New responses sent within a PJSIP sessions are based on those that were
sent before. Therefore, adding/modifying a header once causes it to be
sent on all responses that follow.

Sending 181 Call Is Being Forwarded many times first adds "histinfo"
duplicated more and more, and eventually overflows past the array
boundary.

This commit adds a check preventing adding "histinfo" more than once,
and skipping it if there is no more space in the header.

Similar overflow situations can also occur in res_pjsip_path and
res_pjsip_outbound_registration so those were also modified to
check the bounds and suppress duplicate Supported values.

ASTERISK-29227
Reported by: Ivan Poddubny

Change-Id: Id43704a1f1a0293e35cc7f844026f0b04f2ac322
2021-02-18 10:35:05 -06:00
Sean Bright
76125bec4a res_rtp_asterisk.c: Fix signed mismatch that leads to overflow
ASTERISK-29205 #close

Change-Id: Ib7aa65644e8df76e2378d7613ee7cf751b9d0bea
2021-02-18 10:33:08 -06:00
Joshua C. Colp
5a4531782c pjsip: Make modify_local_offer2 tolerate previous failed SDP.
If a remote side is broken and sends an SDP that can not be
negotiated the call will be torn down but there is a window
where a second 183 Session Progress or 200 OK that is forked
can be received that also attempts to negotiate SDP. Since
the code marked the SDP negotiation as being done and complete
prior to this it assumes that there is an active local and remote
SDP which it can modify, while in fact there is not as the SDP
did not successfully negotiate. Since there is no local or remote
SDP a crash occurs.

This patch changes the pjmedia_sdp_neg_modify_local_offer2
function to no longer assume that a previous SDP negotiation
was successful.

ASTERISK-29196

Change-Id: I22de45916d3b05fdc2a67da92b3a38271ee5949e
2021-02-18 10:08:14 -06:00
George Joseph
3be7de5b11 res_pjsip_refer: Always serialize calls to refer_progress_notify
refer_progress_notify wasn't always being called from the progress
serializer.  This could allow clearing notification->progress->sub
in one thread while another was trying to use it.

* Instances where refer_progress_notify was being called in-line,
  have been changed to use ast_sip_push_task().

Change-Id: Idcf1934c4e873f2c82e2d106f8d9f040caf9fa1e
2021-02-17 11:02:47 -06:00
Ben Ford
215550ed4b core_unreal: Fix T.38 faxing when using local channels.
After some changes to streams and topologies, receiving fax through
local channels stopped working. This change adds a stream topology with
a stream of type IMAGE to the local channel pair and allows fax to be
received.

ASTERISK-29035 #close

Change-Id: Id103cc5c9295295d8e68d5628e76220f8f17e9fb
2021-02-16 18:11:07 -06:00
Boris P. Korzun
f996c7a48f format_wav: Support of MIME-type for wav16
Provided a support of a MIME-type for wav16. Added new MIME-type
for classic wav.

ASTERISK-29275 #close

Change-Id: I749bda287ba1ab20c1e0af5e4c0153817d47873b
2021-02-12 07:20:44 -06:00
Alexander Traud
2bcec10db8 chan_sip: Allow [peer] without audio (text+video).
Two previous commits, 620d9f4 and 6d980de, allow to set up a call
without audio, again. That was introduced originally with commit f04d5fb
but changed and broke over time. The original commit missed one
scenario: A [peer] section in sip.conf, which does not allow audio at
all. In that case, chan_sip rejected the call, although even when the
requester offered no audio. Now, chan_sip does not check whether there
is no audio format but checks whether there is no format in general. In
other words, if there is at least one format to offer, the call succeeds.

However, to prevent calls with no-audio, chan_sip still rejects calls
when both call parties (caller = requester of the call *and* callee =
[peer] section in sip.conf) included audio. In such a case, it is
expected that the call should have audio.

ASTERISK-29280

Change-Id: I0fb74faf51ef22a60c10b467df6a4d1c1943b73e
2021-02-12 07:18:50 -06:00