Короче говоря: в Linux, как я могу убедиться, что ACK-сообщение получено для определенного TCP-пакета?
Полная история:
Я отлаживаю проблему Asterisk / OpenH323 <-> Panasonic IP-GW16.
Соединение H323 включает два сеанса: H225.0 и H245. Это всего два сеанса TCP, по которым передаются некоторые данные.
Давайте назовем их Session 1
(для H225.0) и Session 2
(для H245).
Session 1
имеет хорошо известный номер TCP-порта 1720, в то время как порт для Session 2
выбирается во время выполнения.
Управление потоком происходит следующим образом:
- Panasonic вызывает Asterisk: он открывает
Session 1
(TCP / 1720) для Asterisk и отправляет сообщение SETUP через Session 1
, которое содержит port 2
, которое Panasonic будет слушать.
- Asterisk отправляет Panasonic сообщение о вызове через
Session 1
- Panasonic начинает слушать на
port 2
- Panasonic отправляет TCP ACK через
Session 1
.
- Asterisk открывает TCP
Session 2
на port 2
.
Порядок шагов 2 и 3 важен: Panasonic не будет слушать port 2
, пока не получит сообщение CALL PROCEEDING на step 2
.
Но в коде OpenH323 step 2
и step 5
находятся всего в нескольких строках.
Именно поэтому соединение sometimes
работает в режиме отладки, а quite never
работает в выпуске.
Это хорошо видно по дампу пакета. Я провел серию экспериментов, и в 52 случаях из 52, если step 5
идет до step 4
, соединение не устанавливается; если нет, соединение установится успешно.
Нет никаких других сообщений от Panasonic, кроме того, что ACK в step 4
, и кажется, что Asterisk может узнать, что прослушивается port 2
, только получение этого ACK.
Конечно, я могу реализовать временное ожидание, но я хочу более чистое решение.
Итак, вопрос повторяется: после отправки сообщения по TCP-соединению в step 2
, как узнать, получен ли ACK для пакета, содержащего сообщение?