Commit graph

437 commits

Author SHA1 Message Date
Joshua Colp
50ac85cb40 stasis: Segment channel snapshot to reduce creation cost.
When a channel snapshot was created it used to be done
from scratch, copying all data (many strings). This incurs
a cost when doing so.

This change segments the channel snapshot into different
components which can be reused if unchanged from the
previous snapshot creation, reducing the cost. In normal
cases this results in some pointers being copied with
reference count being bumped, some integers being set,
and a string or two copied. The other benefit is that it
is now possible to determine if a channel snapshot update
is redundant and thus stop it before a message is published
to stasis.

The specific segments in the channel snapshot were split up
based on whether they are changed together, how often they
are changed, and their general grouping. In practice only
1 (or 0) of the segments actually get changed in normal
operation.

Invalidation is done by setting a flag on the channel when
the segment source is changed, forcing creation of a new
segment when the channel snapshot is created.

ASTERISK-28119

Change-Id: I5d7ef3df963a88ac47bc187d73c5225c315f8423
2018-11-26 12:56:24 -06:00
Corey Farrell
021ce938ca
astobj2: Remove legacy ao2_container_alloc routine.
Replace usage of ao2_container_alloc with ao2_container_alloc_hash or
ao2_container_alloc_list.  Remove ao2_container_alloc macro.

Change-Id: I0907d78bc66efc775672df37c8faad00f2f6c088
2018-11-21 09:56:16 -05:00
Chris-Savinovich
a3fc97aa13 res_pjsip: Send a 503 response when overload state if reliable transport.
When Asterisk's taskprocessors get overloaded we need to reduce the work
load. res_pjsip currently ignores new SIP requests and relies on SIP
retransmissions in the hope that the overload condition will clear soon
enough to handle the retransmitted SIP request.
This change adds the following code after ast_taskprocessor_alert_get()
has returned TRUE:
1- identifies transport type. If non-udp then send a 503 response
2- if transport type is udp/udp6 then ignore, as before.

Change-Id: I1c230b40d43a254ea0f226b7acf9ee480a5d3836
2018-11-07 07:59:03 -05:00
Alexei Gradinari
eee935983b pjsip: new endpoint's options to control Connected Line updates
This patch adds new options 'trust_connected_line' and 'send_connected_line'
to the endpoint.

The option 'trust_connected_line' is to control if connected line updates
are accepted from this endpoint.

The option 'send_connected_line' is to control if connected line updates
can be sent to this endpoint.

The default value is 'yes' for both options.

Change-Id: I16af967815efd904597ec2f033337e4333d097cd
2018-10-30 10:39:28 -05:00
Torrey Searle
cac4ccef25 res_pjsip_session: add new flag use_callerid_contact
Add a new global flag to res_pjsip to allow the callerid to be used
as the username in the contact header.  This allows chan_pjsip to have
the same behavour as chan_sip

ASTERISK-28087 #close

Change-Id: I9a720e058323f6862a91c62f8a8c1a4b5c087b95
2018-10-26 10:39:03 +02:00
Nick French
37b2e68628 res_pjsip: Implement additional SIP RFCs for Google Voice trunk compatability
This change implements a few different generic things which were brought
on by Google Voice SIP.

1.  The concept of flow transports have been introduced.  These are
configurable transports in pjsip.conf which can be used to reference a
flow of signaling to a target.  These have runtime configuration that can
be changed by the signaling itself (such as Service-Routes and
P-Preferred-Identity).  When used these guarantee an individual connection
(in the case of TCP or TLS) even if multiple flow transports exist to the
same target.

2.  Service-Routes (RFC 3608) support has been added to the outbound
registration module which when received will be stored on the flow
transport and used for requests referencing it.

3.  P-Associated-URI / P-Preferred-Identity (RFC 3325) support has been
added to the outbound registration module.  If a P-Associated-URI header
is received it will be used on requests as the P-Preferred-Identity.

4.  Configurable outbound extension support has been added to the outbound
registration module.  When set the extension will be placed in the
Supported header.

5.  Header parameters can now be configured on an outbound registration
which will be placed in the Contact header.

6.  Google specific OAuth / Bearer token authentication
(draft-ietf-sipcore-sip-authn-02) has been added to the outbound
registration module.

All functionality changes are controlled by pjsip.conf configuration
options and do not affect non-configured pjsip endpoints otherwise.

ASTERISK-27971 #close

Change-Id: Id214c2d1c550a41fcf564b7df8f3da7be565bd58
2018-10-24 07:51:25 -05:00
Alexei Gradinari
aae5bdc22e res_pjsip: set callerid_tag to empty string
This patch sets the callerid_tag to empty string by default.

If the callerid_tag is set to NULL then the tag does not
become part of a connected line update.
For example:
Alice's tag is "Alice".
Bob's tag is empty.
Charlie's tag is "Charlie".
Alice calls Bob and then does attended transfer to Charlie.
When Alice hangs up the CONNECTEDLINE(tag) is "Alice"
on the interception routine on the Charlie's channel, but should be empty.

Ths patch also fix memory leaks if there are more then one options
"callerid", "callerid_tag", "voicemail_extension" and "contact_user"
in the pjsip.conf endpoint definition.

Change-Id: I86ba455c4677ca8d516d9a04ce7fb4d24dd576e4
2018-10-15 14:17:43 -05:00
Alexei Gradinari
8bb031abc7 res_pjsip: improve realtime performance on CLI 'pjsip show contacts'
CLI command 'pjsip show contacts' inefficiently make a lot of DB requests.

For example if there are 10k aors then asterisk requests these 10k records
of aor and then does 10k requests of contact - one request per aor.

Even if use 'like <pattern>' the asterisk requests all aor's and contact's
records and then filters them by itself.

This patch gathers contact's container by
- retrieving all dynamic contacts by regex (filtered by reg_server)
- retrieving all aors with permanent contacts
- finally filters container by regex

ASTERISK-28077 #close

Change-Id: Id0ad65d14952a02fb213273a90f3f680a8149618
2018-09-28 17:09:33 -05:00
Joshua Colp
ce9a980be6 pjproject: Upgrade to 2.8.
This change brings in PJSIP 2.8, removes all the patches
that were merged upstream, and makes a minor change to
support a breaking change that was done.

ASTERISK-28059

Change-Id: I5097772b11b0f95c3c1f52df6400158666f0a189
2018-09-18 11:32:18 -05:00
Sean Bright
07cb13f75f res_pjsip: Log IPv6 addresses correctly
Both pjsip_tx_data.tp_info.dst_name and pjsip_rx_data.pkt_info.src_name
store IPv6 addresses without enclosing brackets. This causes some log
output to be confusing because it is difficult to separate the IPv6
address from a port specification.

* Use pj_sockaddr_print() along with pjsip_tx_data.tp_info.dst_addr and
  pjsip_rx_data.pkt_info.src_addr where possible for consistent IPv6
  output.

* When a pj_sockaddr is not available, explicitly wrap IPv6 addresses
  in brackets.

* When assigning pjsip_rx_data.pkt_info.src_name ourselves, make sure
  to also set pjsip_rx_data.pkt_info.src_addr.

Change-Id: I5cfe997ced7883862a12b9c7d8551d76ae02fcf8
2018-09-14 14:59:23 -05:00
Richard Mudgett
d60411a2b4 res_pjsip: Fix mwi_subscribe_replaces_unsolicited type mismatch
ASTERISK-27988

Change-Id: Iccafdd0552ea8aaed647620fb14499f1bf341843
2018-08-29 09:47:59 -05:00
Joshua Colp
5320b18bfe Merge "res_pjsip: Reduce processing when a Contact is updated." 2018-08-22 12:42:46 -05:00
Joshua Colp
457ba355aa res_pjsip: Reduce processing when a Contact is updated.
When a Contact is updated the only material change that qualify
support cares about is the underlying configuration for the AOR.
In this case we will update things with the new AOR information but
otherwise the callback to indicate the Contact has changed can be
ignored.

This is because it is only when a Contact is added or deleted that
material changes occur within the qualify support. An update can't
change the URI since it would result in a new Contact so it can be
ignored.

Change-Id: I2f97ebfa79969a36a97bb7b9afd5b6268cf1a07d
2018-08-18 18:09:25 -03:00
Joshua Colp
a88cec6334 Merge "res_pjsip: Resolve transport management leak at shutdown." 2018-08-17 05:38:56 -05:00
Corey Farrell
24302bda21 res_pjsip: Resolve transport management leak at shutdown.
Cleanup idle check scheduled events at shutdown.

Change-Id: I61bfbb56bac69fe840c3242927d31ff3593be461
2018-08-15 13:55:41 -05:00
Corey Farrell
52fe5fe2c8 res_pjsip: Fix leak in pjsip_options.
sip_options_get_endpoint_state_compositor_state leaked a reference to
the first available endpoint state compositor that was found.

Change-Id: Idb6be19f7219b6eed1dfb19c1e740dd40cb3fdc7
2018-08-15 11:33:21 -05:00
Joshua Colp
39a8920504 Merge "res_pjsip: Make pjlib.h consistently included." 2018-08-08 05:53:53 -05:00
Alexander Traud
603d1e8d4b pjproject_bundled: Fix for Solaris builds. Do not undef s_addr.
The authors of PJProject undef s_addr because of some issue in Microsoft
Windows. However in Oracle Solaris, s_addr is not a structure member, but
defined to map to the real structure member.

Updates the patch from ASTERISK_20366

ASTERISK-27997

Change-Id: I8223026d4d54e2a46521085fcc94bfa6ebe35b11
2018-08-03 16:59:03 -05:00
Richard Mudgett
acbb9f52b2 res_pjsip: Make pjlib.h consistently included.
* Don't include pjlib.h twice in res_pjsip.h
* Consistently use #include <> form for pjproject includes.
(pjsip.h and pjlib.h)

Change-Id: I3f7b42044840de64edf7e9d7695cb60c45990dc7
2018-08-03 16:07:22 -05:00
George Joseph
9e47a7ffca Merge "res_pjsip: Update default keepalive interval to 90 seconds." 2018-07-24 08:30:13 -05:00
Joshua Colp
2c9757bc90 res_pjsip: Update default keepalive interval to 90 seconds.
A change recently went in which disabled the built-in PJSIP
keepalive. This defaulted to 90 seconds and kept TCP/TLS
connections alive. Disabling this functionality has resulted
in a behavior change of not doing keepalives by default resulting
in TCP/TLS connections dropping for some people.

This change makes our default keepalive interval 90 seconds
to match the previous behavior and preserve it.

ASTERISK-27978

Change-Id: Ibd9a45f3cbe5d9bb6d2161268696645ff781b1d6
2018-07-20 06:55:48 -05:00
Richard Mudgett
8a100ca52b pjsip_resolver.c: Use replacement function
* Use the replacement function ast_sip_push_task_wait_servant() instead of
the deprecated ast_sip_push_task_synchronous().

Change-Id: I145b550ba7054640c7faa3b644e63137f505c612
2018-07-19 13:54:29 -05:00
Joshua Colp
59323121f3 res_sorcery_config: Allow configuration section to be used based on name.
A problem I've seen countless times is a global or system section
for PJSIP not getting applied. This is inevitably the result of
the "type=" line missing. This change alleviates that problem.

The ability to specify an explicit section name has been
added to res_sorcery_config. If the configured section
name matches this and there are no unknown things configured
the section is taken as being for the given type.

Both the PJSIP "global" and "system" types now support this
so you can just name your section "global" or "system" and it
will be matched and used, even without a "type=" line.

ASTERISK-27972

Change-Id: Ie22723663c1ddd24f869af8c9b4c1b59e2476893
2018-07-18 13:20:49 -05:00
Joshua Colp
68c0c081f9 Merge "res_pjsip/pjsip_transport_management.c: Fix deadlock with transport keep alive." 2018-07-09 07:14:51 -05:00
George Joseph
8f42447c68 res_pjsip: Add 'suppress_q850_reason_headers' option to endpoint
A new option 'suppress_q850_reason_headers' has been added to the
endpoint object. Some devices can't accept multiple Reason headers and
get confused when both 'SIP' and 'Q.850' Reason headers are received.
This option allows the 'Q.850' Reason header to be suppressed.
The default value is 'no'.

ASTERISK-27949
Reported-by: Ross Beer

Change-Id: I54cf37a827d77de2079256bb3de7e90fa5e1deb1
2018-07-06 07:03:45 -06:00
Richard Mudgett
0aff1a278e res_pjsip/pjsip_transport_management.c: Fix deadlock with transport keep alive.
Using the keep_alive_interval option can result in a deadlock between the
pjproject transport manager group lock and the monitored transports ao2
container lock.  The pjproject transport manager group lock has to be
superior in the locking order to the monitored transports ao2 container
lock because of pjproject callbacks called when already holding the group
lock.  The lock inversion happens when Asterisk attempts to send a keep
alive packet over the reliable transports.

* Made keepalive_transport_thread() iterate over the monitored transports
container rather than use the ao2_callback() method.  This avoids holding
the container lock when sending the keep alive packet.

ASTERISK-26686

Change-Id: I5d5392a52e698bbe41a93f7d8e92bf0e61fe3951
2018-07-03 12:15:40 -05:00
Joshua Colp
de5144e751 pjsip: Clarify certificate configuration for Websocket.
The Websocket transport uses the built-in HTTP server. As a result
the TLS configuration is done in http.conf and not in pjsip.conf.

This change adds a warning if this is configured in pjsip.conf and
also clarifies in the sample configuration file.

Change-Id: I187d994d328c3ed274b6754fd4c2a4955bdc6dd9
2018-07-03 07:56:45 -05:00
George Joseph
880fbff6b7 res_pjsip_session: Add ability to accept multiple sdp answers
pjproject by default currently will follow media forked during an INVITE
on outbound calls if the To tag is different on a subsequent response as
that on an earlier response.  We handle this correctly.  There have
been reported cases where the To tag is the same but we still need to
follow the media.  The pjproject patch in this commit adds the
capability to sip_inv and also adds the capability to control it at
runtime.  The original "different tag" behavior was always controllable
at runtime but we never did anything with it and left it to default to
TRUE.

So, along with the pjproject patch, this commit adds options to both the
system and endpoint objects to control the two behaviors, and a small
logic change to session_inv_on_media_update in res_pjsip_session to
control the behavior at the endpoint level.

The default behavior for "different tags" remains the same at TRUE and
the default for "same tag" is FALSE.

Change-Id: I64d071942b79adb2f0a4e13137389b19404fe3d6
ASTERISK-27936
Reported-by: Ross Beer
2018-06-26 07:05:34 -06:00
Richard Mudgett
cad50d6dbf VECTOR: Passing parameters with side effects to macros is dangerous.
* Fix several instances where we were bumping a ref in the parameter and
then unrefing the object if it failed.  The way the AST_VECTOR_APPEND()
and AST_VECTOR_REPLACE() macros are implemented means if it fails the new
value was never evaluated.

Change-Id: I2847872a455b11ea7e5b7ce697c0a455a1d0ac9a
2018-06-21 16:10:52 -06:00
Richard Mudgett
81ac32a85f AST-2018-008: Fix enumeration of endpoints from ACL rejected addresses.
When endpoint specific ACL rules block a SIP request they respond with a
403 forbidden.  However, if an endpoint is not identified then a 401
unauthorized response is sent.  This vulnerability just discloses which
requests hit a defined endpoint.  The ACL rules cannot be bypassed to gain
access to the disclosed endpoints.

* Made endpoint specific ACL rules now respond with a 401 unauthorized
which is the same as if an endpoint were not identified.  The fix is
accomplished by replacing the found endpoint with the artificial endpoint
which always fails authentication.

ASTERISK-27818

Change-Id: Icb275a54ff8e2df6c671a6d9bda37b5d732b3b32
2018-06-11 09:28:43 -06:00
George Joseph
7b5fc5d20f Merge "pjsip_options: handle modification of qualify options in realtime" 2018-06-06 10:12:58 -05:00
Alexei Gradinari
7af5e86821 pjsip_options: show/reload AOR qualify options using CLI
Currentrly pjsip_options code does not handle the situation when the
AOR qualify options were changed.

Also there is no way to find out what qualify options are using.

This patch add CLI commands to show and synchronize Aor qualify options:
pjsip show qualify endpoint <id>
    Show the current qualify options for all Aors on the PJSIP endpoint.
pjsip show qualify aor <id>
    Show the PJSIP Aor current qualify options.
pjsip reload qualify endpoint <id>
    Synchronize the qualify options for all Aors on the PJSIP endpoint.
pjsip reload qualify aor <id>
    Synchronize the PJSIP Aor qualify options.

ASTERISK-27872

Change-Id: I1746d10ef2b7954f2293f2e606cdd7428068c38c
2018-06-05 14:46:51 -04:00
Alexei Gradinari
e46b442e38 pjsip_options: handle modification of qualify options in realtime
Currentrly pjsip_options code does not handle the situation when the
qualify options were changed in realtime database.
Only 'module reload res_pjsip' helps.

This patch add a check on contact add/update observers if the contact
qualify options are different than local aor qualify options.
If the qualify options were modified then synchronize
the pjsip_options AOR local state.

ASTERISK-27872

Change-Id: Id55210a18e62ed5d35a88e408d5fe84a3c513c62
2018-06-05 12:35:24 -06:00
Joshua Colp
195af35026 Merge "Fix GCC 8 build issues." 2018-05-16 13:56:34 -05:00
Joshua Colp
a103221de2 Merge "pjsip: Rewrite OPTIONS support with new eyes." 2018-05-14 04:06:53 -05:00
Corey Farrell
b5914d90ac Fix GCC 8 build issues.
This fixes build warnings found by GCC 8.  In some cases format
truncation is intentional so the warning is just suppressed.

ASTERISK-27824 #close

Change-Id: I724f146cbddba8b86619d4c4a9931ee877995c84
2018-05-11 09:48:58 -04:00
Jenkins2
8e228fc138 Merge "res_pjsip/pjsip_distributor.c: Add missing off-nominal request response." 2018-05-03 11:32:08 -05:00
Jenkins2
706b899358 Merge "pjsip: Increase maximum number of usable ciphers & other cleanups" 2018-05-03 07:41:33 -05:00
Sean Bright
239074c759 pjsip: Increase maximum number of usable ciphers & other cleanups
* Increase maximum number of ciphers from 100 to 256 (or whatever
  PJ_SSL_SOCK_MAX_CIPHERS is #define'd to)

* Simplify logic in cipher_name_to_id()

* Make signed/unsigned comparison consistent

Re: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=897412

Reported by: Ondřej Holas

Change-Id: Iea620f03915a1b873e79743154255c3148a514e7
2018-05-02 07:06:07 -06:00
Richard Mudgett
11b7de82c5 res_pjsip/pjsip_distributor.c: Add missing off-nominal request response.
Change-Id: I389579b39c523d1d1e8ce020ef549a8bb5781c9b
2018-05-01 16:23:33 -06:00
Richard Mudgett
6cab3c836a res_pjsip/pjsip_distributor.c: Pull some assignments out of if tests.
Change-Id: I3d30d638b53a4bbe9bf9aad853c649d583894112
2018-05-01 16:17:20 -06:00
Joshua Colp
882e79b77e pjsip: Rewrite OPTIONS support with new eyes.
The OPTIONS support in PJSIP has organically grown, like many things in
Asterisk.  It has been tweaked, changed, and adapted based on situations
run into.  Unfortunately this has taken its toll.  Configuration file
based objects have poor performance and even dynamic ones aren't that
great.

This change scraps the existing code and starts fresh with new eyes.  It
leverages all of the APIs made available such as sorcery observers and
serializers to provide a better implementation.

1.  The state of contacts, AORs, and endpoints relevant to the qualify
process is maintained.  This state can be updated by external forces (such
as a device registering/unregistering) and also the reload process.  This
state also includes the association between endpoints and AORs.

2.  AORs are scheduled and not contacts.  This reduces the amount of work
spent juggling scheduled items.

3.  Manipulation of which AORs are being qualified and the endpoint states
all occur within a serializer to reduce the conflict that can occur with
multiple threads attempting to modify things.

4.  Operations regarding an AOR use a serializer specific to that AOR.

5.  AORs and endpoint state act as state compositors.  They take input
from lower level objects (contacts feed AORs, AORs feed endpoint state)
and determine if a sufficient enough change has occurred to be fed further
up the chain.

6.  Realtime is supported by using observers to know when a contact has
been registered.  If state does not exist for the associated AOR then it
is retrieved and becomes active as appropriate.

The end result of all of this is best shown with a configuration file of
3000 endpoints each with an AOR that has a static contact.  In the old
code it would take over a minute to load and use all 8 of my cores.  This
new code takes 2-3 seconds and barely touches the CPU even while dealing
with all of the OPTIONS requests.

ASTERISK-26806

Change-Id: I6a5ebbfca9001dfe933eaeac4d3babd8d2e6f082
2018-04-27 17:28:16 -05:00
Richard Mudgett
d50d637764 stringfields: Collect extended stringfields into the stringfield section.
Use of extended stringfields is a temporary mechanism to avoid ABI
breakage in released branches without resorting to more inconvienient
methods.

* Collect existing extended stringfields into the parent stringfield
section of the struct.

Change-Id: I8d46d037801b4518837c3ea4b6df95ceadc9436b
2018-04-16 16:43:20 -05:00
George Joseph
38dae51b78 Merge "res_pjsip.c: Split ast_sip_push_task_synchronous() to fit expectations." 2018-04-16 11:12:30 -05:00
Jenkins2
267e007c28 Merge "pjsip_scheduler.c: Add ability to trace scheduled tasks." 2018-04-16 07:11:26 -05:00
Jenkins2
1f6fc78a2e Merge "pjsip_scheduler.c: Fix some corner cases." 2018-04-16 06:49:14 -05:00
Richard Mudgett
3bb6cf43b5 pjsip_scheduler.c: Add ability to trace scheduled tasks.
When a scheduled task is created you can pass in the
AST_SIP_SCHED_TASK_TRACK flag.  This new flag causes scheduling events to
be logged.

Change-Id: I91967eb3d5a220915ce86881a28af772f9a7f56b
2018-04-12 17:35:19 -05:00
Richard Mudgett
237d341bbd res_pjsip.c: Split ast_sip_push_task_synchronous() to fit expectations.
ast_sip_push_task_synchronous() did not necessarily execute the passed in
task under the specified serializer.  If the current thread is any
registered pjsip thread then it would execute the task immediately instead
of under the specified serializer.  Reentrancy issues could result if the
task does not execute with the right serializer.

The original reason ast_sip_push_task_synchronous() checked to see if the
current thread was a registered pjsip thread was because of a deadlock
with masquerades and the channel technology's fixup callback
(ASTERISK_22936).  A subsequent masquerade deadlock fix (ASTERISK_24356)
involving call pickups avoided the original deadlock situation entirely.
The PJSIP channel technology's fixup callback no longer needed to call
ast_sip_push_task_synchronous().

However, there are a few places where this unexpected behavior is still
required to avoid deadlocks.  The pjsip monitor thread executes callbacks
that do calls to ast_sip_push_task_synchronous() that would deadlock if
the task were actually pushed to the specified serializer.  I ran into one
dealing with the pubsub subscriptions where an ao2 destructor called
ast_sip_push_task_synchronous().

* Split ast_sip_push_task_synchronous() into
ast_sip_push_task_wait_servant() and ast_sip_push_task_wait_serializer().
ast_sip_push_task_wait_servant() has the old behavior of
ast_sip_push_task_synchronous().  ast_sip_push_task_wait_serializer() has
the new behavior where the task is always executed by the specified
serializer or a picked serializer if one is not passed in.  Both functions
behave the same if the current thread is not a SIP servant.

* Redirected ast_sip_push_task_synchronous() to
ast_sip_push_task_wait_servant() to preserve API for released branches.

ASTERISK_26806

Change-Id: Id040fa42c0e5972f4c8deef380921461d213b9f3
2018-04-12 17:34:16 -05:00
Richard Mudgett
c2f85e881d pjsip_scheduler.c: Fix some corner cases.
* Fix the periodic interval wander because it may take significant time
between the sched thread queueing the task in the serializer and the
serializer actually executing the task.  The time it takes to actually
execute the task was already taken into account.

* Pass a schtd ref to the serializer when we queue a scheduled task on
the serializer.  We don't want it going away on us while it is in the
serializer queue.

* Skip the scheduled task if the task was canceled between queueing the
task to the serializer and the serializer actually executing the task.

* Reorder struct ast_sip_sched_task to avoid unnecessary padding.  Removed
task_id and added next_periodic.

* Hold a ref to the passed in serializer so the serializer cannot go away
on the scheduled task.

ASTERISK_26806

Change-Id: I6c8046b75f6953792c8c30e55b836a4291143f24
2018-04-12 17:34:16 -05:00
Richard Mudgett
96c4a57edf pjsip_scheduler.c: Sort "pjsip show scheduled_tasks" output.
* A side benefit is that the scheduled tasks are not completely blocked
while the CLI command executes.

* Adjusted the "Task Name" column width to have more room for longer
names.

Change-Id: Iec64aa463ee8b10eef90120e00c38b1fb444087e
2018-04-12 16:46:50 -05:00