3. Hogyan működik?

Két alapvető lépéssel optimalizálhatjuk a kifelé menő sávszélességet. Először találnunk kell egy módot arra, hogy megakadályozzuk az ADSL modemet a csomagok sorba állításában, mivel nincs ráhatásunk a várakozósor kezelésére. Ennek érdekében visszafogjuk az útválasztó által az eth0-n kiküldött adat mennyiségét, kicsit kevesebbre, mint a modem teljes kimenő sávszélessége. Ez azt eredményezi, hogy az útválasztó rakja várakozósorba a helyi hálózatról érkező csomagokat, amik gyorsabban érkeznek, mint megengedett kiküldésük.

A második lépés egy prioritásos várakozósor-fegyelmi szabály felállítása az útválasztón. Meg fogunk valósítani egy olyan sort, amit be lehet állítani úgy, hogy elsőbbséget adjon az interaktív forgalomnak, mint a telnet vagy a többszereplős játékok.

A végső lépés a tűzfal beállítása, hogy az fwmark segítségével biztosítsa a csomagok elsőbbségét.

3.1. A HTB alkalmazása a kimenő forgalom visszafogására

Bár az útválasztó és a modem közti kapcsolat 10 Mbit/s sebességű, a modem csak 128 kbit/s sebességgel tud adatokat küldeni. Minden ezt a rátát meghaladó sebességű csomag várakozósorba áll a modemnél. Ezért egy ping csomag, amit az útválasztóról küldünk, azonnal elmehet a modemhez, de néhány másodpercet vehet igénybe, amíg ténylegesen kikerül az Internetre, ha a modem várakozósora tartalmaz már valamennyi csomagot. Sajnos a legtöbb ADSL modem esetében nem adhatjuk meg a várakozósor kezelésének módját illetve annak nagyságát. Így először a kimenő csomagokat átirányítjuk oda, ahol mindezt megtehetjük.

Ezt a HTB sorral valósítjuk meg, így csökkentve az ADSL modemhez küldött csomagok számát. Még ha a kifelé menő sávszélességünk a 128kbit/s is lehetne, kicsivel ez alá korlátozzuk le a csomagküldés mértékét. Ha csökkenteni akarjuk a lappangási időt, BIZONYOSNAK kell lennünk, hogy soha egyetlen csomag sem áll sorba a modemnél. Kísérletezések során azt találtam, hogy a kimenő forgalom körülbelül 90kbit/s-ra való visszavételével a sávszélesség majdnem 95%-át tudom elérni a HTB vezérlés nélkül. A HTB engedélyezésével ennél a mértéknél kivédjük, hogy a modem várakozósorba rakja a csomagokat.

3.2. Prioritásos várakozósor kialakítása HTB-vel

Megjegyzés

Megjegyzés: az ebben a részben lévő előző igények (eredetileg N-sávos prioritásos várakozósor kialakításának hívták) később hibásnak találtattak. LEHETETLEN volt a várakozósor különböző sávjaiba tartozó csomagok megjelölése csak a fwmark mező által, viszont ezt gyengén dokumentáltuk a dokumentum 0.1-es verziójának írásakor.

Ennél a pontnál még nem veszünk észre semmi változást a teljesítményben. Pusztán csak áthelyezzük a FIFO sort az ADSL modemtől az útválasztóhoz. Valójában, a Linux alapértelmezésben beállított 100 csomag méretű FIFO sorával, valószínűleg még rosszabbá is tettük a helyzetünket! De nem sokáig...

Minden szomszédos osztálynak adhatunk egy prioritást a HTB soron belül. A különböző típusú forgalom különböző osztályokba helyezésével, majd ezen osztályokhoz különböző prioritások csatolásával, vezérelhetjük a csomagok várakozási sorból való kivételét és elküldését. A HTB lehetővé teszi ezt, miközben megakadályozza egy osztály "kiéheztetését", mivel megadhatjuk a minimálisan garantált mértéket minden osztály számára. Ezenfelül a HTB megengedi azt is, hogy megadjuk egy osztálynak: használhatja másik osztályok nem használt sávszélességét, egy bizonyos felső határig.

Miután beállítottuk az osztályainkat, szűrőket helyezünk el, hogy a forgalmat elhelyezzük beléjük. Több útja is van ennek, de az itt leírt módszer az ismerős iptables/ipchains-t használja a csomagok fwmark-al (tűzfal jelölése a csomagon) történő megjelölésére. A szűrők a csomagok fwmark-ját figyelembe véve helyezik el a forgalmat a HTB sor osztályaiba. Ezen a módon képesek leszünk megfelelő szabályok felállítására az iptables-en belül, hogy bizonyos típusú forgalmat egy bizonyos osztályba küldjön.

3.3. A kimenő csomagok osztályozása iptables-szel

Megjegyzés

eredetileg a dokumentumban az ipchains-t használtuk a csomagok besorolására. Most az újabb iptables-t használjuk.

Az utolsó lépés ahhoz, hogy az útválasztó elsőbbséget adjon az interaktív forgalomnak - a tűzfal beállítása: adjuk meg a forgalom besorolásának módját. Ez a csomag fwmark mezőjének beállításával érhető el.

Anélkül, hogy túlzottan a részletekbe merülnénk, álljon itt az egyszerűsített leírása annak, hogyan lehet a kimenő csomagokat 4 osztályba sorolni úgy, hogy a legmagasabb prioritású lesz a 0x00:

  1. Jelöljünk MINDEN csomagot 0x03-al. Ez alapértelmezésben minden csomagot a legalacsonyabb prioritású sorba helyez el.

  2. Jelöljük az ICMP csomagokat 0x00-al. Szeretnénk, ha a ping mutatná a legmagasabb prioritású csomagok várakozási idejét.

  3. Jelöljünk minden csomagot, aminek célportja 1024 vagy kisebb, 0x01-el. Ez elsőbbséget biztosít az olyan rendszerszolgáltatásoknak, mint a Telnet és SSH. Az FTP portja szintén ebbe a körbe esik, de az FTP adatforgalom a magasabb portokon helyezkedik el és marad a 0x03 sávban.

  4. Jelöljünk minden csomagot, aminek a célportja 25 (SMTP), a 0x03-al. Ha valaki levelet fog küldeni egy nagy csatolt állománnyal, nem akarjuk, hogy elárassza az interaktív forgalmat.

  5. Jelöljünk minden csomagot, aminek célja egy többszereplős játék-szerver, 0x02-vel. Ez a játékosoknak alacsony lappangási időt biztosít, de megakadályozza, hogy elfoglalják az alacsony várakozást igénylő rendszerszolgáltatásokat.

    Jelöljünk minden "kicsi" csomagot 0x02-vel. A kimenő ACK csomagokat a befelé irányuló letöltésekből azonnal ki kell küldenünk, hogy biztosítsuk a megfelelő letöltéseket. Ez az iptables "length" moduljával lehetséges.

Természetesen ezeket a kívánalmaknak megfelelően átalakíthatod.

3.4. Még néhány fogás...

Két további dolgot tehetsz a lappangási idő javítására. Először is, a maximális átvihető egység (MTU) méretét kisebbre veheted, mint az alapértelmezett 1500 bájt. Ennek a számnak a csökkentése egyben az átlagos időt is csökkenti, amit az elsőbbséget élvező csomagok elküldésére kell fordítani, ha már egy teljes méretű alacsony prioritású csomag küldése folyamatban van. Ennek az értéknek a csökkentése kicsit csökkenti a teljesítményt is, mivel minden csomag legalább 40 bájtnyi IP és TCP fejléc-információt tartalmaz.

A másik dolog a javításhoz, még alacsony prioritású forgalom esetén is, hogy csökkented a várakozási sor méretét az alapértelmezett 100-ról, ami egy ADSL vonalon 10 másodperc alatt ürül ki egy 1500 bájtos MTU-t alapul véve.

3.5. Próbálkozás a bejövő forgalom visszafogására

A "közbenső várakozósor-eszköz" (Intermediate Queuing Device, IMQ) használatával az összes bejövő csomagot ugyanúgy egy várakozósoron futtathatjuk át, mint amilyen módon a kimenőket is. A csomagok prioritása ebben az esetben jóval egyszerűbb. Mivel csak a bejövő TCP forgalmat (próbáljuk meg) vezérelni, az összes nem-TCP forgalmat a 0x00 osztályba rakjuk, az összes TCP forgalmat pedig a 0x01 osztályba. A "kis" TCP csomagokat szintén a 0x00 osztályba soroljuk, mert ezek nagy valószínűséggel a már elküldött kimenő adatok ACK csomagjai. Egy standard FIFO sort állítunk be a 0x00 osztályhoz, illetve egy "véletlenszerű korai eldobás" (Random Early Drop, RED) várósort a 0x01 osztályhoz. A RED jobb a FIFO-nál a TCP vezérlését tekintve, mert eldobja a csomagokat már a sor olyan túlcsordulása előtt, mikor megpróbálja lelassítani a forgalmat az ellenőrzés fenntartása érdekében. Ezen kívül mindkét osztályt le fogjuk korlátozni egy maximális bejövő forgalmi határra, ami kisebb, mint a valós, ADSL modemen bejövő sebesség.

3.5.1. Miért nem olyan jó a bejövő forgalom korlátozása?

Korlátozni szeretnénk a bejövő forgalmunkat, hogy elkerüljük a várakozósor betelését a szolgáltatónál, ami néha 5 másodpernyi adat pufferelését jelentheti. A probléma abban áll, hogy jelenleg a bejövő TCP forgalom korlátozásának egyetlen módja a teljesen jó csomagok eldobálása. Ezek a csomagok már foglaltak némi sávszélességet az ADSL modemen, csak a Linux gép dobta el őket abból a célból, hogy a jövőbeni csomagokat lelassítsa. Ezek az eldobott csomagok időnként újra elküldésre kerülnek, még több sávszélességet foglalva. Amikor korlátozzuk a forgalmat, korlátozzuk azon csomagok mértékét, amiket elfogadunk a hálózatunk számára. Mivel az aktuális bejövő adatráta valahol efölött van az eldobott csomagok miatt, a bejövő águnkat sokkal jobban le kell korlátoznunk az ADSL modem aktuális rátájánál, az alacsony lappangási idő biztosítása érdekében. A gyakorlatban az én 1.5Mbit/s bejövő ágamat 700kbit/s-re kellett korlátoznom, hogy elfogadható szinten tartsam a lappangást 5 egyidejű letöltésnél. Minél több TCP folyamatod van, annál több sávszélességet vesztesz az eldobott csomagok miatt, és annál kisebbre kell venned a korlátozás mértékét.

A bejövő TCP forgalom ellenőrzésének sokkal jobb módja a TCP ablak manipulációja, de ebben a pillanatban nincs (szabadon elérhető) megvalósítása ennek Linuxra (amennyire én tudom...).