کلودفلر اخیراً مستند کرده است که تیم توسعه‌دهندگان آن چگونه یک باگ نادر را در کتابخانه پرکاربرد HTTP راست به نام hyper شناسایی و رفع کردند. این باگ می‌توانست پاسخ‌های بزرگ HTTP را بی‌صدا کوتاه کند و در عین حال وضعیت موفقیت‌آمیز 200 OK را بازگرداند. این مشکل سال‌ها وجود داشت و تنها در شرایط زمانی خاصی فعال می‌شد و اکنون در بالادست رفع شده است و بحث‌هایی را در میان کاربران راست در مورد این رویداد و نحوه برخورد کلودفلر با آن برانگیخته است.

شرح باگ و تأثیر آن

این باگ در سرویس Cloudflare Images و در حین بازطراحی binding آن برای Workers Images ظاهر شد. پس از انتشار، برخی از درخواست‌های بزرگ تبدیل تصویر به صورت متناوب داده‌های کوتاه شده را بازمی‌گرداندند، با وجودی که وضعیت HTTP 200 موفقیت را گزارش می‌کردند. در یکی از موارد، پاسخ تنها ۲۰۰ کیلوبایت از ۳.۳ مگابایت مورد انتظار را تحویل داد که شناسایی منبع کوتاه‌شدن را دشوار می‌کرد.

ریشه‌یابی مشکل

تیم کلودفلر به صورت سیستماتیک هر جزء در مسیر درخواست را با ساخت یک بازتولید قابل اعتماد، آزمایش در نسخه‌ها و محیط‌های مختلف hyper، ابزار دقیق هر سرویس، و استفاده از ردیابی توزیع‌شده جدا کرد تا علل احتمالی را به تدریج حذف کند. در نهایت، با استفاده از ردیابی فراخوان‌های سیستم در سطح هسته (strace) مشخص شد که hyper قبل از انتقال کامل داده‌های پاسخ بافر شده، اتصالات را زودتر از موعد می‌بندد. این یک شرایط رقابتی (race condition) وابسته به زمان بود.

«ما شش هفته را صرف تعقیب یک باگ تقریباً نامرئی کردیم – یک شرایط رقابتی که فقط در شرایط خاص رخ می‌داد – در کتابخانه hyper که بر نحوه بازگرداندن داده‌های تصویر پردازش‌شده به کلاینت توسط binding Images تأثیر می‌گذاشت. در نهایت، برای رفع آن فقط چهار خط کد نیاز بود.»

— دینا لام، مدیر محصول کلودفلر؛ دیرتنان دومنان، مهندس ارشد سیستم؛ مت لوئیس، مهندس ارشد سیستم
نمودار معماری سرویس Cloudflare Images و مسیر درخواست

نحوه کشف باگ با strace

ردیابی و لاگ‌های سطح برنامه هیچ خطایی نشان ندادند، اما strace، ابزار ردیابی فراخوان‌های سیستم در لینوکس، نشان داد که hyper قبل از انتقال کامل داده‌های بافر شده، اتصال را می‌بندد. کلودفلر این باگ را به حلقه dispatch HTTP/1 کتابخانه hyper ردیابی کرد که به اشتباه یک flush ناقص بافر را نادیده می‌گرفت و اتصال را زودتر از موعد می‌بست. این پنجره زمانی تنها چند میلی‌ثانیه بین یک flush جزئی و خاموشی زودهنگام ایجاد می‌شد که پس از سریع‌تر کردن سیستم باز شد.

برای رفع این باگ، تیم یک آزمایش قطعی اضافه کرد که شرایط رقابتی را بازتولید می‌کرد و Hyper را اصلاح کرد تا اطمینان حاصل شود که داده‌های بافر شده قبل از بستن اتصال به طور کامل flush می‌شوند. این وصله در مخزن رسمی hyper در گیت‌هاب اعمال شده است.

بازخورد جامعه برنامه‌نویسان راست

این رویداد بحث‌هایی را در میان جامعه برنامه‌نویسان زبان برنامه‌نویسی راست (Rust) برانگیخت. مارتین نوردولتز، یکی از مشارکت‌کنندگان در کامپایلر راست، در Reddit اظهار داشت که این مشکل یک نقص طراحی شناخته شده در async Rust است و به لغو خاموش (silent cancellation) مربوط می‌شود. برخی دیگر از کاربران به lint های Clippy مانند let_underscore_untyped اشاره کردند که می‌توانست این باگ را شناسایی کند اما به طور پیش‌فرض فعال نیستند.

همچنین، جیم فولر اشاره کرد که کلودفلر با درآمد ۲ میلیارد دلاری، مستقیماً از شان مک‌آرتور، نگهدارنده کتابخانه hyper، حمایت مالی نمی‌کند. این موضوع بحث در مورد حمایت مالی شرکت‌های بزرگ از توسعه‌دهندگان کتابخانه‌های متن‌باز حیاتی را داغ کرد.

نتیجه‌گیری

این حادثه نشان‌دهنده اهمیت ابزارهای ردیابی سطح پایین مانند strace در یافتن باگ‌های وابسته به زمان است. کلودفلر با انتشار این گزارش، شفافیت خود را در برخورد با مشکلات فنی نشان داد و جامعه راست نیز از این فرصت برای بهبود کیفیت کد و افزایش نظارت بر کتابخانه‌های حیاتی استفاده کرد. وصله اعمال‌شده به hyper، امنیت و قابلیت اطمینان این کتابخانه پرکاربرد را افزایش داده است.