Ruslan1 17 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба Начитался в интернете, что TCP соединение на сервере после закрытия все еще занято в течении 2*MSL и имеет статус "TIME_WAIT". А может ли клиент как-нибудь сказать серверу что оно "точно-точно закрыто, гейтсом клянусь!", так чтоб сервер перестал считать соединение занятым раньше, чем после 2*MSL ? Нашел вот такой документ прошлого века, где предлагается обход: https://tools.ietf.org/html/draft-faber-time-wait-avoidance-00 там описан дополнительный пересыл RTS, и авторы документа таким образом патчили определенные системы. Quote rom CLOSE_WAIT based on whether the application issues a close or a close_swap. The current passive close path is: server client ----------------------------------------------------------- ESTABLISHED ESTABLISHED (get application close) goto FIN_WAIT_1 send FIN ---FIN---> goto CLOSE_WAIT <---ACK--- send ACK goto FIN_WAIT_2 (get application close) goto LAST_ACK <---FIN--- send FIN goto TIME_WAIT send ACK ---ACK---> goto CLOSED This solution adds this branch from CLOSE_WAIT on the client side: server client ----------------------------------------------------------- ESTABLISHED ESTABLISHED (get application close) goto FIN_WAIT_1 send FIN ---FIN---> goto CLOSE_WAIT <---ACK--- send ACK goto FIN_WAIT_2 (get application close_swap) goto LAST_ACK_SWAP <---FIN--- send FIN goto TIME_WAIT send ACK ---ACK---> goto TIME_WAIT <---RST--- send RST goto CLOSED Strictly speaking, the transition of the client to TIME_WAIT is extraneous, because any host sending an RST is obligated not to allow a connection between the same pair of addresses and ports for a time of at least 2 MSL. Но да, нужно дополнительно на клиенте не использовать этот порт следующие 2*MSL время, и вообще это не стандарт. И вообще статью написали 22 года назад. А стандартно ничего не придумали с тех пор? Откуда вопрос возник: есть встроенный FTP сервер, где количество возможных соединений небольшое, и там в ограничение очень легко превысить, если много мелких файлов передавать: насколько я понял, каждый порт остается висеть эти 2*MSL и считается занятым. И очень хотелось бы помочь решить эту проблему со стороны клиента (если возможно), может действительно у меня в lwIP чего-то покрутить можно, и серверу станет легче. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 232 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба 56 минут назад, Ruslan1 сказал: А может ли клиент как-нибудь сказать серверу что оно "точно-точно закрыто, гейтсом клянусь!", так чтоб сервер перестал считать соединение занятым раньше, чем после 2*MSL ? Причём тут "клиент" и его состояние? Это время никак не зависит от состояния клиента. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 232 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба 1 час назад, Ruslan1 сказал: А стандартно ничего не придумали с тех пор? Откуда вопрос возник: есть встроенный FTP сервер, где количество возможных соединений небольшое, и там в ограничение очень легко превысить Стандартно - увеличить число доступных соединений в TCP-стеке. И мудрить ничего не надо Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 76 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба 1 час назад, Ruslan1 сказал: Откуда вопрос возник: есть встроенный FTP сервер, где количество возможных соединений небольшое, и там в ограничение очень легко превысить, если много мелких файлов передавать: насколько я понял, каждый порт остается висеть эти 2*MSL и считается занятым. И очень хотелось бы помочь решить эту проблему со стороны клиента (если возможно), может действительно у меня в lwIP чего-то покрутить можно, и серверу станет легче. Со стороны клиента можно увеличить таймауты между передаваемыми файлами - передачу ведь инициирует клиент, а со стороны сервера только собрать ftp-сервер с нужными задержками. А так то в чём проблема - сервер скажет busy, клиент подождёт и еще раз попытается передать файл. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan1 17 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба 40 minutes ago, jcxz said: Причём тут "клиент" и его состояние? Это время никак не зависит от состояния клиента. перефразирую, если фраза чересчиу витиевата и сложна для понимания: Может ли клиент как-то сообщить серверу, что он не собирается ничего больше прередавать, и заставить сервер забыть об этом соединении быстрее, чем 2*MSL ? 25 minutes ago, jcxz said: Стандартно - увеличить число доступных соединений в TCP-стеке. И мудрить ничего не надо Я тоже не люблю встроенные FTP, но вот попался у одной конторы synology с запасом 512 соединений. И есть у меня подозрение, что эта цифра "512" относится ко всему устройству, а не конкретно под FTP выделено. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 232 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба 13 минут назад, Ruslan1 сказал: Может ли клиент как-то сообщить серверу, что он не собирается ничего больше прередавать, и заставить сервер забыть об этом соединении быстрее, чем 2*MSL ? Ещё раз - зачем? Если вопрос слишком сложен для понимания, перефразирую: Чем это поможет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan1 17 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба 10 minutes ago, HardEgor said: Со стороны клиента можно увеличить таймауты между передаваемыми файлами - передачу ведь инициирует клиент, а со стороны сервера только собрать ftp-сервер с нужными задержками. Ситуация смешная- все началось после того, как новая прошивка стала доставлять данные раз в 10 быстрее. Что при наличии кучки мелких файлов понятно к чему ведет. Ну что ж, как ускорил- так и замедлить смогу, вероятно лучше всего ограничить количество TCP соединений в единицу времени. Если превышено- рвать соединение и впадать в коммуникационную спячку на сколько-нибудь MSL. 10 minutes ago, HardEgor said: А так то в чём проблема - сервер скажет busy, клиент подождёт и еще раз попытается передать файл. У меня кучка приборов рандомно данные кидают. И в результате кто-то часто достукивается, а кто-то раз в час получает "счастливый билетик". Ну, раз нельза вылечить, попробую просто упорядочить это безобразие. 1 minute ago, jcxz said: Ещё раз - зачем? Чем это поможет? тем, что сервер вычеркнет это соединение из списка занятых, и у него появится на одно свободное соединение больше для следующих соединений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 232 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба 8 минут назад, Ruslan1 сказал: У меня кучка приборов рандомно данные кидают. И в результате кто-то часто достукивается, а кто-то раз в час получает "счастливый билетик". Ну, раз нельза вылечить, попробую просто упорядочить это безобразие. Ну так на стороне сервера можно же как-то наверное разравнивать приоритеты "достукивания". Если есть доступ к его коду. Можно придумать алгоритм. Например: после успешного соединения, понижать приоритет для данного клиента до минимума. А все свободные сокеты разбить на группы по приоритету: одна группа - позволяет входящие соединения от клиентов с любым уровнем приоритета, а другая группа - только с уровнем не ниже некоторого значения. 8 минут назад, Ruslan1 сказал: тем, что сервер вычеркнет это соединение из списка занятых, и у него появится на одно свободное соединение больше для следующих соединений. Тогда такой сервер нарушит правила работы TCP. Вы видимо плохо читали описание TCP и для чего нужно TIME_WAIT. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба 1 hour ago, Ruslan1 said: И очень хотелось бы помочь решить эту проблему со стороны клиента (если возможно), может действительно у меня в lwIP чего-то покрутить можно, и серверу станет легче. Ну так посыл последнего RST и происходит со стороны клиента. Добавьте там генерацию такого сегмента в состоянии получения ACK на FIN, и все будет хорошо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan1 17 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба 7 minutes ago, jcxz said: Ну так на стороне сервера можно же как-то наверное разравнивать приоритеты "достукивания". Если есть доступ к его коду. Можно придумать алгоритм. Например: после успешного соединения, понижать приоритет для данного клиента до минимума. А все свободные сокеты разбить на группы по приоритету: одна группа - позволяет входящие соединения от клиентов с любым уровнем приоритета, а другая группа - только с уровнем не ниже некоторого значения. Согласен. но уже несколько раз видел как, люди бодаются с разными zyxel, synology и прочими, где как бы уже есть FTP. Я уже склоняюсь к тому, что самое дешевое для меня- поставить файлзиллу сервер на китайском безвентиляторнике за 200 баксов и подарить клиенту, если сам не разберется. Но это не наш метод. Нужно в гамаке и не снимая лыж... 4 minutes ago, Rst7 said: Ну так посыл последнего RST и происходит со стороны клиента. Добавьте там генерацию такого сегмента в состоянии получения ACK на FIN, и все будет хорошо. То есть этот RST стандартно кем-то ждется? Ага, попробую понять. вроде и в инете что-то гуглится на тему RST. Попробую. Смутило то, что все нагугленные картинки по стейт-машине TCP на сервере заканчиваются состоянием WAIT_TIME. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 76 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба 22 минуты назад, Ruslan1 сказал: Ну что ж, как ускорил- так и замедлить смогу, вероятно лучше всего ограничить количество TCP соединений в единицу времени. Если превышено- рвать соединение и впадать в коммуникационную спячку на сколько-нибудь MSL. Термин CSMA/CD поможет. Множество желающих на ограниченный ресурс - простые случайные задержки между файлами помогут, особенно если готовность возникает почти синхронно. 10 минут назад, Ruslan1 сказал: Смутило то, что все нагугленные картинки по стейт-машине TCP на сервере заканчиваются состоянием WAIT_TIME. Есть в TCP/IP разные подводные камни и разные сервера их решают по разному.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan1 17 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба 28 minutes ago, Rst7 said: Ну так посыл последнего RST и происходит со стороны клиента. Добавьте там генерацию такого сегмента в состоянии получения ACK на FIN, и все будет хорошо. вот тут обсуждается: http://lwip.100.n7.nabble.com/How-to-send-RST-td8880.html Quote err_ttcp_close(struct tcp_pcb *pcb){ .... case ESTABLISHED: if( rstClose & 0x1) // rstClose is a control flag. { err = tcp_send_ctrl(pcb, TCP_FIN); if (err == ERR_OK) { snmp_inc_tcpestabresets(); pcb->state = FIN_WAIT_1; } } else { tcp_abort(pcb); err = ERR_OK; pcb = NULL; } break;...} но там же и комментарий Quote It looks like you made changes to cause the stack to send RST instead of FIN when you close the socket (at least in some situations - there's not enough context to indicate when rstClose would be set).That might be a reasonable choice in your particular environment but it's not a very good plan in the general case. It risks stranding resources in the peer in the event that the RST packet gets dropped somewhere in the path between the two hosts.By default, TCP connections don't time out. So, if your RST packet is lost, the peer will just never hear from you again but will think that the connection is still alive. Even with TCP keepalives enabled (and they are not enabled by default in most systems), the default connection idle timeout is usually two hours. This is probably why the ability to generate RST packets is not typically extended to applications: it's not meant for ordinary session teardown; it's intended to notify the peer of an exceptional condition.Again, this may be fine for your environment, but someone else looking at your suggestion should be aware of the consequences. В-общем, как-то и мне не хочется одно другим подменять. А еще он в WireShark красным показывается, что как бы намекает на необычность действия. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smart_pic 7 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба Код lwIP открыт. Его можно поправить в нужную вам сторону. Код не сложный. Я переделывал под свои нужды для PIC32. Знаю одного кадра , который для STM много че там переделал в этом стеке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба 34 minutes ago, Ruslan1 said: В-общем, как-то и мне не хочется одно другим подменять. Не надо заменять FIN на RST. Надо послать дополнительный сегмент (RST) при приходе валидного ACK в состоянии CLOSING и LAST-ACK. 37 minutes ago, Ruslan1 said: А еще он в WireShark красным показывается, что как бы намекает на необычность действия. Ну WireShark много чего красным красит. Это ж не повод для беспокойства в конкретно данном случае. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 232 24 июля, 2020 Опубликовано 24 июля, 2020 · Жалоба Не важно посылать или нет RST (или что-то другие внутри текущего соединения), от этого необходимость TIME_WAIT не исчезает. Сказано же: "Другое назначение ожидания 2MSL заключается в том, что пока TCP соединение находится в ожидании 2MSL, пара сокетов, выделенная для этого соединения (IP адрес клиента, номер порта клиента, IP адрес сервера и номер порта сервера), не может быть повторно использована. Это соединение может быть использовано повторно только когда истечет время ожидания 2MSL." Вполне обоснованное требование. Потому сервер и должен выдерживать TIME_WAIT. "Это делается для того, чтобы опоздавшие пакеты не были восприняты как часть нового соединения". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться