-auto
módban?-auto
módban?-nat
kapcsoló
megadásával?Elsőként mindenképpen olvassuk el a ppp(8) man oldalt és a kézikönyv PPP-vel foglalkozó részét. A következő paranccsal engedélyezzük a naplózást:
set log Phase Chat Connect Carrier lcp ipcp ccp command
Ezt a parancsot a ppp(8) parancssorában vagy az /etc/ppp/ppp.conf konfigurációs állományban kell megadnunk (leginkább a default szakasz elejére érdemes betennünk). Gondoskodjunk róla, hogy az /etc/syslog.conf állomány (lásd syslog.conf(5)) tartalmazza az alábbi sort, illetve az /var/log/ppp.log állomány létezzen:
!ppp *.* /var/log/ppp.log
A napló segítségével már több mindent ki tudunk deríteni a ppp(8) működéséről. Ne aggódjunk, ha nem értünk belőle semmit. Kérjünk segítséget másoktól, nekik minden bizonnyal segíteni fog a probléma felderítésében.
Ilyen általában azért történik, mert nem tudta feloldani a hálózati nevet. Ezt a legkönnyebben úgy tudjuk orvosolni, ha az /etc/host.conf állományba előre rakjuk a hosts sort, így a névfeloldó először az /etc/hosts állománnyal fog próbálkozni. Ezután a /etc/hosts állományba vegyük fel a helyi gépet. Ha nincs helyi hálózatunk, akkor így írjuk át a localhost sort:
127.0.0.1 ize.minta.com ize localhost
Minden más esetben egyszerűen csak vegyünk fel egy újabb bejegyzést a gépünkhöz. Ennek pontosabb részleteivel kapcsolatban nézzük meg a megfelelő man oldalakat.
Ha mindent jól csináltunk, akkor a ping -c1 `hostname` parancs hiba nélkül tér vissza.
Először is ellenőrizzük, hogy létezik az alapértelmezett útvonal. A netstat -rn parancs (lásd netstat(1)) kiadása után nagyjából a következő két bejegyzést kell látnunk:
Destination Gateway Flags Refs Use Netif Expire default 10.0.0.2 UGSc 0 0 tun0 10.0.0.2 10.0.0.1 UH 0 0 tun0
Feltételezzük, hogy a kézikönyvből, a man oldalról vagy ppp.conf.sample állományból másoltuk ki ezeket a címeket. Ha nincs alapértelmezett útvonalunk, akkor annak az lehet az oka, hogy a ppp.conf állományba elfelejtettük felvenni a HISADDR kulcsszót.
Az alapértelmezett útvonal hiányának másik oka lehet még, ha az /etc/rc.conf állományban (lásd rc.conf(5)) beállítottunk egy alapértelmezett átjárót, de elfelejtettük az ppp.conf állományba betenni a következő sort:
delete ALL
Ebben az esetben menjünk vissza a kézikönyv A rendszer végső beállítása című részéhez.
Általában azért jelentkezik, mert az /etc/ppp/ppp.linkup állományban nem adtuk meg az alábbiakat:
MYADDR: delete ALL add 0 0 HISADDR
Erre csak akkor van szükségünk, ha dinamikus IP-címünk van, vagy nem ismerjük az átjáró címét. Ha az interaktív módot használjuk, akkor ehhez a következőket kell begépelni csomag módba lépés után (a csomag módot a csupa nagybetűs PPP jelzi a parancssorban):
delete ALL add 0 0 HISADDR
A kézikönyv A PPP és a dinamikus IP-címek című részében olvashatunk erről bővebben.
A PPP alrendszer alapértelmezett lejárati ideje 3 perc. Ezt a beállítást a következő sor megadásával tudjuk módosítani:
set timeout NNN
ahol az NNN másodpercekben megadja a kapcsolat lezárása előtti inaktivitás maximális idejét. Ha az NNN értéke nulla, akkor a kapcsolat időtúllépés miatt soha nem fog magától megszakadni. Ezt a parancsot a ppp.conf állományba tudjuk felvenni, vagy interaktív módban a parancssorban gépelhetjük be. Emellett menet közben is állítani tudjuk ezt az értéket, ha a ppp szerverre a telnet(1) vagy a pppctl(8) segítségével rácsatlakozunk. Erről a ppp(8) man oldal ad részletesebb tájékoztatást.
Ha beállítottuk a Link Quality Reporting (LQR) használatát, akkor előfordulhat, hogy túlságosan sok csomag veszik el a gépünk és a másik oldal között. A ppp(8) ezért a vonalat rossznak érzékeli és bontja. A FreeBSD 2.2.5 változata előtt az LQR alapértelmezés szerint engedélyezett volt. Az LQR így tiltható le:
disable lqr
Néha előfordulhat, hogy a zajos telefonvonal esetén vagy a hívásvárakoztatás használatakor a modem bontja a vonalat, mivel (helytelenül) azt hiszi, hogy nincs kapcsolat.
Manapság a legtöbb modemen általában be lehet valahogy állítani, hogy mennyire legyenek elnézőek a kapcsolat ideiglenes megszakadásával szemben. Például egy U.S. Robotics® Sportster® esetén ezt tizedmásodpercekben mérik az S10 regiszter segítségével. A modemünk ilyenkor tehát úgy tehető sokkal toleránsabbá, ha a következő hívási beállítást adjuk:
set dial "...... ATS10=10 OK ......"
További részleteket a modem kézikönyvéből tudhatunk meg.
Sokan tapasztalják, hogy a kapcsolat minden különösebb magyarázat nélkül lefullad. Ilyenkor elsőként azt érdemes tisztázni, hogy az összeköttetés melyik oldalán történt a vonal bontása.
Ha belső modemet használunk, akkor próbáljuk meg a ping(8) paranccsal ellenőrizni, hogy a modem TD lámpája villog-e az adatok küldésekor. Amennyiben igen (miközben az RD lámpa viszont nem), akkor a gond a vonal másik végén lesz. Ha viszont a TD nem villog, akkor a probléma a mi oldalunkon áll fenn. A belső modemek esetében a ppp.conf állományban a set server parancsot is érdemes megadnunk, így amikor a kapcsolat leállását tapasztaljuk, a pppctl(8) segítségével rá tudunk csatlakozni a ppp(8) démonra. Ha a hálózati kapcsolat ekkor hirtelen erőre kapna (mivel rácsatlakoztunk kívülről) vagy egyáltalán nem tudunk csatlakozni (feltételezve, hogy a set socket parancs sikeresen lefutott az induláskor), akkor a probléma még mindig nálunk lesz. Ha viszont sikerül csatlakoznunk és a vonallal még mindig gondok vannak, akkor próbáljuk a set log local async parancs használatával engedélyezni a helyi aszinkron naplózást, majd egy másik konzolból a ping(8) parancs segítségével kezdjük el használni az összeköttetést. Az aszinkron naplózás jelezni fogja, ha sikerül adatokat átvinni és fogadni a kapcsolaton keresztül. Ha ilyenkor nem látunk visszafele érkező adatokat, akkor az arra utal, hogy a gond a vonal távoli végén van.
Miután sikeresen kiderítettük, hogy az adott probléma helyi vagy távoli, két lehetőségünk van:
Ezzel szemben nagyon keveset tudunk mi, felhasználók tenni. A legtöbb internetszolgáltató egyszerűen nem hajlandó segítséget nyújtani abban az esetben, ha nem valamelyik Microsoft® operációs rendszert használjuk. A ppp.conf állományunkban a enable lqr sor megadásával engedélyezni tudjuk a ppp(8) számára, hogy észlelhesse a távoli hibákat és bontsa a vonalat, de ez a vizsgálat viszonylag időigényes és ennélfogva nem túlságosan hasznos. A szolgáltatónknak pedig ne nagyon emlegessük, hogy felhasználói PPP-t futtatunk.
Először próbáljunk meg letiltani mindenféle tömörítést a következő sor megadásával:
disable pred1 deflate deflate24 protocomp acfcomp shortseq vj deny pred1 deflate deflate24 protocomp acfcomp shortseq vj
Kapcsolódjunk újra és ellenőrizzük, hogy továbbra is működőképes a kapcsolat. Ha ennek hatására javul a helyzet vagy a probléma teljesen megoldódik, akkor a beállítások egyenkénti próbálgatásával keressük meg, hogy melyik okozta a gondot. Ez már elegendő lesz ahhoz, hogy komolyabban felvegyük a kapcsolatot a szolgáltatónkkal (habár ebből gyorsan ki fog derülni, hogy nem Microsoft terméket használunk).
Mielőtt szólnánk a szolgáltatónknak, a gépünkön engedélyezzük az aszinkron naplózást és várjuk meg, amíg a kapcsolat újra megszakad. Erre nem árt felkészülnünk, mert viszonylag sok tárhelyet igényel. Innen majd a portról utoljára olvasott adat lesz a lényeges. Ez általában szöveges adat és akár a probléma konkrét okára is utalhat (“Memory fault”, “Core dumped”?).
Ha segítőkész
szolgáltatót választottuk, akkor a
naplózást akár az ő oldalunkon is
engedélyezhetjük, így amikor a vonal
megszakad, az ő szemszögükből is
képesek leszünk elemezni a
problémát. Ilyen esetben nyugodtan
küldjünk egy levelet Brian Somers <brian@FreeBSD.org>
címére vagy kérjük meg a
szolgáltatónkat, hogy közvetlenül
vele tárgyaljon.
A legjobban úgy járunk, ha a ppp(8) programot nyomkövetési információkkal fordítjuk újra, majd a gdb(1) segítségével lekérünk egy hívási láncot az éppen megakadt ppp példánytól. A ppp alkalmazást a következő parancsokkal tudjuk úgy újrafordítani, hogy tartalmazza a kívánt információkat:
# gdb ppp `pgrep ppp`
Ezt követően a gdb parancssorában a bt és where parancsok segítségével hozzá tudunk jutni a hívási lánchoz. Mentsük el valahova a gdb által kinyert adatokat, majd a detach paranccsal váljunk le a futó programról és a quit begépelésével lépjünk ki a gdb programból.
Végezetül az elmentett eredményeket
küldjük el Brian Somers <brian@FreeBSD.org>
címére.
A FreeBSD 2.2.5 előtti kiadásaiban a ppp(8) az összeköttetés létrejötte után megvárta, hogy a távoli pont kezdeményezze a kapcsolatvezérlő protokoll (Line Control Protocol, LCP) használatát. Sok szolgáltató azonban nem csinál ilyet, ehelyett inkább a klienstől várják mindezt. Az LCP kezdeményezését így kényszeríthetjük ki a ppp(8) használata során:
set openmode active
Megjegyzés: Általában semmilyen gond nem származik abból, ha a mind a két oldal kezdeményez, így az
openmode
alapértelmezés szerint active értékű. A következő szakaszban azonban bemutatjuk mikor gondot okoz a használata.
Csatlakozás után időnként előfordulhat, hogy “magic is the same” hibaüzeneteket látunk a naplóban. Ezek az üzenetek bizonyos esetekben teljesen ártalmatlanok, máskor viszont akár komolyabb problémákat is jelezhet. A legtöbb PPP implementáció nem él túl egy ilyen hibát, és még ha látszólag létre is jön ilyenkor a kapcsolat, folyamatosan konfigurációs kérések és válaszok jönnek-mennek a naplóban egészen addig, amíg a ppp(8) végül fel nem adja és lezárja a kapcsolatot.
Ez általában olyan szervereken jelenik meg, ahol nem elég gyorsak a lemezek és minden kapcsolathoz elindítanak egy getty(8) és a bejelentkezéskor vagy azt következő elindítják a ppp(8) programot. Egyes visszajelzések szerint ilyen egyébként gyakran előfordul a slirp használatakor. A problémát egyébként a getty(8) és a ppp(8) indítása között eltelt idő okozza, amikor a kliens oldalán futó ppp(8) elkezdi küldeni a kapcsolatvezérlő (Line Control Protocol, LCP) csomagokat. Mivel ilyenkor az ECHO még mindig aktív a szerver adott portján, a kliens ppp(8) a saját csomagjainak “tükröződését” fogja látni.
Az LCP beállításának része az összeköttetés két oldalán egy-egy bűvös szám (“magic number”) megállapítása, amellyel ezután észlelhetőek az ilyen “tükröződések”. A protokoll szerint amikor a két pont megpróbálja ugyanazt a bűvös számot használni, akkor visszautasítja (NAK jelzést küld) és egy másikat választ. Ha ilyenkor még a szerver portján aktív az ECHO, akkor a kliens oldali ppp(8) azt tapasztalja, hogy elkezd LCP csomagokat küldeni, majd mivel ugyanazt kapja vissza, erre egy NAK jelzést válaszol. Ugyanígy látja magát a NAK jelzést (aminek hatására a ppp(8) megváltoztatja a bűvös számát) is. Ennek eredményeképpen hirtelen nagy mennyiségű bűvösszám-váltás keletkezik, ami pedig szépen felhalmozódik a szerver terminálpufferében. Ahogy a ppp(8) végre elindul a szerveren, elönti ez a rengeteg információ, aminek alapján sikertelennek ítéli meg az LCP beállítását és feladja a további próbálkozást. Eközben a kliens számára megszűnnek a visszaverődő csomagok és csak annyit lát, hogy a szerver bontja a kapcsolatot.
Ezt úgy tudjuk elkerülni, ha a ppp.conf állományban a távoli pontra bízzuk az beállítás kezdeményezését:
set openmode passive
Ennek hatására a ppp(8) megvárja, hogy a szerver kezdeményezze az LCP beállítását. Egyes szerverek azonban sosem teszik meg ezt. Ilyenkor valami ilyesmit tudunk tenni:
set openmode active 3
Így a ppp(8) 3 másodpercig passzív marad, majd csak ezután kezd el LCP kérésket küldeni. Ha a távoli pont eközben küld valamilyen kérést, az ppp(8) azonnal válaszol rá és nem várja végig a 3 másodperces időtartamot.
A ppp(8) programban jelenleg van egy olyan hibásan implementált jellemző, ahol az LCP, CCP és IPCP válaszokat nem társítja az eredeti kérésekhez. Ennek következményeképpen, ha az egyik PPP implementáció 6 másodperccel lassabb a másik oldalnál, akkor az még két további LCP konfigurációs kérést is küld, ami viszont végzetesnek bizonyul.
Vegyünk például két implementációt, az A és a B pontokat. Az A már közvetlenül a csatlakozás után LCP kéréseket kezd el küldeni, miközben a B csak 7 másodperc múlva tud elindulni. Mire végre a B pont is elindul, addigra az A már kiküldött 3 LCP kérést. Most feltételezzük, hogy nincs ECHO, máskülönben az előző szakaszban leírt, bűvös számokkal kapcsolatos problémába ütköznénk. A B ekkor tehát küld egy kérést, majd nyugtázza az A ponttól kapott korábbi kérést. Ennek hatására az A pont OPENED állapotba megy át, újra küld és nyugtázza az előző kérést B felé. Eközben a B további két nyugtázást küld az A pontról kapott további két kérésre, a B indulása előttről. A B ekkor megkapja az A első nyugtáját és átvált OPENED állapotba. Az A ekkor megkapja a második nyugtát a B ponttól és visszavált REQ-SENT állapotba, majd az RFC szerint elküld (előre) egy újabb kérést. Ekkor megkapja a harmadik nyugtát és OPENED állapotba vált. Eközben a B megkapja előre küldött kérést a A ponttól, amelynek hatására ACK-SENT állapotba vált vissza, és az RFC szerint ismét küld egy (második) kérést és egy nyugtázást. Az A erre megkapja a kérést, visszavált REQ-SENT állapotban és küld egy újabb kérést. Ekkor közvetlenül megkapja a rákövetkező nyugtázást és átvált OPENED állapotba.
Ez egészen addig folytatódik, amíg az egyik oldal rá nem eszmél, hogy ennek nincs túlságosan sok értelme és feladja a próbálkozást.
Ez legkönnyebben úgy kerülhető el, ha ilyenkor az egyik oldalt passive típusúra állítjuk, vagyis az egyik oldalon várunk egy keveset a beállítás kezdeményezésére. Ezt a következő paranccsal lehet megoldani:
set openmode passive
Óvatosan bánjunk ezzel a paraméterrel! A beállítás kezdeményezésének várakoztatási idejét a következő paraméterrel tudjuk megadni:
set stopped N
Használhatjuk viszont ezt a parancsot is (ahol N adja meg, hogy mennyi másodperc teljen el a beállítás megkezdése előtt):
set openmode active N
Az ezzel kapcsolatos további részleteket a man oldalon olvashatjuk.
A shell vagy ! parancsok végrehajtásakor a ppp(8) elindít egy parancsértelmezőt (illetve ha paramétereket is adtunk meg, akkor a ppp(8) átadja azokat is), majd megvárja annak befejeződését. Ha a parancs futtatása közben éppen egy PPP kapcsolatot akartunk használni, akkor erre az időre az előbbiek miatt látszólag meg fog állni. Ez tehát azért történik, mert a ppp(8) megvárja a parancs lefutását.
Ha nem akarjuk megvárni a parancs befejeződését, akkor inkább használjuk a !bg parancsot. Ennek hatására az adott parancs a háttérben fog lefutni és a ppp(8) képes lesz folyamatosan szemmel tartani az összeköttetést.
A ppp(8) ilyen esetekben nem képes magától megállapítani, hogy mikor bontották a vonalat. Ennek oka a tűk null-modem kábelben kiosztott szerepében keresendő. Amikor ilyen típusú kapcsolattal dolgozunk, a következő sor megadásával ne felejtsük el engedélyezni az LQR használatát:
enable lqr
Ha a távoli pont LQR csomagokat küld, akkor a ppp(8) alapértelmezés szerint fogadja azokat.
Amennyiben a ppp(8) szándékainkkal szemben váratlanul kezdene el tárcsázni, akkor keressük meg kiváltó okát és használjunk hívási szűrést (Dial filter, dfilter) ennek megelőzésére.
A tárcsázás okát a következő sor használatával tudjuk kideríteni:
set log +tcp/ip
Ennek hatására a kapcsolaton keresztüláramló összes forgalmat naplózni fogjuk. Így a legközelebb, amikor a vonal hirtelen aktív lesz, a hozzátartozó időbélyegek alapján könnyen elő tudjuk keresni, hogy pontosan miért is történt.
Az automatikus tárcsázást bizonyos esetekben le tudjuk tiltani. Ez általában egy olyan probléma, amely a névfeloldások miatt keletkezik. Úgy tudjuk megakadályozni, hogy a névfeloldások felépítsék a kapcsolatot (ami viszont nem gátolja abban a ppp(8) programot, hogy egy már meglevő kapcsolaton keresztül küldjön ilyen csomagokat), ha az alábbi beállításokat adjuk meg:
set dfilter 1 deny udp src eq 53 set dfilter 2 deny udp dst eq 53 set dfilter 3 permit 0/0 0/0
Ezek az értékek nem minden esetben megfelelőek számunkra, hiszen ezzel együtt az igény szerinti tárcsázás kényelmét is szűkítjük, mivel a legtöbb program közvetlenül névfeloldással kezd, mielőtt komolyabb hálózati forgalmat bonyolítana le.
A névfeloldás esetében igyekezzünk kideríteni, hogy pontosan melyik program is próbál hálózati neveket feloldatni. Az esetek többségében valószínűleg a sendmail(8) lesz a bűnös. Amennyiben ez a helyzet, akkor az sendmail démonnak a saját konfigurációs állományában kell beállítanunk, hogy ne oldasson fel hálózati neveket. Az érintett konfigurációs állomány módosításának pontos részleteiről a kézikönyv Levelezés betárcsázós kapcsolattal című szakszában olvashatunk bővebben. Továbbá az .mc állományunkba a következő sort is érdemes felvennünk:
define(`confDELIVERY_MODE', `d')dnl
Ezzel a sendmail
beindításáig mindent egy sorban fog
eltárolni (általában a
sendmail démont a
-bd -q30m
paraméterekkel
szokták meghívni, ami arra utasítja,
hogy 30 percenként dolgozza fel a sorát)
vagy amíg a sendmail
-q
parancs le nem fut
(például a ppp.linkup
állományból).
A naplóban folyamatosan a következő üzeneteket lehet látni:
CCP: CcpSendConfigReq CCP: Received Terminate Ack (1) state = Req-Sent (6)
Ilyenek azért keletkeznek, mert a ppp(8) a Predictor1 tömörítési eljárást próbálja meg beállítani, azonban a távoli pont egyáltalán semmilyen tömörítést nem akar használni. Az ilyen üzenetek többnyire ártalmatlanok, de ha el akarjuk tüntetni ezeket, akkor próbáljuk meg a következő módon kikapcsolni a Predictor1 tömörítés használatát:
disable pred1
A modemmel végzett teljes “beszélgetés” szövegének rögzítéséhez a következőket kell engedélyezni:
set log +connect
Ennek eredményeképpen a ppp(8) egészen az utolsóként lekért karakterláncig naplóz mindent.
Ha PAP vagy CHAP hitelesítést használunk (ezért a CONNECT parancs kiadása után már nincs semmi “mondanivalónk” a hívószkriptben, tehát nincs set login szkript), és szeretnénk látni a csatlakozási sebességet, ne felejtsük el utasítani a ppp(8) programot, hogy a teljes CONNECT sort kérje le, valahogy így:
set dial "ABORT BUSY ABORT NO\\sCARRIER TIMEOUT 4 \ \"\" ATZ OK-ATZ-OK ATDT\\T TIMEOUT 60 CONNECT \\c \\n"
Itt most megkapjuk a CONNECT sort, ezután nem küldünk semmit, majd várunk egy soremelést, aminek hatására a ppp(8) arra kényszerül, hogy a teljes CONNECT választ beolvassa.
A ppp a konfigurációs állományokból minden sort külön beolvas, ezért a set phone "123 456 789" és hozzá hasonló karakterláncok esetén képes felismerni, hogy a megadott számok valójában egyetlen paramétert formáznak. A " megadásához a visszaper karaktert (\) kell használnunk.
Amikor tárcsázásért felelős értelmező beolvassa az egyes paramétereket, újraértelmezi ezeket olyan speciális helyettesítési szekvenciák után kutatva, mint például a \P vagy \T (részletesebben lásd a man oldalon). A kettős elemzés miatt nekünk is a megfelelő számban kell megadnunk ezeket a helyettesítendő karaktereket.
Ha tehát egy \ karaktert szeretnénk átküldeni a modemünknek, akkor nagyjából valami ilyesmit kellene írnunk:
set dial "\"\" ATZ OK-ATZ-OK AT\\\\X OK"
Ennek az eredménye a következő lesz:
ATZ OK AT\X OK
Vagy:
set phone 1234567 set dial "\"\" ATZ OK ATDT\\T"
Ez pedig a következő szekvenciát adja:
ATZ OK ATDT1234567
14.20. A ppp(8) miért küld “Segmentation Fault” hibát, miközben nem is keletkezik ppp.core állomány?
A ppp (vagy más hasonló program) elméletileg soha nem hoz létre .core állományt. Mivel a ppp(8) tulajdonképpen a nullás felhasználói azonosítóval fut, az operációs rendszer soha nem fogja a ppp(8) memórialenyomatát leállítása előtt a lemezre menteni. Ha viszont ppp(8) működése valóban leáll egy szegmentációs hiba vagy bármilyen más .core állományt eredményező jelzés miatt, és valóban a legfrissebb változatát használjuk (lásd a fejezet elejét), akkor a következőt tehetjük:
# cd /usr/src/usr.sbin/ppp
# echo STRIP= >> /etc/make.conf
# echo CFLAGS+=-g
>> /etc/make.conf
# make install clean
A fenti parancsokkal telepíteni tudjuk a ppp(8) egy nyomonkövethető változatát. A ppp(8) futtatásához root felhasználónak kell lennünk, mivel minden korábbi engedélyét felülírtuk az előbbiek során. A ppp(8) indításakor ne felejtsük el megjegyezni pontosan az aktuális könyvtárat sem.
Innentől kezdve, amikor a ppp(8) kap egy szegmentációs hibára vonatkozó jelzést, létre fog hozni egy ppp.core nevű állományt. Ennek birtokában a következőt kell csinálnunk:
% su # gdb /usr/sbin/ppp ppp.core (gdb) bt ..... (gdb) f 0 .... (gdb) i args .... (gdb) l .....
Az így beszerzett információkat mellékelve nagyobb valószínűséggel kaphatunk választ az ezzel kapcsolatos kérdésünkre.
Ha járatosak vagyunk a gdb(1) használatában, akkor a .core állományban további részletek és információk utáni is kutathatunk, például mi okozta a hibát, milyen változóknak ekkor milyen értékei voltak stb.
Ez korábban egy ismert probléma volt a
ppp(8) használatával kapcsolatban, amikor
dinamikus helyi IP-címet akart
beállítani -auto
módban. Ez a hiba az újabb
változatokban már nem nincs meg (a man oldalon
keressünk rá az iface
részre).
A gondot az okozta, hogy amikor a tárcsázást elindító program meghívja a connect(2) rendszerhívást, akkor a tun(4) interfészhez tartozó IP-cím a végpontot képviselő sockethez társul. A rendszermag létrehozza az első kimenő csomagot és kiírja a tun(4) eszközre. A ppp(8) ekkor beolvassa a csomagot és felépíti a kapcsolatot. Ha a ppp(8) dinamikus IP-cím kiosztásának eredményeképpen ilyenkor az interfész címe megváltozik, akkor azzal egyidőben az eredeti socket végpont érvénytelenné válik. Így a távoli végpont felé küldött további csomagok általában eldobódnak. Ha valahogy mégis eljutnának a céljukhoz, a válasz már semmiképpen sem érkezhet meg, mivel a küldéshez használt IP-címnek már nem az adott gép a tulajdonosa.
Számos elméleti megközelítés létezik az imént felvázolt probléma megoldására. A legszebb az lenne, ha a távoli pont lehetőség szerint a korábban használt IP-címet osztaná ki újra. A ppp(8) jelenlegi változata pontosan ugyanezt teszi, viszont a legtöbbi implementáció már nem.
Részünkről az bizonyulna a
legegyszerűbb megoldásnak, ha a tun(4)
intefész IP-címe egyáltalán nem
változhatna meg, hanem helyette menet közben az
összes kimenő csomag, köztük
természetesen a forrás IP-címe az
interfész IP-címéről az
időközben beállított IP-címre
változna. Ez lényegében az, amit a
ppp(8) legújabb változataiban
felbukkanó iface-alias
opció is csinál (a libalias(3) és
a ppp(8) -nat
kapcsolója
segítségével): karbantartja az
összes korábban használt interfész
címét és átfordítja
ezeket az utoljára beállított
címre.
A másik (és valószínűleg a sokkal megbízhatóbb) lehetőség egy olyan rendszerhívás implementálása lenne, amely képes az összes használatban levő socketet egyik IP-címről a másik IP-címre átállítani. A ppp(8) ekkor fel tudná használni ezt arra, hogy módosítsa az összes addig futó program socketjét az új IP-cím beállításakor. Ugyanezzel a rendszerhívással a DHCP kliensek is képesek lennének átállítani a socketjeiket.
Lehetőségünk van még IP-cím nélkül is létrehozni interfészeket. A kimenő csomagok ekkor a 255.255.255.255 IP-címet használnák egészen addig, amíg az első SIOCAIFADDR ioctl(2) rendszerhívás le nem zajlik. A ppp(8) feladata ilyenkor a forrás IP-cím megváltoztatása, de ha ez 255.255.255.255, akkor egyedül csak az IP-címnek és az ellenőrzőösszegnek kell megváltoznia. Ez viszont már valamilyen mértékben trükközést a rendszermagon belül, mivel így könnyen tudunk csomagokat küldeni egy rosszul beállított interfészre is, feltételezve, hogy valamilyen módon képesek vagyunk ilyeneket visszamenőleg helyreállítani.
A játékok és a hozzájuk hasonló alkalmazások általában azért nem működnek, amikor a libalias(3) könyvtárat használjuk, mert a távoli gép megpróbál kapcsolódni a belső hálózatunkon levő géphez és kéretlen UDP csomagokat kezd el küldeni neki. A címfordítást végző programnak fogalma sincs róla, hogy ezeket a csomagokat egy belső gépnek kell továbbküldenie.
Akkor lehetünk biztosak ebben, ha egyedül csak azt a szoftvert indítjuk el, amellyel gondjaink akadtak, majd a vagy az átjáró tun(4) interfészét kezdjük el a tcpdump(1) segítségével, vagy pedig engedélyezzük az átjárón a ppp(8) TCP/IP naplózó funkcióját (set log +tcp/ip).
Ahogy elindítjuk a gondokat okozó programot, látnunk kell a csomagjait, ahogy megpróbálnak keresztüljutni az átjárón. Az erre érkező válaszolok eldobódnak (ez jelenti a problémát). Jegyezzük fel a csomagokhoz társuló portszámokat és állítsuk el a programot. Csináljuk meg néhányszor ezt a vizsgálatot, így ellenőrizni tudjuk, hogy mindig ugyanazokat a portokat használja-e. Amennyiben úgy tapasztaljuk, hogy igen, akkor az /etc/ppp/ppp.conf állományba a következő sort kell betenni a megfelelő helyre a működés helyreállításához:
nat port protokoll belső-gép:port port
ahol a protokoll lehet tcp vagy udp, a belső-gép annak a gépnek a címe, ahova tovább akarjuk küldeni a csomagokat, valamint a port a csomagok célportját adja meg.
A fenti parancs megváltoztatása nélkül nem tudjuk ugyanezt a szoftvert más gépeken is használni, és itt azzal most nem is foglalkozunk, hogy miként lehet két belső gépről használni ugyanazt a programot. Mindenesetre annyi biztos, hogy a külvilág felé a belső hálózatunk csupán egyetlen gépnek fog látszani.
Ha azt látjuk, hogy az alkalmazás nem mindig ugyanazt a portot használja, akkor három választási lehetőségünk van:
Készítsük el a támogatását a libalias(3) függvénykönyvtárhoz. A különböző “szélsőséges esetekre” a /usr/src/sys/netinet/libalias/alias_*.c állományokban találhatunk példákat (az alias_ftp.c tökéletes kiindulási alap). Ez általában annyit jelent, hogy beolvasunk bizonyos ismert kimenő csomagokat, beazonosítjuk benne azt az utasítást, amelynek hatására a külső gép csatlakozni próbál a belső géphez egy adott (véletlenszerűen választott) porton, majd beállítunk hozzá egy “útvonalat”, így a rákövetkező csomagok már tudni fogják, hogy merre menjenek.
Ez ugyan a legnehezebb megoldás, de egyben ez is a legjobb, ráadásul így a szoftver több gépen is működtethető.
Proxy használata. Előfordulhat, hogy az alkalmazás támogatja a socks5 protokollt vagy (mint ahogy a cvsup is csinálja) rendelkezik “passzív” móddal, és így lehetőleg igyekszik elkerülni azt, hogy a távoli gépről kapcsolatot próbáljanak meg indítani a helyi gépre.
A nat addr használatával irányítsunk át mindent a belső gépre. Ez viszont egy nagyon durva megközelítés.
Egyelőre még nem, de szándékunkban áll összeállítani egy ilyen listát (már amennyiben igény lesz rá). Minden itt szereplő példában az belső helyett mindig annak a gépnek a belső IP-címét írjuk, amelyről játszani akarunk.
Asheron's Call
nat port udp belső :65000 65000
Manuálisan változtassuk meg a játékon belül a portszámot 65000-re. Ha a belső hálózatunkról több gépen is szeretnénk játszni, akkor mindegyiknek adjuk meg egy egyedi portot (vagyis 65001, 65002 stb.), majd vegyünk fel mindegyikhez egy-egy nat port sort.
Half Life
nat port udp belső:27005 27015
PCAnywhere 8.0
nat port udp belső:5632 5632
nat port tcp belső:5631 5631
Quake
nat port udp belső:6112 6112
Quake 2
nat port udp belső:27901 27910
nat port udp belső:60021 60021
nat port udp belső:60040 60040
Red Alert
nat port udp belső:8675 8675
nat port udp belső:5009 5009
Az FCS jelentése Frame Check Sequence, vagyis az “Adatkeret ellenőrzésének sorozata”. Mindegyik PPP csomaghoz tartozik egy ellenőrzőösszeg, amely arról gondoskodik, hogy ugyanaz az adat érkezzen meg, mint amit elküldtek. Amennyiben egy bejövő csomag FCS értéke érvénytelennek minősül, a csomag eldobódik és a HDLC FCS számláló értékkel eggyel növekszik. A HDLC hibaszámlálói a show hdlc parancs segítségével tekinthetőek meg.
Ha rosszul működik az összeköttetés (vagy a soros vonali meghajtónk folyamatosan eldobja a csomagokat), akkor láthatunk helyenként FCS hibákat. Többnyire nem érdemes az ilyenek miatt aggódni, habár ez jelentős mértékben lassítja a tömörítést végző protokollok munkáját. Ha külső modemünk van, akkor ne felejtsük el a megfelelő módon leárnyékolni, mivel ebből is származhat a probléma.
Ha a vonal a kapcsolódást követően szinte azonnal lemerevedik és hirtelen nagy mennyiségű FCS hiba jelentkezik, akkor az arra is utalhat, hogy az összeköttetés nem tisztán 8 bites. Gondoskodjunk róla, hogy a modem ne a szoftveres forgalomirányítást (XON/XOFF) használja. Ha viszont az adatok közvetítéséhez mégis szoftveres forgalomirányítást kell használnunk, akkor a set accmap 0x000a0000 parancs kiadásával jelezzük a ppp(8) felé, hogy a ^Q és ^S karaktereket helyettesítse.
Nagy mennyiségű FCS hibát olyan esetekben is tapasztalhatunk, amikor a távoli pont abbahagyta a PPP üzenetek küldését. Ilyenkor javasolt engedélyezni az aszinkron naplózás használatát, aminek segítségével gyorsan meg tudjuk állapítani, hogy a beérkező adatok bejelentkező vagy shell üzeneteket. Ha a másik oldalon egy shell parancssorát kapjuk meg, akkor a ppp(8) a close lcp megadásával a vonal eldobása nélkül leállítható (az utána következő term paranccsal pedig a távoli gépen futó shellre tudunk csatlakozni).
Ha a naplókban látszólag semmi sem indokolja az összeköttetés leállását, próbáljunk meg erre rákérdezni a távoli pont (talán a szolgáltató?) karbantartójánál.
A probléma megoldását Michael
Wozniak (<mwozniak@netcom.ca>
) adta meg, valamint
Dan Flemming (<danflemming@mac.com>
) alkalmazta
ugyanezt Macre:
Ennek oka az ún. útválasztási “fekete lyuk”. A Mac OS és a Windows 98 (de valószínűleg az összes többi Microsoft operációs rendszer) olyan nagy méretű TCP csomagokat küld, amelyek már nem férnek bele egy PPPoE keretbe (amely mérete Ethernet estén 1500 byte alapértelmezés szerint) és beállítja hozzá a darabolás letiltását jelző (“do not fragment”) bitet (TCP esetén ez alapértelmezett), és a Telco útválasztó pedig nem küldi el a “must fragment” (“darabolni kell”) ICMP csomagot a letölteni kívánt oldal szolgáltatója felé. (Másik lehetőség, hogy az útválasztó ugyan küld egy ilyen ICMP csomagot, de ezt a tartalomszolgáltatónál található tűzfal eldobja.) Amikor válaszul a szolgáltató olyan kereteket kezd el küldeni, amelyek nem illeszkednek a PPPoE keresztmetszetébe, a Telco útválasztó egyszerűen eldobja ezeket és a lap nem pedig nem lesz elérhető (egyes képek és oldalak esetén előfordul). Úgy tűnik, ez az alapbeállítás a legtöbb Telco PPPoE konfiguráció esetében.
Ezt a hibát úgy javíthatjuk, ha a Windows 95/98 rendszerekben megtalálható regedit segítségével felvesszük a következő regisztrációs bejegyzést:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\NetTrans\0000\MaxMTU
A karakterlánc értéke legyen 1436, mivel bizonyos ADSL útválasztók állítólag nem képesek ennél nagyobb méretű csomagokat kezelni. Windows 2000 esetén ezt a beállítást a Tcpip\Parameters\Interfaces\a hálózati kártya azonosítója\MTU helyen kell keresni és típusa duplaszó (DWORD).
A Windows MTU beállításaival kapcsolatban olvassuk el a Microsoft Knowledge Base címén található dokumentumokat: Q158474 - Windows TCPIP Registry Entries és Q120642 - TCPIP & NBT Configuration Parameters for Windows NT® .
Windows 2000 alatt a regisztrációs adatbázisban érdemes még a Tcpip\Parameters\Interfaces\a hálózati kártya azonosítója\EnablePMTUBHDetect duplaszó értékét 1-re állítani, ahogy arra az imént említett 120642-es Microsoft dokumentum is hivatkozik.
Sajnos a Mac OS nem nyújt semmilyen beállítási lehetőséget a TCP/IP beállítások megváltoztatására. Léteznek viszont kereskedelmi termékek, amelyek lehetővé teszi a felhasználók számára, hogy igényeik szerint módosítsák rendszerük TCP/IP beállításait. A hálózati címfordítást használók keressék meg az MTU beállításaikat és adják meg az 1450 értéket az eredeti 1500 helyett.
A ppp(8) újabb (2.3 vagy afeletti) változatai már tartalmaznak egy enable tcpmssfixup parancsot, amellyel az MSS értéke tetszőlegesen átállítható. Ez alapértelmezés szerint engedélyezett. Ha valamiért mégis a ppp(8) egy korábbi változatával kellene dolgoznunk, akkor érdemes megnéznünk net/tcpmssd portot.
Ha eddig minden más csődött mondott, akkor próbáljuk meg elküldeni az összes beszerezhető információt, beleértve a konfigurációs állományokat, hogyan indítjuk el a ppp(8) programot, a naplók fontosabb részeit és a netstat -rn parancs kimenetét (a csatlakozás előtt és után) a FreeBSD general questions levelezési lista címére vagy a comp.unix.bsd.freebsd.misc hírcsoportba, és valaki talán majd megmutatja a helyes irányt.
Ha kérdése van a FreeBSD-vel kapcsolatban, a következő
címre írhat (angolul): <freebsd-questions@FreeBSD.org>.
Ha ezzel a dokumentummal kapcsolatban van kérdése,
kérjük erre a címre írjon: <gabor@FreeBSD.org>.