LINUX.ORG.RU

Пинг-Понг пересылка для поддержки конекта

 


0

0

Приветствую участников форума! Вопрос по большей части относительно фаерволов.
Разрабатывается простой клиент-серверный сервис, клиент подключается по протоколу tcp к этому сервису и устанавливается соединение, но как-бы данные не пересылаются, а просто клиент ожидает поступления данных от сервера.
Стоит ли ожидать каких либо действий со стороны фаервола в отношении таких соединений?
Думаю сделать типа пинг-понг пересылку с интервалом для ожидающих клиентов до поступления целевых данных, потом как только пересылка важных данных закончена, опять переводить в пинг-понг режим до поступления очередной порции данных.

Если критично по отклику — делай как задумал. Если нет — то всеравно у тебя будет кусок кода, который будет делать реконнект в случае разрыва.

deep-purple ★★★★★
()

опять переводить в пинг-понг режим до поступления очередной порции данных.

Что-что ещё раз? В реализации tcp и так есть встроенный keep-alive, ничего в ручную переводить не надо

anonymous
()
Ответ на: комментарий от deep-purple

в http нет кипалива с вариантом пинг понг, кип алив хттп это не делать слоуз сессии и использовать ее для других данных

anonymous
()
Ответ на: комментарий от anonymous

А линк то есть какой нормальный?

Википедики пишут:

TCP keepalive

Transmission Control Protocol (TCP) keepalives are an optional feature, and if included must default to off.[1] The keepalive packet contains null data. In an Ethernet network, a keepalive frame length is 60 bytes, while the server response to this, also a null data frame, is 54 bytes.[citation needed] There are three parameters[2] related to keepalive:

Keepalive time is the duration between two keepalive transmissions in idle condition. TCP keepalive period is required to be configurable and by default is set to no less than 2 hours. Keepalive interval is the duration between two successive keepalive retransmissions, if acknowledgement to the previous keepalive transmission is not received. Keepalive retry is the number of retransmissions to be carried out before declaring that remote end is not available.

Keepalive on higher layers

Since TCP keepalive is optional, various protocols (e.g. SMB[3] and TLS[4]) add a similar feature on top of it. This is also common for protocols which maintain a session over a connectionless protocol, e.g. OpenVPN over UDP.[5]

Эмм..

duration between two keepalive transmissions in idle condition ... set to no less than 2 hours

Что-то как-то...

deep-purple ★★★★★
()

Используй функцию read с коротким таймаутом. Она возвратит ошибку в сокете, 0 - если сокет закрыт, данные если они есть, либо ничего.

Bobby_
()
Ответ на: комментарий от deep-purple

Что-то как-то...

По-сути название keep-alive здесь понимать надо не как «поддерживать живое соединение», а как «находить и закрывать мертвое». Если оба хоста работают и у них установлено соединение, то оно и так будет открыто, пока один из них его не закроет, или не произойдет что-то нештатное. Для нештатных ситуаций, если данные передаются редко, и нужен keep-alive

anonymous
()
Ответ на: комментарий от anonymous

если данные передаются редко

Насколько редко?

Написано: интервал в простое по дефолту НЕ МЕНЕЕ двух часов, и есть еще про интревал между успешными понгами (которые они самые — не чаще 2 часов?), но про время ничего не пишут. Муть мутная. Можно ли поставить меньше 2 часов? 5 секунд? Я потому и прошу нормальный линк сразу по теме, ну не гуглится оно у меня.

deep-purple ★★★★★
()

Стоит ли ожидать каких либо действий со стороны фаервола в отношении таких соединений?

Может быть, но тебе об этом беспокоится не нужно. По той причине, что ты не можешь знать какие 100500 закидонов у админов-параноиков могут быть. Это не твоя проблема.

no-such-file ★★★★★
()
Ответ на: комментарий от deep-purple

Можно ли поставить меньше 2 часов?

Можно, наверное. Как — в зависимости от ОС по разному. У меня вот sysctl net.inet.tcp.keepidle=N, где N — кол-во миллисекунд. Но сам понимаешь, что 5 секунд дадут приличный оверхед, если соединений открыто много.

У меня всё хорошо расписано в man getsockopt. Асло, в FreeBSD по-дефолту keep-alive включен для всех tcp соединений (что немного нарушает RFC1122).

deadplace
()
Ответ на: комментарий от deadplace

наверное

Это ответ на мой вопрос? Никаких претензий, просто обратил внимание.

в man getsockopt

А у меня там всего 120 строчек (не читал).

RFC1122

Может там будет ответ?

deep-purple ★★★★★
()

Лучше не нужно. Просто сделай нормальный реконнект в случае обрыва или ошибки при чтении/записи в сокет. Постоянно идущие данные (при условии, что можно сделать без них), хоть и маленькими порциями - плохой тон.

rumgot ★★★★★
()
Ответ на: комментарий от deep-purple

это такая особенность лора ? вы начали с http keep-alive, я вам сказал что в http кип алива нет, вместо этого вы идете и достаете информацию про tcp
давай те раз уж вы хотите ответить на мой пост, то достаните информацию про http keep-alive ну и за одно найдете там пинг понг, автор топика же это хотел

anonymous
()
Ответ на: комментарий от anonymous

вы начали с http keep-alive

Нет, я лишь сказал что знаю про хттп кипалайф и хочу узнать про тисипи и, естественно, чем они отличаются.

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

Тебе уже сказали, что в http (начиная с 1.1) нет keepalive.

6.3. Persistence

HTTP/1.1 defaults to the use of «persistent connections», allowing multiple requests and responses to be carried over a single connection. The «close» connection option is used to signal that a connection will not persist after the current request/response. HTTP implementations SHOULD support persistent connections.

https://tools.ietf.org/html/rfc7230#section-6.3

Bobby_
()
Ответ на: комментарий от Bobby_

Мне сначала сказали что он какой-то не такой как в тисипи, потом сказали что его вообще нет.

Тебе за конкретику и корректность — снова премного сяп.

deep-purple ★★★★★
()

если соединение разорвется, например кабель через километр обрубили, то ты никак об этом не узнаешь, до тех пор пока не начнешь работать с сокетом в очередной раз
поэтому пиши как и задумал свой пинг-понг/getState/etc
при этом также задавай свой таймер-таймаут на ответ, ибо tcp обычно настроен на очень большой таймаут

сервер также должен получать ответ от клиента о приеме данных т.к. иначе он также не узнает что клиент отвалился

x905 ★★★★★
()
Ответ на: комментарий от rumgot

Просто сделай нормальный реконнект в случае обрыва или ошибки при чтении/записи в сокет. Постоянно идущие данные (при условии, что можно сделать без них), хоть и маленькими порциями - плохой тон.

Не будет обрыва. У cisco дурной брандмауэр. Например, если SSH-сессия не получает клавиатурного ввода, то минут через 10 все пакеты по этому соединению начинают сбрасываться. То есть обрыва связи тоже нет, я только вижу, что при нажатии на кнопки больше ничего не происходит, но состояние соединения с обоих концов ESTABLISHED.

Поэтому в своих приложениях аналогичного типа пришлось делать пинг-понг с реконнектом при отсутствии ответа. Пакет раз в минуту обычно достаточен.

monk ★★★★★
()
Ответ на: комментарий от x905

если соединение разорвется, например кабель через километр обрубили, то ты никак об этом не узнаешь

Если нормально разорвётся, то получишь закрытие сетевого интерфейса или ICMP от коммутатора. Но в общем случае, действительно, на это лучше не закладываться.

сервер также должен получать ответ от клиента о приеме данных т.к. иначе он также не узнает что клиент отвалился

Узнает. TCP ACK не придёт, через пару минут отвалится.

monk ★★★★★
()
Ответ на: комментарий от x905

ответ от клиента о приеме данных

Причем тут клиент? Это ядро подтверждает прием данных. Оно же формирует состояние сокета.

Bobby_
()
Ответ на: комментарий от monk

Если нормально разорвётся

очевидно обрыв кабеля это не нормальное завершение fin/rst не придет


через пару минут отвалится

это очень долго, 5-10 сек уже достаточно для 99% случаев
да и вообще передавать данные без ожидания результата, что они хотябы приняты, признак необдуманности протокола, сложность в отладке

x905 ★★★★★
()
Ответ на: комментарий от x905

Зачем поверх tcp/ip (который обеспечивает гарантированную доставку) наворачивать логику подверждения на уровне приложения? Может ты еще контрольные суммы для гарантии вставляешь?

Bobby_
()

Если конкретнее то там у сервера два слушающих порта, один :8080, другой :1080.
Поставщики конекта(если так назвать) соединяются к :8080, и ожидают пакеты от сервера, потом веб-браузер соединяется к этому же серверу на порту :1080. Здесь сервер выступает в роли шлюза от браузера к поставщикам, и данные передаются по протоколу socks4. Ну и плюс еще менеджер поставщиков, выбирает того поставщика для браузера, котороый, был использован, последний раз не раньше чем через 3 мин.
Основная цель всей этой бутафории, снятие позиций с выдачи по запросам с гугла, единственное что удручает, так это локация поставщиков в разных странах, данные будут неточны.
Надо поробовать сделать с пинг-понг, главное то-что благословение от ЛОР'а получил).

domik_v_derevne
() автор топика

Подчеркну что, пинг-понг нужен, не для того чтобы поддерживать в актуальном состоянии список сокетов, а чтобы не было, ну или хотя бы минимизировать кол-во санкций в отношении таких соединений, типа вот соединение ESTABLISHED а данные не передаются, давайка будем дропать пакеты со всех сторон или вовсе закроем коннект.

domik_v_derevne
() автор топика
Ответ на: комментарий от x905

очевидно обрыв кабеля это не нормальное завершение fin/rst не придет

По отключению интерфейса соединения тоже сбрасываются. RST от коммутатора прилетает на попытку отправить на отсутствующий маршрут.

это очень долго, 5-10 сек уже достаточно для 99% случаев

От задачи зависит.

monk ★★★★★
()
Ответ на: комментарий от Bobby_

Зачем поверх tcp/ip (который обеспечивает гарантированную доставку) наворачивать логику подверждения на уровне приложения?

Затем, что у TCP нет нормальной оперативной сигнализации о потере связи. Если для соединения нормально, что сообщение может прийти через несколько часов, то достаточно TCP.

monk ★★★★★
()
Ответ на: комментарий от Bobby_

А что с ним еще можно сделать?

cisco при каких-то настройках пакеты начинает сбрасывать. Но RST не отправляет.

Нормальные системы позволяют висеть в ESTABLISHED до 5 дней. Вот, нашёл пример гадости: https://wiki.rtzra.ru/software/mikrotik/mikrotik-tcp-established-timeout

monk ★★★★★
()
Ответ на: комментарий от monk

TCP нет нормальной оперативной сигнализации о потере связи

Вызов read вернет eof, если сокет закрыт нормально, ошибку или заблокируется, если данных нет.

Bobby_
()
Ответ на: комментарий от monk

Почему нельзя использовать просто таймаут? За 10 сек данные не пришли, принимаем меры, тут его можно уже пинговать.

Bobby_
()
int optval = 1; // Включить keepalive
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(int));
optval = 5; // количество неотвеченных чтобы считать соединение дохлым
setsockopt(sock, SOL_TCP, TCP_KEEPCNT, &optval, sizeof(int));
optval = 5; // через какое время после пакета с данными посылать первый keep-alive
setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &optval, sizeof(int));
optval = 5; // с каким интервалом посылать последующие keep-alive
setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &optval, sizeof(int));

Keepalive нужен как минимум в паре случаев:

1. Если провайдер урод и отрубает подключение при отсутствии передаваемых данных или просто так, или не умеет в хэндовер (опсосы)

2. Если нужно узнавать, что связи нету ещё до передачи очередного пакета с данными.

Stanson ★★★★★
()
Последнее исправление: Stanson (всего исправлений: 3)
Ответ на: комментарий от anonymous

Батенька, Вы идиот!

я вам сказал что в http кип алива нет, вместо этого вы идете и достаете информацию про tcp

Keep-alive это не свойство протокола прикладного уровня, коим является http. Это свойство всего стека tcp/ip. Т.е., похрен какой там протокол реализован — http/s, ftp, ssh (в котором есть свой, внутренний механизм поддержания соединения, кстати). Вам именно об этом и сказали.

Вы же продолжаете нести околесицу:

давай те раз уж вы хотите ответить на мой пост, то достаните информацию про http keep-alive ну и за одно найдете там пинг понг

Нет. В http не было, нет и он там не нужен в принципе keep-alive.

Не мелите херню, сделайте милость.

anonymous
()
Ответ на: Батенька, Вы идиот! от anonymous

В http не было, нет и он там не нужен в принципе keep-alive

The Keep-Alive general header allows the sender to hint about how the connection and may be used to set a timeout and a maximum amount of requests.

HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Thu, 11 Aug 2016 15:23:13 GMT
Keep-Alive: timeout=5, max=1000
Last-Modified: Mon, 25 Jul 2016 04:32:39 GMT
Server: Apache
Bobby_
()
Ответ на: комментарий от deep-purple

По сути...

Если честно, то keep-alive в протоколе прикладного уровня и в самом стеке это разные вещи. На уровне протокола (что в http, что в ssh) это внутренняя реализация контроля наличия соединения. Она может быть, а может и не быть. Например, на веб-сервере с большой нагрузкой лучше отключать такие вещи. Там назначение keep-alive состоит в том, чтобы через одно соединение передать несколько документов html или xml или что там передавать будете. Ну, типа, соединение одно, а источников данных несколько. Если нагрузка велика, а все клиенты с разными скоростями, то пофиг, лучше отрубить эту возможности и каждый документ пулять в своей сессии. Так хоть дескрипторы впустую висеть не будут. Сервер и так захлёбывается, а тут ещё херова гора дескрипторов висит просто так.

В самом же стеке tcp/ip этот механизм вообще не зависит от конкретного протокола. Этот механизм просто позволяет удостовериться что клиент ещё жив и убивать его сокет не нужно, т.к., возможно что ещё будут передаваться данные по совету. Но и тут надо заметить что всё зависит от протокола обмена и нагрузки на сервер. Если обмен идёт сравнительно короткими пакетами, случайным образом, то keep-alive тут на хер не нужен. Пульнул данные, закрыл сокет и до следующего обмена данными.

Когда keep-alive нужен. Например, есть устройства, передающие телеметрию и получающие команды на отработку. Т.е., двунаправленный протокол. Вот тогда да. Отвалилось соединение, самое время для тревоги. Потому как отваливаться оно не должно. Данные идут потоком и команды тоже потоком. Девайсы постоянно на связи с сервером управления. Это совершенно иной случай, нежели http/s.

anonymous
()
Ответ на: комментарий от Bobby_

Я уже ответил чуть выше.

В случае сервера http/s есть шанс, что в пределах одного коннекта можно будет передать несколько документов html/xml/json/чё там ещё.

Но если клиенты тупят, сервер захлёбывается, то этот механизм лучше отключить. Чтобы не оставлять подвисшие сокеты, по которым ни чего не передаётся. И механизм kerp-alive в http/s и ssh ни как не зависит от механизма kerp-slive самого по себе стека tcp/ip. По смыслу и по названию можно подумать что это одно и то же, но нет. Tcp/ip всё таки, главнее в общем и целом.

anonymous
()

По теме если...

У ТС реализация получается здорово похожа на backconnect из реализаций для троянов. Тоже зловред попадает на машину за файервол-роутер и оттуда поднимает соединение с удалённым сервером контроля и управления сети троянов (зомби). Пришла команда, отработал. Извините за аналогию, но да, так и делают. =)))

Причина в том, что одмины понимают что входящий в их сеть трафик несёт угрозу. А исходящий из их сети, типа белый и пушистый. =))) На деле, нет. Надо чётко контролировать оба направления. И да, под исходящий из сети из-за файера, http-трафик я бы и маскировал трафик для сети троянов. Наверное. Снилось мне... =)))

anonymous
()
Ответ на: Батенька, Вы идиот! от anonymous

facepalm кому вы лечите ?
где я сказал что в http есть кипалив ?
я наоборот сказал - пойдите для начала найдите мне его с реализацией пинг понг - конечно его там нет
но предыдущие ораторы пытались выдавить что он там есть но потом спрыгнули на тсп обсуждение

anonymous
()

Пинг-понг на уровне собственного протокола крайне желателен, а если это система уровне продакшена, то просто обязателен. Просто всякие циски имеют особенность резать простаивающие соединения без всякого уведомления. Поэтому без вариантов.

Такой пинг-понг известен в разных протоколах под названиями Keep Alive, Enquire Link или Heart Beat, что говорит об актуальности и распространенности данного подхода. Есть что-то такое и в современных реализациях протокола TCP/IP на низком уровне, но я бы на это уже не полагался, да и на уровне приложения у тебя просто больше информации, да и больше возможностей для настройки.

dave ★★★★★
()
Ответ на: комментарий от anonymous

Да блин! Тут путаница в терминологии. Тут бы задать вопрос — если есть три человека с именем Михаил, то все ли три человека являются разными людьми или это один человек (имя-то одно и то же и принадлежат к виду Homo-легка-Sapiens!). В http/s да, есть некая сущность, именуемая keep-alive, по сути, она для того же что и keep-alive в tcp/ip. Но несмотря на схожесть названий и назначения, по уровням реализации это охеренно разные вещи.

Всё остальное, что сказать хотел, изложено выше. Я высказался.

anonymous
()
Ответ на: комментарий от dave

Всё будет зависеть от двух вещей.

Первая вещь это настройки сервера. Будет ли там включён keep-alive для tcp (и тогда нам не надо писать свой вариант в своём протоколе). Кроме того, в настройках tcp на хосте-сервере могут быть ещё модификации (те же tcp_wmem, tcp_rmem, время на ожидание закрытия сокета и т.д. и т.п., что важно именно для реализуемого самостоятельно протокола и именно для продакшона). Т.е., тут всё зависит от имеющихся в нашем распоряжении ресурсов сервера или серверов.

Вторая вещь это требования к клиенту. Как и писал выше, иной раз надо держать соединение (как следствие, тратить ресурсы и сервера и клиента на поддержание линка в актуальном состоянии), а иногда можно забить и забыть. Пульнул данные раз в сутки, получил команды раз в сутки и закрыл коннект на сутки. Смысл держать-то его, если он просто сутки будет простаивать?

Если, я добавлю, тюнинговать готовые http-сервера, то там тоже для протокола http/s не всё так просто. Если брать lighttpd, то согласно https://redmine.lighttpd.net/projects/1/wiki/Docs_Performance

Disabling keep-alive completely is the last resort if you are still short on file descriptors: ::
server.max-keep-alive-requests = 0

Т.е., клиентов гора, все хотят данные, но не все успевают их получить или отправить (т.н. slow connection clients, что было во времена GPRS просто атас для серваков), тогда да, keep-alive на уровне протокола лучше отрубить. Тем самым мы принудительно закрываем соединение и заставляем клиента для каждого документа открывать его заново. Мы избавляемся от непроизводительного расхода сокетов (файловых дескрипторов), когда они просто висят, но по ним трафика нет, например, сервер не успевает всех их обслужить.

В nginx почти так же:

# Timeout for keep-alive connections. Server will close connections after this time.
keepalive_timeout 30;
# Number of requests a client can make over the keep-alive connection.
keepalive_requests 1000;
# Allow the server to close the connection after a client stops responding.
reset_timedout_connection on;

Тогда, уж заодно, чтоб два раза не вставать (на keep-alive влияют, но косвенно):

# Send the client a «request timed out» if the body is not loaded by this time.
client_body_timeout 10;
# If the client stops reading data, free up the stale client connection after this much time.
send_timeout 2;
# Don't buffer data-sends (disable Nagle algorithm).
tcp_nodelay on;

В своём протоколе, если это не http/s, смотреть надо — использовать ли именно существующий в стеке механизм или реализовывать свой. Или вообще, для своего протокола даже и внимания на keep-alive не обращать из-за короткого времени жизни соединения. Persistent connection это вовсе не всегда благо.

anonymous
()
Ответ на: Всё будет зависеть от двух вещей. от anonymous

Согласен, что сильно зависит от ситуации. Я про те случаи, где важно наличие живого соединения, например, при передаче больших потоков смсок по протоколу SMPP, или там кластер какой, который не должен разваливаться на части.

dave ★★★★★
()
Ответ на: комментарий от monk

Я знаю. Я же написал, про ошибки при чтении и записи. Пусть висит соединение, и читать из него не нужно постоянно. Запоминаешь время последнего удачного чтения из данного сокета, а когда будет достигнут таймаут, просто рубить соединение. Т.е. решается проблема дизайном алгоритма, не нужно гонять постоянный траффик.

rumgot ★★★★★
()
Ответ на: комментарий от domik_v_derevne

Я бы не socks5, а socks4a рекомендовал.

Socks4a это без разрешения DNS-имени к которому обращаемся. В той же libcurl оно поддерживается на раз. Например,

CURL *curl = curl_easy_init();
if(curl) {
  CURLcode ret;
  curl_easy_setopt(curl, CURLOPT_URL, "https://какой.то.хост/");
  curl_easy_setopt(curl, CURLOPT_PROXY, "IP.нашего.прокси:порт");
  /* Внимание на последний параметр! */
  curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4A);
  ret = curl_easy_perform(curl);
  curl_easy_cleanup(curl);
}
Прокси сам должен будет разрешить имя в адрес и бросить на целевой сервер наш запрос. Именно по этой причине по дефолту в сети Tor и предлагается использовать не socks4, не socks5, а именно socks4a. См. настройки того же privoxy. Но это уже так, мелочи.

Единственное что добавлю, так это то, что прокси (в данном случае тор) может принимать соединения как локально, на том же хосте, так и удалённо, на сервере где-либо. Т.е., мы из сети поднимаем соединение через backconnect с тором не внутри сети, а именно снаружи сети. Ну а дальше всё уже просто. Могу сразу сказать что снилось мне что это работает. Хотя и оффтоп конечно по отношению к обсуждаемой теме. =) Прошу прощения.

anonymous
()
Ответ на: комментарий от dave

В SMPP да.

Абсолютно верно! Вообще, там очень сильно не любт когда логинами сервера дёргаются. И требование к наличию надёжного соединения, это одно из первых, если вообще не самое первое.

Да. Тут определяется протоколом и его реализацией.

anonymous
()
Ответ на: Я бы не socks5, а socks4a рекомендовал. от anonymous

Благодарю за предложение, вообще еще рассматривался вариант с туннелем ssh, но потом отбросил, по причине того что необходимо тянуть внешние либы для работы с этим протоколом, с соксом проще.

domik_v_derevne
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.