Prosljeđivanje TCP poluzatvaranja nakon pražnjenja bajtova na čekanju
Rukujte EOF-om u TCP proxyju bez gubljenja podataka iz reda i bez prekidanja odgovora u drugom smjeru.
Klijent završava slanje, proxy vidi EOF i odgovor nestaje. Trenutno zatvaranje oba proxy socketa može izazvati upravo taj slijed. U TCP releju, uredan kraj u jednom smjeru ne znači da je drugi smjer završen.
Zamislite klijenta koji pošalje zahtjev, zatvori svoju stranu za slanje i čeka odgovor:
client -- request, then FIN --> proxy --> service
client <-------- reply ------- proxy <-- service
Proxy ima dvije TCP veze i dva nezavisno pokretna toka bajtova. Mora prenijeti naznaku kraja ulaza dalje, nakon što prenese bajtove koji joj prethode.
Ispraznite red prije prosljeđivanja EOF-a
Za prijem nenulte veličine na TCP toku, povratak nule označava uredan kraj tog dolaznog toka. Označite taj smjer čitanja kao završen. Prestanite čekati dodatni ulaz iz njega, ali zadržite bajtove koji su već u redu za suprotni socket.
Kada se red od klijenta prema servisu isprazni, pozovite shutdown(service_socket, SHUT_WR) na POSIX socketu. To prekida dalje slanje prema servisu, a smjer od servisa prema klijentu ostaje dostupan. Kada servis završi svoj odgovor, primijenite zrcalnu operaciju nakon pražnjenja reda odgovora.
Zatvaranje deskriptora pripada trenutku kada su oba smjera i njihovi međuspremnici na čekanju završeni, ili kada greška ili otkazivanje zahtijevaju prekid. Držite ograničen timeout za peer koji nikada ne dovrši svoju preostalu polovinu.
Spremnost je poziv za čitanje
Socket koji je čitljiv može imati podatke ili EOF stanje. Pozovite recv i protumačite rezultat. Pozitivni brojevi su bajtovi za prosljeđivanje; nula je kraj smjera. Na neblokirajućem socketu, EAGAIN ili EWOULDBLOCK znači da trenutno nema više ulaza, dok EINTR može zahtijevati ponovni pokušaj. Nijedno nije isti događaj kao EOF.
Ne tražite FIN zastavicu u vraćenom međuspremniku bajtova. TCP ovom API-ju dostavlja uređeni tok bajtova; granice paketa i FIN segment nisu obični aplikacijski teret.
Ovo je životni ciklus sirovog bajt tunela. HTTP proxy koji parsira poruke ipak mora poštovati HTTP uokvirivanje, a proxy koji prekida TLS ima i TLS protokol zatvaranja. Držite te protokolarne odluke iznad smjernog TCP releja.