Opened 4 years ago

Closed 4 years ago

#333 closed баг (fixed)

Не синхронизируется время после смены IP адреса

Reported by: AlexLir Owned by: alx
Priority: средний Milestone: 2 очередь
Component: VE-02 Keywords:
Cc:

Description

Провел два эксперимента с блоком MC04-DSL-VIP r1632.

Эксперимент 1:

  1. Подал питание
  2. Через пару минут время блока было синхронизировано (проверял командой date)

Эксперимент 2:

  1. Подал питание
  2. Сразу же после загрузки сменил Ip-адрес блока на соседний(из той же подсети)
  3. Время блока не было синхронизировано в течении продолжительного времени (ждал полчаса)

Повторил эксперименты несколько раз, воспроизводимость 100%.

Change History (6)

comment:1 by alx, 4 years ago

Не могу воспроизвести эксперимент 2.

Проблема в том, что с момента установки сетевому интерфейсу IP адреса до момента установки системным часам текущего времени проходит мене 2 секунд. За столь короткое время я никак не успеваю аутентифицироваться и войти в веб-интерфейс, изменить там IP адрес и нажать "Применить". На тот момент, когда я нажимаю "Применить", в системных часах уже правильное текущее время (в терминах описания тикета "время уже синхронизировано"). Повторил эксперимент несколько раз - ни разу не успел сменить адрес...

comment:2 by alx, 4 years ago

Немного модифицировал эксперимент 2:

  1. Снимаю питание.
  2. Отключаю блок от локальной сети.
  3. Подключаю консоль к интерфейсу RS-232.
  4. Подаю питание.
  5. Через консоль, наблюдая вывод в лог, жду когда установится адрес IP и сетевом интерфейсе.
  6. Командой ifconfig eth0 ... изменяю IP адрес.
  7. Подключаю ethermet.

После подключения ethernet вижу, что время остается 1 января.

comment:3 by alx, 4 years ago

Как показали наблюдения, после модифицированного эксперимента 2 ntpclient не посылает в сеть запросов к серверу. Если затем адрес интерфейса вернуть в исходное значение, ntpclient начинает отправлять запросы серверу, получает ответ и устанавливает время.

comment:4 by alx, 4 years ago

Как показал анализ кода ntpclient, он работает следующим образом:

  1. создает UDP сокет
  2. выполняет bind() на адрес INADDR_ANY (то есть принимает пакеты на любой локальный адрес)
  3. выполняет connect() на адрес сервера (принимает пакеты только от адреса указанного сервера)
  4. затем в бесконечном цикле посылает и принимает пакеты.

В такой схеме я вижу сразу несколько проблем:

  • Вызов connect() устанавливает сокету не только адрес удаленного хоста, но и локальный адрес:
    root@comcerto:/# netstat -unp
    Active Internet connections (w/o servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    udp        0      0 192.168.0.207:32768     192.168.0.13:123        ESTABLISHED 488/ntpclient
    
  • ресолвинг имени хоста выполняется только один раз: если в какой-то момент сервер изменит свой адрес IP, ntpclient будет продолжать обращаться к старому адресу.
  • при изменении локального адреса ядро перестает передавать, при этом успешность завершения send() ntpclient не проверяет (если бы он, например, аварийно завершился из-за неуспешности send(), его бы просто запустили заново, и проблемы бы не было!)

В качестве эксперимента внес в рабочий цикл перед каждой отправкой запроса серверу полное пересоздание сокета: старый закрываем, новый создаем и повторно выполняем ресолвинг, bind() и connect(). После этого ntpclient начал нормально переживать смену локального адреса: модифицированный эксперимент 2 больше не воспроизводит проблему.

comment:5 by alx, 4 years ago

А еще я сейчас обнаружил, что ntpclient поддерживает только протокол IPv4...

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

comment:6 by alx, 4 years ago

Resolution: fixed
Status: newclosed

In 1691/sip_ua:

Добавлен патч ntpclient, позволяющий ему переживать изменение локального адреса. Closes #333.

Note: See TracTickets for help on using tickets.