Traffic shaping که به فارسی «شکل‌دهی ترافیک» ترجمه شده روشی برای کنترل ترافیک و پهنای باند مصرفی کامپیوترها می‌باشد. به کمک این تکنیک می‌توانید پهنای باند شبکه خود را به طور عادلانه بین سرویس‌ها و رایانه‌های موجود در شبکه تقسیم کنید و مانع این شوید که بعضی سرویس‌ها از کل پهنای باند استفاده کنند. همچنین می‌توانید برای بسته‌ها اولویت قائل شوید. بدین صورت که بسته‌هایی که اولیت بیشتری دارند، از پهنای باند بیشتری برخوردار شوند و به ترافیک غیر ضروری پهنای باند کمتری اختصاص یابد. این کار در FreeBSD به کمک dummynet انجام می‌شود. همچنین به کمک ipfw می‌توانید dummynet را پیکربندی کنید.

پیکربندی در هسته:

مطمئن شوید که خطوط زیر در فایل پیکربندی هسته وجود دارند:

options IPFIREWALL
options DUMMYNET
options HZ=1000

وجود خط سوم اجباری نیست. اما استفاده از آن در صفحه ‎dummynet‎ به شدت توصیه شده. اساس کار traffic shaping ایجاد تاخیر در عبور و مرور بسته‌ها است. بسته‌ها قبل از اینکه ارسال شوند، در جایی ذخیره شده و پس از مدتی ارسال می‌شوند. در هسته یک تایمر وجود دارد که این تایمر زمان ارسال بسته‌ها را کنترل می‌کند. خط سوم فرکانس این تایمر را مشخص می‌کند. بدیهی است که هر چه این فرکانس بالاتر باشد تایمر دقیق‌تر بوده و تاخیر بسته‌ها کمتر می‌شود. این فرکانس به صورت پیش فرض بر روی ۱۰۰ قرار دارد که ما آن را به ۱۰۰۰ تغییر دادیم.

انجام traffic shaping سه مرحله دارد. ایجاد pipeها، ایجاد صف یا queueها، توزیع و ارسال کردن بسته‌ها در بین این pipeها و queueها. بیایید ابتدا این مفاهیم را تشریح کنیم.

Pipe یا queue چیست؟ پایپ‌ها و صف‌ها را یک خط ارتباطی بین رایانه‌ها در نظر بگیرید که رایانه‌ها از طریق این دو به یکدیگر متصل شده و بسته‌ها از طریق پایپ و صف بین آنها منتقل می‌شود. حرکت بسته‌ها در پایپ‌ها یا صف‌ها شباهت زیادی به حرکت الکترون‌ها در یک هادی دارد. وقتی الکترون‌ها در داخل یک سیم به حرکت در می‌آیند، می گوییم جریان الکتریکی برقرار شده. به همین صورت وقتی بسته‌ها در لوله‌ها یا صف‌ها حرکت می‌کنند، می گوییم جریانی از بسته‌ها به وجود آمده.

باید گفت که pipeها و queueها با هم تفاوت هایی دارند. پایپ‌ها از اجزاء پایه هستند که پهنای باند کل بین آنها تقسیم می‌شود. مهمترین ویژگی یک پایپ پهنای باند آن است. پهنای باند یک پایپ مشخص می‌کند که حداکثر چه مقدار جریانی می‌تواند از پایپ مورد نظر عبور کند. صف‌ها جزء کوچکتری نسبت به پایپ‌ها محسوب می‌شوند و بدون پایپ‌ها قابل استفاده نیستند. صف‌ها به پایپ‌ها متصل شده و پهنای باند مربوط آن پایپ را به اجزای کوچکتری تقسیم می‌کنند. پس pipeها برای تقسیم کردن پهنای باند کل استفاده می‌شوند و صف‌ها برای تقسیم کردن پهنای باند مربوط به یک پایپ استفاده می‌شوند. مهمترین ویژگی یک صف وزن آن است. به هر صف یک عدد از ۱ تا ۱۰۰ اختصاص داده می‌شود که وزن آن صف را مشخص می‌کند. وزن یک صف اولویت آن صف را مشخص می‌کند. بدیهی است که هر چه وزن یک صف بیشتر باشد، اولویت بیشتری برای استفاده از پهنای باند دارد.

در ادامه توضیحات بیشتری را ارائه خواهیم داد. فعلا بیایید نحوه ایجاد یک پایپ را یاد بگیریم:

# ipfw pipe 1 config bw 120kbit/s

دستور بالا یک پایپ با شماره یک ایجاد کرده و میزان پهنای باند آن را ۱۲۰kbit/s قرار می‌دهد. اگر پایپ مورد نظر از قبل وجود داشته باشد، پهنای باند آن به ۱۲۰kbit/s تغییر می‌کند.

تا اینجا یاد گرفتیم که چگونه یک پایپ ایجاد کرده و پهنای باندی را به آن اختصاص دهیم. بیایید نحوه ایجاد صف‌ها را یاد بگیریم. هر صف دو مشخصه اصلی دارد؛ اولین مشخصه این است که صف مورد نظر چقدر وزن داشته باشد و دومین مشخصه این است که صف مورد نظر به کدام پایپ متصل شود. همان طور که گفته شد وزن یک صف عددی بین ۱ تا ۱۰۰ هست که پیش فرض ۱ می‌باشد.

# ipfw queue 5 config pipe 1 weight 20

دستور بالا یک صف با شماره ۵ ایجاد می‌کند که این صف دارای وزنی به اندازه ۲۰ بوده و به پایپ شماره یک متصل می‌شود. وزن یک صف مشخص کننده میزان پهنای باند مصرفی توسط آن صف می‌باشد. می‌توانید چندین صف را با وزن‌های مختلفی به یک پایپ متصل کنید. در این صورت پهنای باند مربوط به آن پایپ بر اساس وزن صف‌ها بین آنها تقسیم می‌شود. برای روشن‌تر شدن مطلب یک مثال می‌زنیم. فرض کنید که یک پایپ داریم که پهنای باند آن ۱۲۰kbit/s است. سه تا صف به این پایپ متصل کرده‌ایم که این صف‌ها دارای وزنهای ۱,۲,۳ هستند. خب به این صف‌ها پهنای باندی معادل ۶۰kbit/s و ۴۰kbit/s و ۲۰kbit/s اختصاص می‌یابد. اگر جریان در صفی که وزن ۲ دارد قطع شود، به صف هایی که وزن ۱ و ۳ دارند پهنای باندی معدل ۹۰kbit/s و ۳۰kbit/s اختصاص می‌یابد. این حرف به این معنی است که به صفی که جریانی ندارد پهنای باندی هم اختصاص داده نخواهد شد. فرض کنید دو صف داریم که وزن یکی ۹۹ (برای ترافیک مهم) و وزن دیگری ۱ (برای ترافیک بی اهمیت) باشد. اگر جریان در هر دو صف برقرار باشد، صف اول ۹۹% از پهنای باند را به خود اختصاص داده و صف دوم یک درصد را به خود اختصاص می‌دهد. اما اگر جریان در صفی که وزن ۹۹ دارد قطع شود، صف دوم از تمام پهنای باند استفاده خواهد کرد.

ممکن است مفهوم وزن داشتن صف‌ها کمی گنگ باشد. اما می‌توان به سادگی آن را یاد گرفت. اگر صف‌ها وزن برابری داشته باشند، پهنای باند مساوی به آنها اختصاص می‌یابد. اگر صفی دو برابر دیگری وزن داشته باشد، پهنای باند اختصاص یافته به آن هم دو برابر خواهد بود. در حالت کلی برای محاسبه پهنای باند هر صف به صورت زیر عمل کنید:

ابتدا کل پهنای باند پایپ را بر وزن کل تقسیم کنید. و سپس وزن هر صف را در عدد به دست آمده ضرب کنید. مثلا فرض کنید که پایپی با پهنای باند ۳۶۰kbit/s داریم که سه تا صف با وزن‌های ۱,۲,۳ به آن متصل شده‌اند. در این صورت وزن کل برابر با ‎ ۱+۲+۳=۶ است. حالا عدد ۳۶۰ را بر آن تقسیم می‌کنیم:

۳۶۰/۶=۶۰

حالا وزن هر صف را در عدد ۶۰ ضرب می‌کنیم تا پهنای باند هر صف به دست آید:

۱*۶۰=۶۰kbit/s
۲*۶۰=۱۲۰kbit/s
۳*۶۰=۱۸۰kbit/s

بعد از اینکه پایپ‌ها و صف‌ها را ایجاد کرده و پهنای باند و وزن آنها را تعیین کردیم، باید ترافیک مورد نظر خود را برای آنها ارسال کنیم. این کار با نوشتن ruleهایی توسط ipfw امکان‌پذیر است. این ruleها با ruleهای معمولی فرق خاصی ندارند. فقط به‌جای اینکه بسته‌ای را accept یا drop کنند، آن را به یک پایپ یا صف ارسال می‌کنند.

مثال‌ها

مثال زیر به ترافیک TCP ورودی پهنای باند ۲Mbit/s و به ترافیک UDPورودی پهنای باند ۳۰۰kbit/s اختصاص می‌دهد:

   ipfw add pipe 2 in proto tcp
   ipfw add pipe 3 in proto udp
   ipfw pipe 2 config bw 2Mbit/s
   ipfw pipe 3 config bw 300Kbit/s