Linux - сбой соединения TCP () с ETIMEDOUT - PullRequest
4 голосов
/ 12 декабря 2011

Для TCP-клиента connect () вызывает TCP-сервер.

Книга сетевого программирования UNIX® Ричарда Стивенса гласит следующее.

Если клиентский TCP не получает ответа на свой сегмент SYN, возвращается ETIMEDOUT. 4.4BSD, например, отправляет один SYN при вызове connect, еще через 6 секунд и другой 24 секунды спустя (стр. 828 из TCPv2). Если по истечении 75 секунд ответа не получено, ошибка возвращается.

В Linux я хотел бы знать, что такое механизм повторных попыток (сколько раз и как далеко друг от друга). Запрашиваемая, потому что для TCP-клиента connect () я получаю ошибку ETIMEDOUT. Этот сокет имеет опцию O_NONBLOCK и отслеживается epoll () для событий.

Если кто-то может указать мне, где в коде реализована эта логика повторения, это тоже будет полезно. Я попытался следовать немного, начиная с tcp_v4_connect () из net / ipv4 / tcp_ipv4.c, но довольно скоро потерял свой путь ..

Ответы [ 2 ]

8 голосов
/ 12 декабря 2011

Время ожидания масштабируется на основе измеренного времени прохождения сигнала туда и обратно.

tcp_connect() устанавливает таймер:

    /* Timer for repeating the SYN until an answer. */
    inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
                              inet_csk(sk)->icsk_rto, TCP_RTO_MAX);

icsk_rto будет использовать для каждого пункта назначения тайм-аут повторной передачи ; если предыдущие показатели из пункта назначения доступны из предыдущих подключений, они используются повторно. (Подробнее см. Обсуждение tcp_no_metrics_save в tcp(7).) Если метрики не сохранены, ядро ​​вернется к значению RTO по умолчанию:

#define TCP_RTO_MAX     ((unsigned)(120*HZ))
#define TCP_RTO_MIN     ((unsigned)(HZ/5))
#define TCP_TIMEOUT_INIT ((unsigned)(1*HZ))     /* RFC2988bis initial RTO value */
#define TCP_TIMEOUT_FALLBACK ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value, now
                                                 * used as a fallback RTO for the
                                                 * initial data transmission if no
                                                 * valid RTT sample has been acquired,
                                                 * most likely due to retrans in 3WHS.
                                                 */

tcp_retransmit_timer() имеет некоторый код в нижней части для пересчета задержки:

    inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
    if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0, 0))
            __sk_dst_reset(sk);

retransmits_timed_out() сначала выполняет линейный откат, а затем экспоненциальный откат.

Я думаю, что в общем и целом, вы можете ожидать приблизительно 120 секунд, прежде чем получите ETIMEDOUT ошибку, возвращаемую из connect(2), если только у ядра нет веских оснований подозревать, что удаленный узел должен ответить раньше. 1024 *

4 голосов
/ 12 декабря 2011

Типичная причина для ETIMEOUT - брандмауэр, который просто глотает пакеты, а не отвечает с помощью ICMP Destination Unreachable .

Это обычная настройка, которая не позволяет хакерам проверять сеть на наличие хостов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...