واکنشهای زنجیرهای در شبکههای کامپیوتری
یافتن الگوریتمی جهت جلوگیری از واكنشهای زنجیرهای به شكل یك polynomial غیرممكن است؛ اما با تبعیت از روشهای این مقاله، میتوان این گونه واكنشهای مخرب را در شبكههای كامپیوتری كاهش داد. نه برنامههای كامپیوتری همیشه صحیحاند و نه سخت افزار كامپیوتر همواره بدون عیب. یك نقص سخت افزاری، به راحتی می تواند كامپیوتری را از كار بیندازد و این موضوع در مورد برنامههای نرم افزاری هم صدق می كند.اغلب كامپیوترها، به صورت دورهای از كار میافتند و حتی كامپیوترهای با قابلیت اطمینان بالا نیز، گاهی دچار مشكل می شوند. اما اكنون كه كامپیوترها، در شبكههای متفاوت قرار گرفتهاند، خطر احتمال بروز نقص در یكی از كامپیوترهای شبكه، یا وجود نقص در یكی از پروتكلها- كه باعث از كارافتادن كل سیستم شبكهای شود-بیشتر است. بدین ترتیب روشن است كه از كار افتادن كل سیستم در اثر از كار افتادن یك كامپیوتر قابل قبول نیست. در این مقاله از" واكنشهای زنجیرهای" برای مشخص كردن این گونه از كار افتادگی در شبكهها بحث میشود." واكنش زنجیرهای" را فرهنگنامه و بستر (Webster)" سلسله واكنشهای شیمیایی یا هستهای خودجوشی كه در آن محصولات واكنش سبب ادامه روند واكنشها می شوند" تعریف كرده است. این تعریف به غیر از قسمتی از آن كه، تعریف را منحصر به واكنشهای شیمیایی و هستهای كرده است، برای منظور ما كاملا"مناسب است. قابلیت دسترسی هر چه بیشتر به شبكهها سبب به وجود آمدن انواع كاربردها كه محتاج به الگوریتمها و پروتكلهای پیچیده برای پردازش توزیعی در شبكههاست، شده است. این پیچیدگی مضاعف باعث بالا رفتن امكان پیدایش نقص در طراحی شبكهها شده است. هدف اصلی این مقاله، معرفی تعدادی از این نقایص و بحث در مورد جلوگیری از بروز آنهاست.متاسفانه هیچ راهی برای بالا بردن قابلیت اطمینان سیستمهای نرم افزاری وجود ندارد. اما هر چقدر نقاط ضعفها را بهتر تشخیص دهیم، بهتر می توانیم خود را جهت محافظت از كل سیستم مجهز كنیم.این مقاله وضعیتهایی كه منجر به پایین آمدن كل سیستم می شود، مشخص می كند و نقصهای حقیقی را كه در سیستمهای متفاوت اتفاق افتاده اند و دارای شباهتهای زیادی هستند، ارائه می دهد. همچنین در این مقاله، مثالهایی از فروریزی احتمالی سیستمها كه در نتیجه نقصهای جزئی در طراحی آنها وجود داشته، ارائه می گردد. ساختن یك برنامه كامپیوتری كلی، كه بتواند تمام واكنشهای زنجیره ای را بشناسد و از آنها جلوگیری كند همچنانكه در نظریه۱ در این مقاله نشان داده خواهد شد، غیرممكن است؛اما این مقاله، به چند قانون برای كم مردن احتمال وقوع هر گونه نقص در سیستم شبكهای، اشاره خواهد كرد. مقدار زیادی از مطالب آن مثل قصههای رایج بین اهل فن است. اما هدف كلی، جمع آوری و یكی كردن یك سری مشاهدات و راهحلهای فاقد عمومیت است. عده زیادی معتقدند كه برنامههای توزیعی، كلا" می توانند دارای آن چنان نواقص جزئی باشند كه پیدا كردن آنها فوق تا مشكل است. این مقاله، از این درك حمایت می كند؛ اما در ضمن كمك می نماید تا درك نواقص و جلوگیری آنها مشخصتر شود.این موضوع، بویژه اهمیت زیادی دارد، چرا كه شبكه ها هر روز پیچیدهتر و گستردهتر می شوند.
● یك واكنش زنجیره ای در یك"Ethernet"
اولین مثال، شامل یك شبكه محلی است. مسئله، در اثر وجود نقص پروتكل سیستم عامل جدیدی به نام ۴.۳ Unix به وجود آمد. سیستم جدید، روی تعدادیWorkstations به نام Microuaxs نصب شد. این كامپیوترها، توسط یك شبكه محلی Ethernet به یك سری Workstation دیگر كه قبلا" با سیستم عامل قدیمیتر (Unix ۴.۲) به یكدیگر مرتبط بودند، متصل شدند. در این مقاله, به بحث در جزئیات مربوط به كاربرد پروتكلها و قسمتی از شبكه كه دراز كار افتادگی كل آن سهیم بوده است خواهیم پرداخت.
● سابقه
Ethernet یك وسیله داده پراكنی است كه پیغامها را به تمامی مقصدها میفرستد. هر كامپیوتر میزبان، دارای یك كنترلكننده Ethernet است كه مسوول شناختن پیغامهای آدرس شده، به كامپیوتر میزبان وصل شده به اوست. پیغامهای كه به وسیله كنترل كننده دریافت می شود دو نوع اند:
۱) پیغام آدرس شده به كامپیوتر میزبان
۲) پیغام داده پراكنده به كلیه وسایل روی شبكه.IP- Internet Protocol نام پروتكلی است كه رابطه "بین شبكهای" است و مسوءول دریافت پیغامهای گرفته شده توسط كنترل كننده Ethernet است. IP پروتكل پیچیدهای است كه مسوءولیتهای زیادی دارد مخصوصا" كه این پروتكل به پروتكل دیگری به نام ARP یاAddress Resolution Protocol متصل است. ARP كار ترجمه آدرسهای بین شبكه ای، به آدرسهای فیزیكی كامپیوترهای میزبان را، عهده دار می باشد. در واقع، هر پیغام روی شبكه دارای دو آدرس است:
۱) آدرس IP
۲) آدرس ARP
Ethernet پروتكل رابط میانی بین این دو آدرس است. هر دو پروتكلهای IP و APR، پروتكلهای همه منظوره برای شبكههای بزرگاند؛ اما از آنها میتوان در شبكههای محلی نیز استفاده كرد.شكل (۱) نشان دهنده رابطه بین كنترل كننده ARP,IP,Ethernet است.
هر پیغام درستی كه روی شبكه فرستاده می شود، دارای یك آدرس صحیحEthernet و یك آدرس صحیح IP است. پیغام توسط كنترل شونده Ethernet ، با آدرس برابر با آدرس پیغام، گرفته می شود و از آنجا ارسال می گردد. IP ابتدا آدرس خود را امتحان میكند و در صورت برابری، كاری را كه در پیغام نهفته است، انجام میدهد (مانند حوركردن بستههای دادهها) و پیغام را توسط پروتكلهای دیگر، به كامپیوتر میزبان واگذار می كند. IP همچنین پیغامهای را از كامپیوتر میزبان دریافت مینماید و با استفاده از ARP آدرس Ethernet صحیح را پیدا و پیغام را برای آن میفرستد.
● فروریزی شبكه بالا
در زیر خواهیم دید كه در اثر واكنش زنجیرهای ناشی از ناسازگاری بین دو سیستم عامل۴.۲ Unix Berkeley و Unix ۴.۳ Berkeley در مشخص نمودن پیغامهای داده پراكنی، كل سیستم شبكه فرو میریزد. در سیستم Berkeley Unix ۴.۲ یك پیغام داده پراكنی به وسیله تمام صفر OO..O Unix در كامپیوتر میزبان در آدرس IP مشخص می۰۱۵۷گردد، در صورتی كه با تمام یك مشخص ۱۱.. ۱ در سیستم عامل ۴.۳ كامپیوتر Berkeley میشود. یك پیغام داده پراكنی از سیستم عامل مشخص Unix ۴.۳ را در نظر بگیرید كه در آدرس IP میزبان، با تمام یك دریافت شد۱۱..۱ میشود. این پیغام توسط IP از نوع ۴.۲ كنترل كنندههای Ethernet در سیستم ۴.۲ (چون آدرس ۱۱..۱ آدرس را Ethernet آن درست بود) و سپس به OO..O فرستاده شد. اما آدرس IP سیستم ۴.۲ به تمام یك نمیشناخت. چرا كه در این سیستم تمام صفر سعی كرد این درست است. در این موقع تصحیح كند. IP اشتباه آشكار را بنابراین، با استفاده از مكانیزمی كه در آن وجود صحیح داشت، از پیدا APR خواست كه آدرس Ethernet را، برای آن آدرس IP كند تا پیغام بدین ترتیب به مقصد اصلیاش فرستاده شود. ولی یك ARP هیچ گونه اطلاعی از این آدرس بخصوص نداشت. بنابراینهای ARP پیغام در خواستی برای كلیه قدرت ARP روی شبكه فرستاد. آیا كسی میتواند این آدرس را ترجمه كند؟ به دلیل هیچ آن ARP ترجمه پیغام بخصوص را نداشت، در نتیجه پیغام داده پراكنی مزبور به دور انداخته شد. این اشتباه، نتیجه غیرقابل جبرانی به وجود نیاورد. تعدادی پیغانهای داده پراكنی به مقصدشان نرسیدند. این باعث به وجود آمدن پیغامهای خطا شد كه خود باعث اضافهشدن بار شبكه و پروتكلها گردید. بعضی از فرمانهای سیستم عامل كه شبكه، مانند متداول rwho پیغامهای داده شدن تعداد پیغامهای خطا و افزودن بار شبكه شدند. سیستم شبكه ای كه Unix ۴.۲ و Unix ۴.۳ را بهم متصل میكرد، در اثر وجود بار زیاد از سرعتش بسیار كاسته شد، لیكن از كار نیفتاد، اما سعی در از بین بردن این نقص، باعث پایین آوردن سیستم گردید. برای كارشناسانی كه كل سیستم را نظارت میگردند، اشكال در آدرس IP با تمام یك ۱۱..۱ بود، كه به دلیلی باعث به وجود آمدن درخواستهای متعدد از ها ARP میشد. در یك سایت، این راه حل برای مسئله پیدا شد: در جدول یكی از ARP ها، آدرس داده پراكنی Ethernet مترادف با داده پراكنی تمام یك ۱۱..۱ IP قرار داده شد، به این منظور كه درخواست ARP ها بالاخره به آن ARP مخصوص با جدول دستكاری شده خواهد رسید و در آنجا مسئله حل ناسازگاری بین دو سیستم نتیجه ۴.۲ و ۴.۳ خواهدگردید. اما را IP عمل، كاملا" متفاوت بود. برای روشن شدن موضوع، یك پیغام متصل به آن IP از سیستم ۴.۲ در نظر بگیرید كه پیغام سیستم فهمید كه پیغام ۴.۳ را نمیشناخت و در نتیجه از ARP در خواست كمك كرد پیغام را با یك.ARP واقعا" یك پیغام داده پراكنی است. اما این IP آدرس داده به وجود IP پراكنی پیغام Ethernet پیغام رد شده خود باعث بدون تغییر IP آمدن مسئله میشد. علتش این بود كه آدرس ترجمه شده بود. بنابراین، این پیغام به وسیله بقیه شناخته ۴.۲ های كار ۴.۲ نمی شد. پس مسئله پیشین، دوباره تكرار میگشت. پس اگر در سیستم شبكه، تا پیغام K ماشین با سیستمK می كرد هر پیغام داده پراكنی، باعث به وجود آمدن تا پیغام K جدید می شد و هر كدام از آن جدید K تا پیغام به نوبه خود به وجود میآورد و غیره. نتیجتا" كل شبكه، از این پیغامها پرشد و تعدادی ماشین از كارافتاد تا كار شناسان سایت مجبور شدند كابلهایی را كه سیستمها را به هم متصل میكرد از هم جدا كرده و دوباره ماشینها را به كار بیندازند و كابلها را ببندند.
● حلقه بسته بینهایت"Infinite Loop"
وقتی كه یك استفاده كننده شبكه از ماشینی به ماشینی دیگر رفت، باید كاری كند كه پیغامهای دریافتی را به ماشین جدید منتقل نماید. این كار، با به كار بردن فرمانهای منتقل كننده قابل انجام است. برای مثال، در سیستم عاملUnix شخص میتواند آدرس ماشین جدید را در فایلی به نام Forward مشخص كند. قبل از اینكه پیغامی به شخص استفاده كننده ماشین انتقال یابد، این فایل امتحان میشود و چنانچه در داخل آن خالی نباشد، پیغام به طور اتوماتیك، به آدرس جدید فرستاده میشود. حال وضعیتی را در نظر بگیرید كه، شخص بی احتیاطی در فایلهایForward. دو كامپیوتر مختلف دو آدرس قرار میدهد. به عبارت دیگر، او در Forward A ، آدرس ماشین B و در Forward ماشین B آدرس ماشین A را قرار میدهد و بدین ترتیب یك سیكل به وجود میآورد. پس، یك پیغام فرستاده شده به ماشین A ، از A به B و از B به A در حلقه بسته بی نهایت باقی میماند. عمل این گونه پیغامها، دارای طول عمرند هر بار كه از ماشین، به ماشین دیگر فرستاده میشوند، از عمر پیغام كاسته میگردد تا اینكه عمر آن تمام میشود و قبل از اینكه پیغام از بین برود یك پیغام خطا به وجود میآورد.● از كار افتادگی
معمولا" این گونه حلقه بسته ها، مشكلی به وجود نمیآوردند، بجز آنكه شخص استفاده كننده هیچ گاه پیغامی دریافت نمیكند؛ اما در سناریوی زیر مشكل تفاوت میكند: جان كه، در دام چنین حلقه بستهای افتاده بود، بدون كوچكترین اطلاعی متوجه میشود كه پیغامی دریافت نمیكند. او تصمیم میگیرد كه برای خودش پیغامی بفرستد، تا ببیند نتیجه چه میشود. پیغامی كه او برای خودش فرستاد البته در داخل حلقه بسته افتاد و بعد از آنكه طول عمرش سپری شد از بین رفت و پیغام به وجود آورد. آن پیغام خطایی ایجاد شده، به كسی كه پیغام را فرستاده بود (جان)، فرستاده شد. البته سر نوشت پیغام خطا، همانند پیغام اصلی بود و این پیغام هم قبل از از بین رفتن، پیغام خطای دیگری به وجود آورد. اما هر بار كه یك پیغام خطای جدید به وجود میآمد، طولش بزرگتر میشد به دلیل اینكه، هر پیغام، شامل پیغام، مشخصات پیغام و صادر كننده پیغام بود. این روند رو به رشد در حجم پیغامها، از تابع خطی پیروی میكرد كه برای از كار انداختن كل سیستم كافی بود. در مثال بالا، دو ماشین A و B در یك شبكه با سرعت زیاد قرار گرفته بودند. بنابراین، پیغامها خیلی سریع از A به B و بر عكس میرفت و بزرگتر میشد و در نتیجه سیستم خیلی سریع پایین آمد. اگر سرعت شبكه، پایین بود پیغامها با سرعت كمتری رد و بدل میشدند كه خود باعث پایین آمدن كارآیی سیستم و تاخیر در تشخیص مشكل می گشت. مثال دیگر، عبارت است از یك حلقه بسته بینهایت كه در دانشگاه آریزونا در سال ۱۹۸۶ اتفاق افتاده. به علت اشتباه در دادن مقادیر به فایلهای اولیه، یك كامپیوتر مشحص به نام Corana فكر میكرد كه اسمش كامپیوتر دیگری است بنام Baskerville كه با Corana روی یك شبكه بودند. وقتی كه Corana به كار افتاد، تلاش كرد كه اتصالش را با Baskerville همانند بقیه كامپیوترها برقرار كند. این اتصال ناموفق بود برای اینكه Baskerville نمی خواست كه با خود صحبت كند، چرا كه Baskerville ازCorana پیغامی به صورت سلام، من Baskerville هستم دریافت كرد. این اتصال ناموفق باعث به وجود آمدن یك پیغام خطا شد. پیغام خطا به طور اتوماتیك به كامپیوتر دیگری به نام مگارون (Megaron) روی شبكه فرستاده شد. مگارون مسوول نگهداری آدرس كارشناسان سایت بود. متاسفانه كارشناسی كه مسوول بود، پیغامهایش را روی Corana دریافت می كرد؛ اما چون Corana فكر می كرد كه Baskerville است، كارشناس سایت هیچ وقت پیغام خطا را دریافت نكرد. چون پیغام خطا، نمیتوانست به مقصدش برسد. همین باعث به وجود آمدن پیغام خطای دیگری شد كه، به نوبه خود پیغام خطایی دیگری شد كه، به نوبه خود پیغام خطای دیگری را به وجود آورد و غیره. باید توجه كرد به علت اینكه چندین استفاده كننده در این مورد دخیل بودند، اثرات نامطلوب حلقه بسته خیلی جدیتر بود: هر پیغام خطا، به تمام آدرسها فرستاده میشد. نتیجه اینكه، در اثر پر شدن دیسكها، تعداد زیادی ماشین، از جمله ماشینهای كارشناسان سایت از كار افتادند. این مثال، نشان دهنده خطر فرستادن بیش از یك پیغام و یا استفاده از یك لیست بلند در نامهنگاری است. بهتر است كه پیغامهای خطا را در یك فایل ریخت و مسوول آن گاهگاهی به آن فایل نگاه كند تا اینكه، از روش پیغام رسانی استفاده شود. امروزه، استفاده از لیستهای بلند نامه نگاری، در سراسر جهان متداول است و از كارافتادگی سیستم شامل آنها می تواند بسیار مضر باشد.
● مثالهای بیشتر:
چهار مثال دیگر در مورد واكنشهای زنجیرهای، نشان می دهد كه پروتكلهای شبكهای تا چه اندازه میتوانند آسیب پذیر باشند. مشهورترین واكنش زنجیرهای، در سال ۱۹۸۰ روی شبكه Arpanet رخ داد: یك نقص سخت افزاری در یك كامپیوتر میزبان، باعث به وجود آمدن حلقه بسته ای از پیغامهای مسیرگزین در شبكه شد كه در انتها، كل سیستم را پایین آورد. همچنانكه قبلا" گفته شد، هر پیغام، همیشه داده پراكنی می شود؛ لیكن مقصد پیغام، پیغام را می خواند. حال فرض كنید، میخواهیم تعدادی شبكه محلی را به وسیله چند پل(Bridges) به یكدیگر متصل نماییم. همچنین فرض كنید میخواهیم شكل فرستادن پیغامهای داده پراكنی را روی كل سیستم حفظ كنیم. اگر سیستم جدید كه از مجموعه سیستمهای قبلی به وجود آمده، دارای حلقه بسته نباشد، یك الگوریتم سیل آسا (Flooding) این كار را انجام خواهد داد. بدین ترتیب كه، پلی كه تعدادی شبكه محلی را به یكدیگر متصل میكند، هر پیغامی را كه از یك شبكه دریافت مینماید، آن را به همه شبكههایی كه به آن متصلاند میفرستد به غیر از شبكه ای كه پیغام را از آن دریافت كرده است. اما اگر كل سیستم دارای حلقه بسته بود، از الگوریتم درخت پوشا (Spanning Tree) استفاده میكنیم. درخت پوشا، عبارت است از یك زیر گراف (Subgraph) كه تمام گرهها (Nodes) را شامل میشود بدون اینكه حلقه بستهای داشته باشد.پرلمن (Perlman) الگریتمی دارد كه می تواند یك درخت پوشا را پیدا كند. پرلمن و وارگیز (Varghese) نشان میدهند كه این پروتكل، چگونه می تواند تعداد زیادی پیغام به صورت نمایی به وجود آورد. ما در اینجا، جزئیات این پروتكل را بررسی نمیكنیم؛ بلكه فقط به نقصهای اصلی آن میپردازیم. كار اصلی پروتكل، این است كه از طرف هر پل روی شبكه برای یافتن حلقه بسته پیغامی به صورت سیل آسا به تمام گرههای شبكه بفرستد. از این جهت كه بالاخره تمام این پیغامها جذب میشوند، هیچ گونه حلقه بسته بی نهایتی ظاهر نمیگردد. مسئله در اینجاست كه برای شبكه های چون شبكه زیر، چنین پیغامهای سیل آسا تعداد زیادی پیغام به صورت نمایی به وجود میآورد.
در اینجا خطری وجود دارد و آن این است كه، قبل از اینكه پیغامی بتواند جذب شود، آن تعداد پیغام به وجود آید كه كل سیستم غیر قابل استفاده گردد. بنابراین در این مثال، تنها بودن حلقههای بسته بینهایت كافی نیست؛ بلكه ما باید مطمئن شویم كه تعداد زیادی پیغام به وجود نیاید. یك مثال دیگر، پروتكل سوال كردن روی شبكه است. یك گروه می تواند پیغام سوال را می دهد و یا آن را به گره دیگری ارسال می دارد. فرض كنید كه هر سوال یك مشخصه دارد و هر گروه سوالاتش را در حافظه اش ضبط می نماید. سوالات به صورت سیل آسا پخش می شوند و توسط الگوریتمی كه سوالات را جذب میكند، محو می شوند به طوری كه هیچ گرهای، یك سوال را دوبار از خود عبور نمیدهند و فرض كنید شخصی به بهتر كردن این الگوریتم به روش زیر مصمم شود: سوالی از گره ای به وجود آمده است. گرههای دیگر، اگر بتوانند قسمتی از سوال را جواب دهند آن را به طور كامل از خود عبور نمیدهد. و فقط قسمتهای را كه جواب داده نشدهاند به جلو میفرستند. فرض كنید وقتی كه قسمتی از سوال، جواب داده شد، بقیه آن دارای یك مشخصه جدید شود، چرا كه بقیه سوال، سوالی جدید است كه با سوال قبلی تفاوت دارد. این باعث به وجود آمدن هیچ گونه حلقه بسته بی نهایت نمیشود؛ چرا كه اگر سوالی از K قسمت به وجود آمده باشد حداكثر تا۱-K دفعه میتواند تغییر كند (هر بار از دفعه قبل كوچكتر میگردد). گر چه تعداد تغییرات۱- K دفعه است؛ اما ما میتوانیم K ۲ سوال جدید از یك سوال داشته باشیم. بنابراین در بدترین وضعیت K۲ پیغام از یك پیغام روی شبكه به وجود میآید كه این قابل قبول نیست. آخرین مثال، با بقیه مثالها تفاوت دارد. این مثال، درباره پارازیت بین شبكه ای "Internet Worm" است كه در سال ۱۹۸۸ به كلیه كامپیوترها در آمریكا حمله كرد. علت به وجود آمدن پارازیت نا مشخص است. از مشخصات پارازیت این بود كه، سعی كرد تا آنجا كه می تواند در شبكه پخش و پراكنده شود و موقعی كه در ماشینی قرار گرفت، تكثیر شده و تعداد بیشتری از خود به وجود آورد. البته، این مشخصات یك واكنش زنجیرهای است. به دلیل نبودن مكانیزمی در پروتكلهای شبكه جهت جلوگیری یا لااقل كاهش پارازیتها، تعداد آنها به قدری زیاد شد كه كل سیستم از كار افتاد.● شناسایی و جلوگیری از واكنشهای زنجیرهای
كلیه مثالهای بالا دارای مشخصات مشتركاند. در این قسمت، مشخصات مشترك مورد بررسی قرار میگیرد و توصیههای در مورد جلوگیری از واكنشهای زنجیرهای پیشنهاد میشود. در ضمن، مشخص خواهد شد كه، جلوگیری از بروز نقصها غیر ممكن است و در این زمینه بهترین روش، عمل به توصیههایی است كه، به وجود آمدن واكنشهای زنجیرهای را به حداقل میرساند. عامل مشترك بین تمام مثالهای فوق، یك حلقه بسته بینهایت"Infinite Loop" یا یك حلقه بسته نمایی"Exponential Loop" است. این حلقههای بسته از پیغامهای كنترل، معمولی و داده پراكنی به وجود میآوردند. وجود حلقههای بسته در اثر نقصهای جزئی در طراحی سیستم بود. اولین سوال این است كه، آیا امكان تشخیص چنین حلقههای بستهای وجود دارد؟یعنی آیا ما می توانیم پروتكلها را تجزیه و تحلیل كنیم و وجود این گونه وضعیتها را پیش بینی كنیم؟ متاسفانه، پاسخ سوالات فوق خیر است.
● غیر ممكن بودن تشخیص حلقه های بسته بینهایت
اجازه بدهید ابتدا از یك مدل ساده محاسبات توزیعی؛ صحبت كنیم. N عدد ماشین وجود دارد كه هر كدام مشغول اجرا كردن یك برنامه محلی (پروتكلی) میباشد. برنامهها ترتیبی هستند. در ضمن دو فرمان اصلی به نامهای Send و Receive وجود دارد. فرمان Send تعدادی داده را از ماشینی به ماشین دیگر، مشخص شده در فرمان، میفرستد و در حافظه واسطه (Buffer) ماشین مقصد قرار می دهد. فرمان Receive پیغامها را میگیرد و روی آنها عمل میكند. برای ساده كردن مطلب از موضوعات مربوط به همزمانی (Synchronization)، وقفهها (Interrupts) و اتصال (Connectivity) صرف نظر مینماییم و فرض میكنیم كه تمام ماشینها كاملا" به یگدیگر متصلاند. سوال مطرح شده این است كه، آیا تعداد پیغامها محدودند؟ خیر؛ زیرا این مسئله مكث كردن است. در مسئله مكث، صورت مسئله این است كه، به فرض داشتن یك برنامه هرگز پایان میپذیرد؟ این مسئله فاقد جواب است. بدلیل معنی كه، هیچ برنامهای نمیتواند آن را در طول مدت معینی حل كند (اثبات در مرجع شماره۵ پایان مقاله :(J.E.Hopcraft, J.D.Ullman) اثبات مسئله بالا از اثبات مسئله مكث كردن پیروی میكند.
● نظریه ۱
با فرض داشتن یك سیستم توزیعی، مشخص كردن تعداد پیغامهای به وجود آمده توسط یك برنامه غیرممكن است.
▪ اثبات:
فرض كنیدكه، یك برنامه به نامP داریم كه میتواند با داشتن مدل بالا مشخص كند كه، آیا تعداد پیغامها محدودندیا نه؟ چنین برنامهای می تواند برای حل مسئله مكث كردن به كار رود. چرا كه اگر بخواهیم مسئله مكث كردن را برای برنامهای ترتیبی چون S حل كنیم، میتوانیم بعد از هر فرمان درS یك فرمان Send به یك ماشین اختیاری، بدهیم. در آن صورت بدیهی است و به وضوح معلوم است كه تعداد پیغامهای صادر شده از S محدود است، اگر و فقط اگر S پایان پذیرد. در عمل، غیر قابل حل كردن مسئله مكث، از نوشتن برنامه توسط برنامهنویسها جلوگیری نمیكند. معمولا" میتوان مدت زمانی را كه یك برنامه اجرا میشود تخمین زد و چنانكه خیلی طولانی بود، آن را از كار انداخت. اما یك تفاوت اساسی بین محاسبات ترتیبی و توزیعی، در این است كه به سادگی محاسبات ترتیبی، نمیتوان محاسبات توزیعی را در هنگام اجرا از كار انداخت. مثلا"نمیتوانیم كلیدی مانند Kill را فشار دهیم و روند اجرا را پایان دهیم. چرا كه تعداد بیش از یك كامپیوتر، در آن واحد مشغول كار هستند. از طرف دیگر، در شبكهاست. اما به دلیل وجود واكنش زنجیرهای شبكه غیرقابل استفاده است. به همین دلیل جلوگیری از واكنشهای زنجیرهای بسیار مهم است.
▪ تشابهات مثالهای فوق:
در مثال Ethernet، مسئله پیغامهای داده پراكنی بدون اینكه تشخیص داده شوند، از ماشینی به ماشین دیگر انتقال یافتند. یك حلقه بسته شامل پیغامهای داده پراكنی، بسیار مشكل ساز است؛ اما اساس مسئله، در ناتوانی پروتكل IP میباشد و در تشخیص اینكه، مشغول فرستادن پیغامی است كه قبلا" از خود عبور كرده است. در مثال بعدی، حلقه بسته پیغامها از پیغامهای خطایی به وجود آمده بود كه، خود از پیغامهای خطای دیگر مایه میگرفتند. باز هم در این مثال، ساز و كار پردازش خطا، به قدر كافی باهوش نبود كه متوجه شود در حال گزارش دادن خطای قبلی است. توجه كنید در مثال هر بار، پیغام خطای جدیدی از پیغام خطای قبلی كه ریشه در پیغام خطای اولیه داشت، گزارش میشد. در مثال مجموعه شبكههای متصل محلی، مسئله در ناتوانی تشخیص حلقه بسته نبود؛ بلكه در رشد نمایی پیغامها بود قبل از اینكه حلقه بستهای توسط الگوریتم مخصوصی تشخیص داده شود. این مثال، نشان میدهد كه حتی داشتن یك حلقه بسته موقتی نیز میتواند، باعث از كار انداختن سیستم شود.
● تولید اتوماتیكی پیغام
Automatic Generation of Message - AGM
علت اصلی نهفته در مثالهای فوق را میتواند AGM نامید. این تعریف، شامل هر پیغامی كه به وسیله برنامهای كه خود توسط یك پیغام از ماشین دیگری به وجود آمده، میشود. بنابراین، به جلو فرستادن یك پیغام، یك AGM است. استفاده از آن امری است ضروری. زیرا كه انتشار متناوب اطلاعات مسیرگزینی نمیتواند، بدون AGM انجام شود و یا اینكه پیغامهای خطا، همواره اتوماتیكی به وجود میآیند و داشتن فایلForward، به AGM نیاز دارد. اما از طرفی AGM باعث ضربهپذیر شدن پروتكلهای شبكه میگردد. حتی سادهترین AGM می تواند باعث واكنش زنجیرهای شود. یك مثال دیگر: برنامه تعطیلات، برنامهای است ساده و پر طرفدار. این برنامه، پیغامهای رسیده را میخواند و به طور اتوماتیك جواب میدهد. مثلا": من به تعطیلات رفته ام و وقتی برگشتم جوابتان را میدهم. با تمام سادگی، چون این برنامه AGM است، باید در نوشتن آن محتاط بود. برای مثال، اگر پیغامی كه توسط برنامه داده میشود، باعث به وجود آمدن پیغام خطایی شود خود پیغام خطا، پیغام برنامه را دریافت خواهد كرد و بدین ترتیب، یك حلقه بسته بی نهایت به وجود میآید. یك برنامه خوب تعطیلات، باید تمام آدرسهایی را كه به آنها جواب داده، به حافظه بسپارد تا به آنها دوباره جواب ندهد لااقل در یك زمان مشخص. در آن مو قع، اگر برنامه در تشخیص آدرس پیغام اصلی درماند، به وجود آمدن حلقه بسته بینهایت امكانپذیر میشود.
● روشهای كنترل AGM
روشهای كنترل AGM، فاقد عمومیت بوده و ناكا فیاند. بهترین روش در مقابله با بینهایت پیغام، پیرشدن Aging است. هر پیغام دارای محدودهای است كه به طور متناوب هر بار كه پیغام به جلو فرستاده میشود، پیرامونش افزایش می یابد، تا زمانی كه پیغام خیلی كهنه شود. كهنه شدن میتواند به تعداد جهشهای پیغام، از كامپیوتری به كامپیوتر دیگر بستگی داشته باشد. اگر پیغام، تعداد زیادی جهش داشته باشد كنار زده میشود. این روشی است كه قرار بود از به وجود آمدن حلقه بسته پیغامها جلوگیری كند. یك روش دیگر، عبارت است از: استفاده از زمان معینی از تولد یك پیغام به دور انداخته میشود. این روش احتیاج به همزمان سازی با ساعت سیستم دارد. در بسیاری موراد، كهولت نمیتواند كافی باشد. علت آن این است كه، AGM نه تنها باعث جلو رفتن پیغامها میشود؛ بلكه می تواند پیغامهای كاملا" جدیدی ایجاد كند. یك پیغام جدید، بنا به تعریف یك پیغام جوان است. توجه كنید كه این، دقیقا" عامل به وجود آمدن حلقههای بسته بینهایت در مثالهای قبلی است. روند كهنه شدن حلقه بسته اصلی تشخیص داده شده بود؛ ولی یك پیغام خطا (تولد پیغام جوان) باعث به وجود آمدن حلقه بسته دیگری شد. بنابراین میتوان استدلال كرد كه پیغامهای خطا، با داشتن سن پیغامهایی كه درباره آنها هستند، باید به وجود آیند. ساختن چنین مكانیزمی كار آسانی نیست. برای مثال، پیغام خطایی كه راجع به پیغام كهنهای است، نمیتواند گزارشش را به كسی دهد؛ زیرا كه قبلا" زندگی خودش هم به سر آمده است. شاید بهتر باشد كه تعداد جهشهای پیغام خطا را، برابر ماكزیمم تعداد جهشها منهای K قرار دهیم. K عددی است كوچك و اختیاری، برای دادن زمان كافی به كلیه پیغامهای خطا. اما اشكال دیگری پیدا میشود و آن امكان دوباره به وجود آمدن حلقه های بسته بینهایت است. راه حل دیگر تكیه بر Time-outs است چنانچه پیغامی در مدت مشخصی به مقصدش نرسید، آن را كنار میگذاریم و یا یك كپی از پیغام فرستاده شده را نگه داشته، در صورتی كه بعد از مدتی جواب پیغام دریافت نشد؛ پیغام را دوباره میفرستیم. گرچه این روش، باعث جلوگیری از زیست پیغامهای كهنه میشود؛ لیكن از تولد پیغامهای جوان جلوگیری نخواهد كرد. یك نقص دیگر این روش، این است كه واكنشهای زنجیرهای میتوانند زودتر از Time-outs شبكه را پراز پیغام كنند. روش دیگر برای جلوگیری از بینهایت AGM، جذب است. به پیغامها اجازه تولید پیغامها اجازه تولید پیغامهای جوان داده میشود؛ اما هر پیغامی بنا به قانونهایی جذب میشود. یك قانون كلی چسباندن یك شناسنامه به هر پیغام و به حافظه سپردن تمام شناسنامههاست. اگریك پیغام، دوبار به یك گره رسید، كنار گذاشته میشود. اشكال این روش، این است كه چگونه شناسنامهها را به وجود آورد و برای چه مدتی آنها را به حافظه سپرد.
● یك روش نسبتا" بی خطر برای كم كردن واكنشهای زنجیرهای
با مخلوط كردن روشهایی كه تا به حال راجع به آنها صحبت شد، می توانیم الگوریتمی به دست آوریم كه در بیشتر موارد از واكنشهای زنجیرهای جلوگیری كند. تعدادی الگوریتم مشابه پیشنهاد شده است (مرجع شماره۷ در پایان مقاله:R.Periman). الگوریتم پیشنهادی من ( نویسنده) بیشتر از دیگران عمومیت دارد و تنها آن دسته AGM را كه در این بحث مطرح شدند در برنمیگیرد. البته به خاطر عمومیت آن، ممكن است از راندمان كمتری نسبت به دیگر الگوریتمها بر خوردار باشد؛ ولی در نظر گرفتن AGM به صورت عمومی از اهمیت كافی برخوردار است. این الگوریتم لااقل میتواند به عنوان راهنما مورد استفاده قرار گیرد. همان طور كه دیدیم، AGM ریشه به وجود آمدن واكنشهای زنجیرهای میباشد؛ لیكن وجود آن برای پروتكلهای شبكه ضروری است. ما نمیتوانیم و نمیخواهیم كه استفاده از AGM را محدود كنیم، همین طور ما نمیتوانیم بین AGM خوب و بد تشخیص دهیم. من (نویسنده) بر این باور هستم كه هر AGM را باید با پتانسیل ایجاد واكنش زنجیرهای در نظر گرفت. قبلا" مثالهایی را دیدیم كه چگونه واكنشهای زنجیرهای ناشی از پیغامهای خطا و گم شده (چون پیغامهای داده پراكنی)، شبكه را از كار انداختند. هر وقت كه یك پروتكل مجبور شد كه یك پیغام را در جواب یك پیغام دیگر به وجود آورد، آن پروتكل باید مورد آزمایش قرار گیرد. مشكل در اینجاست كه پروتكلها بسیار پیچیده و مرتبط به هماند. بعضی مواقع غیر ممكن است كه تمام احتمالات پیش بینی شود. اگر ما AGM را یك ریسك در نظر بگیریم، باید یك الگوریتم جذبی كلی در اختیار داشته باشیم كه به هر AGM بخورد. البته ممكن است كه الگوریتم را در یك مورد بخصوص طوری تغییر داد كه راندمان آن بیشتر شود؛ اما داشتن الگوریتم كلی برای تمام پروتكلها مورد نظر است. در اینجا به چهار قانون اشاره شد.
۱) یك شناسنامه منحصر به فرد برای هر پیغام در شبكه لازم است. در بعضی موارد در خود پیغام به قدر كافی اطلاعات برای مشخص كردن وجود دارد (مانند اسم كامپیوتر میزبان، فرستنده، روز و غیره).
۲) هر موقع كه یك پیغام مانند ۲M در اثر پیغام دیگری مثل۱M به وجود آمد و به عبارت دیگر AGM اجرا شد، باید پیغام۲M دارای شناسنامهای مانند پیغام۱M شود. این قانون، باید برای هر AGM اجرا شود بدون در نظر گرفتن اینكه، پروتكل چقدر ساده با چقدر مورد استفاده قرار میگیرد.
۳) تمام شناسنامههای پیغامهایی كه AGM از آنها به وجود آمده، باید در كامپیوتر میزبان به حافظه شوند.
۴) وقتی كه یك پیغام ضبط شده در یك كامپیوتر میزبان، دوباره به كامپیوتر میزبان بر میگردد، باید از تولید دوبارهAGM توسط آن جلوگیری كرد. قوانین فوق اگر به صورت صحیح اجرا شوند، برای جلوگیری از واكنشهای زنجیرهای كافی هستند.● نظریه ۲
فرض كنید قوانین فوق، توسط تمام پروتكلها اجرا شوند، و H حداكثر تعداد پیغام به وجود آمده توسط شخص در تمام شبكه باشد. فرض كنید L تعداد پلها در شبكه باشد. در این صورت، تعداد كل پیغامها در شبكه حداكثر ۲LH میشود.
▪ اثبات:
قانون دوم، اشاره میكند به اینكه تمام پیغامهایی كه از برنامهها به وجود میآیند، دارای همان شناسنامههای پیغامهای نوشته شده به وسیله اشخاص هستند. بنابراین برنامه ها هیچ گونه پیغام جدیدی به وجود نمیآورند. هر پیغامی مانند M كه با دست نوشته شده است، حداكثر دو دفعه (در دو جهت مختلف) میتواند از یك پل عبور كند. قوانین فوق نشان دادند كه از هر گره، یك پیغام بیش از یك بار عبور نمی كند. بنابراین، تعداد كل پیغامها برابر ۲LH است. قوانین۱ تا۴ ممكن است، نتواند وجود واكنشهای زنجیرهای را به طور كامل محو كند؛ زیرا كه تضمینی در اجرا صحیح آنها و یا، بدون نقص بودن سخت افزارها وجود ندارد. اگر سختافزاری، متحمله داشتن نقص فنی باشد، عملكرد هیچ الگوریتمی صد در صد نیست.در ضمن، اثبات درستی پروتكلها بسیار مشكل است و در اینجا از آنها صحبت نخواهد شد. به دلایل زیر، این قوانین به نظر ناكافی و محدود میآید: ۱-شرط به حافظه سپردن شناسنامه هر پیغامی كه روی شبكه قرار گیرد، به نظر صحیح نمیآید. زیرا برای این كار، به مقدار زیادی حافظه نیاز خواهیم داشت. خوشبختانه ما میتوانیم این شرط را سادهتر كرده و مقرر كنیم كه: فقط پیغامهای رسیده در فاصله زمانی T (مثلا" یك ساعت) تا زمان حاضر حفظ شوند. مقدار T به سرعت و بزرگی شبكه بستگی دارد. این شرط ساده شده، از واكنشهای زنجیرهای جلوگیری نمیكند؛ زیرا ممكن است حلقههای بسته بینهایت به وجود آید، لیكن در اثر وجود فاصله زمانی معینی آنها شدیدا" كاهش مییابد. مثلا" اگر T، یك ساعت باشد در آن صورت، هر حلقه بسته بینهایت، میتواند یك بار در یك ساعت به وجود آید. به حافظه سپردن پیغامهای اخیر در فاصله زمانی T، به مقدار زیادی حافظه احتیاج ندارد. همچنین امتحان كردن پیغامها، برای یافتن كپی آنها به پردازش چندانی احتیاج ندارد. پس كافی نیست كه فقط K پیغام را در فاصله زمانی محدودی چون T به حافظه سپرد. اگر واكنش زنجیرهای، برای یك كامپیوتر میزبان شامل بیش از K پیغام باشد، آن واكنش زنجیرهای ممكن است قابل جلوگیری نباشد. دومین مسئله به وجود آوردن شناسنامههاست. یك پیغام، معمولا" از تعدادی لایههای پروتكلی عبور میكند كه هر كدام مستقلاند و ممكن است، یك AGM تعداد زیادی از آنها را شامل گردد. اگر یك شناسنامه در یك پروتكل نزدیك به سخت افزار ایجاد شود، پروتكلهای فوق ممكن است، نتوانند آنرا بشناسند. برای اینكه آن شناسنامه قسمتی از پیغامی است كه برای پروتكلهای فوق، غیرقابل دسترسی است.برای جلوگیری از واكنشهای زنجیرهای، باید هر چه زودتر شناسنامه به وجود آیند (مثلا" به وسیله برنامههای كاربردی) و بعد از به وجود آمدن،در جایی محفوظ باشند تا در دسترس تمامی پروتكلهای AGM قرار گیرند. البته امكان داشتن شناسنامه برای هر لایه پروتكلی وجود دارد؛ ولی ضروری نیست. این روش، ممكن است باعث زیر پا گذاشتن استقلال هر لایه شود.سومین مسئله نیز، در اثر تعدد در پروتكلها و استقلال آنهاست. پیغامی كه به یك ماشین میزبان بخصوص میرسد، ممكن است چند AGM را در لایههای مختلف شامل گردد. بنا به تعریف، AGM به پیغامهای گفته میشود كه از ماشین دیگری نشات گرفته شده باشند اما پیدا كردن منشا كار سادهای نیست. طبق قوانین۳ و۴، در هر كامپیوتر میزبان جدولی وجود دارد كه، باعث جلوگیری از دومین AGM وارد شده به كامپیوتر می شود. برای از بین بردن مسئله AGM در لایهها، میتوان برای هرلایهای، یك جدول بنا كرد و یا آن دسته AGM را كه در یك ماشین حركت میكنند، به عنوان پیغام معمولی و نه AGM در نظر گرفت. مسئله چهارم در بسیار محدود كردن پیغامهای خطا توسط قانون چهارم است. اگر خطایی به وسیله ماشینی كه قبلا" پیغام آن را فرستاده است تشخیص داده شود، آن ماشین، دیگر نمیتواند پیغام خطا به وجود آورد، ساده كردن قانون چهارم، می تواند به صورت زیر انجام گیرد: ما می توانیم دو و یا بیشتر پیغام تعریف كنیم. مثلا" پیغامهای نرمال و پیغامهای خطا. یك پیغام خطای به وجود آمده از یك پیغام نرمال، همان شناسنامه را حفظ میكند، اما اسم یك پیغام خطا را خواهدگرفت. بنابراین، قانون۴ به صورت زیر تغییر می یابد: هیچ كامپیوتر میزبان نمی تواند پیغامی كه دارای شناسنامه و هویت بخصوص است بیش از یك مرتبه از خود عبور دهد. توجه كنید كه این قانون از به وجود آمدن پیغامهای خطا توسط پیغامهای خطای دیگر جلوگیری میكند. پنجمین اشكال، در مدت زمان و فضای لازم جهت اجرای قوانین است. بعضی از پروتكلها، مانند پروتكلهای مسیر گزینی، تا حد زیادی به اجرا با راندمان بالا نیاز دارند، و نمی توانند با راندمان پایین عمل كنند. ما میتوانیم تعداد زیادی از قوانین را ساده كنیم؛ اما این كار باعث افزایش احتمال وقوع واكنشهای زنجیرهای خواهد شد. برای مثال هنگامی كه یك پیغام فرستاده شده از A به B، از چند كامپیوتر دیگر عبور میكند، كامپیوترهای سر راه به ثبت كردن این واقعه احتیاج ندارند و ما میتوانیم فرض كنیم كه پیغام از A به B مستقیما" ارسال شده است. اساس كار این قوانین، بر عمومیت آنها بر تمام پروتكلهاست بعضی از پروتكلها نوشته شدهاند كه قوانین فوق را در كل یا جزء اجرا كنند. برای مثال: ICMP Internet Control Message Protocol پروتكلی است مسوءول پیغامهای خطا، كه اجازه به وجود آمدن یك پیغام خطا از پیغام خطای دیگر را نمیدهد (مرجع شماره۸ در پایان مقاله:D.Comer). برنامه تعطیلات كه یك قسمتی از بركلی Unix است، كه كپی آدرسهایی را كه به آنها پیغام فرستاده نگه میدارد و به طور قرار دادی به هر آدرسی، فقط یك بار در هفته پیغام میفرستد. قوانین فوق، باعث محدودیت در طراحی پروتكل می گردند.بعضی مواقع، یك كامپیوتر به فرستادن یك پیغام، بیش از یك بار احتیاج دارد. در این صورت میتوان برای تعداد دفعاتی كه میتوان یك پیغام را فرستاد، حد بالایی قائل شد و در عوض داشتن یك نوع پیغام، چند نوع را در نظر گرفت. پیدا كردن این موارد و مشخص كردن نوع پیغامها مهم است. حتی اگر قوانین ترمیم شده اجرا نگردد. برای مثال، پروتكل سوال كردن را در نظر بگیرید. فرض كنید كه كامپیوتری درصدد فرستادن جواب به سوال كننده برآید. اگر پیغام جواب، از كامپیوتری بگذرد كه در فرستادن پیغام سوال دخالت داشته، بنابر قوانین فوق، نباید جواب فرستاده شود. (جواب AGM پیغام سوال خواهد بود و در این صورت دارای همان شناسنامه است). راه حل این سوال واضح است. باید دو نوع پیغام باشد: ۱- سوالی ۲- جوابی. ما می توانیم قانون چهارم را قدری سادهتر كنیم: پیغامهایی كه از یك كامپیوتر عبور می كنند، برای مدتی ذخیره شوند (مثلا" یك ساعت). این كار، باعث برداشتن تعدادی از محدودیتها میگردد. مانند محدودیت در برابر پیغامهای خطا، در جواب پیغامهای خطای دیگر و در ضمن باعث كم شدن سرعت به وجود آمدن واكنشهای زنجیرهای نیز میگردد. ضروری است كه قبل از ذخیره كردن یك پیغام، وجود یا عدم وجود آن در حافظه مشخص میگردد