docker: RST -> FIN
От: Sazon  
Дата: 30.08.22 08:06
Оценка:
Добрый день, такой вопрос.

На 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.

Есть ли возможность избежать данную подмену или это адекватное поведение ?

Заранее благодарен.
Re: docker: RST -> FIN
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 31.08.22 06:31
Оценка:
Здравствуйте, 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 на нормальные соединения? Это тут самое сомнительное.
The God is real, unless declared integer.
Re[2]: docker: RST -> FIN
От: Sazon  
Дата: 31.08.22 08:03
Оценка:
Здравствуйте, 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 это есть, и мы используем, но тем не менее...
Re[2]: docker: RST -> FIN
От: Sazon  
Дата: 31.08.22 13:56
Оценка:
Здравствуйте, 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.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.