На debian 10 развернут docker(v.20.10.7).
Есть клиент и сервис, которые общаются между собой через некий прикладной протокол над tcp. Клиент развернут на localhost, сервис в docker на localhost, общение через docker-proxy. Проблема следующая.
В случае закрытия соединения сервисом через RST, docker — proxy "подменяет" RST на FIN. По трафику четко это видно.
Как итог, client -> docker_proxy переходит в CLOSE_WAIT, docker_proxy -> client — в FIN_WAIT2.
Есть ли возможность избежать данную подмену или это адекватное поведение ?
Здравствуйте, Sazon, Вы писали:
S>На debian 10 развернут docker(v.20.10.7). S>Есть клиент и сервис, которые общаются между собой через некий прикладной протокол над tcp. Клиент развернут на localhost, сервис в docker на localhost, общение через docker-proxy. Проблема следующая.
S>В случае закрытия соединения сервисом через RST, docker — proxy "подменяет" RST на FIN. По трафику четко это видно. S>Как итог, client -> docker_proxy переходит в CLOSE_WAIT, docker_proxy -> client — в FIN_WAIT2.
S>Есть ли возможность избежать данную подмену или это адекватное поведение ?
Предполагаю, что docker-proxy определяет закрытие сервисом по факту того, что сокет становится доступным на чтение, но read() возвращает 0 байт. На этом уровне отличить закрытие по RST от закрытия по FIN может быть уже невозможно. (Точнее, попытка реальной записи дала бы тут ECONNRESET, но она не делается.)
Тогда он в сторону клиента зовёт shutdown(,SHUT_WR).
А какой вообще смысл различать? И почему при нормальном ходе событий сервис может начать раздавать RST на нормальные соединения? Это тут самое сомнительное.
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, Sazon, Вы писали:
S>>На debian 10 развернут docker(v.20.10.7). S>>Есть клиент и сервис, которые общаются между собой через некий прикладной протокол над tcp. Клиент развернут на localhost, сервис в docker на localhost, общение через docker-proxy. Проблема следующая.
S>>В случае закрытия соединения сервисом через RST, docker — proxy "подменяет" RST на FIN. По трафику четко это видно. S>>Как итог, client -> docker_proxy переходит в CLOSE_WAIT, docker_proxy -> client — в FIN_WAIT2.
S>>Есть ли возможность избежать данную подмену или это адекватное поведение ?
N>Предполагаю, что docker-proxy определяет закрытие сервисом по факту того, что сокет становится доступным на чтение, но read() возвращает 0 байт. На этом уровне отличить закрытие по RST от закрытия по FIN может быть уже невозможно. (Точнее, попытка реальной записи дала бы тут ECONNRESET, но она не делается.) N>Тогда он в сторону клиента зовёт shutdown(,SHUT_WR).
N>А какой вообще смысл различать? И почему при нормальном ходе событий сервис может начать раздавать RST на нормальные соединения? Это тут самое сомнительное.
В самом прикладном amqp — протоколе есть heartbeat — функционал детектирования "залипших" соединений. Формально соединения могут быть в корректном состоянии, однако в случае отсутствия какой-либо активности в течение N сек сервис, rabbitmq,
в праве грохнуть через RST данное соединение. В то же время добавлять ping — и со стороны клиента не хочется, но и отказываться от этого "рубильника" нет желания.
Основная проблема заключается в том, что в состоянии FIN_WAIT2 отправка данных в сервис развернутый в docker — е через proxy завершается как минимум без ошибок на user-space уровне, это вроде как нормально.
Однако фактически это соединение в контексте докера уже не существует: netstat в докере ничего не выдает по исходному порту.
В принципе я в курсе, что в любом случае гарантированную доставку именно до сервиса можно реализовать только на прикладном уровне, в amqp это есть, и мы используем, но тем не менее...
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, Sazon, Вы писали:
S>>На debian 10 развернут docker(v.20.10.7). S>>Есть клиент и сервис, которые общаются между собой через некий прикладной протокол над tcp. Клиент развернут на localhost, сервис в docker на localhost, общение через docker-proxy. Проблема следующая.
S>>В случае закрытия соединения сервисом через RST, docker — proxy "подменяет" RST на FIN. По трафику четко это видно. S>>Как итог, client -> docker_proxy переходит в CLOSE_WAIT, docker_proxy -> client — в FIN_WAIT2.
S>>Есть ли возможность избежать данную подмену или это адекватное поведение ?
N>Предполагаю, что docker-proxy определяет закрытие сервисом по факту того, что сокет становится доступным на чтение, но read() возвращает 0 байт. На этом уровне отличить закрытие по RST от закрытия по FIN может быть уже невозможно. (Точнее, попытка реальной записи дала бы тут ECONNRESET, но она не делается.) N>Тогда он в сторону клиента зовёт shutdown(,SHUT_WR).
N>А какой вообще смысл различать? И почему при нормальном ходе событий сервис может начать раздавать RST на нормальные соединения? Это тут самое сомнительное.
В любом случае спасиб за наводку, гляну исходники docker-proxy.