Данный пример повторяет случай из реальной жизни, когда проблема решилась при помощи анализа протокола. Суть проблемы: время от времени происходил сбой в работе ftp со следующим сообщением об ошибке:
netout: Option not supported by protocol 421 Service not available, remote server has closed connection
О проблеме заявил только один пользователь, и он сталкивался с ней только при передаче больших файлов с рабочей станции на центральную машину по нашей магистральной сети.
Мы взяли файл данных пользователя и смогли воспроизвести проблему с других рабочих станций. При этом проблема возникала только при передаче файла на ту же центральную систему по магистральной сети. Рисунок 13.4 наглядно отражает тесты, которые мы выполнили для воспроизведения проблемы.
Рис. 13.4. Резюме теста FTP
Мы уведомили о проблеме всех пользователей. В ответ мы получили сообщения, что и другие пользователи сталкивались с проблемой, но опять же - только при передаче данных на центральную систему и только при передаче по магистрали. Другие пользователи не сообщали о проблеме, поскольку редко сталкивались с ней. Эти дополнительные сообщения свидетельствовали в пользу того, что проблема не связана с последними изменениями в сети.
Поскольку мы воспроизвели проблему на других системах, вероятнее всего, ее причина не в неверных настройках системы пользователя. Кроме того, сбой ftp происходил только в случаях, когда взаимодействовали маршрутизаторы магистральной сети и центральная система. Поэтому мы сосредоточили внимание на этих машинах. Мы проверили таблицы маршрутизации и таблицы ARP, а также выполнили прозвонку центральной системы и маршрутизатораов. И не столкнулись ни с какими проблемами.
На основе предварительных данных можно было предположить, что сбой ftp происходил в результате некой проблемы взаимодействия маршрутизаторов определенной фирмы и центрального компьютера. Мы сделали такое предположение потому, что передача данных устойчиво прерывалась только при взаимодействии этих двух видов систем, но никогда - в других ситуациях.
Если неверны настройки маршрутизатора или центральной системы, сбой должен возникать и при передаче данных на другие узлы. Если проблема связана со случайными сбоями физического характера, она должна возникать время от времени и не зависеть от того, какие узлы участвуют в процессе. Проблема же, напротив, поддавалась прогнозированию и возникала только при взаимодействии машин определенных типов. Возможно, дело было в несовместимости реализаций TCP/IP этих систем.
Поэтому мы воспользовались snoop и перехватили заголовки TCP/IP в ходе нескольких сеансов тестирования ftp. Изучение результатов показало, что во всех сеансах, заканчивающихся сообщением об ошибке «netout», ближе к концу сеанса присутствовал пакет ICMP Parameter Error - обычно за 50 пакетов до окончания передачи. Ни в одном успешном сеансе передачи такого пакета не было. Обратите внимание, что ошибка возникала вовсе не на последнем пакете потока данных, как можно было бы предположить. Часто бывает так, что после обнаружения ошибки поток данных остается открытым какоето время до разрыва соединения. Не следует считать, что ошибка всегда присутствует в конце потока данных.
Вот заголовки из ключевых пакетов. Сначала IP-заголовок пакета от магистрального маршрутизатора, который привел к созданию сообщения об ошибке на центральной системе:
ETHER: ..... Ether Header ----- ETHER: ETHER: Packet 1 arrived at 16:56:36.39 ETHER: Packet size = 60 bytes ETHER: Destination =8:0:25:30:6:51, CDC ETHER: Source = 0:0:93:e0:a0:bf, Proteon ETHER: Ethertype = 0800 (IP) ETHER: IP: -----IP Header----- IP: IP: Version = 4 IP: Header length = 20 bytes IP: Type of service = 0x00 IP: xxx.....=0 (precedence) IP: ...0 ____ = normal delay IP: ____ 0... = normal throughput IP: .....0.. = normal reliability IP: Total length = 552 bytes IP: Identification = 8a22 IP: Flags = 0x0 IP: .0......= may fragment IP: ..0.....= last fragment IP: Fragment offset = 0 bytes IP: Time to live = 57 seconds/hops IP: Protocol = 6 (TCP) IP: Header checksum = ffff IP: Source address = 172.16.55.106, fs.wrotethebook.com IP: Destination address = 172.16.51.252, bnos.wrotethebook.com IP: No options IP:
А вот пакет ICMP Parameter Error, отправленный центральной системой в ответ:
ETHER: ----- Ether Header ..... ETHER: ETHER: Packet 3 arrived at 16:56:57.90 ETHER: Packet size = 98 bytes ETHER: Destination = 0:0:93:e0:a0:bf, Proteon ETHER: Source = 8:0:25:30:6:51, CDC ETHER: Ethertype = 0800 (IP) ETHER: IP: .....IP Header..... IP: IP: Version = 4 IP: Header length = 20 bytes IP: Type of service = 0x00 IP: xxx. .... =0 (precedence) IP: ...0 ____ = normal delay IP: ____ 0... = normal throughput IP: .....0.. = normal reliability IP: Total length = 56 bytes IP: Identification = 000c IP: Flags = 0x0 IP: .0......= may fragment IP: ..0.....= last fragment IP: Fragment offset = 0 bytes IP: Time to live = 59 seconds/hops IP: Protocol = 1 (ICMP) IP: Header checksum = 8a0b IP: Source address = 172.16.51.252, bnos.wrotethebook.com IP: Destination address = 172.16.55.106, fs.wrotethebook.com IP: No options IP: ICMP: ..... ICMP Header ..... ICMP: ICMP: Type = 12 (Parameter problem) ICMP: Code = 0 ICMP: Checksum = 0d9f ICMP: Pointer = 10
Каждый из заголовков поделен на биты и связан с соответствующими полями заголовка TCP/IP. Из этого подробного анализа каждого пакета мы можем видеть, что маршрутизатор передал параметр IP Header Checksum (контрольная сумма заголовка IP) со значением Oxffff, и центральной системе контрольная сумма не понравилась. Нам известно, что центральная система среагировала именно на этот параметр, поскольку она вернула ошибку ICMP Parameter Error и указатель (Pointer) со значением 10. Parameter Error указывает на некорректность только что полученных данных, a Pointer указывает на данные, которые система полагает ошибочными. Десятый байт в заголовке IP-пакета маршрутизатора - поле IP Header Checksum. Поле данных сообщения об ошибке ICMP содержит заголовок, который считается ошибочным. При просмотре этих данных мы заметили, что, возвращая заголовок, центральная система «скорректировала» поле контрольной суммы и записала в него значение 0000. Очевидно, центральная система не согласна с вычисленной маршрутизатором контрольной суммой.
Время от времени ошибки с вычислением контрольной суммы происходят. Они могут быть вызваны проблемами передачи и необходимы для выявления подобного рода проблем. В каждом семействе протоколов существует механизм для восстановления после ошибок в контрольной сумме. Как они могут обрабатываться в TCP/IP?
Чтобы определить действие протокола, корректное в данной ситуации, мы обратились к авторитетным источникам - документам RFC. RFC 791, Internet Protocol, снабдил нас информацией о вычислении контрольной суммы, но лучшим источником для данной конкретной проблемы стал документ RFC 1122 , Requirements for Internet Hosts - Communication Layers (Требования к узлам сети Интернет - уровни передачи данных), за авторством Р. Брейдена (R. Braden). Этот документ содержит две отсылки к действиям, которые должны быть предприняты. Следующие выдержки взяты со стра- ницы 29 документа RFC 1122:
В нижеследующем тексте в определенных случаях в отношении полученной дейтаграммы используется выражение «молча удалить». Это означает, что дейтаграмма удаляется без дополнительной обработки, а узел не посылает какие-либо ICMP-сообщения об ошибках (см. раздел 3.2.2) в результате... ...Узел ОБЯЗАН проверять правильность контрольной суммы заголовка IP для каждой полученной дейтаграммы и молча удалять все дейтаграммы с невер- ными контрольными суммами.
Следовательно, получив пакет с неверной контрольной суммой, система не должна ничего с ним делать. Пакет следует удалить, а затем ожидать поступления следующего пакета. Система не должна отвечать сообщением об ошибке. Система не может ответить на неверную контрольную сумму 1Р-заголовка, поскольку не может определить, откуда в действительности поступил пакет. Если под сомнением контрольная сумма заголовка, как определить, что верны адреса в заголовке? А если нет уверенности относительно источника пакета, как можно на него ответить?
IP полагается на протоколы верхних уровней в восстановлении после таких ошибок. Если используется TCP (как было в данном случае), источник TCP в конечном итоге замечает, что получатель не подтвердил доставку сегмента, и посылает сегмент заново. Если используется UDP, приложение-источник отвечает за восстановление после ошибки. Ни в том ни в другом случае восстановление не зависит от сообщения об ошибке, генерируемого получателем. Итак, получив неверную контрольную сумму, центральная система должна была просто удалить испорченный пакет. Мы уведомили о проблеме разработчиков, и, следует отметить, они прислали нам поправку к программному обеспечению в пределах двух недель. Более того, поправка замечательно работала!
Не все проблемы разрешаются так же прямолинейно. Однако методика анализа не зависит от того, какова проблема.