From: Yohanes Santoso Date: 2005-03-29T12:12:04+09:00 Subject: Re: bwlimit or throttle in WEBrick? --=-=-= Magnus Bodin writes: > As webrick has no throttling capacity of its own I started to dig the > archives and found 'bwlimit' as a dead and lost RAA-project. Anyone have > a copy left? Any good parts to share? Hi, I'm the author of the dead bwlimit. It is really a simple program and does not really do exactly what you expect it to do. Partly because of buffering done at the OS level. Basically it boils down to the OS sending a TCP packet whenever it wants to. This is part of the nagle algorithm designed to reduce network congestion by coalescing several small transmision unit into a single big packet. The only way to disable this is to disable the nagle algorithm by using the TCP_NODELAY socket option (note, that this is only an advisory to the OS, the OS still is not bound to send the packet when you write to the socket). But that introduces a significant increase in bandwidth consumption that is more difficult to calculate and predict. For local network, this may not be a detrimental reason. But if you have a 500Kbps (62.5KBps) connection to Internet and over 60%-80% is consumed by the overhead of small packets (yes, it is a reasonable overhead figure for small packets on that kind of connection), then you may think twice. There are various user-level bandwidth limiter out there, and all of them have this same problem. Bittorrent's bwlimit option does not stay on the target bandwidth. Freenet's bwlimit does not either. The one I have found that have the tightest output rate is trickle, but that too, often misses its mark. IMO, the right way to do bandwidth limiting is at the kernel-level where you have a precise control of what is being sent, and also a guarantee that the data is sent when you want it sent. Anyway, I am attaching bwlimit.rb here. May you find it useful. Yours, YS. --=-=-= Content-Type: application/octet-stream Content-Disposition: attachment; filename=bwlimit.rb Content-Transfer-Encoding: base64 IyEvdXNyL2Jpbi9lbnYgcnVieQoKCnJlcXVpcmUgJ3NvY2tldCcKcmVxdWlyZSAnZmNudGwnCnJl cXVpcmUgJ3RocmVhZCcKCgojIExpbWl0cyB0aGUgYW1vdW50IG9mIGRhdGEgc2VudC9yZWN2Lgoj IEl0IGFjdHMgYXMgYSBhdXRob3Jpc2F0aW9uLXRvLXNlbnQvcmVjdi1kYXRhIGRpc3BlbnNlcgoj IFdob2V2ZXIgd2FudHMgdG8gc2VuZC9yZWN2IGRhdGEgbXVzdCBjYWxsIHRoZSAjZGlzcGVuc2Ug bWV0aG9kCiMgdG8ga25vdyBob3cgbWFueSBpdCBzaG91bGQgc2VuZC9yZWN2IGF0IHRoYXQgdGlt ZQpjbGFzcyBCd0xpbWl0ZXIKICBkZWYgaW5pdGlhbGl6ZShyYXRlLCB0aWNrcykKICAgIEBieXRl c19wZXJfdGljayA9IDEuMCpyYXRlL3RpY2tzCiAgICBAaHogPSAxLjAvdGlja3MKICAgIGlmIEBi eXRlc19wZXJfdGljayA8IDEgCiAgICAgIHJhaXNlICJyYXRlIHRvbyBsb3cgb3IgdGlja3MgdG9v IGhpZ2giCiAgICBlbmQKICAgIEBieXRlc19wZXJfdGljayA9IEBieXRlc19wZXJfdGljay5yb3Vu ZAogICAgaWYgQGJ5dGVzX3Blcl90aWNrICogdGlja3MgIT0gcmF0ZQogICAgICBwdXRzICJBZGp1 c3RpbmcgcmF0ZSB0byAje0BieXRlc19wZXJfdGljayAqIHRpY2tzfSIKICAgIGVuZAogICAgQGxh c3RfdGljayA9IFRpbWUubm93CiAgZW5kCiAgZGVmIGRpc3BlbnNlCiAgICBjdXJyID0gVGltZS5u b3cKICAgIGRlbHRhID0gY3VyciAtIEBsYXN0X3RpY2sKICAgIGlmIGRlbHRhIDwgQGh6CiAgICAg IHNsZWVwKEBoeiAtIGRlbHRhKQogICAgZW5kCiAgICAjcHV0cyAiUmVsZWFzaW5nICN7QGJ5dGVz X3Blcl90aWNrfS4gU3BlZWQgPSAje0BieXRlc19wZXJfdGljayAvIChUaW1lLm5vdyAtIGN1cnIp fSIKICAgIEBsYXN0X3RpY2sgPSBjdXJyCiAgICBAYnl0ZXNfcGVyX3RpY2sKICBlbmQKZW5kCgpj bGFzcyBDb25zdGFudEJ3TGltaXRlciA8IEJ3TGltaXRlcgogIGRlZiBpbml0aWFsaXplCiAgZW5k CiAgZGVmIGRpc3BlbnNlCiAgICA4MTkyCiAgZW5kCmVuZAoKCgpjbGFzcyBCd0xpbWl0ZXJQcm94 eQogIGRlZiBzZWxmLmNyZWF0ZV9wcm9kdWNlcl90aHJlYWQobmFtZSwgc29ja2V0LCBzb2NrZXRf bXV0ZXgsIAoJCQkJICBxdWV1ZSwgcXVldWVfbXV0ZXgsIHF1ZXVlX2FkZGVkX2NvbmQsCgkJCQkg IHJlYWRfbGltaXRlciwga2lsbF90aHJlYWRfcHJvYykKICAgIFRocmVhZC5uZXcgewogICAgICBy ZWFkX3MgPSBuaWwKICAgICAgd2hpbGUgKDEpCglyZXN1bHQgPSBzZWxlY3QoW3NvY2tldF0sIG5p bCwgW3NvY2tldF0sIG5pbCkKCWlmIHJlc3VsdFswXS5sZW5ndGggPiAwCgkgIG5fcmVhZCA9IHJl YWRfbGltaXRlci5kaXNwZW5zZQoJICAjcHV0cyAiI3tuYW1lfSBuZWVkIHRvIHJlYWQgI3tuX3Jl YWR9IgoJICBzb2NrZXRfbXV0ZXguc3luY2hyb25pemUgewoJICAgIHJlYWRfcyA9IHNvY2tldC5y ZWN2KG5fcmVhZCkKCSAgfQoJICBpZiAocmVhZF9zLmxlbmd0aCA9PSAwKQoJICAgICNwdXRzICIj e25hbWV9IGNsb3NlZCIKCSAgICBraWxsX3RocmVhZF9wcm9jLmNhbGwKCSAgICBicmVhayAjIG9y IFRocmVhZC5zdG9wCgkgIGVsc2UKCSAgICBxdWV1ZV9tdXRleC5zeW5jaHJvbml6ZSB7CgkgICAg ICByZWFkX3Muc3BsaXQoLy8pLmVhY2gge3xpfCBxdWV1ZSA8PCBpfQoJICAgICAgI3B1dHMgIiN7 bmFtZX06IHJlYWQgI3tyZWFkX3MubGVuZ3RofSIKCSAgICAgIHF1ZXVlX2FkZGVkX2NvbmQuc2ln bmFsCgkgICAgfQoJICBlbmQKCWVsc2lmIHJlc3VsdFsyXS5sZW5ndGggPiAwCgkgIHJhaXNlICIj e25hbWV9IHJlYWQgZXJyb3IiCgllbmQKICAgICAgZW5kCiAgICB9CiAgZW5kCgoKCiAgZGVmIHNl bGYuY3JlYXRlX2NvbnN1bWVyX3RocmVhZChuYW1lLCBzb2NrZXQsIHNvY2tldF9tdXRleCwgCgkJ CQkgIHF1ZXVlLCBxdWV1ZV9tdXRleCwgcXVldWVfYWRkZWRfY29uZCwKCQkJCSAgd3JpdGVfbGlt aXRlcikKICAgIG15X3F1ZXVlID0gbmlsCiAgICBUaHJlYWQubmV3ewogICAgICB3aGlsZSAoMSkK CXF1ZXVlX211dGV4LnN5bmNocm9uaXplIHsKCSAgcXVldWVfYWRkZWRfY29uZC53YWl0KHF1ZXVl X211dGV4KQoJICBteV9xdWV1ZSA9IHF1ZXVlLmNsb25lCgkgIHF1ZXVlLmNsZWFyCgl9Cgl3aGls ZSAobXlfcXVldWUgJiYgbXlfcXVldWUubGVuZ3RoID4gMCkKCSAgcmVzdWx0ID0gc2VsZWN0KG5p bCwgW3NvY2tldF0sIFtzb2NrZXRdLCBuaWwpCgkgIGlmIHJlc3VsdFsxXS5sZW5ndGggPiAwCgkg ICAgbl93cml0ZSA9IHdyaXRlX2xpbWl0ZXIuZGlzcGVuc2UKCSAgICBzb2NrZXRfbXV0ZXguc3lu Y2hyb25pemUgewoJICAgICAgbl93cml0ZSA9IHNvY2tldC5zZW5kKG15X3F1ZXVlWzAuLm5fd3Jp dGVdLmpvaW4sIDApCgkgICAgfQoJICAgIG15X3F1ZXVlLnNsaWNlISgwLi5uX3dyaXRlKTsKCSAg ICAjcHV0cyAiUkVNT1RFOiB3cml0dGVuICN7bl93cml0ZX0iCgkgIGVsc2lmIHJlc3VsdFsyXS5s ZW5ndGggPiAwCgkgICAgcmFpc2UgIiN7bmFtZX0gc2VuZCBlcnJvciIKCSAgZW5kCgllbmQKICAg ICAgZW5kCiAgICB9CiAgZW5kCiAgCgoKICBkZWYgc2VsZi5tYWtlX25vbmJsb2NraW5nKGlvKQog ICAgaW8uZmNudGwoRmNudGw6OkZfU0VURkQsIGlvLmZjbnRsKEZjbnRsOjpGX0dFVEZEKSB8IEZj bnRsOjpPX05PTkJMT0NLKQogIGVuZAoKCiAgZGVmIHNlbGYubWFrZV9wcm9jX2tpbGxfdGhyZWFk KHRfcGFyZW50KQogICAgcHJvY3t0X3BhcmVudFs6dGhyZWFkX2xpc3RdLmVhY2gge3x0fCAKCXQu a2lsbCBpZiBUaHJlYWQuY3VycmVudCAhPSB0CgkjcHV0cyAiS2lsbGVkOiAje3QuaW5zcGVjdH0i OyAKICAgICAgfQogICAgfQogIGVuZAoKICAgIAogIGF0dHJfcmVhZGVyIDppc19nbG9iYWxfbGlt aXQKICBhdHRyX3JlYWRlciA6aW5wdXRfcmF0ZQogIGF0dHJfcmVhZGVyIDpvdXRwdXRfcmF0ZQog IGF0dHJfcmVhZGVyIDp0aWNrcwogIGF0dHJfcmVhZGVyIDppbnB1dF9saW1pdGVyCiAgYXR0cl9y ZWFkZXIgOm91dHB1dF9saW1pdGVyCiAgCiAgZGVmIHNlc3Npb24obF9zb2NrZXQsIHJfc29ja2V0 KQogICAgW2xfc29ja2V0LCByX3NvY2tldF0uZWFjaCB7fGlvfAogICAgICBCd0xpbWl0ZXJQcm94 eS5tYWtlX25vbmJsb2NraW5nIGlvCiAgICB9CiAgICAKICAgIHByb2Nfa2lsbF90aHJlYWQgPSAg QndMaW1pdGVyUHJveHkubWFrZV9wcm9jX2tpbGxfdGhyZWFkKFRocmVhZC5jdXJyZW50KQogICAg CiAgICBpZiBAaXNfZ2xvYmFsX2xpbWl0CiAgICAgIGlucHV0X2xpbWl0ZXIgPSBAaW5wdXRfbGlt aXRlcgogICAgICBvdXRwdXRfbGltaXRlciA9IEBvdXRwdXRfbGltaXRlcgogICAgZWxzZQogICAg ICB0X2N1cnJlbnQgPSBUaHJlYWQuY3VycmVudDsKICAgICAgaW5wdXRfbGltaXRlciA9IEJ3TGlt aXRlci5uZXcoQGlucHV0X3JhdGUsIEB0aWNrcykKICAgICAgb3V0cHV0X2xpbWl0ZXIgPSBCd0xp bWl0ZXIubmV3KEBvdXRwdXRfcmF0ZSwgQHRpY2tzKQogICAgZW5kCiAgICBsb2NhbF9pbnB1dF9s aW1pdGVyID0gQ29uc3RhbnRCd0xpbWl0ZXIubmV3CiAgICBsb2NhbF9vdXRwdXRfbGltaXRlciA9 IENvbnN0YW50QndMaW1pdGVyLm5ldwoKICAgIG91dGdvaW5nX3F1ZXVlID0gW10gI2Zyb20gbC0+ cgogICAgb3V0Z29pbmdfbXV0ZXggPSBNdXRleC5uZXcKICAgIG91dGdvaW5nX3Byb2R1Y2VkID0g Q29uZGl0aW9uVmFyaWFibGUubmV3CgogICAgaW5jb21pbmdfcXVldWUgPSBbXSAjZnJvbSByLT5s CiAgICBpbmNvbWluZ19tdXRleCA9IE11dGV4Lm5ldwogICAgaW5jb21pbmdfcHJvZHVjZWQgPSBD b25kaXRpb25WYXJpYWJsZS5uZXcKICAgIAogICAgbF9zb2NrZXRfbXV0ZXggPSBNdXRleC5uZXcK ICAgIHJfc29ja2V0X211dGV4ID0gTXV0ZXgubmV3CgogICAgdF9vdXRnb2luZ19wcm9kdWNlciA9 IAogICAgICBCd0xpbWl0ZXJQcm94eS5jcmVhdGVfcHJvZHVjZXJfdGhyZWFkKCJMT0NBTCIsIGxf c29ja2V0LCBsX3NvY2tldF9tdXRleCwKCQkJCQkgICAgb3V0Z29pbmdfcXVldWUsIG91dGdvaW5n X211dGV4LCAKCQkJCQkgICAgb3V0Z29pbmdfcHJvZHVjZWQsCgkJCQkJICAgIGxvY2FsX291dHB1 dF9saW1pdGVyLCAKCQkJCQkgICAgcHJvY19raWxsX3RocmVhZCkKICAgIHRfaW5jb21pbmdfcHJv ZHVjZXIgPSAKICAgICAgQndMaW1pdGVyUHJveHkuY3JlYXRlX3Byb2R1Y2VyX3RocmVhZCgiUkVN T1RFIiwgcl9zb2NrZXQsIHJfc29ja2V0X211dGV4LAoJCQkJCSAgICBpbmNvbWluZ19xdWV1ZSwg aW5jb21pbmdfbXV0ZXgsIAoJCQkJCSAgICBpbmNvbWluZ19wcm9kdWNlZCwKCQkJCQkgICAgaW5w dXRfbGltaXRlciwgCgkJCQkJICAgIHByb2Nfa2lsbF90aHJlYWQpCiAgICB0X291dGdvaW5nX2Nv bnN1bWVyID0gCiAgICAgIEJ3TGltaXRlclByb3h5LmNyZWF0ZV9jb25zdW1lcl90aHJlYWQoIlJF TU9URSIsIHJfc29ja2V0LCByX3NvY2tldF9tdXRleCwKCQkJCQkgICAgb3V0Z29pbmdfcXVldWUs IG91dGdvaW5nX211dGV4LCAKCQkJCQkgICAgb3V0Z29pbmdfcHJvZHVjZWQsCgkJCQkJICAgIG91 dHB1dF9saW1pdGVyKQogICAgdF9pbmNvbWluZ19jb25zdW1lciA9CiAgICAgIEJ3TGltaXRlclBy b3h5LmNyZWF0ZV9jb25zdW1lcl90aHJlYWQoIkxPQ0FMIiwgbF9zb2NrZXQsIGxfc29ja2V0X211 dGV4LAoJCQkJCSAgICAgaW5jb21pbmdfcXVldWUsIGluY29taW5nX211dGV4LCAKCQkJCQkgICAg IGluY29taW5nX3Byb2R1Y2VkLAoJCQkJCSAgICAgbG9jYWxfaW5wdXRfbGltaXRlcikKICAgIAog ICAgdF9jdXJyZW50ID0gVGhyZWFkLmN1cnJlbnQKICAgIHRfY3VycmVudFs6dGhyZWFkX2xpc3Rd ID0gW3Rfb3V0Z29pbmdfcHJvZHVjZXIsIHRfaW5jb21pbmdfcHJvZHVjZXIsIAogICAgICB0X291 dGdvaW5nX2NvbnN1bWVyLCB0X2luY29taW5nX2NvbnN1bWVyXQogICAgI3RfY3VycmVudFs6dGhy ZWFkX2xpc3RdLmVhY2h7fHR8IHB1dHMgIlRocmVhZHM6ICN7dC5pbnNwZWN0fSJ9CgogICAgdF9j dXJyZW50Wzp0aHJlYWRfbGlzdF0uZWFjaCB7fHR8IAogICAgICB0LmpvaW47IAogICAgICAjcHV0 cyAiSm9pbmVkOiAje3QuaW5zcGVjdH0iOyAKICAgIH0KICAgIGxfc29ja2V0LmNsb3NlCiAgICBy X3NvY2tldC5jbG9zZQogICAgI3B1dHMgIkV4aXRpbmcgY2xlYW5seSIKICBlbmQKCgogIGRlZiBp bml0aWFsaXplKGlucHV0X3JhdGUsIG91dHB1dF9yYXRlLCBpc19nbG9iYWxfbGltaXQsIHRpY2tz KQogICAgQGlucHV0X3JhdGUgPSBpbnB1dF9yYXRlCiAgICBAb3V0cHV0X3JhdGUgPSBvdXRwdXRf cmF0ZQogICAgQHRpY2tzID0gdGlja3MKICAgIGlmIEBpc19nbG9iYWxfbGltaXQgPSBpc19nbG9i YWxfbGltaXQKICAgICAgQGlucHV0X2xpbWl0ZXIgPSBCd0xpbWl0ZXIubmV3KEBpbnB1dF9yYXRl LCBAdGlja3MpCiAgICAgIEBvdXRwdXRfbGltaXRlciA9IEJ3TGltaXRlci5uZXcoQG91dHB1dF9y YXRlLCBAdGlja3MpCiAgICBlbmQKICBlbmQKZW5kCgoKZGVmIHByaW50X2hlbHAKICBwdXRzIDw8 LUVPRgogICMgI3skMH0gW29wdGlvbnNdIHJob3N0IHJwb3J0CiAgIwogICMgLS1saG9zdCB4ICAg ICAgICAgICBsaXN0ZW4gdG8gdGhlIGludGVyZmFjZSB4IChkZWY6IGxvY2FsaG9zdCkKICAjIC0t bHBvcnQgeCAgICAgICAgICAgbGlzdGVuIHRvIHBvcnQgeCAoZGVmOiA4MTE5KQogICMgLS1vdXRn b2luZy1yYXRlIHgKICAjIC1vIHggICAgICAgICAgICAgICAgb3V0cHV0IGF0IHggS0JwcyAoZGVm OiA1KQogICMgLS1pbmNvbWluZy1yYXRlIHgKICAjIC1pIHggICAgICAgICAgICAgICAgYWNjZXB0 cyBpbnB1dCBhdCB4S0JwcyAoZGVmOiA1KQogICMgLS1nbG9iYWwtbGltaXQKICAjIC1nICAgICAg ICAgICAgICAgICAgaWYgc2V0LCB0aGUgcmF0ZSBpcyBmb3IgdG90YWwgcmF0ZSAoZGVmOiB0aGUg cmF0ZSBpcyBwZXIgY29ubmVjdGlvbikKICAjIC0tdGlja3MKICAjIC10ICAgICAgICAgICAgICAg ICAgdGlja3MgcGVyIHNlY29uZCwgaGlnaGVyIG1vcmUgYWNjdXJhdGUgYnV0IGNvbnN1bWVzIG1v cmUgY3B1IChkZWY6IDEwMCkKICAjIC0taGVscAogICMgLWggICAgICAgICAgICAgICAgICB0aGlz IHBhZ2UKICAjIHJob3N0ICAgICAgICAgICAgICAgaG9zdCB0byBjb25uZWN0IHRvCiAgIyBycG9y dCAgICAgICAgICAgICAgIHBvcnQgdG8gY29ubmVjdCB0bwogIEVPRgplbmQJCQkJCQkJICAgIAoK CgppZiAkMCA9PSBfX0ZJTEVfXwogIHJlcXVpcmUgJ2dldG9wdGxvbmcnCgogIGlmIEFSR1YubGVu Z3RoIDwgMgogICAgcHJpbnRfaGVscAogICAgZXhpdAogIGVuZAogIG9wdHMgPSBHZXRvcHRMb25n Lm5ldyhbIi0tbGhvc3QiLCBHZXRvcHRMb25nOjpSRVFVSVJFRF9BUkdVTUVOVCBdLAoJCQlbIi0t bHBvcnQiLCBHZXRvcHRMb25nOjpSRVFVSVJFRF9BUkdVTUVOVCBdLAoJCQlbIi0tb3V0Z29pbmct cmF0ZSIsICItbyIsIEdldG9wdExvbmc6OlJFUVVJUkVEX0FSR1VNRU5UIF0sCgkJCVsiLS1pbmNv bWluZy1yYXRlIiwgIi1pIiwgR2V0b3B0TG9uZzo6UkVRVUlSRURfQVJHVU1FTlQgXSwKCQkJWyIt LW91dGdvaW5nLXJhdGUtYnl0ZSIsICItLW9yYiIsICBHZXRvcHRMb25nOjpSRVFVSVJFRF9BUkdV TUVOVCBdLAoJCQlbIi0taW5jb21pbmctcmF0ZS1ieXRlIiwgIi0taXJiIiwgR2V0b3B0TG9uZzo6 UkVRVUlSRURfQVJHVU1FTlQgXSwKCQkJWyItLWdsb2JhbC1saW1pdCIsICItZyIsIEdldG9wdExv bmc6Ok5PX0FSR1VNRU5UXSwKCQkJWyItLXRpY2tzIiwgIi10IiwgR2V0b3B0TG9uZzo6UkVRVUlS RURfQVJHVU1FTlRdLAoJCQlbIi0taGVscCIsICItaCIsIEdldG9wdExvbmc6Ok5PX0FSR1VNRU5U XSkKICBob3B0cyA9IHt9CiAgb3B0cy5lYWNoIHt8b3B0LCBhcmd8CiAgICBob3B0c1tvcHRdID0g YXJnCiAgfQogIGlmIEFSR1YubGVuZ3RoICE9IDIKICAgIHByaW50X2hlbHAKICBlbmQKCiAgCiAg TFBPUlQgPSAoaG9wdHNbIi0tbHBvcnQiXSB8fCA4MTE5KS50b19pCiAgTEhPU1QgPSBob3B0c1si LS1saG9zdCJdIHx8ICJsb2NhbGhvc3QiCiAgT1VUR09JTkdfUkFURSA9IChob3B0c1siLS1vdXRn b2luZy1yYXRlIl0gfHwgNSkudG9faSAqIDEwMjQKICBJTkNPTUlOR19SQVRFID0gKGhvcHRzWyIt LWluY29taW5nLXJhdGUiXSB8fCA1KS50b19pICogMTAyNAogIElTX0dMT0JBTF9MSU1JVCA9IGlm IGhvcHRzWyItLWdsb2JhbC1saW1pdCJdIHRoZW4gdHJ1ZSBlbHNlIGZhbHNlIGVuZAogIFRJQ0tT ID0gKGhvcHRzWyItLXRpY2tzIl0gfHwgMTAwKS50b19pCiAgUkhPU1QgPSBBUkdWWzBdCiAgUlBP UlQgPSBBUkdWWzFdLnRvX2kKICAKICBpZiBob3B0c1siLS1vdXRnb2luZy1yYXRlLWJ5dGUiXQog ICAgT1VUR09JTkdfUkFURSA9IGhvcHRzWyItLW91dGdvaW5nLXJhdGUtYnl0ZSJdLnRvX2kKICBl bmQKICBpZiBob3B0c1siLS1pbmNvbWluZy1yYXRlLWJ5dGUiXQogICAgSU5DT01JTkdfUkFURSA9 IGhvcHRzWyItLWluY29taW5nLXJhdGUtYnl0ZSJdLnRvX2kKICBlbmQKCiAgcHV0cyAiTFBPUlQ9 I3tMUE9SVH0iCiAgcHV0cyAiTEhPU1Q9I3tMSE9TVH0iCiAgcHV0cyAiT1VUR09JTkdfUkFURT0j e09VVEdPSU5HX1JBVEV9IgogIHB1dHMgIklOQ09NSU5HX1JBVEU9I3tJTkNPTUlOR19SQVRFfSIK ICBwdXRzICJUSUNLUz0je1RJQ0tTfSIKICBwdXRzICJJU19HTE9CQUxfTElNSVQ9I3tJU19HTE9C QUxfTElNSVQudG9fc30iCiAgcHV0cyAiUkhPU1Q9I3tSSE9TVH0iCiAgcHV0cyAiUlBPUlQ9I3tS UE9SVH0iCgogIHRocmVhZHMgPSBbXQogIHRocmVhZHNfbXV0ZXggPSBNdXRleC5uZXcKICBwcm94 eSA9IEJ3TGltaXRlclByb3h5Lm5ldyhJTkNPTUlOR19SQVRFLCBPVVRHT0lOR19SQVRFLCBJU19H TE9CQUxfTElNSVQsIFRJQ0tTKQogIHNlcnZlciA9IFRDUFNlcnZlci5uZXcoTEhPU1QsIExQT1JU KQogICNzZXJ2ZXIuc2V0c29ja29wdChTb2NrZXQ6OlNPTF9TT0NLRVQsIFNvY2tldDo6U09fUkVV U0VBRERSLCAxKQogIHB1dHMgIlJlYWR5IgogIHdoaWxlIChsb2NhbF9zb2NrZXQgPSBzZXJ2ZXIu YWNjZXB0KQogICAgYmVnaW4KICAgICAgcmVtb3RlX3NvY2tldCA9IFRDUFNvY2tldC5uZXcoUkhP U1QsIFJQT1JUKQogICAgICB0ID0gVGhyZWFkLm5ldyB7IAoJcHJveHkuc2Vzc2lvbihsb2NhbF9z b2NrZXQsIHJlbW90ZV9zb2NrZXQpCgl0aHJlYWRzX211dGV4LnN5bmNocm9uaXplIHsgdGhyZWFk cy5kZWxldGVfaWZ7fHR8IFRocmVhZC5jdXJyZW50ID09IHR9fQoJcHV0cyAiTm93IHNlcnZpbmcg I3t0aHJlYWRzLnNpemV9IGNvbm5lY3Rpb25zIgogICAgICB9CiAgICAgIHRocmVhZHNfbXV0ZXgu c3luY2hyb25pemUgeyB0aHJlYWRzIDw8IHQgfQogICAgICBwdXRzICJOb3cgc2VydmluZyAje3Ro cmVhZHMuc2l6ZX0gY29ubmVjdGlvbnMiCiAgICByZXNjdWUgPT4gZQogICAgICBwIGUKICAgIGVu ZAogIGVuZAplbmQK --=-=-=--