Full-duplexverkeer en tegendruk in een SOCKS-relay
Ontwerp de relaystroom rond onafhankelijke bytestromen, gedeeltelijke I/O, begrensde buffers en tegendruk in plaats van geraden responsgroottes.
De SOCKS-handshake is geslaagd. Nu leest de relay van de client, schrijft naar de bestemming, wacht op een volledig antwoord en leest pas daarna weer van de client. Die volgorde kan een volkomen geldige applicatie vastlopen.
Zodra de TCP-tunnel is opgezet, definieert SOCKS de berichten erin niet. De bestemming kan eerst sturen. Beide kanten kunnen onafhankelijk sturen. Eén kant kan een kort record sturen en dan op het antwoord van de andere wachten.
Stuur bytes door, geen geraden transacties
Een receive-aanroep geeft beschikbare bytes terug op basis van zijn flags en de socketstatus. Hij vertelt een generieke relay niet dat een applicatierespons compleet is. Wachten tot een willekeurig grote buffer vol is, kan verhinderen dat het kleine bericht wordt doorgestuurd dat de peer nodig heeft om verder te gaan.
Gebruik het bestaande concurrencymodel van de applicatie om beide richtingen te bedienen: een event loop, asynchrone I/O of een ander bewust gekozen ontwerp. Het belangrijke gedrag is dat vooruitgang in de ene richting geen verzonnen berichtgrens in de andere vereist.
Houd twee begrensde wachtende buffers bij
Gegevens die van de client zijn gelezen, wachten mogelijk nog tot ze de bestemming bereiken, terwijl gegevens van de bestemming wachten tot ze de client bereiken. Volg die wachtende bytes afzonderlijk.
Een send kan minder bytes schrijven dan gevraagd. Bewaar het ongeschreven deel; gooi het niet weg en speel de hele buffer niet opnieuw af. Een tijdelijk niet-beschrijfbare socket is een reden om op de juiste gereedheidsgebeurtenis te wachten, niet om continu te draaien.
Begrens de buffers. Als de bestemming traag is, verplaatst het blijven lezen van onbeperkte clientgegevens de wachtrij eenvoudig naar het geheugen van de relay. Tegendruk betekent het lezen pauzeren wanneer de bijbehorende wachtende buffer vol is en hervatten wanneer schrijfacties ruimte maken.
Een einde in één richting vereist een beleid
TCP kan een verzendrichting sluiten terwijl de andere richting nog nuttige gegevens heeft. Bepaal hoe die toestand wordt doorgegeven nadat gebufferde bytes zijn weggewerkt, en onderscheid een ordelijke sluiting van een fout of deadline.
Niets hiervan vereist dat de relay de payload van de applicatie ontsleutelt of parseert. Hij heeft correcte stroomafhandeling nodig. Alleen de buffergrootte vergroten kan een relay niet repareren die op de verkeerde kant wacht of aanneemt dat elke leesactie overeenkomt met één volledig verzoek.