Záznam o odpojení dorazí poté, co už začalo druhé připojení pod stejným jménem, a obsluha, která aktualizuje nejnovější řádek pro tohoto uživatele, uzavře špatnou relaci. Chyba není v porovnání časových razítek. Je v předpokladu, že jméno plus celá sekunda identifikují jednu relaci. Události hooků popisují připojení a připojení potřebuje klíč, který patří jen jemu.

Začněte tím, co proměnné odpojení skutečně znamenají. Teprve pak má volba identifikátoru smysl.

Co hook odpojení skutečně nese

V Community OpenVPN 2.6 reference hooků time_unix definuje jako okamžik, kdy se klient připojil; nastavuje se před spuštěním hooku připojení a není znovu definován, když později zasáhne hook odpojení. time_duration udává délku této relace v sekundách, takže konec je přibližně čas připojení plus trvání. Oba jsou celé sekundy a ani jeden není okamžik, kdy vaše databáze událost zpracovala. Právě oddělení těchto tří časů způsobuje, že korelace vydrží, místo aby jen vypadala správně během testování.

Tato aritmetika si zaslouží zápis, protože je to jediný čas konce, který hook sám nabízí. Zpoždění zpracování a rozdíly hodin mezi hostiteli zůstávají mimo něj.

Proč očividná dvojice není jedinečná

Spárování jména s časem připojení zúží hledání a stále relaci neidentifikuje. Klient se může znovu připojit během stejné sekundy, takže dvě relace mohou sdílet obě hodnoty. Dvě instance démona nebo výměna serveru, která zachová stejnou konfiguraci, mohou tuto dvojici vytvořit z různých procesů. Adresy tunelů se recyklují ze stejného důvodu, což z nich činí atributy relace, nikoli identifikátory pro ni.

Režim selhání je tichý. Pozdní odpojení první relace odpovídá nejnovějšímu řádku a ukončí přidělení, které druhá relace stále používá, takže uživatel zažije náhodnou ztrátu přístupu, kterou ničím nezavinil. Počet řádků, který potom vypadá správně, činí problém hůře odhalitelným.

Odkud pochází stabilní identita

Rozhraní pro správu přiděluje každému klientovi identifikátor klientské instance a tento identifikátor je omezen na instanci démona, která jej vydala. Použitelný externí klíč kombinuje stabilní identifikátor serveru, epochu, která se mění při startu démona, a toto klientské ID. Epocha je důležitá, protože identifikátory se restartují spolu s procesem a holé ID procesu může později znovu použít něco nesouvisejícího.

Proměnné prostředí nastavené uvnitř podřízeného skriptu připojení se nepřenášejí do pozdějšího skriptu odpojení nadřazeného démona, protože tyto skripty běží jako samostatné procesy s vlastními prostředími. Generování UUID v době připojení je proto polovina řešení. Strana odpojení musí umět pojmenovat stejné UUID, což znamená, že identita musí žít někde, kam dosáhnou obě události.

Ukončování udělejte podmíněné a idempotentní

Ukončujte podle vlastníka relace, ne podle uživatele. Obsluha, která smaže jakékoli přidělení, jež právě patří nějakému jménu, nakonec smaže špatné, a jedinou obranou je zkontrolovat, že záznam, který se odstraňuje, je záznam, který tato událost popisuje.

Rozhraní pro správu přijímá vždy jednoho připojeného klienta správy, proto se integrujte s tím, kdo ho už vlastní, místo abyste připojovali druhého pozorovatele, který soutěží o stejný socket.

Opakované události zpracovávejte, aniž byste výsledek změnili dvakrát, a nespárované události uchovávejte pro usmíření, místo abyste je zahazovali. Zpětné volání odpojení má dokumentované podmínky životního cyklu a po pádu nebo tvrdém zastavení nemusí nikdy dorazit, takže návrh potřebuje způsob, jak znázornit relaci, jejíž událost konce chybí.

Otestujte nepříjemné případy záměrně: dvě opětovná připojení během jedné sekundy, dvě instance démona, připojení, jehož zpracování selhalo, a restart démona uprostřed relace. Klíč, který přežije všechny čtyři, si zaslouží důvěru.

Související články