Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Sep 2022 19:18:57 +0300
From:      Maxim Sobolev <sobomax@freebsd.org>
To:        Alan Somers <asomers@freebsd.org>
Cc:        src-committers <src-committers@freebsd.org>, dev-commits-src-all@freebsd.org,  dev-commits-src-main@freebsd.org
Subject:   Re: git: d3f96f661050 - main - Fix O(n^2) behavior in sysctl
Message-ID:  <CAH7qZfvgRyva8gry0J1VX2oUGcJ8ncPsavkjHa9GdYYiSu_-DQ@mail.gmail.com>
In-Reply-To: <202209270004.28R04K1r086731@gitrepo.freebsd.org>
References:  <202209270004.28R04K1r086731@gitrepo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
--000000000000cb322605e9bf1ee0
Content-Type: text/plain; charset="UTF-8"

This also brings a question as to whether sysctl is the right interface to
pull this data from the kernel in the first place? From my somewhat
ignorant look this approach is likely to be poised with all sorts of race
conditions, such so if configuration changes while you are pulling it out
you'd get some inconsistent view that is not here not there. Wouldn't it be
easier to use some other mechanism to pull configuration of all 1,000
datasets as one blob in one or few system calls? Like read(2) from
/dev/zfsstats or something like that? Then you can iterate over it as much
as you need in userland.

-Max

On Tue, Sep 27, 2022, 3:04 AM Alan Somers <asomers@freebsd.org> wrote:

> The branch main has been updated by asomers:
>
> URL:
> https://cgit.FreeBSD.org/src/commit/?id=d3f96f661050e9bd21fe29931992a8b9e67ff189
>
> commit d3f96f661050e9bd21fe29931992a8b9e67ff189
> Author:     Alan Somers <asomers@FreeBSD.org>
> AuthorDate: 2022-09-07 14:12:49 +0000
> Commit:     Alan Somers <asomers@FreeBSD.org>
> CommitDate: 2022-09-27 00:03:34 +0000
>
>     Fix O(n^2) behavior in sysctl
>
>     Sysctl OIDs were internally stored in linked lists, triggering O(n^2)
>     behavior when userland iterates over many of them.  The slowdown is
>     noticeable for MIBs that have > 100 children (for example, vm.uma).
> But
>     it's unignorable for kstat.zfs when a pool has > 1000 datasets.
>
>     Convert the linked lists into RB trees.  This produces a ~25x speedup
>     for listing kstat.zfs with 4100 datasets, and no measurable penalty for
>     small dataset counts.
>
>     Bump __FreeBSD_version for the KPI change.
>
>     Sponsored by:   Axcient
>     Reviewed by:    mjg
>     Differential Revision: https://reviews.freebsd.org/D36500
> ---
>  sys/compat/linuxkpi/common/include/linux/sysfs.h |   2 +-
>  sys/kern/kern_sysctl.c                           | 149
> +++++++++++------------
>  sys/kern/vfs_init.c                              |   2 +-
>  sys/sys/param.h                                  |   2 +-
>  sys/sys/sysctl.h                                 |  31 ++++-
>  5 files changed, 99 insertions(+), 87 deletions(-)
>
> diff --git a/sys/compat/linuxkpi/common/include/linux/sysfs.h
> b/sys/compat/linuxkpi/common/include/linux/sysfs.h
> index 0b6b479d9362..881a72e62ed9 100644
> --- a/sys/compat/linuxkpi/common/include/linux/sysfs.h
> +++ b/sys/compat/linuxkpi/common/include/linux/sysfs.h
> @@ -246,7 +246,7 @@ sysfs_unmerge_group(struct kobject *kobj, const struct
> attribute_group *grp)
>         struct attribute **attr;
>         struct sysctl_oid *oidp;
>
> -       SLIST_FOREACH(oidp, SYSCTL_CHILDREN(kobj->oidp), oid_link) {
> +       RB_FOREACH(oidp, sysctl_oid_list, SYSCTL_CHILDREN(kobj->oidp)) {
>                 if (strcmp(oidp->oid_name, grp->name) != 0)
>                         continue;
>                 for (attr = grp->attrs; *attr != NULL; attr++) {
> diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
> index 9bc595f111cc..e1cd6ea4bd61 100644
> --- a/sys/kern/kern_sysctl.c
> +++ b/sys/kern/kern_sysctl.c
> @@ -84,6 +84,8 @@ static MALLOC_DEFINE(M_SYSCTL, "sysctl", "sysctl
> internal magic");
>  static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids");
>  static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output
> buffer");
>
> +RB_GENERATE(sysctl_oid_list, sysctl_oid, oid_link, cmp_sysctl_oid);
> +
>  /*
>   * The sysctllock protects the MIB tree.  It also protects sysctl
>   * contexts used with dynamic sysctls.  The sysctl_register_oid() and
> @@ -120,7 +122,7 @@ static struct sx sysctlstringlock;
>  static int sysctl_root(SYSCTL_HANDLER_ARGS);
>
>  /* Root list */
> -struct sysctl_oid_list sysctl__children =
> SLIST_HEAD_INITIALIZER(&sysctl__children);
> +struct sysctl_oid_list sysctl__children =
> RB_INITIALIZER(&sysctl__children);
>
>  static char*   sysctl_escape_name(const char*);
>  static int     sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del,
> @@ -134,7 +136,7 @@ sysctl_find_oidname(const char *name, struct
> sysctl_oid_list *list)
>         struct sysctl_oid *oidp;
>
>         SYSCTL_ASSERT_LOCKED();
> -       SLIST_FOREACH(oidp, list, oid_link) {
> +       RB_FOREACH(oidp, sysctl_oid_list, list) {
>                 if (strcmp(oidp->oid_name, name) == 0) {
>                         return (oidp);
>                 }
> @@ -356,11 +358,14 @@ sysctl_search_oid(struct sysctl_oid **nodes, struct
> sysctl_oid *needle)
>         indx = 0;
>         while (indx < CTL_MAXNAME && indx >= 0) {
>                 if (nodes[indx] == NULL && indx == 0)
> -                       nodes[indx] = SLIST_FIRST(&sysctl__children);
> +                       nodes[indx] = RB_MIN(sysctl_oid_list,
> +                           &sysctl__children);
>                 else if (nodes[indx] == NULL)
> -                       nodes[indx] = SLIST_FIRST(&nodes[indx -
> 1]->oid_children);
> +                       nodes[indx] = RB_MIN(sysctl_oid_list,
> +                           &nodes[indx - 1]->oid_children);
>                 else
> -                       nodes[indx] = SLIST_NEXT(nodes[indx], oid_link);
> +                       nodes[indx] = RB_NEXT(sysctl_oid_list,
> +                           &nodes[indx - 1]->oid_children, nodes[indx]);
>
>                 if (nodes[indx] == needle)
>                         return (indx + 1);
> @@ -425,8 +430,7 @@ void
>  sysctl_register_oid(struct sysctl_oid *oidp)
>  {
>         struct sysctl_oid_list *parent = oidp->oid_parent;
> -       struct sysctl_oid *p;
> -       struct sysctl_oid *q;
> +       struct sysctl_oid *p, key;
>         int oid_number;
>         int timeout = 2;
>
> @@ -476,25 +480,21 @@ sysctl_register_oid(struct sysctl_oid *oidp)
>          * Insert the OID into the parent's list sorted by OID number.
>          */
>  retry:
> -       q = NULL;
> -       SLIST_FOREACH(p, parent, oid_link) {
> -               /* check if the current OID number is in use */
> -               if (oid_number == p->oid_number) {
> -                       /* get the next valid OID number */
> -                       if (oid_number < CTL_AUTO_START ||
> -                           oid_number == 0x7fffffff) {
> -                               /* wraparound - restart */
> -                               oid_number = CTL_AUTO_START;
> -                               /* don't loop forever */
> -                               if (!timeout--)
> -                                       panic("sysctl: Out of OID
> numbers\n");
> -                               goto retry;
> -                       } else {
> -                               oid_number++;
> -                       }
> -               } else if (oid_number < p->oid_number)
> -                       break;
> -               q = p;
> +       key.oid_number = oid_number;
> +       p = RB_FIND(sysctl_oid_list, parent, &key);
> +       if (p) {
> +               /* get the next valid OID number */
> +               if (oid_number < CTL_AUTO_START ||
> +                   oid_number == 0x7fffffff) {
> +                       /* wraparound - restart */
> +                       oid_number = CTL_AUTO_START;
> +                       /* don't loop forever */
> +                       if (!timeout--)
> +                               panic("sysctl: Out of OID numbers\n");
> +                       goto retry;
> +               } else {
> +                       oid_number++;
> +               }
>         }
>         /* check for non-auto OID number collision */
>         if (oidp->oid_number >= 0 && oidp->oid_number < CTL_AUTO_START &&
> @@ -504,10 +504,7 @@ retry:
>         }
>         /* update the OID number, if any */
>         oidp->oid_number = oid_number;
> -       if (q != NULL)
> -               SLIST_INSERT_AFTER(q, oidp, oid_link);
> -       else
> -               SLIST_INSERT_HEAD(parent, oidp, oid_link);
> +       RB_INSERT(sysctl_oid_list, parent, oidp);
>
>         if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE &&
>  #ifdef VIMAGE
> @@ -556,7 +553,6 @@ sysctl_enable_oid(struct sysctl_oid *oidp)
>  void
>  sysctl_unregister_oid(struct sysctl_oid *oidp)
>  {
> -       struct sysctl_oid *p;
>         int error;
>
>         SYSCTL_ASSERT_WLOCKED();
> @@ -564,14 +560,8 @@ sysctl_unregister_oid(struct sysctl_oid *oidp)
>                 error = EINVAL;
>         } else {
>                 error = ENOENT;
> -               SLIST_FOREACH(p, oidp->oid_parent, oid_link) {
> -                       if (p == oidp) {
> -                               SLIST_REMOVE(oidp->oid_parent, oidp,
> -                                   sysctl_oid, oid_link);
> -                               error = 0;
> -                               break;
> -                       }
> -               }
> +               if (RB_REMOVE(sysctl_oid_list, oidp->oid_parent, oidp))
> +                       error = 0;
>         }
>
>         /*
> @@ -732,17 +722,14 @@ int
>  sysctl_remove_name(struct sysctl_oid *parent, const char *name,
>      int del, int recurse)
>  {
> -       struct sysctl_oid *p, *tmp;
> +       struct sysctl_oid *p;
>         int error;
>
>         error = ENOENT;
>         SYSCTL_WLOCK();
> -       SLIST_FOREACH_SAFE(p, SYSCTL_CHILDREN(parent), oid_link, tmp) {
> -               if (strcmp(p->oid_name, name) == 0) {
> -                       error = sysctl_remove_oid_locked(p, del, recurse);
> -                       break;
> -               }
> -       }
> +       p = sysctl_find_oidname(name, &parent->oid_children);
> +       if (p)
> +               error = sysctl_remove_oid_locked(p, del, recurse);
>         SYSCTL_WUNLOCK();
>
>         return (error);
> @@ -811,14 +798,16 @@ sysctl_remove_oid_locked(struct sysctl_oid *oidp,
> int del, int recurse)
>          */
>         if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
>                 if (oidp->oid_refcnt == 1) {
> -                       SLIST_FOREACH_SAFE(p,
> -                           SYSCTL_CHILDREN(oidp), oid_link, tmp) {
> +                       for(p = RB_MIN(sysctl_oid_list,
> &oidp->oid_children);
> +                           p != NULL; p = tmp) {
>                                 if (!recurse) {
>                                         printf("Warning: failed attempt to
> "
>                                             "remove oid %s with child
> %s\n",
>                                             oidp->oid_name, p->oid_name);
>                                         return (ENOTEMPTY);
>                                 }
> +                               tmp = RB_NEXT(sysctl_oid_list,
> +                                   &oidp->oid_children, p);
>                                 error = sysctl_remove_oid_locked(p, del,
>                                     recurse);
>                                 if (error)
> @@ -895,7 +884,7 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct
> sysctl_oid_list *parent,
>         }
>         oidp = malloc(sizeof(struct sysctl_oid), M_SYSCTLOID,
> M_WAITOK|M_ZERO);
>         oidp->oid_parent = parent;
> -       SLIST_INIT(&oidp->oid_children);
> +       RB_INIT(&oidp->oid_children);
>         oidp->oid_number = number;
>         oidp->oid_refcnt = 1;
>         oidp->oid_name = escaped;
> @@ -1016,7 +1005,7 @@ sysctl_sysctl_debug_dump_node(struct sysctl_oid_list
> *l, int i)
>         struct sysctl_oid *oidp;
>
>         SYSCTL_ASSERT_LOCKED();
> -       SLIST_FOREACH(oidp, l, oid_link) {
> +       RB_FOREACH(oidp, sysctl_oid_list, l) {
>                 for (k=0; k<i; k++)
>                         printf(" ");
>
> @@ -1081,7 +1070,7 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
>         int *name = (int *) arg1;
>         u_int namelen = arg2;
>         int error;
> -       struct sysctl_oid *oid;
> +       struct sysctl_oid *oid, key;
>         struct sysctl_oid_list *lsp = &sysctl__children, *lsp2;
>         struct rm_priotracker tracker;
>         char buf[10];
> @@ -1105,10 +1094,9 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
>                         continue;
>                 }
>                 lsp2 = NULL;
> -               SLIST_FOREACH(oid, lsp, oid_link) {
> -                       if (oid->oid_number != *name)
> -                               continue;
> -
> +               key.oid_number = *name;
> +               oid = RB_FIND(sysctl_oid_list, lsp, &key);
> +               if (oid) {
>                         if (req->oldidx)
>                                 error = SYSCTL_OUT(req, ".", 1);
>                         if (!error)
> @@ -1120,14 +1108,9 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
>                         namelen--;
>                         name++;
>
> -                       if ((oid->oid_kind & CTLTYPE) != CTLTYPE_NODE)
> -                               break;
> -
> -                       if (oid->oid_handler)
> -                               break;
> -
> -                       lsp2 = SYSCTL_CHILDREN(oid);
> -                       break;
> +                       if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE &&
> +                               !oid->oid_handler)
> +                               lsp2 = SYSCTL_CHILDREN(oid);
>                 }
>                 lsp = lsp2;
>         }
> @@ -1239,13 +1222,25 @@ static bool
>  sysctl_sysctl_next_action(struct sysctl_oid_list *lsp, int *name, u_int
> namelen,
>      int *next, int *len, int level, bool honor_skip)
>  {
> -       struct sysctl_oid *oidp;
> +       struct sysctl_oid_list *next_lsp;
> +       struct sysctl_oid *oidp = NULL, key;
>         bool success = false;
>         enum sysctl_iter_action action;
>
>         SYSCTL_ASSERT_LOCKED();
> -       SLIST_FOREACH(oidp, lsp, oid_link) {
> -               action = sysctl_sysctl_next_node(oidp, name, namelen,
> honor_skip);
> +       /*
> +        * Start the search at the requested oid.  But if not found, then
> scan
> +        * through all children.
> +        */
> +       if (namelen > 0) {
> +               key.oid_number = *name;
> +               oidp = RB_FIND(sysctl_oid_list, lsp, &key);
> +       }
> +       if (!oidp)
> +               oidp = RB_MIN(sysctl_oid_list, lsp);
> +       for(; oidp != NULL; oidp = RB_NEXT(sysctl_oid_list, lsp, oidp)) {
> +               action = sysctl_sysctl_next_node(oidp, name, namelen,
> +                   honor_skip);
>                 if (action == ITER_SIBLINGS)
>                         continue;
>                 if (action == ITER_FOUND) {
> @@ -1254,13 +1249,13 @@ sysctl_sysctl_next_action(struct sysctl_oid_list
> *lsp, int *name, u_int namelen,
>                 }
>                 KASSERT((action== ITER_CHILDREN),
> ("ret(%d)!=ITER_CHILDREN", action));
>
> -               lsp = SYSCTL_CHILDREN(oidp);
> +               next_lsp = SYSCTL_CHILDREN(oidp);
>                 if (namelen == 0) {
> -                       success = sysctl_sysctl_next_action(lsp, NULL, 0,
> +                       success = sysctl_sysctl_next_action(next_lsp,
> NULL, 0,
>                             next + 1, len, level + 1, honor_skip);
>                 } else {
> -                       success = sysctl_sysctl_next_action(lsp, name + 1,
> namelen - 1,
> -                           next + 1, len, level + 1, honor_skip);
> +                       success = sysctl_sysctl_next_action(next_lsp, name
> + 1,
> +                           namelen - 1, next + 1, len, level + 1,
> honor_skip);
>                         if (!success) {
>
>                                 /*
> @@ -1332,13 +1327,12 @@ name2oid(char *name, int *oid, int *len, struct
> sysctl_oid **oidpp)
>         for (*len = 0; *len < CTL_MAXNAME;) {
>                 p = strsep(&name, ".");
>
> -               oidp = SLIST_FIRST(lsp);
> -               for (;; oidp = SLIST_NEXT(oidp, oid_link)) {
> -                       if (oidp == NULL)
> -                               return (ENOENT);
> +               RB_FOREACH(oidp, sysctl_oid_list, lsp) {
>                         if (strcmp(p, oidp->oid_name) == 0)
>                                 break;
>                 }
> +               if (oidp == NULL)
> +                       return (ENOENT);
>                 *oid++ = oidp->oid_number;
>                 (*len)++;
>
> @@ -2162,16 +2156,15 @@ sysctl_find_oid(int *name, u_int namelen, struct
> sysctl_oid **noid,
>  {
>         struct sysctl_oid_list *lsp;
>         struct sysctl_oid *oid;
> +       struct sysctl_oid key;
>         int indx;
>
>         SYSCTL_ASSERT_LOCKED();
>         lsp = &sysctl__children;
>         indx = 0;
>         while (indx < CTL_MAXNAME) {
> -               SLIST_FOREACH(oid, lsp, oid_link) {
> -                       if (oid->oid_number == name[indx])
> -                               break;
> -               }
> +               key.oid_number = name[indx];
> +               oid = RB_FIND(sysctl_oid_list, lsp, &key);
>                 if (oid == NULL)
>                         return (ENOENT);
>
> diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c
> index 6572a8e362c2..6e2e78aaf597 100644
> --- a/sys/kern/vfs_init.c
> +++ b/sys/kern/vfs_init.c
> @@ -525,7 +525,7 @@ vfs_register(struct vfsconf *vfc)
>          * number.
>          */
>         sysctl_wlock();
> -       SLIST_FOREACH(oidp, SYSCTL_CHILDREN(&sysctl___vfs), oid_link) {
> +       RB_FOREACH(oidp, sysctl_oid_list, SYSCTL_CHILDREN(&sysctl___vfs)) {
>                 if (strcmp(oidp->oid_name, vfc->vfc_name) == 0) {
>                         sysctl_unregister_oid(oidp);
>                         oidp->oid_number = vfc->vfc_typenum;
> diff --git a/sys/sys/param.h b/sys/sys/param.h
> index f875d839d41f..3f5da06ef951 100644
> --- a/sys/sys/param.h
> +++ b/sys/sys/param.h
> @@ -76,7 +76,7 @@
>   * cannot include sys/param.h and should only be updated here.
>   */
>  #undef __FreeBSD_version
> -#define __FreeBSD_version 1400070
> +#define __FreeBSD_version 1400071
>
>  /*
>   * __FreeBSD_kernel__ indicates that this system uses the kernel of
> FreeBSD,
> diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
> index 451d83bbe125..3bd77cf87243 100644
> --- a/sys/sys/sysctl.h
> +++ b/sys/sys/sysctl.h
> @@ -39,7 +39,8 @@
>  #define        _SYS_SYSCTL_H_
>
>  #ifdef _KERNEL
> -#include <sys/queue.h>
> +#include <sys/tree.h>
> +#include <sys/systm.h>
>  #endif
>
>  /*
> @@ -173,20 +174,25 @@ struct sysctl_req {
>         int              flags;
>  };
>
> -SLIST_HEAD(sysctl_oid_list, sysctl_oid);
> +struct sysctl_oid;
> +
> +/* RB Tree handling */
> +RB_HEAD(sysctl_oid_list, sysctl_oid);
>
>  /*
>   * This describes one "oid" in the MIB tree.  Potentially more nodes can
>   * be hidden behind it, expanded by the handler.
>   */
>  struct sysctl_oid {
> -       struct sysctl_oid_list oid_children;
> -       struct sysctl_oid_list *oid_parent;
> -       SLIST_ENTRY(sysctl_oid) oid_link;
> +       struct sysctl_oid_list  oid_children;
> +       struct sysctl_oid_list* oid_parent;
> +       RB_ENTRY(sysctl_oid) oid_link;
> +       /* Sort key for all siblings, and lookup key for userland */
>         int              oid_number;
>         u_int            oid_kind;
>         void            *oid_arg1;
>         intmax_t         oid_arg2;
> +       /* Must be unique amongst all siblings. */
>         const char      *oid_name;
>         int             (*oid_handler)(SYSCTL_HANDLER_ARGS);
>         const char      *oid_fmt;
> @@ -196,6 +202,19 @@ struct sysctl_oid {
>         const char      *oid_label;
>  };
>
> +static inline int
> +cmp_sysctl_oid(struct sysctl_oid *a, struct sysctl_oid *b)
> +{
> +       if (a->oid_number > b->oid_number)
> +               return (1);
> +       else if (a->oid_number < b->oid_number)
> +               return (-1);
> +       else
> +               return (0);
> +}
> +
> +RB_PROTOTYPE(sysctl_oid_list, sysctl_oid, oid_link, cmp_sysctl_oid);
> +
>  #define        SYSCTL_IN(r, p, l)      (r->newfunc)(r, p, l)
>  #define        SYSCTL_OUT(r, p, l)     (r->oldfunc)(r, p, l)
>  #define        SYSCTL_OUT_STR(r, p)    (r->oldfunc)(r, p, strlen(p) + 1)
> @@ -275,7 +294,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
>  #define        SYSCTL_OID_RAW(id, parent_child_head, nbr, name, kind, a1,
> a2, handler, fmt, descr, label) \
>         struct sysctl_oid id = {                                        \
>                 .oid_parent = (parent_child_head),                      \
> -               .oid_children = SLIST_HEAD_INITIALIZER(&id.oid_children), \
> +               .oid_children = RB_INITIALIZER(&id.oid_children), \
>                 .oid_number = (nbr),                                    \
>                 .oid_kind = (kind),                                     \
>                 .oid_arg1 = (a1),                                       \
>
>

--000000000000cb322605e9bf1ee0
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: base64

PGRpdiBkaXI9ImF1dG8iPjxkaXY+VGhpcyBhbHNvIGJyaW5ncyBhIHF1ZXN0aW9uIGFzIHRvIHdo
ZXRoZXIgc3lzY3RsIGlzIHRoZSByaWdodCBpbnRlcmZhY2UgdG8gcHVsbCB0aGlzIGRhdGEgZnJv
bSB0aGUga2VybmVsIGluIHRoZSBmaXJzdCBwbGFjZT8gRnJvbSBteSBzb21ld2hhdCBpZ25vcmFu
dCBsb29rIHRoaXMgYXBwcm9hY2ggaXMgbGlrZWx5IHRvIGJlIHBvaXNlZCB3aXRoIGFsbCBzb3J0
cyBvZiByYWNlIGNvbmRpdGlvbnMsIHN1Y2ggc28gaWYgY29uZmlndXJhdGlvbiBjaGFuZ2VzIHdo
aWxlIHlvdSBhcmUgcHVsbGluZyBpdCBvdXQgeW91JiMzOTtkIGdldCBzb21lIGluY29uc2lzdGVu
dCB2aWV3IHRoYXQgaXMgbm90IGhlcmUgbm90IHRoZXJlLiBXb3VsZG4mIzM5O3QgaXQgYmUgZWFz
aWVyIHRvIHVzZSBzb21lIG90aGVyIG1lY2hhbmlzbSB0byBwdWxsIGNvbmZpZ3VyYXRpb24gb2Yg
YWxsIDEsMDAwIGRhdGFzZXRzIGFzIG9uZSBibG9iIGluIG9uZSBvciBmZXcgc3lzdGVtIGNhbGxz
PyBMaWtlIHJlYWQoMikgZnJvbSAvZGV2L3pmc3N0YXRzIG9yIHNvbWV0aGluZyBsaWtlIHRoYXQ/
IFRoZW4geW91IGNhbiBpdGVyYXRlIG92ZXIgaXQgYXMgbXVjaCBhcyB5b3UgbmVlZCBpbiB1c2Vy
bGFuZC48L2Rpdj48ZGl2IGRpcj0iYXV0byI+PGJyPjwvZGl2PjxkaXYgZGlyPSJhdXRvIj4tTWF4
PGJyPjxicj48ZGl2IGNsYXNzPSJnbWFpbF9xdW90ZSIgZGlyPSJhdXRvIj48ZGl2IGRpcj0ibHRy
IiBjbGFzcz0iZ21haWxfYXR0ciI+T24gVHVlLCBTZXAgMjcsIDIwMjIsIDM6MDQgQU0gQWxhbiBT
b21lcnMgJmx0OzxhIGhyZWY9Im1haWx0bzphc29tZXJzQGZyZWVic2Qub3JnIj5hc29tZXJzQGZy
ZWVic2Qub3JnPC9hPiZndDsgd3JvdGU6PGJyPjwvZGl2PjxibG9ja3F1b3RlIGNsYXNzPSJnbWFp
bF9xdW90ZSIgc3R5bGU9Im1hcmdpbjowIDAgMCAuOGV4O2JvcmRlci1sZWZ0OjFweCAjY2NjIHNv
bGlkO3BhZGRpbmctbGVmdDoxZXgiPlRoZSBicmFuY2ggbWFpbiBoYXMgYmVlbiB1cGRhdGVkIGJ5
IGFzb21lcnM6PGJyPg0KPGJyPg0KVVJMOiA8YSBocmVmPSJodHRwczovL2NnaXQuRnJlZUJTRC5v
cmcvc3JjL2NvbW1pdC8/aWQ9ZDNmOTZmNjYxMDUwZTliZDIxZmUyOTkzMTk5MmE4YjllNjdmZjE4
OSIgcmVsPSJub3JlZmVycmVyIG5vcmVmZXJyZXIiIHRhcmdldD0iX2JsYW5rIj5odHRwczovL2Nn
aXQuRnJlZUJTRC5vcmcvc3JjL2NvbW1pdC8/aWQ9ZDNmOTZmNjYxMDUwZTliZDIxZmUyOTkzMTk5
MmE4YjllNjdmZjE4OTwvYT48YnI+DQo8YnI+DQpjb21taXQgZDNmOTZmNjYxMDUwZTliZDIxZmUy
OTkzMTk5MmE4YjllNjdmZjE4OTxicj4NCkF1dGhvcjrCoCDCoCDCoEFsYW4gU29tZXJzICZsdDth
c29tZXJzQEZyZWVCU0Qub3JnJmd0Ozxicj4NCkF1dGhvckRhdGU6IDIwMjItMDktMDcgMTQ6MTI6
NDkgKzAwMDA8YnI+DQpDb21taXQ6wqAgwqAgwqBBbGFuIFNvbWVycyAmbHQ7YXNvbWVyc0BGcmVl
QlNELm9yZyZndDs8YnI+DQpDb21taXREYXRlOiAyMDIyLTA5LTI3IDAwOjAzOjM0ICswMDAwPGJy
Pg0KPGJyPg0KwqAgwqAgRml4IE8obl4yKSBiZWhhdmlvciBpbiBzeXNjdGw8YnI+DQo8YnI+DQrC
oCDCoCBTeXNjdGwgT0lEcyB3ZXJlIGludGVybmFsbHkgc3RvcmVkIGluIGxpbmtlZCBsaXN0cywg
dHJpZ2dlcmluZyBPKG5eMik8YnI+DQrCoCDCoCBiZWhhdmlvciB3aGVuIHVzZXJsYW5kIGl0ZXJh
dGVzIG92ZXIgbWFueSBvZiB0aGVtLsKgIFRoZSBzbG93ZG93biBpczxicj4NCsKgIMKgIG5vdGlj
ZWFibGUgZm9yIE1JQnMgdGhhdCBoYXZlICZndDsgMTAwIGNoaWxkcmVuIChmb3IgZXhhbXBsZSwg
dm0udW1hKS7CoCBCdXQ8YnI+DQrCoCDCoCBpdCYjMzk7cyB1bmlnbm9yYWJsZSBmb3Iga3N0YXQu
emZzIHdoZW4gYSBwb29sIGhhcyAmZ3Q7IDEwMDAgZGF0YXNldHMuPGJyPg0KPGJyPg0KwqAgwqAg
Q29udmVydCB0aGUgbGlua2VkIGxpc3RzIGludG8gUkIgdHJlZXMuwqAgVGhpcyBwcm9kdWNlcyBh
IH4yNXggc3BlZWR1cDxicj4NCsKgIMKgIGZvciBsaXN0aW5nIGtzdGF0LnpmcyB3aXRoIDQxMDAg
ZGF0YXNldHMsIGFuZCBubyBtZWFzdXJhYmxlIHBlbmFsdHkgZm9yPGJyPg0KwqAgwqAgc21hbGwg
ZGF0YXNldCBjb3VudHMuPGJyPg0KPGJyPg0KwqAgwqAgQnVtcCBfX0ZyZWVCU0RfdmVyc2lvbiBm
b3IgdGhlIEtQSSBjaGFuZ2UuPGJyPg0KPGJyPg0KwqAgwqAgU3BvbnNvcmVkIGJ5OsKgIMKgQXhj
aWVudDxicj4NCsKgIMKgIFJldmlld2VkIGJ5OsKgIMKgIG1qZzxicj4NCsKgIMKgIERpZmZlcmVu
dGlhbCBSZXZpc2lvbjogPGEgaHJlZj0iaHR0cHM6Ly9yZXZpZXdzLmZyZWVic2Qub3JnL0QzNjUw
MCIgcmVsPSJub3JlZmVycmVyIG5vcmVmZXJyZXIiIHRhcmdldD0iX2JsYW5rIj5odHRwczovL3Jl
dmlld3MuZnJlZWJzZC5vcmcvRDM2NTAwPC9hPjxicj4NCi0tLTxicj4NCsKgc3lzL2NvbXBhdC9s
aW51eGtwaS9jb21tb24vaW5jbHVkZS9saW51eC9zeXNmcy5oIHzCoCDCoDIgKy08YnI+DQrCoHN5
cy9rZXJuL2tlcm5fc3lzY3RsLmPCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoHwgMTQ5ICsrKysrKysrKysrLS0tLS0tLS0tLS0tPGJyPg0KwqBzeXMva2Vybi92ZnNfaW5p
dC5jwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgfMKgIMKgMiAr
LTxicj4NCsKgc3lzL3N5cy9wYXJhbS5owqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgfMKgIMKgMiArLTxicj4NCsKgc3lzL3N5cy9zeXNjdGwuaMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfMKgIDMxICsrKyst
PGJyPg0KwqA1IGZpbGVzIGNoYW5nZWQsIDk5IGluc2VydGlvbnMoKyksIDg3IGRlbGV0aW9ucygt
KTxicj4NCjxicj4NCmRpZmYgLS1naXQgYS9zeXMvY29tcGF0L2xpbnV4a3BpL2NvbW1vbi9pbmNs
dWRlL2xpbnV4L3N5c2ZzLmggYi9zeXMvY29tcGF0L2xpbnV4a3BpL2NvbW1vbi9pbmNsdWRlL2xp
bnV4L3N5c2ZzLmg8YnI+DQppbmRleCAwYjZiNDc5ZDkzNjIuLjg4MWE3MmU2MmVkOSAxMDA2NDQ8
YnI+DQotLS0gYS9zeXMvY29tcGF0L2xpbnV4a3BpL2NvbW1vbi9pbmNsdWRlL2xpbnV4L3N5c2Zz
Lmg8YnI+DQorKysgYi9zeXMvY29tcGF0L2xpbnV4a3BpL2NvbW1vbi9pbmNsdWRlL2xpbnV4L3N5
c2ZzLmg8YnI+DQpAQCAtMjQ2LDcgKzI0Niw3IEBAIHN5c2ZzX3VubWVyZ2VfZ3JvdXAoc3RydWN0
IGtvYmplY3QgKmtvYmosIGNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgKmdycCk8YnI+DQrC
oCDCoCDCoCDCoCBzdHJ1Y3QgYXR0cmlidXRlICoqYXR0cjs8YnI+DQrCoCDCoCDCoCDCoCBzdHJ1
Y3Qgc3lzY3RsX29pZCAqb2lkcDs8YnI+DQo8YnI+DQotwqAgwqAgwqAgwqBTTElTVF9GT1JFQUNI
KG9pZHAsIFNZU0NUTF9DSElMRFJFTihrb2JqLSZndDtvaWRwKSwgb2lkX2xpbmspIHs8YnI+DQor
wqAgwqAgwqAgwqBSQl9GT1JFQUNIKG9pZHAsIHN5c2N0bF9vaWRfbGlzdCwgU1lTQ1RMX0NISUxE
UkVOKGtvYmotJmd0O29pZHApKSB7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKHN0
cmNtcChvaWRwLSZndDtvaWRfbmFtZSwgZ3JwLSZndDtuYW1lKSAhPSAwKTxicj4NCsKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGNvbnRpbnVlOzxicj4NCsKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIGZvciAoYXR0ciA9IGdycC0mZ3Q7YXR0cnM7ICphdHRyICE9IE5VTEw7IGF0dHIr
Kykgezxicj4NCmRpZmYgLS1naXQgYS9zeXMva2Vybi9rZXJuX3N5c2N0bC5jIGIvc3lzL2tlcm4v
a2Vybl9zeXNjdGwuYzxicj4NCmluZGV4IDliYzU5NWYxMTFjYy4uZTFjZDZlYTRiZDYxIDEwMDY0
NDxicj4NCi0tLSBhL3N5cy9rZXJuL2tlcm5fc3lzY3RsLmM8YnI+DQorKysgYi9zeXMva2Vybi9r
ZXJuX3N5c2N0bC5jPGJyPg0KQEAgLTg0LDYgKzg0LDggQEAgc3RhdGljIE1BTExPQ19ERUZJTkUo
TV9TWVNDVEwsICZxdW90O3N5c2N0bCZxdW90OywgJnF1b3Q7c3lzY3RsIGludGVybmFsIG1hZ2lj
JnF1b3Q7KTs8YnI+DQrCoHN0YXRpYyBNQUxMT0NfREVGSU5FKE1fU1lTQ1RMT0lELCAmcXVvdDtz
eXNjdGxvaWQmcXVvdDssICZxdW90O3N5c2N0bCBkeW5hbWljIG9pZHMmcXVvdDspOzxicj4NCsKg
c3RhdGljIE1BTExPQ19ERUZJTkUoTV9TWVNDVExUTVAsICZxdW90O3N5c2N0bHRtcCZxdW90Oywg
JnF1b3Q7c3lzY3RsIHRlbXAgb3V0cHV0IGJ1ZmZlciZxdW90Oyk7PGJyPg0KPGJyPg0KK1JCX0dF
TkVSQVRFKHN5c2N0bF9vaWRfbGlzdCwgc3lzY3RsX29pZCwgb2lkX2xpbmssIGNtcF9zeXNjdGxf
b2lkKTs8YnI+DQorPGJyPg0KwqAvKjxicj4NCsKgICogVGhlIHN5c2N0bGxvY2sgcHJvdGVjdHMg
dGhlIE1JQiB0cmVlLsKgIEl0IGFsc28gcHJvdGVjdHMgc3lzY3RsPGJyPg0KwqAgKiBjb250ZXh0
cyB1c2VkIHdpdGggZHluYW1pYyBzeXNjdGxzLsKgIFRoZSBzeXNjdGxfcmVnaXN0ZXJfb2lkKCkg
YW5kPGJyPg0KQEAgLTEyMCw3ICsxMjIsNyBAQCBzdGF0aWMgc3RydWN0IHN4IHN5c2N0bHN0cmlu
Z2xvY2s7PGJyPg0KwqBzdGF0aWMgaW50IHN5c2N0bF9yb290KFNZU0NUTF9IQU5ETEVSX0FSR1Mp
Ozxicj4NCjxicj4NCsKgLyogUm9vdCBsaXN0ICovPGJyPg0KLXN0cnVjdCBzeXNjdGxfb2lkX2xp
c3Qgc3lzY3RsX19jaGlsZHJlbiA9IFNMSVNUX0hFQURfSU5JVElBTElaRVIoJmFtcDtzeXNjdGxf
X2NoaWxkcmVuKTs8YnI+DQorc3RydWN0IHN5c2N0bF9vaWRfbGlzdCBzeXNjdGxfX2NoaWxkcmVu
ID0gUkJfSU5JVElBTElaRVIoJmFtcDtzeXNjdGxfX2NoaWxkcmVuKTs8YnI+DQo8YnI+DQrCoHN0
YXRpYyBjaGFyKsKgIMKgc3lzY3RsX2VzY2FwZV9uYW1lKGNvbnN0IGNoYXIqKTs8YnI+DQrCoHN0
YXRpYyBpbnTCoCDCoCDCoHN5c2N0bF9yZW1vdmVfb2lkX2xvY2tlZChzdHJ1Y3Qgc3lzY3RsX29p
ZCAqb2lkcCwgaW50IGRlbCw8YnI+DQpAQCAtMTM0LDcgKzEzNiw3IEBAIHN5c2N0bF9maW5kX29p
ZG5hbWUoY29uc3QgY2hhciAqbmFtZSwgc3RydWN0IHN5c2N0bF9vaWRfbGlzdCAqbGlzdCk8YnI+
DQrCoCDCoCDCoCDCoCBzdHJ1Y3Qgc3lzY3RsX29pZCAqb2lkcDs8YnI+DQo8YnI+DQrCoCDCoCDC
oCDCoCBTWVNDVExfQVNTRVJUX0xPQ0tFRCgpOzxicj4NCi3CoCDCoCDCoCDCoFNMSVNUX0ZPUkVB
Q0gob2lkcCwgbGlzdCwgb2lkX2xpbmspIHs8YnI+DQorwqAgwqAgwqAgwqBSQl9GT1JFQUNIKG9p
ZHAsIHN5c2N0bF9vaWRfbGlzdCwgbGlzdCkgezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IGlmIChzdHJjbXAob2lkcC0mZ3Q7b2lkX25hbWUsIG5hbWUpID09IDApIHs8YnI+DQrCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCByZXR1cm4gKG9pZHApOzxicj4NCsKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIH08YnI+DQpAQCAtMzU2LDExICszNTgsMTQgQEAgc3lzY3RsX3NlYXJj
aF9vaWQoc3RydWN0IHN5c2N0bF9vaWQgKipub2Rlcywgc3RydWN0IHN5c2N0bF9vaWQgKm5lZWRs
ZSk8YnI+DQrCoCDCoCDCoCDCoCBpbmR4ID0gMDs8YnI+DQrCoCDCoCDCoCDCoCB3aGlsZSAoaW5k
eCAmbHQ7IENUTF9NQVhOQU1FICZhbXA7JmFtcDsgaW5keCAmZ3Q7PSAwKSB7PGJyPg0KwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgaWYgKG5vZGVzW2luZHhdID09IE5VTEwgJmFtcDsmYW1wOyBpbmR4
ID09IDApPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbm9kZXNbaW5k
eF0gPSBTTElTVF9GSVJTVCgmYW1wO3N5c2N0bF9fY2hpbGRyZW4pOzxicj4NCivCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG5vZGVzW2luZHhdID0gUkJfTUlOKHN5c2N0bF9vaWRf
bGlzdCw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAmYW1w
O3N5c2N0bF9fY2hpbGRyZW4pOzxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGVsc2UgaWYg
KG5vZGVzW2luZHhdID09IE5VTEwpPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgbm9kZXNbaW5keF0gPSBTTElTVF9GSVJTVCgmYW1wO25vZGVzW2luZHggLSAxXS0mZ3Q7
b2lkX2NoaWxkcmVuKTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBu
b2Rlc1tpbmR4XSA9IFJCX01JTihzeXNjdGxfb2lkX2xpc3QsPGJyPg0KK8KgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgJmFtcDtub2Rlc1tpbmR4IC0gMV0tJmd0O29pZF9j
aGlsZHJlbik7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZWxzZTxicj4NCi3CoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG5vZGVzW2luZHhdID0gU0xJU1RfTkVYVChub2Rl
c1tpbmR4XSwgb2lkX2xpbmspOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoG5vZGVzW2luZHhdID0gUkJfTkVYVChzeXNjdGxfb2lkX2xpc3QsPGJyPg0KK8KgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgJmFtcDtub2Rlc1tpbmR4IC0gMV0tJmd0
O29pZF9jaGlsZHJlbiwgbm9kZXNbaW5keF0pOzxicj4NCjxicj4NCsKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIGlmIChub2Rlc1tpbmR4XSA9PSBuZWVkbGUpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgcmV0dXJuIChpbmR4ICsgMSk7PGJyPg0KQEAgLTQyNSw4ICs0MzAs
NyBAQCB2b2lkPGJyPg0KwqBzeXNjdGxfcmVnaXN0ZXJfb2lkKHN0cnVjdCBzeXNjdGxfb2lkICpv
aWRwKTxicj4NCsKgezxicj4NCsKgIMKgIMKgIMKgIHN0cnVjdCBzeXNjdGxfb2lkX2xpc3QgKnBh
cmVudCA9IG9pZHAtJmd0O29pZF9wYXJlbnQ7PGJyPg0KLcKgIMKgIMKgIMKgc3RydWN0IHN5c2N0
bF9vaWQgKnA7PGJyPg0KLcKgIMKgIMKgIMKgc3RydWN0IHN5c2N0bF9vaWQgKnE7PGJyPg0KK8Kg
IMKgIMKgIMKgc3RydWN0IHN5c2N0bF9vaWQgKnAsIGtleTs8YnI+DQrCoCDCoCDCoCDCoCBpbnQg
b2lkX251bWJlcjs8YnI+DQrCoCDCoCDCoCDCoCBpbnQgdGltZW91dCA9IDI7PGJyPg0KPGJyPg0K
QEAgLTQ3NiwyNSArNDgwLDIxIEBAIHN5c2N0bF9yZWdpc3Rlcl9vaWQoc3RydWN0IHN5c2N0bF9v
aWQgKm9pZHApPGJyPg0KwqAgwqAgwqAgwqAgwqAqIEluc2VydCB0aGUgT0lEIGludG8gdGhlIHBh
cmVudCYjMzk7cyBsaXN0IHNvcnRlZCBieSBPSUQgbnVtYmVyLjxicj4NCsKgIMKgIMKgIMKgIMKg
Ki88YnI+DQrCoHJldHJ5Ojxicj4NCi3CoCDCoCDCoCDCoHEgPSBOVUxMOzxicj4NCi3CoCDCoCDC
oCDCoFNMSVNUX0ZPUkVBQ0gocCwgcGFyZW50LCBvaWRfbGluaykgezxicj4NCi3CoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoC8qIGNoZWNrIGlmIHRoZSBjdXJyZW50IE9JRCBudW1iZXIgaXMgaW4gdXNl
ICovPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKG9pZF9udW1iZXIgPT0gcC0mZ3Q7
b2lkX251bWJlcikgezxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC8q
IGdldCB0aGUgbmV4dCB2YWxpZCBPSUQgbnVtYmVyICovPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgaWYgKG9pZF9udW1iZXIgJmx0OyBDVExfQVVUT19TVEFSVCB8fDxi
cj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG9pZF9udW1iZXIg
PT0gMHg3ZmZmZmZmZikgezxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoC8qIHdyYXBhcm91bmQgLSByZXN0YXJ0ICovPGJyPg0KLcKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgb2lkX251bWJlciA9IENUTF9BVVRP
X1NUQVJUOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoC8qIGRvbiYjMzk7dCBsb29wIGZvcmV2ZXIgKi88YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoIXRpbWVvdXQtLSk8YnI+DQotwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBwYW5p
YygmcXVvdDtzeXNjdGw6IE91dCBvZiBPSUQgbnVtYmVyc1xuJnF1b3Q7KTs8YnI+DQotwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBnb3RvIHJldHJ5Ozxicj4N
Ci3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH0gZWxzZSB7PGJyPg0KLcKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgb2lkX251bWJlcisrOzxi
cj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQotwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqB9IGVsc2UgaWYgKG9pZF9udW1iZXIgJmx0OyBwLSZndDtvaWRfbnVtYmVy
KTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFrOzxicj4NCi3C
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoHEgPSBwOzxicj4NCivCoCDCoCDCoCDCoGtleS5vaWRfbnVt
YmVyID0gb2lkX251bWJlcjs8YnI+DQorwqAgwqAgwqAgwqBwID0gUkJfRklORChzeXNjdGxfb2lk
X2xpc3QsIHBhcmVudCwgJmFtcDtrZXkpOzxicj4NCivCoCDCoCDCoCDCoGlmIChwKSB7PGJyPg0K
K8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogZ2V0IHRoZSBuZXh0IHZhbGlkIE9JRCBudW1iZXIg
Ki88YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAob2lkX251bWJlciAmbHQ7IENUTF9B
VVRPX1NUQVJUIHx8PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgb2lkX251bWJl
ciA9PSAweDdmZmZmZmZmKSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgLyogd3JhcGFyb3VuZCAtIHJlc3RhcnQgKi88YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqBvaWRfbnVtYmVyID0gQ1RMX0FVVE9fU1RBUlQ7PGJyPg0KK8KgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogZG9uJiMzOTt0IGxvb3AgZm9yZXZlciAqLzxi
cj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmICghdGltZW91dC0tKTxi
cj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHBhbmlj
KCZxdW90O3N5c2N0bDogT3V0IG9mIE9JRCBudW1iZXJzXG4mcXVvdDspOzxicj4NCivCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGdvdG8gcmV0cnk7PGJyPg0KK8KgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgfSBlbHNlIHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqBvaWRfbnVtYmVyKys7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfTxicj4NCsKg
IMKgIMKgIMKgIH08YnI+DQrCoCDCoCDCoCDCoCAvKiBjaGVjayBmb3Igbm9uLWF1dG8gT0lEIG51
bWJlciBjb2xsaXNpb24gKi88YnI+DQrCoCDCoCDCoCDCoCBpZiAob2lkcC0mZ3Q7b2lkX251bWJl
ciAmZ3Q7PSAwICZhbXA7JmFtcDsgb2lkcC0mZ3Q7b2lkX251bWJlciAmbHQ7IENUTF9BVVRPX1NU
QVJUICZhbXA7JmFtcDs8YnI+DQpAQCAtNTA0LDEwICs1MDQsNyBAQCByZXRyeTo8YnI+DQrCoCDC
oCDCoCDCoCB9PGJyPg0KwqAgwqAgwqAgwqAgLyogdXBkYXRlIHRoZSBPSUQgbnVtYmVyLCBpZiBh
bnkgKi88YnI+DQrCoCDCoCDCoCDCoCBvaWRwLSZndDtvaWRfbnVtYmVyID0gb2lkX251bWJlcjs8
YnI+DQotwqAgwqAgwqAgwqBpZiAocSAhPSBOVUxMKTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoFNMSVNUX0lOU0VSVF9BRlRFUihxLCBvaWRwLCBvaWRfbGluayk7PGJyPg0KLcKgIMKgIMKg
IMKgZWxzZTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFNMSVNUX0lOU0VSVF9IRUFEKHBh
cmVudCwgb2lkcCwgb2lkX2xpbmspOzxicj4NCivCoCDCoCDCoCDCoFJCX0lOU0VSVChzeXNjdGxf
b2lkX2xpc3QsIHBhcmVudCwgb2lkcCk7PGJyPg0KPGJyPg0KwqAgwqAgwqAgwqAgaWYgKChvaWRw
LSZndDtvaWRfa2luZCAmYW1wOyBDVExUWVBFKSAhPSBDVExUWVBFX05PREUgJmFtcDsmYW1wOzxi
cj4NCsKgI2lmZGVmIFZJTUFHRTxicj4NCkBAIC01NTYsNyArNTUzLDYgQEAgc3lzY3RsX2VuYWJs
ZV9vaWQoc3RydWN0IHN5c2N0bF9vaWQgKm9pZHApPGJyPg0KwqB2b2lkPGJyPg0KwqBzeXNjdGxf
dW5yZWdpc3Rlcl9vaWQoc3RydWN0IHN5c2N0bF9vaWQgKm9pZHApPGJyPg0KwqB7PGJyPg0KLcKg
IMKgIMKgIMKgc3RydWN0IHN5c2N0bF9vaWQgKnA7PGJyPg0KwqAgwqAgwqAgwqAgaW50IGVycm9y
Ozxicj4NCjxicj4NCsKgIMKgIMKgIMKgIFNZU0NUTF9BU1NFUlRfV0xPQ0tFRCgpOzxicj4NCkBA
IC01NjQsMTQgKzU2MCw4IEBAIHN5c2N0bF91bnJlZ2lzdGVyX29pZChzdHJ1Y3Qgc3lzY3RsX29p
ZCAqb2lkcCk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBlcnJvciA9IEVJTlZBTDs8YnI+
DQrCoCDCoCDCoCDCoCB9IGVsc2Ugezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGVycm9y
ID0gRU5PRU5UOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFNMSVNUX0ZPUkVBQ0gocCwg
b2lkcC0mZ3Q7b2lkX3BhcmVudCwgb2lkX2xpbmspIHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqBpZiAocCA9PSBvaWRwKSB7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgU0xJU1RfUkVNT1ZFKG9pZHAtJmd0O29pZF9w
YXJlbnQsIG9pZHAsPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgc3lzY3RsX29pZCwgb2lkX2xpbmspOzxicj4NCi3CoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGVycm9yID0gMDs8YnI+DQotwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazs8YnI+DQotwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgfTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChSQl9SRU1PVkUoc3lzY3Rs
X29pZF9saXN0LCBvaWRwLSZndDtvaWRfcGFyZW50LCBvaWRwKSk8YnI+DQorwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlcnJvciA9IDA7PGJyPg0KwqAgwqAgwqAgwqAgfTxicj4N
Cjxicj4NCsKgIMKgIMKgIMKgIC8qIDxicj4NCkBAIC03MzIsMTcgKzcyMiwxNCBAQCBpbnQ8YnI+
DQrCoHN5c2N0bF9yZW1vdmVfbmFtZShzdHJ1Y3Qgc3lzY3RsX29pZCAqcGFyZW50LCBjb25zdCBj
aGFyICpuYW1lLDxicj4NCsKgIMKgIMKgaW50IGRlbCwgaW50IHJlY3Vyc2UpPGJyPg0KwqB7PGJy
Pg0KLcKgIMKgIMKgIMKgc3RydWN0IHN5c2N0bF9vaWQgKnAsICp0bXA7PGJyPg0KK8KgIMKgIMKg
IMKgc3RydWN0IHN5c2N0bF9vaWQgKnA7PGJyPg0KwqAgwqAgwqAgwqAgaW50IGVycm9yOzxicj4N
Cjxicj4NCsKgIMKgIMKgIMKgIGVycm9yID0gRU5PRU5UOzxicj4NCsKgIMKgIMKgIMKgIFNZU0NU
TF9XTE9DSygpOzxicj4NCi3CoCDCoCDCoCDCoFNMSVNUX0ZPUkVBQ0hfU0FGRShwLCBTWVNDVExf
Q0hJTERSRU4ocGFyZW50KSwgb2lkX2xpbmssIHRtcCkgezxicj4NCi3CoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoGlmIChzdHJjbXAocC0mZ3Q7b2lkX25hbWUsIG5hbWUpID09IDApIHs8YnI+DQotwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlcnJvciA9IHN5c2N0bF9yZW1vdmVfb2lk
X2xvY2tlZChwLCBkZWwsIHJlY3Vyc2UpOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoGJyZWFrOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQotwqAg
wqAgwqAgwqB9PGJyPg0KK8KgIMKgIMKgIMKgcCA9IHN5c2N0bF9maW5kX29pZG5hbWUobmFtZSwg
JmFtcDtwYXJlbnQtJmd0O29pZF9jaGlsZHJlbik7PGJyPg0KK8KgIMKgIMKgIMKgaWYgKHApPGJy
Pg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZXJyb3IgPSBzeXNjdGxfcmVtb3ZlX29pZF9sb2Nr
ZWQocCwgZGVsLCByZWN1cnNlKTs8YnI+DQrCoCDCoCDCoCDCoCBTWVNDVExfV1VOTE9DSygpOzxi
cj4NCjxicj4NCsKgIMKgIMKgIMKgIHJldHVybiAoZXJyb3IpOzxicj4NCkBAIC04MTEsMTQgKzc5
OCwxNiBAQCBzeXNjdGxfcmVtb3ZlX29pZF9sb2NrZWQoc3RydWN0IHN5c2N0bF9vaWQgKm9pZHAs
IGludCBkZWwsIGludCByZWN1cnNlKTxicj4NCsKgIMKgIMKgIMKgIMKgKi88YnI+DQrCoCDCoCDC
oCDCoCBpZiAoKG9pZHAtJmd0O29pZF9raW5kICZhbXA7IENUTFRZUEUpID09IENUTFRZUEVfTk9E
RSkgezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChvaWRwLSZndDtvaWRfcmVmY250
ID09IDEpIHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBTTElTVF9G
T1JFQUNIX1NBRkUocCw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqBTWVNDVExfQ0hJTERSRU4ob2lkcCksIG9pZF9saW5rLCB0bXApIHs8YnI+DQorwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBmb3IocCA9IFJCX01JTihzeXNjdGxfb2lkX2xp
c3QsICZhbXA7b2lkcC0mZ3Q7b2lkX2NoaWxkcmVuKTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBwICE9IE5VTEw7IHAgPSB0bXApIHs8YnI+DQrCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpZiAoIXJlY3Vyc2UpIHs8
YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCBwcmludGYoJnF1b3Q7V2FybmluZzogZmFpbGVkIGF0dGVtcHQgdG8gJnF1b3Q7PGJy
Pg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgJnF1b3Q7cmVtb3ZlIG9pZCAlcyB3aXRoIGNoaWxkICVzXG4mcXVvdDssPGJy
Pg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgb2lkcC0mZ3Q7b2lkX25hbWUsIHAtJmd0O29pZF9uYW1lKTs8YnI+DQrCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBy
ZXR1cm4gKEVOT1RFTVBUWSk7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgfTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoHRtcCA9IFJCX05FWFQoc3lzY3RsX29pZF9saXN0LDxicj4NCivCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCZhbXA7b2lkcC0m
Z3Q7b2lkX2NoaWxkcmVuLCBwKTs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCBlcnJvciA9IHN5c2N0bF9yZW1vdmVfb2lkX2xvY2tlZChwLCBkZWws
PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgcmVjdXJzZSk7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgaWYgKGVycm9yKTxicj4NCkBAIC04OTUsNyArODg0LDcgQEAgc3lzY3RsX2FkZF9v
aWQoc3RydWN0IHN5c2N0bF9jdHhfbGlzdCAqY2xpc3QsIHN0cnVjdCBzeXNjdGxfb2lkX2xpc3Qg
KnBhcmVudCw8YnI+DQrCoCDCoCDCoCDCoCB9PGJyPg0KwqAgwqAgwqAgwqAgb2lkcCA9IG1hbGxv
YyhzaXplb2Yoc3RydWN0IHN5c2N0bF9vaWQpLCBNX1NZU0NUTE9JRCwgTV9XQUlUT0t8TV9aRVJP
KTs8YnI+DQrCoCDCoCDCoCDCoCBvaWRwLSZndDtvaWRfcGFyZW50ID0gcGFyZW50Ozxicj4NCi3C
oCDCoCDCoCDCoFNMSVNUX0lOSVQoJmFtcDtvaWRwLSZndDtvaWRfY2hpbGRyZW4pOzxicj4NCivC
oCDCoCDCoCDCoFJCX0lOSVQoJmFtcDtvaWRwLSZndDtvaWRfY2hpbGRyZW4pOzxicj4NCsKgIMKg
IMKgIMKgIG9pZHAtJmd0O29pZF9udW1iZXIgPSBudW1iZXI7PGJyPg0KwqAgwqAgwqAgwqAgb2lk
cC0mZ3Q7b2lkX3JlZmNudCA9IDE7PGJyPg0KwqAgwqAgwqAgwqAgb2lkcC0mZ3Q7b2lkX25hbWUg
PSBlc2NhcGVkOzxicj4NCkBAIC0xMDE2LDcgKzEwMDUsNyBAQCBzeXNjdGxfc3lzY3RsX2RlYnVn
X2R1bXBfbm9kZShzdHJ1Y3Qgc3lzY3RsX29pZF9saXN0ICpsLCBpbnQgaSk8YnI+DQrCoCDCoCDC
oCDCoCBzdHJ1Y3Qgc3lzY3RsX29pZCAqb2lkcDs8YnI+DQo8YnI+DQrCoCDCoCDCoCDCoCBTWVND
VExfQVNTRVJUX0xPQ0tFRCgpOzxicj4NCi3CoCDCoCDCoCDCoFNMSVNUX0ZPUkVBQ0gob2lkcCwg
bCwgb2lkX2xpbmspIHs8YnI+DQorwqAgwqAgwqAgwqBSQl9GT1JFQUNIKG9pZHAsIHN5c2N0bF9v
aWRfbGlzdCwgbCkgezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGZvciAoaz0wOyBrJmx0
O2k7IGsrKyk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBwcmludGYo
JnF1b3Q7ICZxdW90Oyk7PGJyPg0KPGJyPg0KQEAgLTEwODEsNyArMTA3MCw3IEBAIHN5c2N0bF9z
eXNjdGxfbmFtZShTWVNDVExfSEFORExFUl9BUkdTKTxicj4NCsKgIMKgIMKgIMKgIGludCAqbmFt
ZSA9IChpbnQgKikgYXJnMTs8YnI+DQrCoCDCoCDCoCDCoCB1X2ludCBuYW1lbGVuID0gYXJnMjs8
YnI+DQrCoCDCoCDCoCDCoCBpbnQgZXJyb3I7PGJyPg0KLcKgIMKgIMKgIMKgc3RydWN0IHN5c2N0
bF9vaWQgKm9pZDs8YnI+DQorwqAgwqAgwqAgwqBzdHJ1Y3Qgc3lzY3RsX29pZCAqb2lkLCBrZXk7
PGJyPg0KwqAgwqAgwqAgwqAgc3RydWN0IHN5c2N0bF9vaWRfbGlzdCAqbHNwID0gJmFtcDtzeXNj
dGxfX2NoaWxkcmVuLCAqbHNwMjs8YnI+DQrCoCDCoCDCoCDCoCBzdHJ1Y3Qgcm1fcHJpb3RyYWNr
ZXIgdHJhY2tlcjs8YnI+DQrCoCDCoCDCoCDCoCBjaGFyIGJ1ZlsxMF07PGJyPg0KQEAgLTExMDUs
MTAgKzEwOTQsOSBAQCBzeXNjdGxfc3lzY3RsX25hbWUoU1lTQ1RMX0hBTkRMRVJfQVJHUyk8YnI+
DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBjb250aW51ZTs8YnI+DQrCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCB9PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgbHNwMiA9
IE5VTEw7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgU0xJU1RfRk9SRUFDSChvaWQsIGxz
cCwgb2lkX2xpbmspIHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBp
ZiAob2lkLSZndDtvaWRfbnVtYmVyICE9ICpuYW1lKTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGNvbnRpbnVlOzxicj4NCi08YnI+DQorwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqBrZXkub2lkX251bWJlciA9ICpuYW1lOzxicj4NCivCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoG9pZCA9IFJCX0ZJTkQoc3lzY3RsX29pZF9saXN0LCBsc3AsICZhbXA7a2V5
KTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAob2lkKSB7PGJyPg0KwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKHJlcS0mZ3Q7b2xkaWR4KTxicj4NCsKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGVycm9yID0gU1lTQ1RM
X09VVChyZXEsICZxdW90Oy4mcXVvdDssIDEpOzxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIGlmICghZXJyb3IpPGJyPg0KQEAgLTExMjAsMTQgKzExMDgsOSBAQCBzeXNj
dGxfc3lzY3RsX25hbWUoU1lTQ1RMX0hBTkRMRVJfQVJHUyk8YnI+DQrCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCBuYW1lbGVuLS07PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgbmFtZSsrOzxicj4NCjxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoGlmICgob2lkLSZndDtvaWRfa2luZCAmYW1wOyBDVExUWVBFKSAhPSBDVExU
WVBFX05PREUpIDxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoGJyZWFrOzxicj4NCi08YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqBpZiAob2lkLSZndDtvaWRfaGFuZGxlcik8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazs8YnI+DQotPGJyPg0KLcKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbHNwMiA9IFNZU0NUTF9DSElMRFJFTihvaWQpOzxicj4N
Ci3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFrOzxicj4NCivCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmICgob2lkLSZndDtvaWRfa2luZCAmYW1wOyBD
VExUWVBFKSA9PSBDVExUWVBFX05PREUgJmFtcDsmYW1wOzxicj4NCivCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCFvaWQtJmd0O29pZF9oYW5kbGVyKTxicj4N
CivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGxzcDIgPSBT
WVNDVExfQ0hJTERSRU4ob2lkKTs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9PGJyPg0K
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgbHNwID0gbHNwMjs8YnI+DQrCoCDCoCDCoCDCoCB9PGJy
Pg0KQEAgLTEyMzksMTMgKzEyMjIsMjUgQEAgc3RhdGljIGJvb2w8YnI+DQrCoHN5c2N0bF9zeXNj
dGxfbmV4dF9hY3Rpb24oc3RydWN0IHN5c2N0bF9vaWRfbGlzdCAqbHNwLCBpbnQgKm5hbWUsIHVf
aW50IG5hbWVsZW4sIDxicj4NCsKgIMKgIMKgaW50ICpuZXh0LCBpbnQgKmxlbiwgaW50IGxldmVs
LCBib29sIGhvbm9yX3NraXApPGJyPg0KwqB7PGJyPg0KLcKgIMKgIMKgIMKgc3RydWN0IHN5c2N0
bF9vaWQgKm9pZHA7PGJyPg0KK8KgIMKgIMKgIMKgc3RydWN0IHN5c2N0bF9vaWRfbGlzdCAqbmV4
dF9sc3A7PGJyPg0KK8KgIMKgIMKgIMKgc3RydWN0IHN5c2N0bF9vaWQgKm9pZHAgPSBOVUxMLCBr
ZXk7PGJyPg0KwqAgwqAgwqAgwqAgYm9vbCBzdWNjZXNzID0gZmFsc2U7PGJyPg0KwqAgwqAgwqAg
wqAgZW51bSBzeXNjdGxfaXRlcl9hY3Rpb24gYWN0aW9uOzxicj4NCjxicj4NCsKgIMKgIMKgIMKg
IFNZU0NUTF9BU1NFUlRfTE9DS0VEKCk7PGJyPg0KLcKgIMKgIMKgIMKgU0xJU1RfRk9SRUFDSChv
aWRwLCBsc3AsIG9pZF9saW5rKSB7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYWN0aW9u
ID0gc3lzY3RsX3N5c2N0bF9uZXh0X25vZGUob2lkcCwgbmFtZSwgbmFtZWxlbiwgaG9ub3Jfc2tp
cCk7PGJyPg0KK8KgIMKgIMKgIMKgLyo8YnI+DQorwqAgwqAgwqAgwqAgKiBTdGFydCB0aGUgc2Vh
cmNoIGF0IHRoZSByZXF1ZXN0ZWQgb2lkLsKgIEJ1dCBpZiBub3QgZm91bmQsIHRoZW4gc2Nhbjxi
cj4NCivCoCDCoCDCoCDCoCAqIHRocm91Z2ggYWxsIGNoaWxkcmVuLjxicj4NCivCoCDCoCDCoCDC
oCAqLzxicj4NCivCoCDCoCDCoCDCoGlmIChuYW1lbGVuICZndDsgMCkgezxicj4NCivCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoGtleS5vaWRfbnVtYmVyID0gKm5hbWU7PGJyPg0KK8KgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgb2lkcCA9IFJCX0ZJTkQoc3lzY3RsX29pZF9saXN0LCBsc3AsICZhbXA7a2V5
KTs8YnI+DQorwqAgwqAgwqAgwqB9PGJyPg0KK8KgIMKgIMKgIMKgaWYgKCFvaWRwKTxicj4NCivC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoG9pZHAgPSBSQl9NSU4oc3lzY3RsX29pZF9saXN0LCBsc3Ap
Ozxicj4NCivCoCDCoCDCoCDCoGZvcig7IG9pZHAgIT0gTlVMTDsgb2lkcCA9IFJCX05FWFQoc3lz
Y3RsX29pZF9saXN0LCBsc3AsIG9pZHApKSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
YWN0aW9uID0gc3lzY3RsX3N5c2N0bF9uZXh0X25vZGUob2lkcCwgbmFtZSwgbmFtZWxlbiw8YnI+
DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBob25vcl9za2lwKTs8YnI+DQrCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCBpZiAoYWN0aW9uID09IElURVJfU0lCTElOR1MpPGJyPg0KwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgY29udGludWU7PGJyPg0KwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgaWYgKGFjdGlvbiA9PSBJVEVSX0ZPVU5EKSB7PGJyPg0KQEAgLTEyNTQsMTMg
KzEyNDksMTMgQEAgc3lzY3RsX3N5c2N0bF9uZXh0X2FjdGlvbihzdHJ1Y3Qgc3lzY3RsX29pZF9s
aXN0ICpsc3AsIGludCAqbmFtZSwgdV9pbnQgbmFtZWxlbiw8YnI+DQrCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCB9PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgS0FTU0VSVCgoYWN0aW9uPT0g
SVRFUl9DSElMRFJFTiksICgmcXVvdDtyZXQoJWQpIT1JVEVSX0NISUxEUkVOJnF1b3Q7LCBhY3Rp
b24pKTs8YnI+DQo8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBsc3AgPSBTWVNDVExfQ0hJ
TERSRU4ob2lkcCk7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbmV4dF9sc3AgPSBTWVND
VExfQ0hJTERSRU4ob2lkcCk7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKG5hbWVs
ZW4gPT0gMCkgezxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHN1Y2Nl
c3MgPSBzeXNjdGxfc3lzY3RsX25leHRfYWN0aW9uKGxzcCwgTlVMTCwgMCw8YnI+DQorwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzdWNjZXNzID0gc3lzY3RsX3N5c2N0bF9uZXh0
X2FjdGlvbihuZXh0X2xzcCwgTlVMTCwgMCw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCBuZXh0ICsgMSwgbGVuLCBsZXZlbCArIDEsIGhvbm9yX3NraXApOzxi
cj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH0gZWxzZSB7PGJyPg0KLcKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgc3VjY2VzcyA9IHN5c2N0bF9zeXNjdGxfbmV4dF9hY3Rpb24o
bHNwLCBuYW1lICsgMSwgbmFtZWxlbiAtIDEsPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgbmV4dCArIDEsIGxlbiwgbGV2ZWwgKyAxLCBob25vcl9za2lwKTs8
YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzdWNjZXNzID0gc3lzY3Rs
X3N5c2N0bF9uZXh0X2FjdGlvbihuZXh0X2xzcCwgbmFtZSArIDEsPGJyPg0KK8KgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbmFtZWxlbiAtIDEsIG5leHQgKyAxLCBsZW4s
IGxldmVsICsgMSwgaG9ub3Jfc2tpcCk7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgaWYgKCFzdWNjZXNzKSB7PGJyPg0KPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLyo8YnI+DQpAQCAtMTMzMiwxMyArMTMyNywxMiBA
QCBuYW1lMm9pZChjaGFyICpuYW1lLCBpbnQgKm9pZCwgaW50ICpsZW4sIHN0cnVjdCBzeXNjdGxf
b2lkICoqb2lkcHApPGJyPg0KwqAgwqAgwqAgwqAgZm9yICgqbGVuID0gMDsgKmxlbiAmbHQ7IENU
TF9NQVhOQU1FOykgezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHAgPSBzdHJzZXAoJmFt
cDtuYW1lLCAmcXVvdDsuJnF1b3Q7KTs8YnI+DQo8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqBvaWRwID0gU0xJU1RfRklSU1QobHNwKTs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBm
b3IgKDs7IG9pZHAgPSBTTElTVF9ORVhUKG9pZHAsIG9pZF9saW5rKSkgezxicj4NCi3CoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChvaWRwID09IE5VTEwpPGJyPg0KLcKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0dXJuIChFTk9FTlQp
Ozxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFJCX0ZPUkVBQ0gob2lkcCwgc3lzY3RsX29p
ZF9saXN0LCBsc3ApIHs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBp
ZiAoc3RyY21wKHAsIG9pZHAtJmd0O29pZF9uYW1lKSA9PSAwKTxicj4NCsKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGJyZWFrOzxicj4NCsKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIH08YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAob2lkcCA9PSBO
VUxMKTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJldHVybiAoRU5P
RU5UKTs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqb2lkKysgPSBvaWRwLSZndDtvaWRf
bnVtYmVyOzxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICgqbGVuKSsrOzxicj4NCjxicj4N
CkBAIC0yMTYyLDE2ICsyMTU2LDE1IEBAIHN5c2N0bF9maW5kX29pZChpbnQgKm5hbWUsIHVfaW50
IG5hbWVsZW4sIHN0cnVjdCBzeXNjdGxfb2lkICoqbm9pZCw8YnI+DQrCoHs8YnI+DQrCoCDCoCDC
oCDCoCBzdHJ1Y3Qgc3lzY3RsX29pZF9saXN0ICpsc3A7PGJyPg0KwqAgwqAgwqAgwqAgc3RydWN0
IHN5c2N0bF9vaWQgKm9pZDs8YnI+DQorwqAgwqAgwqAgwqBzdHJ1Y3Qgc3lzY3RsX29pZCBrZXk7
PGJyPg0KwqAgwqAgwqAgwqAgaW50IGluZHg7PGJyPg0KPGJyPg0KwqAgwqAgwqAgwqAgU1lTQ1RM
X0FTU0VSVF9MT0NLRUQoKTs8YnI+DQrCoCDCoCDCoCDCoCBsc3AgPSAmYW1wO3N5c2N0bF9fY2hp
bGRyZW47PGJyPg0KwqAgwqAgwqAgwqAgaW5keCA9IDA7PGJyPg0KwqAgwqAgwqAgwqAgd2hpbGUg
KGluZHggJmx0OyBDVExfTUFYTkFNRSkgezxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFNM
SVNUX0ZPUkVBQ0gob2lkLCBsc3AsIG9pZF9saW5rKSB7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgaWYgKG9pZC0mZ3Q7b2lkX251bWJlciA9PSBuYW1lW2luZHhdKTxi
cj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFr
Ozxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqBrZXkub2lkX251bWJlciA9IG5hbWVbaW5keF07PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgb2lkID0gUkJfRklORChzeXNjdGxfb2lkX2xpc3QsIGxzcCwgJmFtcDtrZXkpOzxicj4N
CsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChvaWQgPT0gTlVMTCk8YnI+DQrCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCByZXR1cm4gKEVOT0VOVCk7PGJyPg0KPGJyPg0KZGlm
ZiAtLWdpdCBhL3N5cy9rZXJuL3Zmc19pbml0LmMgYi9zeXMva2Vybi92ZnNfaW5pdC5jPGJyPg0K
aW5kZXggNjU3MmE4ZTM2MmMyLi42ZTJlNzhhYWY1OTcgMTAwNjQ0PGJyPg0KLS0tIGEvc3lzL2tl
cm4vdmZzX2luaXQuYzxicj4NCisrKyBiL3N5cy9rZXJuL3Zmc19pbml0LmM8YnI+DQpAQCAtNTI1
LDcgKzUyNSw3IEBAIHZmc19yZWdpc3RlcihzdHJ1Y3QgdmZzY29uZiAqdmZjKTxicj4NCsKgIMKg
IMKgIMKgIMKgKiBudW1iZXIuPGJyPg0KwqAgwqAgwqAgwqAgwqAqLzxicj4NCsKgIMKgIMKgIMKg
IHN5c2N0bF93bG9jaygpOzxicj4NCi3CoCDCoCDCoCDCoFNMSVNUX0ZPUkVBQ0gob2lkcCwgU1lT
Q1RMX0NISUxEUkVOKCZhbXA7c3lzY3RsX19fdmZzKSwgb2lkX2xpbmspIHs8YnI+DQorwqAgwqAg
wqAgwqBSQl9GT1JFQUNIKG9pZHAsIHN5c2N0bF9vaWRfbGlzdCwgU1lTQ1RMX0NISUxEUkVOKCZh
bXA7c3lzY3RsX19fdmZzKSkgezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChzdHJj
bXAob2lkcC0mZ3Q7b2lkX25hbWUsIHZmYy0mZ3Q7dmZjX25hbWUpID09IDApIHs8YnI+DQrCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBzeXNjdGxfdW5yZWdpc3Rlcl9vaWQob2lk
cCk7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgb2lkcC0mZ3Q7b2lk
X251bWJlciA9IHZmYy0mZ3Q7dmZjX3R5cGVudW07PGJyPg0KZGlmZiAtLWdpdCBhL3N5cy9zeXMv
cGFyYW0uaCBiL3N5cy9zeXMvcGFyYW0uaDxicj4NCmluZGV4IGY4NzVkODM5ZDQxZi4uM2Y1ZGEw
NmVmOTUxIDEwMDY0NDxicj4NCi0tLSBhL3N5cy9zeXMvcGFyYW0uaDxicj4NCisrKyBiL3N5cy9z
eXMvcGFyYW0uaDxicj4NCkBAIC03Niw3ICs3Niw3IEBAPGJyPg0KwqAgKiBjYW5ub3QgaW5jbHVk
ZSBzeXMvcGFyYW0uaCBhbmQgc2hvdWxkIG9ubHkgYmUgdXBkYXRlZCBoZXJlLjxicj4NCsKgICov
PGJyPg0KwqAjdW5kZWYgX19GcmVlQlNEX3ZlcnNpb248YnI+DQotI2RlZmluZSBfX0ZyZWVCU0Rf
dmVyc2lvbiAxNDAwMDcwPGJyPg0KKyNkZWZpbmUgX19GcmVlQlNEX3ZlcnNpb24gMTQwMDA3MTxi
cj4NCjxicj4NCsKgLyo8YnI+DQrCoCAqIF9fRnJlZUJTRF9rZXJuZWxfXyBpbmRpY2F0ZXMgdGhh
dCB0aGlzIHN5c3RlbSB1c2VzIHRoZSBrZXJuZWwgb2YgRnJlZUJTRCw8YnI+DQpkaWZmIC0tZ2l0
IGEvc3lzL3N5cy9zeXNjdGwuaCBiL3N5cy9zeXMvc3lzY3RsLmg8YnI+DQppbmRleCA0NTFkODNi
YmUxMjUuLjNiZDc3Y2Y4NzI0MyAxMDA2NDQ8YnI+DQotLS0gYS9zeXMvc3lzL3N5c2N0bC5oPGJy
Pg0KKysrIGIvc3lzL3N5cy9zeXNjdGwuaDxicj4NCkBAIC0zOSw3ICszOSw4IEBAPGJyPg0KwqAj
ZGVmaW5lwqAgwqAgwqAgwqAgX1NZU19TWVNDVExfSF88YnI+DQo8YnI+DQrCoCNpZmRlZiBfS0VS
TkVMPGJyPg0KLSNpbmNsdWRlICZsdDtzeXMvcXVldWUuaCZndDs8YnI+DQorI2luY2x1ZGUgJmx0
O3N5cy90cmVlLmgmZ3Q7PGJyPg0KKyNpbmNsdWRlICZsdDtzeXMvc3lzdG0uaCZndDs8YnI+DQrC
oCNlbmRpZjxicj4NCjxicj4NCsKgLyo8YnI+DQpAQCAtMTczLDIwICsxNzQsMjUgQEAgc3RydWN0
IHN5c2N0bF9yZXEgezxicj4NCsKgIMKgIMKgIMKgIGludMKgIMKgIMKgIMKgIMKgIMKgIMKgIGZs
YWdzOzxicj4NCsKgfTs8YnI+DQo8YnI+DQotU0xJU1RfSEVBRChzeXNjdGxfb2lkX2xpc3QsIHN5
c2N0bF9vaWQpOzxicj4NCitzdHJ1Y3Qgc3lzY3RsX29pZDs8YnI+DQorPGJyPg0KKy8qIFJCIFRy
ZWUgaGFuZGxpbmcgKi88YnI+DQorUkJfSEVBRChzeXNjdGxfb2lkX2xpc3QsIHN5c2N0bF9vaWQp
Ozxicj4NCjxicj4NCsKgLyo8YnI+DQrCoCAqIFRoaXMgZGVzY3JpYmVzIG9uZSAmcXVvdDtvaWQm
cXVvdDsgaW4gdGhlIE1JQiB0cmVlLsKgIFBvdGVudGlhbGx5IG1vcmUgbm9kZXMgY2FuPGJyPg0K
wqAgKiBiZSBoaWRkZW4gYmVoaW5kIGl0LCBleHBhbmRlZCBieSB0aGUgaGFuZGxlci48YnI+DQrC
oCAqLzxicj4NCsKgc3RydWN0IHN5c2N0bF9vaWQgezxicj4NCi3CoCDCoCDCoCDCoHN0cnVjdCBz
eXNjdGxfb2lkX2xpc3Qgb2lkX2NoaWxkcmVuOzxicj4NCi3CoCDCoCDCoCDCoHN0cnVjdCBzeXNj
dGxfb2lkX2xpc3QgKm9pZF9wYXJlbnQ7PGJyPg0KLcKgIMKgIMKgIMKgU0xJU1RfRU5UUlkoc3lz
Y3RsX29pZCkgb2lkX2xpbms7PGJyPg0KK8KgIMKgIMKgIMKgc3RydWN0IHN5c2N0bF9vaWRfbGlz
dMKgIG9pZF9jaGlsZHJlbjs8YnI+DQorwqAgwqAgwqAgwqBzdHJ1Y3Qgc3lzY3RsX29pZF9saXN0
KiBvaWRfcGFyZW50Ozxicj4NCivCoCDCoCDCoCDCoFJCX0VOVFJZKHN5c2N0bF9vaWQpIG9pZF9s
aW5rOzxicj4NCivCoCDCoCDCoCDCoC8qIFNvcnQga2V5IGZvciBhbGwgc2libGluZ3MsIGFuZCBs
b29rdXAga2V5IGZvciB1c2VybGFuZCAqLzxicj4NCsKgIMKgIMKgIMKgIGludMKgIMKgIMKgIMKg
IMKgIMKgIMKgIG9pZF9udW1iZXI7PGJyPg0KwqAgwqAgwqAgwqAgdV9pbnTCoCDCoCDCoCDCoCDC
oCDCoCBvaWRfa2luZDs8YnI+DQrCoCDCoCDCoCDCoCB2b2lkwqAgwqAgwqAgwqAgwqAgwqAgKm9p
ZF9hcmcxOzxicj4NCsKgIMKgIMKgIMKgIGludG1heF90wqAgwqAgwqAgwqAgwqBvaWRfYXJnMjs8
YnI+DQorwqAgwqAgwqAgwqAvKiBNdXN0IGJlIHVuaXF1ZSBhbW9uZ3N0IGFsbCBzaWJsaW5ncy4g
Ki88YnI+DQrCoCDCoCDCoCDCoCBjb25zdCBjaGFywqAgwqAgwqAgKm9pZF9uYW1lOzxicj4NCsKg
IMKgIMKgIMKgIGludMKgIMKgIMKgIMKgIMKgIMKgIMKgKCpvaWRfaGFuZGxlcikoU1lTQ1RMX0hB
TkRMRVJfQVJHUyk7PGJyPg0KwqAgwqAgwqAgwqAgY29uc3QgY2hhcsKgIMKgIMKgICpvaWRfZm10
Ozxicj4NCkBAIC0xOTYsNiArMjAyLDE5IEBAIHN0cnVjdCBzeXNjdGxfb2lkIHs8YnI+DQrCoCDC
oCDCoCDCoCBjb25zdCBjaGFywqAgwqAgwqAgKm9pZF9sYWJlbDs8YnI+DQrCoH07PGJyPg0KPGJy
Pg0KK3N0YXRpYyBpbmxpbmUgaW50PGJyPg0KK2NtcF9zeXNjdGxfb2lkKHN0cnVjdCBzeXNjdGxf
b2lkICphLCBzdHJ1Y3Qgc3lzY3RsX29pZCAqYik8YnI+DQorezxicj4NCivCoCDCoCDCoCDCoGlm
IChhLSZndDtvaWRfbnVtYmVyICZndDsgYi0mZ3Q7b2lkX251bWJlcik8YnI+DQorwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqByZXR1cm4gKDEpOzxicj4NCivCoCDCoCDCoCDCoGVsc2UgaWYgKGEtJmd0
O29pZF9udW1iZXIgJmx0OyBiLSZndDtvaWRfbnVtYmVyKTxicj4NCivCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoHJldHVybiAoLTEpOzxicj4NCivCoCDCoCDCoCDCoGVsc2U8YnI+DQorwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqByZXR1cm4gKDApOzxicj4NCit9PGJyPg0KKzxicj4NCitSQl9QUk9UT1RZ
UEUoc3lzY3RsX29pZF9saXN0LCBzeXNjdGxfb2lkLCBvaWRfbGluaywgY21wX3N5c2N0bF9vaWQp
Ozxicj4NCis8YnI+DQrCoCNkZWZpbmXCoCDCoCDCoCDCoCBTWVNDVExfSU4ociwgcCwgbCnCoCDC
oCDCoCAoci0mZ3Q7bmV3ZnVuYykociwgcCwgbCk8YnI+DQrCoCNkZWZpbmXCoCDCoCDCoCDCoCBT
WVNDVExfT1VUKHIsIHAsIGwpwqAgwqAgwqAoci0mZ3Q7b2xkZnVuYykociwgcCwgbCk8YnI+DQrC
oCNkZWZpbmXCoCDCoCDCoCDCoCBTWVNDVExfT1VUX1NUUihyLCBwKcKgIMKgIChyLSZndDtvbGRm
dW5jKShyLCBwLCBzdHJsZW4ocCkgKyAxKTxicj4NCkBAIC0yNzUsNyArMjk0LDcgQEAgVEFJTFFf
SEVBRChzeXNjdGxfY3R4X2xpc3QsIHN5c2N0bF9jdHhfZW50cnkpOzxicj4NCsKgI2RlZmluZcKg
IMKgIMKgIMKgIFNZU0NUTF9PSURfUkFXKGlkLCBwYXJlbnRfY2hpbGRfaGVhZCwgbmJyLCBuYW1l
LCBraW5kLCBhMSwgYTIsIGhhbmRsZXIsIGZtdCwgZGVzY3IsIGxhYmVsKSBcPGJyPg0KwqAgwqAg
wqAgwqAgc3RydWN0IHN5c2N0bF9vaWQgaWQgPSB7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgXDxicj4NCsKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIC5vaWRfcGFyZW50ID0gKHBhcmVudF9jaGlsZF9oZWFkKSzCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCBcPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLm9pZF9jaGls
ZHJlbiA9IFNMSVNUX0hFQURfSU5JVElBTElaRVIoJmFtcDtpZC5vaWRfY2hpbGRyZW4pLCBcPGJy
Pg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLm9pZF9jaGlsZHJlbiA9IFJCX0lOSVRJQUxJWkVS
KCZhbXA7aWQub2lkX2NoaWxkcmVuKSwgXDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5v
aWRfbnVtYmVyID0gKG5icikswqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgXDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5vaWRfa2luZCA9
IChraW5kKSzCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoFw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAub2lkX2FyZzEgPSAoYTEpLMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
XDxicj4NCjxicj4NCjwvYmxvY2txdW90ZT48L2Rpdj48L2Rpdj48L2Rpdj4NCg==
--000000000000cb322605e9bf1ee0--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAH7qZfvgRyva8gry0J1VX2oUGcJ8ncPsavkjHa9GdYYiSu_-DQ>