Как настроить постоянный прокси-сервер смены пола TCP?
У меня есть провайдер (A), который хочет отправить нам данные через входящее TCP-соединение. К сожалению, служба-потребитель (B) не может получать входящие TCP-соединения. Также у него нет статического IP, еще одно требование.
Одним из способов решения этой проблемы может быть служба, которая соединяет входящий порт TCP A с другим портом TCP B, чтобы потребитель мог установить исходящее соединение с B.
Это не единственная проблема [1] [2], и с помощью socat я могу сделать что-то очень близкое к тому, что я хочу:
socat -d -d -d -u TCP4-LISTEN:PORT-A,reuseaddr TCP4-LISTEN:PORT-B,reuseaddr
Однако это имеет следующие проблемы:
- Если B отключается, он не может повторно подключиться. С
TCP4-LISTEN:PORT-B,reuseaddr,fork
, он может подключиться, но не получает данные. - B не может подключиться, пока A не установил соединение (преодолимо)
- Только одно соединение может быть установлено
PORT-B
(Преодолимы)
Есть ли способ настроить команду так, чтобы она стала "постоянной" и устойчивой к сбоям?
2 ответа
Важный вопрос: как A будет реагировать на потерю соединения или на отказ в соединении? Все, что предполагает, что одно TCP-соединение будет работать вечно, будет хрупким; это просто природа интернета.
Как насчет настройки socat
как [x]inetd
оказание услуг?
Вы бы установить xinetd
слушать в PORT-B и запустить socat -u TCP4-LISTEN:PORT-A,reuseaddr STDIO
как только B-сторона соединяется.
xinetd
будет проходить входящий трафик со стороны B на стандартный ввод socat
и поймать стандартный вывод socat
и передать его на В-сторону.
Если B отключается, то socat
процесс может быть разрешен до конца; xinetd
начнется новый, как только B подключится снова. Пока B отключен, A получит ошибки "Отказано в соединении".
Когда-то мне приходилось делать что-то похожее на старой системе HP-UX.
Реальный мир грязный.
В реальном мире иногда TCP-соединения умирают, это может произойти, например, если перезагружен межсетевой экран с сохранением состояния или NAT, если соединение проходит слишком долго без трафика, или если основное соединение слишком долго не работает.
Кроме того, иногда, когда умирают соединения, они не умирают симметрично. Если соединение, содержащее большое количество данных, умирает, то, вероятно, отправитель заметит, что оно мертво задолго до того, как получатель сделает это. Это имеет несколько побочных эффектов.
- Если соединение инициируется от отправителя к получателю, может появиться новое соединение, в то время как старое соединение, по-видимому, еще живо.
- Если соединение инициируется от получателя к отправителю, то может существовать существенная задержка между отправителем, обнаружившим разрыв соединения, и получателем, обнаружившим этот факт и инициирующим переподключение.
Кроме того, TCP-соединения представляют собой поток байтов, а НЕ поток сообщений, поэтому, когда ваше соединение прерывается, вы можете получить частичное сообщение.
Итоговый результат этого приводит меня к выводу, что надежное решение требует понимания протокола приложения, чтобы ваше решение могло его понять.
- Как объединить потоки, когда новое соединение входит.
- Должны ли сообщения храниться, когда источник данных подключен получателем данных, нет.
- Подходит ли сквозной механизм подтверждения для предотвращения потери сообщения.
- Необходим ли какой-либо механизм ping уровня приложения для ускорения обнаружения обрывов соединений.