Я разработал распределенный обратный прокси-сервер под названием PortFusion . Его первоначальная цель состояла в том, чтобы установить долгосрочные TCP-туннели с минимальными издержками и высокой пропускной способностью через брандмауэры, особенно для RDP - несколько долгоживущих соединений.
Теперь, чтобы удовлетворить потребности пользователей в безопасности и помощи активистам, я расширяю ее, чтобы она поддерживала шифрование и поддерживала множество недолговечных соединений.
Сеть:
Hu 1000 <============ Cx 1000 Au
[ 1001 1001=Ax:1000
^ |
| |
| |
| v
Cu 1001 Au Hx 1000
Squid <----- 1001=Au:3128 [ 1001 <----- Firefox
Legend:
u you
x person x
A address
H PortFusionHost
[ hosted service
C PortFusionClient
< establish bidirectional link
= encrypted, secure, bidirectional link
- localhost-only, normal, bidirectional link
Notes:
- Squid as a forward HTTP proxy
- Connection between two parties (===) are secure and encrypted
- Cu is in complete control of what services are shared with Hx
- A single Hu and a single Cu can handle multiple persons x y z
Вопросы:
В приведенной выше настройке сети я проверяю свойство Connected
сокетов, например, которое Hx
принимает от Firefox @ Ax:1001
, для распространения замыканий на соответствующие сокеты зеркалирования, используемые Cu
для связи с кальмарами.
Но они всегда остаются на связи !!
- Почему сокеты Firefox всегда остаются подключенными?
- Разве Firefox не отвечает за закрытие сокетов, которые он открывает для HTTP-запросов после получения ответов?
- Есть ли другие внешние триггеры, которые мне не хватает, которые я могу почувствовать и использовать для закрытия сокетов?
Информация о принятом ответе
Использование свойства сокетов Connected
было неправильным. Следуя подсказке в принятом ответе, я прочитал этот пост и эту статью MSDN .
После изменений, показанных ниже, теперь оба конца немедленно получают уведомление , как только запрос полностью отвечает, и распространение закрытия работает прекрасно, как и ожидалось. (В прошлом был другой механизм, запускающий в конечном итоге очистку неактивных сокетов, но это было недостаточно быстро.)
Код (F #) До:
try
request serverPort cl [||]
while transmitting && socket.Connected do
if socket.Available = 0
then Thread.Sleep Wait
else let length = read()
LogFlow "<:>" "Read" serverPort "<-" client length
request serverPort cl <| Array.sub buffer 0 length
with
Код после:
try
request serverPort cl [||]
while transmitting && read() > 0 do
let length = !lengthR
LogFlow "<:>" "Read" serverPort "<-" client length
request serverPort cl <| Array.sub buffer 0 length
with
, где read
содержит вызов Socket.Receive
и устанавливает lengthR
.