سفر یه بسته توی کرنل لینوکس
خلاصهٔ کاملتر
نویسنده تو قسمت هشتم و آخر سری «فهمیدن کرنل لینوکس» یه بسته رو از روی کابل تا داخل برنامه دنبال میکنه و بعد برعکسش رو. همه چی روی لینوکس ۷.۱ و مسیر IPv4 روی TCP روی اترنته. اولین نکتهای که روشن میکنه اینه که کرنل اصلاً نمیدونه HTTP چیه؛ کارش فقط تحویل یه جریان بایت کامل و مرتبه و معنی کردن اون بایتها با خود برنامهست.
کارت شبکه برای هر بسته وقفه (interrupt) نمیفرسته، چون تو ثانیهای میلیونها بسته این روش از هم میپاشه. کارت و کرنل از قبل سر یه تکه حافظه توافق میکنن و کارت با DMA (یعنی نوشتن مستقیم روی RAM بدون اینکه CPU بایتی جابهجا کنه) داده رو همونجا میریزه. حلقهای از رکوردهای کوچیک به اسم descriptor ring فقط آدرس اون صفحهها رو نگه میداره، نه خود داده رو.
بعدش کرنل اون صفحه رو تو یه sk_buff (همون skb) میپیچه که خودش بسته نیست، فقط چند تا اشارهگر به بافر واقعیه. جلوی داده هم عمداً فضای خالی به اسم headroom گذاشته میشه تا هر لایه هدر خودشو همونجا بنویسه و پیلود هیچوقت کپی نشه. قبل از بالا رفتن، GRO بستههای پشتسرهم یه جریان رو به هم میچسبونه و یه skb تا ۶۴ کیلوبایت میسازه، پس بهجای دهها بار فقط یه بار از IP و TCP رد میشه.
پیدا کردن صاحب بسته با یه زنجیره جستوجوئه: دو بایت EtherType میرسونتش به ip_rcv، شماره پروتکل ۶ به TCP، و TCP با چهار عدد آدرس و پورت مبدأ و مقصد سوکت رو پیدا میکنه. اگه ترد برنامه قفل سوکت رو گرفته باشه، بسته تو صف backlog پارک میشه و همون ترد موقع خروج از syscall کارشو تموم میکنه. آخرش sk_data_ready صدا زده میشه و همینه که recv() یا epoll_wait() رو بیدار میکنه.
مسیر خروج اما تقریباً همهاش سر «کِی بفرستیم» میگذره، چون مقصد از همون خط اول معلومه. tcp_write_xmit هر skb رو از هفت دروازه رد میکنه و ششتاش کلاسیک TCPه: pacing، congestion window، receive window، Nagle، TSO deferral و شکستن به اندازه MSS. هفتمی TSQ هست که سقف بایتهای یه سوکت تو صفهای محلی رو نگه میداره؛ به گفته نویسنده چیزی که سوکت throttleشده رو دوباره راه میندازه تایمر نیست، بلکه تموم شدن ارسال بستههای خودشه.
نکات کلیدی:
- همه چی روی لینوکس ۷.۱ و مسیر IPv4 روی TCP روی اترنت بررسی شده.
- GRO بستههای یه جریان رو به یه skb تا ۶۴ کیلوبایت میچسبونه تا یه بار از استک رد شه.
- tcpdump قبل از netfilter کپی میگیره، برای همین بستههایی که iptables میندازه رو هم نشون میده.
- headroom موقع sendmsg رزرو میشه تا هدرهای TCP و IP و اترنت بدون کپی جا بشن.
- TSQ با یه destructor روی skb کار میکنه و سرعت ارسال رو به سرعت واقعی کارت شبکه گره میزنه.




