From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: passt.top; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=UqrHA/wt; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by passt.top (Postfix) with ESMTPS id 1D1C05A0265 for ; Tue, 24 Mar 2026 10:58:40 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1774346320; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=V+buTSObe+e3/y+MVYMAXRzJgIdPVgXiof7IdKlmrqE=; b=UqrHA/wt49bhVfH61ah4NRaeGuKsWKwobUKAfWWPSfMoSLLpHk36G76eZzmi3UHpdDVqF2 x8BR7CB4SEcldb/1ibyR7JvXZj8fB2AwoDvORCTDxlEGZcBk5VM+OnGncKll5PfjXJoelb U7jeq8LIfndFj4YquHUqjcYnp2M1DdA= Received: from mail-lf1-f70.google.com (mail-lf1-f70.google.com [209.85.167.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-338-qxy3nCR_Mgatd26dCJieug-1; Tue, 24 Mar 2026 05:58:37 -0400 X-MC-Unique: qxy3nCR_Mgatd26dCJieug-1 X-Mimecast-MFC-AGG-ID: qxy3nCR_Mgatd26dCJieug_1774346316 Received: by mail-lf1-f70.google.com with SMTP id 2adb3069b0e04-5a1324ae966so3921576e87.0 for ; Tue, 24 Mar 2026 02:58:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774346316; x=1774951116; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=V+buTSObe+e3/y+MVYMAXRzJgIdPVgXiof7IdKlmrqE=; b=jYOjDYCDgBW6wAZIU2S+ShGbwNQLTxe4l0/eTuSyTMHZFAMxEbA5+AhaR/PpevBso8 nKZXzQ7puP1P2QntDwwoSNxyXqKfI2Ec+QBj+cyLYvL13SSU2WFsjhUP29MLpTyHQg7a bfDaarrrtuI0oMHFJ2qQS26WmEAu6FcIjYgi5aHRNQDcTtEp7oRsgvm96jxiDseJrdlB fI6o7Huq4RLvFTeBXO7F6hbIZtoNlQdo1BA1mCQcwWiGFhHluo3GkNCnlwuYkCnSUwzn 2PbEZXbRI2s4Bot1gY+kvo6llRMBk6Rdbx/CGwosGTGQO43rK9gV3zM5MzWrc2FGBVU8 msyQ== X-Gm-Message-State: AOJu0YyZOgCbMnpslad21pDe7yk6SRBb5unbZFkwShTqyt6zyGpkmdPl KAUIhAJZBn8ZaXC99tl6fm209fSElOOu9XnmXShV9boA50Cjxkua5gQcBXI4wXBN6fZi13/TFz6 WN8ue3empuZ/4zEUsHqp13XeKEqRitMbqYonmzc+Acwa6fUD1OPEZtBuwd6hvBy4vtE9knLZ3iT QpxnG/30iDEvDdwVcRIt8Sgd9PKrML X-Gm-Gg: ATEYQzyW4pJ+JQ3tXboo0sXDz27EPMM7j+57AHxW15ZhZgDHYHBjDvEZd1QkPQOaDFz 1QrwAdRd/RjtZ9zz3+IQLTr3t/XnKZMBzAz/RMMKw1z73LRBomzB9D9gLELAB2lCAtO2QXN8T/k W5iW80MDYZob/jYtxCiKM4K126JBJu6LVRa/IJQQZMugqM4ngYiT002QQ6sOluuTpX2ZxXo0xdq pil X-Received: by 2002:a05:6512:3406:b0:5a2:7d78:a890 with SMTP id 2adb3069b0e04-5a29620cd3amr974579e87.19.1774346316054; Tue, 24 Mar 2026 02:58:36 -0700 (PDT) X-Received: by 2002:a05:6512:3406:b0:5a2:7d78:a890 with SMTP id 2adb3069b0e04-5a29620cd3amr974562e87.19.1774346315422; Tue, 24 Mar 2026 02:58:35 -0700 (PDT) MIME-Version: 1.0 References: <20260323090305.319573-3-anskuma@redhat.com> <26136561-fc90-4f74-9984-aa5fd4e5ca97@redhat.com> In-Reply-To: <26136561-fc90-4f74-9984-aa5fd4e5ca97@redhat.com> From: Anshu Kumari Date: Tue, 24 Mar 2026 15:28:23 +0530 X-Gm-Features: AQROBzCEVuy5h6F3-CZxdYMRy_PbF-6P_anO0TdinKenzm1GcbDVjS7OKF-F41c Message-ID: Subject: Re: [PATCH] Bug 134: message rate limiting https://bugs.passt.top/show_bug.cgi?id=134 To: Laurent Vivier X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 7WLmqR2JKosn54Nhrdz3eDI5vNeIyyyrV1_o5r7bTTU_1774346316 X-Mimecast-Originator: redhat.com Content-Type: multipart/alternative; boundary="000000000000d6ef4b064dc2313a" Message-ID-Hash: DWWTS3KMEXABGB7TCQ54NDELXZDEWDPS X-Message-ID-Hash: DWWTS3KMEXABGB7TCQ54NDELXZDEWDPS X-MailFrom: anskuma@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: passt-dev@passt.top, sbrivio@redhat.com, dgibson@redhat.com X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --000000000000d6ef4b064dc2313a Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable > + info_ratelimit(now, LOG_RATELIMIT_INTERVAL, You changed "debug" to "info". Is this intentional? > + "New guest MAC address observed: %s", > + eth_ntop(c->guest_mac, bufmac, > + sizeof(bufmac))); > proto_update_l2_buf(c->guest_mac); > } > Yes, this log-level is changed to info based on the discusion attached with the ticket https://archives.passt.top/passt-dev/20250912082344.01888466@elisabeth/ On Mon, Mar 23, 2026 at 5:48=E2=80=AFPM Laurent Vivier = wrote: > On 3/23/26 10:03, Anshu Kumari wrote: > > Hi Everyone, > > Hi Anshu, > > > Please review patch for Bug 134. > > > > Description:- Inorder to rate limit the messages, each logging function > uses per-call-site static variables, so each macro expansion tracks its o= wn > rate independently. Allows up to LOG_RATELIMIT_BURST messages per window= . > When a new window starts after suppression, a summary of suppressed > messages is logged. > > This should be a message describing the patch, not an email text. > This will be commited and part of the change log of passt. > > If you want to introduce your patch with a message you can write a cover > letter (you can > put " Hi Everyone, Please review patch for Bug 134" in it) > > Put the bug link in the message body with Link: tag > > Link: https://bugs.passt.top/show_bug.cgi?id=3D134 > > Something like: > > "log: Add rate-limiting macros for log messages > > In order to rate limit the messages, each logging function uses > per-call-site static > variables, so each macro expansion tracks its own rate independently. > Allows up to > LOG_RATELIMIT_BURST messages per window. When a new window starts after > suppression, a > summary of suppressed messages is logged. > > Link: https://bugs.passt.top/show_bug.cgi?id=3D134 > Signed-off-by: Anshu Kumari > " > > > > > Signed-off-by: Anshu Kumari > > --- > > log.h | 41 +++++++++++++++++++++++++++++++++++++++++ > > tap.c | 19 ++++++------------- > > 2 files changed, 47 insertions(+), 13 deletions(-) > > > > diff --git a/log.h b/log.h > > index 6ceb686..e989760 100644 > > --- a/log.h > > +++ b/log.h > > @@ -48,6 +48,47 @@ void logmsg_perror(int pri, const char *format, ...) > > passt_exit(EXIT_FAILURE); \ > > } while (0) > > > > +#define LOG_RATELIMIT_BURST 5 /* Max messages per window per call > site */ > > +#define LOG_RATELIMIT_INTERVAL 1 /* Default rate limit window i= n > seconds */ > > + > > +/** > > + * logmsg_ratelimit() - Rate-limited log message > > + * @fn: Logging function > > + * @now: current timestamp > > + * @intv: Minimum interval in seconds between allowed messages > > + */ > > +#define logmsg_ratelimit(fn, now, intv, ...) \ > > + do { \ > > + static time_t _rl_last; \ > > + static unsigned int _rl_printed; \ > > + static unsigned int _rl_suppressed; \ > > + \ > > + if ((now)->tv_sec - _rl_last > (intv)) { \ > > + if (_rl_suppressed) \ > > + fn("(suppressed %u similar messages)", \ > > + _rl_suppressed); \ > > + _rl_last =3D (now)->tv_sec; = \ > > + _rl_printed =3D 0; = \ > > + _rl_suppressed =3D 0; = \ > > + } \ > > + \ > > + if (_rl_printed < LOG_RATELIMIT_BURST) { \ > > + fn(__VA_ARGS__); \ > > + _rl_printed++; \ > > + } else { \ > > + _rl_suppressed++; \ > > + } \ > > + } while (0) > > + > > +#define err_ratelimit(now, intv, ...) > \ > > + logmsg_ratelimit(err, now, intv, __VA_ARGS__) > > +#define warn_ratelimit(now, intv, ...) > \ > > + logmsg_ratelimit(warn, now, intv, __VA_ARGS__) > > +#define info_ratelimit(now, intv, ...) > \ > > + logmsg_ratelimit(info, now, intv, __VA_ARGS__) > > +#define debug_ratelimit(now, intv, ...) > \ > > + logmsg_ratelimit(debug, now, intv, __VA_ARGS__) > > + > > extern int log_file; > > extern int log_trace; > > extern bool log_conf_parsed; > > diff --git a/tap.c b/tap.c > > index 1049e02..0812a8a 100644 > > --- a/tap.c > > +++ b/tap.c > > @@ -686,17 +686,8 @@ static bool tap4_is_fragment(const struct iphdr > *iph, > > const struct timespec *now) > > { > > if (ntohs(iph->frag_off) & ~IP_DF) { > > - /* Ratelimit messages */ > > - static time_t last_message; > > - static unsigned num_dropped; > > - > > - num_dropped++; > > - if (now->tv_sec - last_message > FRAGMENT_MSG_RATE) { > > I think you could remove FRAGMENT_MSG_RATE and use LOG_RATELIMIT_INTERVAL= , > or better > remove the intv parameter and use LOG_RATELIMIT_INTERVAL internally. > > > - warn("Can't process IPv4 fragments (%u dropped)", > > - num_dropped); > > - last_message =3D now->tv_sec; > > - num_dropped =3D 0; > > - } > > + warn_ratelimit(now, FRAGMENT_MSG_RATE, > > + "Can't process IPv4 fragment"); > > return true; > > } > > return false; > > @@ -1115,8 +1106,10 @@ void tap_add_packet(struct ctx *c, struct > iov_tail *data, > > char bufmac[ETH_ADDRSTRLEN]; > > > > memcpy(c->guest_mac, eh->h_source, ETH_ALEN); > > - debug("New guest MAC address observed: %s", > > - eth_ntop(c->guest_mac, bufmac, sizeof(bufmac))); > > + info_ratelimit(now, LOG_RATELIMIT_INTERVAL, > > You changed "debug" to "info". Is this intentional? > > > + "New guest MAC address observed: %s", > > + eth_ntop(c->guest_mac, bufmac, > > + sizeof(bufmac))); > > proto_update_l2_buf(c->guest_mac); > > } > > > > Thanks, > Laurent > > --000000000000d6ef4b064dc2313a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+PHNwYW4gY2xhc3M9ImdtYWlsLWltIj4mZ3Q7ICvCoCDCoCDCoCDCoCDC oCDCoCDCoGluZm9fcmF0ZWxpbWl0KG5vdywgTE9HX1JBVEVMSU1JVF9JTlRFUlZBTCw8YnI+PGJy Pjwvc3Bhbj5Zb3UgY2hhbmdlZCAmcXVvdDtkZWJ1ZyZxdW90OyB0byAmcXVvdDtpbmZvJnF1b3Q7 LiBJcyB0aGlzIGludGVudGlvbmFsPzxzcGFuIGNsYXNzPSJnbWFpbC1pbSI+PGJyPjxicj4mZ3Q7 ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAmcXVvdDtOZXcgZ3Vl c3QgTUFDIGFkZHJlc3Mgb2JzZXJ2ZWQ6ICVzJnF1b3Q7LDxicj4mZ3Q7ICvCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBldGhfbnRvcChjLSZndDtndWVzdF9tYWMsIGJ1 Zm1hYyw8YnI+Jmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqBzaXplb2YoYnVmbWFjKSkpOzxicj4mZ3Q7wqAgwqAgwqAgwqAgwqAgwqAg wqAgwqBwcm90b191cGRhdGVfbDJfYnVmKGMtJmd0O2d1ZXN0X21hYyk7PGJyPiZndDvCoCDCoCDC oCDCoH08YnI+Jmd0O8KgIMKgPGJyPjxicj5ZZXMsIHRoaXMgbG9nLWxldmVsIGlzIGNoYW5nZWQg dG8gaW5mbyBiYXNlZCBvbiB0aGUgZGlzY3VzaW9uIGF0dGFjaGVkIHdpdGggdGhlIHRpY2tldMKg PGEgaHJlZj0iaHR0cHM6Ly9hcmNoaXZlcy5wYXNzdC50b3AvcGFzc3QtZGV2LzIwMjUwOTEyMDgy MzQ0LjAxODg4NDY2QGVsaXNhYmV0aC8iPmh0dHBzOi8vYXJjaGl2ZXMucGFzc3QudG9wL3Bhc3N0 LWRldi8yMDI1MDkxMjA4MjM0NC4wMTg4ODQ2NkBlbGlzYWJldGgvPC9hPsKgPC9zcGFuPjwvZGl2 Pjxicj48ZGl2IGNsYXNzPSJnbWFpbF9xdW90ZSBnbWFpbF9xdW90ZV9jb250YWluZXIiPjxkaXYg ZGlyPSJsdHIiIGNsYXNzPSJnbWFpbF9hdHRyIj5PbiBNb24sIE1hciAyMywgMjAyNiBhdCA1OjQ4 4oCvUE0gTGF1cmVudCBWaXZpZXIgJmx0OzxhIGhyZWY9Im1haWx0bzpsdml2aWVyQHJlZGhhdC5j b20iPmx2aXZpZXJAcmVkaGF0LmNvbTwvYT4mZ3Q7IHdyb3RlOjxicj48L2Rpdj48YmxvY2txdW90 ZSBjbGFzcz0iZ21haWxfcXVvdGUiIHN0eWxlPSJtYXJnaW46MHB4IDBweCAwcHggMC44ZXg7Ym9y ZGVyLWxlZnQ6MXB4IHNvbGlkIHJnYigyMDQsMjA0LDIwNCk7cGFkZGluZy1sZWZ0OjFleCI+T24g My8yMy8yNiAxMDowMywgQW5zaHUgS3VtYXJpIHdyb3RlOjxicj4NCiZndDsgSGkgRXZlcnlvbmUs PGJyPg0KPGJyPg0KSGkgQW5zaHUsPGJyPg0KPGJyPg0KJmd0OyBQbGVhc2UgcmV2aWV3IHBhdGNo IGZvciBCdWcgMTM0Ljxicj4NCiZndDsgPGJyPg0KJmd0OyBEZXNjcmlwdGlvbjotIElub3JkZXIg dG8gcmF0ZSBsaW1pdCB0aGUgbWVzc2FnZXMsIGVhY2ggbG9nZ2luZyBmdW5jdGlvbiB1c2VzIHBl ci1jYWxsLXNpdGUgc3RhdGljIHZhcmlhYmxlcywgc28gZWFjaCBtYWNybyBleHBhbnNpb24gdHJh Y2tzIGl0cyBvd24gcmF0ZSBpbmRlcGVuZGVudGx5LsKgIEFsbG93cyB1cCB0byBMT0dfUkFURUxJ TUlUX0JVUlNUIG1lc3NhZ2VzIHBlciB3aW5kb3cuwqAgV2hlbiBhIG5ldyB3aW5kb3cgc3RhcnRz IGFmdGVyIHN1cHByZXNzaW9uLCBhIHN1bW1hcnkgb2Ygc3VwcHJlc3NlZCBtZXNzYWdlcyBpcyBs b2dnZWQuPGJyPg0KPGJyPg0KVGhpcyBzaG91bGQgYmUgYSBtZXNzYWdlIGRlc2NyaWJpbmcgdGhl IHBhdGNoLCBub3QgYW4gZW1haWwgdGV4dC48YnI+DQpUaGlzIHdpbGwgYmUgY29tbWl0ZWQgYW5k IHBhcnQgb2YgdGhlIGNoYW5nZSBsb2cgb2YgcGFzc3QuPGJyPg0KPGJyPg0KSWYgeW91IHdhbnQg dG8gaW50cm9kdWNlIHlvdXIgcGF0Y2ggd2l0aCBhIG1lc3NhZ2UgeW91IGNhbiB3cml0ZSBhIGNv dmVyIGxldHRlciAoeW91IGNhbiA8YnI+DQpwdXQgJnF1b3Q7IEhpIEV2ZXJ5b25lLCBQbGVhc2Ug cmV2aWV3IHBhdGNoIGZvciBCdWcgMTM0JnF1b3Q7IGluIGl0KTxicj4NCjxicj4NClB1dCB0aGUg YnVnIGxpbmsgaW4gdGhlIG1lc3NhZ2UgYm9keSB3aXRoIExpbms6IHRhZzxicj4NCjxicj4NCkxp bms6IDxhIGhyZWY9Imh0dHBzOi8vYnVncy5wYXNzdC50b3Avc2hvd19idWcuY2dpP2lkPTEzNCIg cmVsPSJub3JlZmVycmVyIiB0YXJnZXQ9Il9ibGFuayI+aHR0cHM6Ly9idWdzLnBhc3N0LnRvcC9z aG93X2J1Zy5jZ2k/aWQ9MTM0PC9hPjxicj4NCjxicj4NClNvbWV0aGluZyBsaWtlOjxicj4NCjxi cj4NCiZxdW90O2xvZzogQWRkIHJhdGUtbGltaXRpbmcgbWFjcm9zIGZvciBsb2cgbWVzc2FnZXM8 YnI+DQo8YnI+DQpJbiBvcmRlciB0byByYXRlIGxpbWl0IHRoZSBtZXNzYWdlcywgZWFjaCBsb2dn aW5nIGZ1bmN0aW9uIHVzZXMgcGVyLWNhbGwtc2l0ZSBzdGF0aWMgPGJyPg0KdmFyaWFibGVzLCBz byBlYWNoIG1hY3JvIGV4cGFuc2lvbiB0cmFja3MgaXRzIG93biByYXRlIGluZGVwZW5kZW50bHku wqAgQWxsb3dzIHVwIHRvIDxicj4NCkxPR19SQVRFTElNSVRfQlVSU1QgbWVzc2FnZXMgcGVyIHdp bmRvdy7CoCBXaGVuIGEgbmV3IHdpbmRvdyBzdGFydHMgYWZ0ZXIgc3VwcHJlc3Npb24sIGEgPGJy Pg0Kc3VtbWFyeSBvZiBzdXBwcmVzc2VkIG1lc3NhZ2VzIGlzIGxvZ2dlZC48YnI+DQo8YnI+DQpM aW5rOiA8YSBocmVmPSJodHRwczovL2J1Z3MucGFzc3QudG9wL3Nob3dfYnVnLmNnaT9pZD0xMzQi IHJlbD0ibm9yZWZlcnJlciIgdGFyZ2V0PSJfYmxhbmsiPmh0dHBzOi8vYnVncy5wYXNzdC50b3Av c2hvd19idWcuY2dpP2lkPTEzNDwvYT48YnI+DQpTaWduZWQtb2ZmLWJ5OiBBbnNodSBLdW1hcmkg Jmx0OzxhIGhyZWY9Im1haWx0bzphbnNrdW1hQHJlZGhhdC5jb20iIHRhcmdldD0iX2JsYW5rIj5h bnNrdW1hQHJlZGhhdC5jb208L2E+Jmd0Ozxicj4NCiZxdW90Ozxicj4NCjxicj4NCiZndDsgPGJy Pg0KJmd0OyBTaWduZWQtb2ZmLWJ5OiBBbnNodSBLdW1hcmkgJmx0OzxhIGhyZWY9Im1haWx0bzph bnNrdW1hQHJlZGhhdC5jb20iIHRhcmdldD0iX2JsYW5rIj5hbnNrdW1hQHJlZGhhdC5jb208L2E+ Jmd0Ozxicj4NCiZndDsgLS0tPGJyPg0KJmd0O8KgIMKgbG9nLmggfCA0MSArKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKzxicj4NCiZndDvCoCDCoHRhcC5jIHwgMTkgKysr KysrLS0tLS0tLS0tLS0tLTxicj4NCiZndDvCoCDCoDIgZmlsZXMgY2hhbmdlZCwgNDcgaW5zZXJ0 aW9ucygrKSwgMTMgZGVsZXRpb25zKC0pPGJyPg0KJmd0OyA8YnI+DQomZ3Q7IGRpZmYgLS1naXQg YS9sb2cuaCBiL2xvZy5oPGJyPg0KJmd0OyBpbmRleCA2Y2ViNjg2Li5lOTg5NzYwIDEwMDY0NDxi cj4NCiZndDsgLS0tIGEvbG9nLmg8YnI+DQomZ3Q7ICsrKyBiL2xvZy5oPGJyPg0KJmd0OyBAQCAt NDgsNiArNDgsNDcgQEAgdm9pZCBsb2dtc2dfcGVycm9yKGludCBwcmksIGNvbnN0IGNoYXIgKmZv cm1hdCwgLi4uKTxicj4NCiZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHBhc3N0X2V4aXQoRVhJ VF9GQUlMVVJFKTvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oFw8YnI+DQomZ3Q7wqAgwqAgwqAgwqB9IHdoaWxlICgwKTxicj4NCiZndDvCoCDCoDxicj4NCiZn dDsgKyNkZWZpbmUgTE9HX1JBVEVMSU1JVF9CVVJTVMKgIDXCoCAvKiBNYXggbWVzc2FnZXMgcGVy IHdpbmRvdyBwZXIgY2FsbCBzaXRlICovPGJyPg0KJmd0OyArI2RlZmluZSBMT0dfUkFURUxJTUlU X0lOVEVSVkFMwqAgwqAgwqAgwqAxwqAgLyogRGVmYXVsdCByYXRlIGxpbWl0IHdpbmRvdyBpbiBz ZWNvbmRzICovPGJyPg0KJmd0OyArPGJyPg0KJmd0OyArLyoqPGJyPg0KJmd0OyArICogbG9nbXNn X3JhdGVsaW1pdCgpIC0gUmF0ZS1saW1pdGVkIGxvZyBtZXNzYWdlPGJyPg0KJmd0OyArICogQGZu OsKgIMKgIMKgIMKgIMKgIMKgIMKgIExvZ2dpbmcgZnVuY3Rpb248YnI+DQomZ3Q7ICsgKiBAbm93 OsKgIMKgIMKgY3VycmVudCB0aW1lc3RhbXA8YnI+DQomZ3Q7ICsgKiBAaW50djrCoCDCoCBNaW5p bXVtIGludGVydmFsIGluIHNlY29uZHMgYmV0d2VlbiBhbGxvd2VkIG1lc3NhZ2VzPGJyPg0KJmd0 OyArICovPGJyPg0KJmd0OyArI2RlZmluZSBsb2dtc2dfcmF0ZWxpbWl0KGZuLCBub3csIGludHYs IC4uLinCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFw8YnI+DQomZ3Q7ICvC oCDCoCDCoGRvIHvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBcPGJyPg0KJmd0OyAr wqAgwqAgwqAgwqAgwqAgwqAgwqBzdGF0aWMgdGltZV90IF9ybF9sYXN0O8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgXDxicj4NCiZndDsgK8KgIMKgIMKg IMKgIMKgIMKgIMKgc3RhdGljIHVuc2lnbmVkIGludCBfcmxfcHJpbnRlZDvCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBcPGJyPg0KJmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqBz dGF0aWMgdW5zaWduZWQgaW50IF9ybF9zdXBwcmVzc2VkO8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgXDxicj4NCiZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgXDxicj4NCiZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKChub3cpLSZn dDt0dl9zZWMgLSBfcmxfbGFzdCAmZ3Q7IChpbnR2KSkge8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IFw8YnI+DQomZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChfcmxfc3Vw cHJlc3NlZCnCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFw8YnI+ DQomZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGZuKCZx dW90OyhzdXBwcmVzc2VkICV1IHNpbWlsYXIgbWVzc2FnZXMpJnF1b3Q7LMKgIFw8YnI+DQomZ3Q7 ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBfcmxfc3Vw cHJlc3NlZCk7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBcPGJyPg0KJmd0OyArwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBfcmxfbGFzdCA9IChub3cpLSZndDt0dl9zZWM7 wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBcPGJyPg0KJmd0OyArwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBfcmxfcHJpbnRlZCA9IDA7wqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgXDxicj4NCiZndDsgK8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgX3JsX3N1cHByZXNzZWQgPSAwO8KgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgXDxicj4NCiZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKg fcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgXDxicj4NCiZndDsgK8KgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgXDxicj4NCiZndDsgK8KgIMKgIMKgIMKgIMKg IMKgIMKgaWYgKF9ybF9wcmludGVkICZsdDsgTE9HX1JBVEVMSU1JVF9CVVJTVCkge8KgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIFw8YnI+DQomZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoGZuKF9fVkFfQVJHU19fKTvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCBcPGJyPg0KJmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBf cmxfcHJpbnRlZCsrO8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIFw8YnI+DQomZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoH0gZWxzZSB7wqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgXDxicj4NCiZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgX3JsX3N1 cHByZXNzZWQrKzvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oFw8YnI+DQomZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoH3CoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoFw8YnI+DQomZ3Q7ICvCoCDCoCDCoH0gd2hpbGUgKDApPGJyPg0KJmd0OyArPGJyPg0KJmd0 OyArI2RlZmluZSBlcnJfcmF0ZWxpbWl0KG5vdywgaW50diwgLi4uKcKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIFw8YnI+DQomZ3Q7ICvC oCDCoCDCoGxvZ21zZ19yYXRlbGltaXQoZXJyLCBub3csIGludHYsIF9fVkFfQVJHU19fKTxicj4N CiZndDsgKyNkZWZpbmUgd2Fybl9yYXRlbGltaXQobm93LCBpbnR2LCAuLi4pwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBcPGJyPg0KJmd0 OyArwqAgwqAgwqBsb2dtc2dfcmF0ZWxpbWl0KHdhcm4sIG5vdywgaW50diwgX19WQV9BUkdTX18p PGJyPg0KJmd0OyArI2RlZmluZSBpbmZvX3JhdGVsaW1pdChub3csIGludHYsIC4uLinCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFw8YnI+ DQomZ3Q7ICvCoCDCoCDCoGxvZ21zZ19yYXRlbGltaXQoaW5mbywgbm93LCBpbnR2LCBfX1ZBX0FS R1NfXyk8YnI+DQomZ3Q7ICsjZGVmaW5lIGRlYnVnX3JhdGVsaW1pdChub3csIGludHYsIC4uLinC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBc PGJyPg0KJmd0OyArwqAgwqAgwqBsb2dtc2dfcmF0ZWxpbWl0KGRlYnVnLCBub3csIGludHYsIF9f VkFfQVJHU19fKTxicj4NCiZndDsgKzxicj4NCiZndDvCoCDCoGV4dGVybiBpbnQgbG9nX2ZpbGU7 PGJyPg0KJmd0O8KgIMKgZXh0ZXJuIGludCBsb2dfdHJhY2U7PGJyPg0KJmd0O8KgIMKgZXh0ZXJu IGJvb2wgbG9nX2NvbmZfcGFyc2VkOzxicj4NCiZndDsgZGlmZiAtLWdpdCBhL3RhcC5jIGIvdGFw LmM8YnI+DQomZ3Q7IGluZGV4IDEwNDllMDIuLjA4MTJhOGEgMTAwNjQ0PGJyPg0KJmd0OyAtLS0g YS90YXAuYzxicj4NCiZndDsgKysrIGIvdGFwLmM8YnI+DQomZ3Q7IEBAIC02ODYsMTcgKzY4Niw4 IEBAIHN0YXRpYyBib29sIHRhcDRfaXNfZnJhZ21lbnQoY29uc3Qgc3RydWN0IGlwaGRyICppcGgs PGJyPg0KJmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGNvbnN0 IHN0cnVjdCB0aW1lc3BlYyAqbm93KTxicj4NCiZndDvCoCDCoHs8YnI+DQomZ3Q7wqAgwqAgwqAg wqBpZiAobnRvaHMoaXBoLSZndDtmcmFnX29mZikgJmFtcDsgfklQX0RGKSB7PGJyPg0KJmd0OyAt wqAgwqAgwqAgwqAgwqAgwqAgwqAvKiBSYXRlbGltaXQgbWVzc2FnZXMgKi88YnI+DQomZ3Q7IC3C oCDCoCDCoCDCoCDCoCDCoCDCoHN0YXRpYyB0aW1lX3QgbGFzdF9tZXNzYWdlOzxicj4NCiZndDsg LcKgIMKgIMKgIMKgIMKgIMKgIMKgc3RhdGljIHVuc2lnbmVkIG51bV9kcm9wcGVkOzxicj4NCiZn dDsgLTxicj4NCiZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgbnVtX2Ryb3BwZWQrKzs8YnI+DQom Z3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChub3ctJmd0O3R2X3NlYyAtIGxhc3RfbWVzc2Fn ZSAmZ3Q7IEZSQUdNRU5UX01TR19SQVRFKSB7PGJyPg0KPGJyPg0KSSB0aGluayB5b3UgY291bGQg cmVtb3ZlIEZSQUdNRU5UX01TR19SQVRFIGFuZCB1c2UgTE9HX1JBVEVMSU1JVF9JTlRFUlZBTCwg b3IgYmV0dGVyIDxicj4NCnJlbW92ZSB0aGUgaW50diBwYXJhbWV0ZXIgYW5kIHVzZSBMT0dfUkFU RUxJTUlUX0lOVEVSVkFMIGludGVybmFsbHkuPGJyPg0KPGJyPg0KJmd0OyAtwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqB3YXJuKCZxdW90O0NhbiYjMzk7dCBwcm9jZXNzIElQdjQgZnJh Z21lbnRzICgldSBkcm9wcGVkKSZxdW90Oyw8YnI+DQomZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCBudW1fZHJvcHBlZCk7PGJyPg0KJmd0OyAtwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqBsYXN0X21lc3NhZ2UgPSBub3ctJmd0O3R2X3NlYzs8YnI+DQom Z3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG51bV9kcm9wcGVkID0gMDs8YnI+ DQomZ3Q7IC3CoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQomZ3Q7ICvCoCDCoCDCoCDCoCDCoCDC oCDCoHdhcm5fcmF0ZWxpbWl0KG5vdywgRlJBR01FTlRfTVNHX1JBVEUsPGJyPg0KJmd0OyArwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAmcXVvdDtDYW4mIzM5O3QgcHJvY2VzcyBJUHY0 IGZyYWdtZW50JnF1b3Q7KTs8YnI+DQomZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXR1cm4g dHJ1ZTs8YnI+DQomZ3Q7wqAgwqAgwqAgwqB9PGJyPg0KJmd0O8KgIMKgIMKgIMKgcmV0dXJuIGZh bHNlOzxicj4NCiZndDsgQEAgLTExMTUsOCArMTEwNiwxMCBAQCB2b2lkIHRhcF9hZGRfcGFja2V0 KHN0cnVjdCBjdHggKmMsIHN0cnVjdCBpb3ZfdGFpbCAqZGF0YSw8YnI+DQomZ3Q7wqAgwqAgwqAg wqAgwqAgwqAgwqAgwqBjaGFyIGJ1Zm1hY1tFVEhfQUREUlNUUkxFTl07PGJyPg0KJmd0O8KgIMKg PGJyPg0KJmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbWVtY3B5KGMtJmd0O2d1ZXN0X21hYywg ZWgtJmd0O2hfc291cmNlLCBFVEhfQUxFTik7PGJyPg0KJmd0OyAtwqAgwqAgwqAgwqAgwqAgwqAg wqBkZWJ1ZygmcXVvdDtOZXcgZ3Vlc3QgTUFDIGFkZHJlc3Mgb2JzZXJ2ZWQ6ICVzJnF1b3Q7LDxi cj4NCiZndDsgLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZXRoX250b3AoYy0mZ3Q7Z3Vl c3RfbWFjLCBidWZtYWMsIHNpemVvZihidWZtYWMpKSk7PGJyPg0KJmd0OyArwqAgwqAgwqAgwqAg wqAgwqAgwqBpbmZvX3JhdGVsaW1pdChub3csIExPR19SQVRFTElNSVRfSU5URVJWQUwsPGJyPg0K PGJyPg0KWW91IGNoYW5nZWQgJnF1b3Q7ZGVidWcmcXVvdDsgdG8gJnF1b3Q7aW5mbyZxdW90Oy4g SXMgdGhpcyBpbnRlbnRpb25hbD88YnI+DQo8YnI+DQomZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAmcXVvdDtOZXcgZ3Vlc3QgTUFDIGFkZHJlc3Mgb2JzZXJ2 ZWQ6ICVzJnF1b3Q7LDxicj4NCiZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIGV0aF9udG9wKGMtJmd0O2d1ZXN0X21hYywgYnVmbWFjLDxicj4NCiZndDsgK8Kg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc2l6 ZW9mKGJ1Zm1hYykpKTs8YnI+DQomZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBwcm90b191cGRh dGVfbDJfYnVmKGMtJmd0O2d1ZXN0X21hYyk7PGJyPg0KJmd0O8KgIMKgIMKgIMKgfTxicj4NCiZn dDvCoCDCoDxicj4NCjxicj4NClRoYW5rcyw8YnI+DQpMYXVyZW50PGJyPg0KPGJyPg0KPC9ibG9j a3F1b3RlPjwvZGl2Pg0K --000000000000d6ef4b064dc2313a--