Jump to content
Калькуляторы

bind 9.6-esv-r1: UDP/IPv4 socket bind failures кто-нибудь знает что на самом деле означает этот счётчик?

Делаю rndc stats, наблюдаю в статистике счётчик "UDP/IPv4 socket bind failures", хотелось бы знать что он значит, в документации http://www.isc.org/files/arm96.html#statistics_counters написано "Failures of binding sockets.", но не очень ясно что же это такое - проблема внутри сервера или не может до куда-то достучаться? может ли быть такая фигня из-за того, что на интерфейсе сервера нет IPv6 адреса, а собран он с поддержкой IPv6?

Share this post


Link to post
Share on other sites

Проблема с привязкой сокета к интерфейсу.

Поищите по исходникам - быстрее и понятнее будет когда возникает.

Share this post


Link to post
Share on other sites

До исходников я ещё доберусь...

Дело в том, что сам-то бинд нормально работает, но этот счётчик понемножечку прибавляется. У кого версия >=9.5, гляньте пожалуйста, может быть не только у меня он прибавляется.

Share this post


Link to post
Share on other sites

На вскидку предположу.

Когда бинд создаёт сокет для отправки запроса и потом посылает запрос, то сокет автоматом биндится, чтобы принять ответ и чтобы получить номер порта в принципе.

Когда пул сокетов не постоянный - те они убиваются после разового использования, то ещё некоторое время система держит их и не отдаёт.

При большой интенсивности у системы не останется свободных портов и она вместо привязки будет возвращать ошибку.

Share this post


Link to post
Share on other sites

Добавил в limits.conf

*       soft    nofile  32768
*       hard    nofile  65534

 

не помогает :(

 

примерно за день набирается такая статистика:

 

++ Socket I/O Statistics ++
            28709590 UDP/IPv4 sockets opened
                   1 UDP/IPv6 sockets opened
               31270 TCP/IPv4 sockets opened
            28709462 UDP/IPv4 sockets closed
                   1 UDP/IPv6 sockets closed
               46540 TCP/IPv4 sockets closed
               77617 UDP/IPv4 socket bind failures
                 743 TCP/IPv4 socket connect failures
            28631771 UDP/IPv4 connections established
                1014 TCP/IPv4 connections established
               15278 TCP/IPv4 connections accepted
                   2 UDP/IPv6 send errors
                   1 TCP/IPv4 send errors
               78302 UDP/IPv4 recv errors
                  10 TCP/IPv4 recv errors
++ Per Zone Query Statistics ++

 

может есть у кого ещё идеи?

 

значение `netstat -ntu | wc -l` прыгает в интервале 100-300, вроде бы не так уж и много

 

Исходники у бинда не самые красивые, но судя по всему счётчик увеличивается в этом куске кода:

isc_result_t
isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
                unsigned int options) {
        char strbuf[ISC_STRERRORSIZE];
        int on = 1;

        LOCK(&sock->lock);

        INSIST(!sock->bound);

        if (sock->pf != sockaddr->type.sa.sa_family) {
                UNLOCK(&sock->lock);
                return (ISC_R_FAMILYMISMATCH);
        }
        /*
         * Only set SO_REUSEADDR when we want a specific port.
         */
#ifdef AF_UNIX
        if (sock->pf == AF_UNIX)
                goto bind_socket;
#endif
        if ((options & ISC_SOCKET_REUSEADDRESS) != 0 &&
            isc_sockaddr_getport(sockaddr) != (in_port_t)0 &&
            setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
                       sizeof(on)) < 0) {
                UNEXPECTED_ERROR(__FILE__, __LINE__,
                                 "setsockopt(%d) %s", sock->fd,
                                 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
                                                ISC_MSG_FAILED, "failed"));
                /* Press on... */
        }
#ifdef AF_UNIX
bind_socket:
#endif
        if (bind(sock->fd, &sockaddr->type.sa, sockaddr->length) < 0) {
                inc_stats(sock->manager->stats,
                          sock->statsindex[STATID_BINDFAIL]);

                UNLOCK(&sock->lock);
                switch (errno) {
                case EACCES:
                        return (ISC_R_NOPERM);
                case EADDRNOTAVAIL:
                        return (ISC_R_ADDRNOTAVAIL);
                case EADDRINUSE:
                        return (ISC_R_ADDRINUSE);
                case EINVAL:
                        return (ISC_R_BOUND);
                default:
                        isc__strerror(errno, strbuf, sizeof(strbuf));
                        UNEXPECTED_ERROR(__FILE__, __LINE__, "bind: %s",
                                         strbuf);
                        return (ISC_R_UNEXPECTED);
                }
        }

        socket_log(sock, sockaddr, TRACE,
                   isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_BOUND, "bound");
        sock->bound = 1;

        UNLOCK(&sock->lock);
        return (ISC_R_SUCCESS);
}

 

(функция inc_stats)

 

bind конфигурился таким образом: STD_CDEFINES='-DISC_SOCKET_MAXEVENTS=256' ./configure --enable-largefile --enable-ipv6 --enable-epoll --enable-threads

 

 

Share this post


Link to post
Share on other sites

Нарисовал график, получается 0-3 фейла в секунду, но вот всё никак не пойму природу этого явления :(

ns2newudp4bindfailday.png

 

Edited by s.lobanov

Share this post


Link to post
Share on other sites

isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__, "bind: %s",strbuf);

 

вставить между

 UNLOCK(&sock->lock);
                switch (errno) {

посмотреть в логах ошибку

скорее всего будет EADDRINUSE

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

Share this post


Link to post
Share on other sites

Сысоев пишет про фряху, а у меня linux. Попробую вставить эту пару строк, посмотрим что выйдет

Share this post


Link to post
Share on other sites

А у меня винда %), это ничего не меняет, кроме названия параметра и места его нахождения - ищите аналог.

Share this post


Link to post
Share on other sites

Действительно, после вставки указанного дебуга, появляется в логах ошибка address in use:

 

named[20545]: socket.c:4692: unexpected error:

named[20545]: bind666: Address already in use

 

буду думать что с этим делать...

Share this post


Link to post
Share on other sites

nuclearcat

Не помогает.

 

У меня тут возникло подозрение, что, возможно, разные потоки бинда пытаются использовать один и тот же порт для исходящего "соединения"(дело в том, что номер исходящего порта бинд генерирует сам(т.к. судя по netstat -ntu они не все попадают в диапазон net.ipv4.ip_local_port_range=32768 61000)).

Share this post


Link to post
Share on other sites
Попробуйте

 

sysctl -w net.ipv4.tcp_orphan_retries=1

У него там UDP.

 

 

номер исходящего порта бинд генерирует сам
Тогда ищите в настройках бинда.

Но я бы в sysctl поискал в начале настройки таймаутов, msl что ли.

 

Share this post


Link to post
Share on other sites
номер исходящего порта бинд генерирует сам
Тогда ищите в настройках бинда.

Но я бы в sysctl поискал в начале настройки таймаутов, msl что ли.

Ну есть настройка по диапозону используемых портов для исходящих запросов, если ничего не указано, то он и использует с 1024-65535, но не ясно чем она может помочь.

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this