Компьютерные сети
В этой главе описан один из важнейших способов организации взаимодействия между процессами — т.н. сетевое взаимодействие (или взаимодействие по сети). В отличие от способов, рассмотренных в предыдущих главах (связь через стандартные потоки ввода-вывода или посредством файла), сетевое взаимодействие позволяет осуществлять коммуникацию между приложениями, запущенными на разных компьютерах под управлением разных ОС (или даже вообще без ОС).
Основные термины
Сетевое взаимодействие основывается на большом количестве стандартов, устанавливающих конкретные детали процедуры обмена сообщениями между приложениями. Эти стандарты называются сетевыми протоколами семейства TCP/IP (далее в этой главе — просто сетевыми протоколами).
Сетевые протоколы разделяются на четыре уровня (в скобках даны альтернативные названия):
- уровень приложений (прикладной уровень, application layer)
- уровень передачи (транспортный уровень, transport layer)
- уровень интернета (сетевой уровень, internet layer)
- уровень связи (канальный уровень, link layer)
Обычно при передаче сообщения по тому или иному каналу используются все 4 уровня:
- сама форма сообщения регламентируется протоколом уровня приложений
- способ доставки кодируется согласно протоколу уровня передачи, закодированная информация добавляется к сообщению (или к его частям, если оно слишком длинное)
- координаты устройства, на которое нужно доставить сообщение, задаются в соответствии с протоколом уровня интернета; эта информация добавляется к каждому из кусков, сформированных на уровне передачи (которые также могут разбиваться на более мелкие куски)
- информация, специфичная для каждого конкретного канала передачи, необходимая для доставки сообщения, регламентируется протоколами уровня связи
Типичные примеры сетевых протоколов:
- приложений: HTTP, FTP, SMTP, SSH
- передачи: TCP, UDP
- интернета: IPv4, IPv6
- связи: Ethernet, Wi-Fi, PPP
Далее в этой главе мы подробно обсудим только протоколы передачи и интернета. Связано это с тем, что протоколы связи — довольно узкоспециализированная область знаний, а наиболее распространённые протоколы приложений будут рассмотрены в следующей главе.
Протоколы интернета
На настоящий момент наиболее распространённым протоколом уровня интернета является IPv4 (по ряду причин IPv6 так и не получил широкого распространения). Поэтому далее будет рассмотрен именно IPv4 (а про IPv6 будет сказано совсем чуть-чуть).
Топология сетей
С точки зрения IPv4 компьютерная сеть представляет собой неориентированный граф, вершины которого соответствуют реальным или виртуальным компьютерам, а рёбра — каналам связи между ними. Концы рёбер этого графа называются сетевыми интерфейсами. Каждый сетевой интерфейс имеет 32-битный адрес, разделённый на две части: префикс и номер узла (host number). Длина префикса определяется суффиксом — числом от 0 до 32, означающем количество бит в префиксе. Традиционно IPv4-адреса записываются побайтово, каждый байт — в десятичной системе счисления. Сами значения байт разделяются точками. Суффикс приписывается справа через дробную черту.
Например, адрес
префикс номер узла
11000000101010000000 000111111110
обычно записывают как 192.168.1.254/20
. Есть ещё устаревший термин
маска подсети: маской подсети, соответствующей суффиксу s
, называется
адрес с суффиксом s
, у которого каждый двоичный разряд префикса равен 1,
а каждый двоичный разряд номера узла равен 0.
Например, суффиксу 20 соответствует маска подсети 255.255.240.0
(суффикс
в записи маски не указывается, поскольку он однозначно восстанавливается по
этой записи).
В каждой вершине компьютерной сети гарантируется наличие ребра-петли
(loopback interface) с адресом 127.0.0.1
(суффикс может быть произвольным).
Алгоритм маршрутизации
Каждое сообщение, передаваемое при помощи IPv4, наделяется IPv4-заголовком, который содержит как минимум следующую информацию: адрес назначения (destination address), обратный адрес (source address), время жизни (Time To Live). Эта информация определяет путь, по которому пойдёт сообщение. Адреса в IPv4-заголовке занимают ровно по 4 байта (соответственно, никакого суффикса не содержат и на части не делятся).
Большинство сетевого оборудования придерживается приблизительно следующего алгоритма (который выполняется сверху вниз до первого подходящего пункта):
-
Если сообщение пришло на какой-то интерфейс и адрес назначения в точности совпадает с адресом интерфейса, оно завершает свой путь (с него снимается IPv4-заголовок, после чего ОС обрабатывает содержимое сообщения в соответствии с одним из протоколов передачи).
-
Если TTL равен 0, сообщение уничтожается, а по обратному адресу отправляется служебное сообщение с соответствующей ошибкой. В противном случае TTL уменьшается на 1. Это необходимо для избежания циклических маршрутов.
-
Если сообщение родилось на устройстве, а адрес назначения совпадает с любым из адресов интерфейсов устройства, сообщение остаётся на этом же устройстве. В противном случае для сообщения, родившегося на устройстве, применяется один из следующих пунктов. При этом при отправке такого сообщения обратный адрес устанавливается равным адресу того интерфейса, по каналу которого сообщение было отправлено.
-
Если адрес назначения полностью совпадает с одним из адресов соседей (то есть адресов, назначенных противоположным концам рёбер, выходящих из текущей вершины), сообщение направляется по соответствующему каналу (произвольному, если кандидатов несколько).
-
Назовём адрес интерфейса хорошим, если его префикс полностью совпадает с началом адреса назначения. Среди всех интерфейсов, соответствующих текущей вершине и имеющих хороший адрес, выбирается интерфейс с самым длинным префиксом (произвольный, если кандидатов несколько). Сообщение направляется по соответствующему каналу.
-
Если интерфейсов с хорошим адресом нет, то сообщение отправляется в
«шлюз по-умолчанию» (default gateway). Отметим небольшую тонкость: при настройке сетевого оборудования default gateway задаётся не названием интерфейса, а IPv4-адресом соответствующего соседа.
Также некоторое сетевое оборудование поддерживает широковещание: если начало адреса назначения совпадает с префиксом интерфейса, с которого оно пришло, а оставшаяся часть адреса назначения имеет единицы во всех двоичных разрядах (или, для некоторой части оборудования, равна 0), сообщение отправляется по всем остальным интерфейсам с тем же префиксом, а также обрабатывается самим узлом.
Поясним всё это на примере. Пусть есть три компьютера А, Б, В, связанные треугольником рёбер. Сеть имеет следующие настройки
АБ: 192.168.1.3/24 -- 192.168.1.5/24
БВ: 192.168.2.1/24 -- 192.168.2.2/24
ВА: 192.168.2.2/16 -- 192.168.1.3/16
А: шлюз по-умолчанию 192.168.1.5
Б: шлюз по-умолчанию 192.168.1.3
В: шлюз по-умолчанию 192.168.1.3
Пусть компьютер А отправляет сообщение с адресом назначения 192.168.1.1
.
Этот адрес не является адресом какого-то из соседей (192.168.1.5
и 192.168.2.2
).
Для него есть два хороших кандидата: канал АБ
(совпадает префикс длины 24) и
канал АВ (совпадает префикс длины 16). Сообщение будет отправлено по каналу АБ
.
Поскольку 192.168.1.1
не совпадает с адресом 192.168.1.5
, который назначен
интерфейсу Б
ребра БА
, сообщение будет перенаправлено дальше.
Для него есть только один хороший кандидат в вершине Б
: это канал БА
с адресом соседа 192.168.1.3
и совпадающим префиксом длины 24. Туда и будет
отправлено сообщение.
Поскольку 192.168.1.1
не совпадает с адресом 192.168.1.3
, который назначен
интерфейсу А
ребра АБ
, сообщение будет перенаправлено дальше. Мы опять оказались
в первоначальной ситуации. Из этого делаем вывод, что такое сообщение
будет ходить между компьютерами А
и Б
до тех пор, пока не истечёт его время
жизни (TTL).
Рассмотрим другой пример. Пусть компьютер В
отправляет сообщение с
адресом назначения 192.168.1.5
. Этот адрес не является адресом
соседнего интерфейса, но совпадает по префиксу с адресом 192.168.1.3/16
.
Поэтому сообщение будет отправлено по каналу ВА
. Попав на компьютер А
,
сообщение будет передано на компьютер Б
, поскольку адрес назначения
полностью совпадает с адресом интерфейса Б
ребра АБ
.
Наконец, рассмотрим ситуацию, когда с компьютера А
уходит сообщение
на адрес 10.0.0.1
. Поскольку этот адрес не является адресом соседа и
не совпадает по префиксу ни с одним из интерфейсов компьютера А
,
сообщение будет отправлено в шлюз по-умолчанию, т.е. на компьютер Б
.
А оттуда по аналогичной причине оно будет отправлено обратно на компьютер А
(откуда опять отправится на Б
и т.д.).
В заключение отметим, что описанная выше модель сильно упрощена по сравению с тем, что бывает при работе с реальным сетевым оборудованием или программным обеспечением. Например, часто вообще запрещено давать один и тот же адрес разным интерфейсам одного устройства. Также не гарантируется возможность доступа с устройства на себя же по какому-либо из адресов его интерфейсов, кроме интерфейса-петли (хотя всё-таки здесь большая часть оборудования и ОС ведут себя единообразно и не пытаются отправить такие пакеты по сети). Поэтому при работе с реальным оборудованием рекомендуется в первую очередь ознакамливаться с документацией и примерами использования.
Зарезервированные адреса
Глобальная сеть интернет работает засчёт правильной организации перенаправления
сетевых пакетов. Оно устроено по принципу инвариантности узла назначения
относительно узла отправления: например, независимо от того, с какого
компьютера, подключённого к сети интернет, отправится сообщение с адресом
назначения 8.8.8.8
, это сообщение придёт на один и тот же компьютер.
К сожалению, из-за небольшого числа возможных IPv4-адресов (4 с небольшим
миллиарда) невозможно назначить уникальный IPv4-адрес для каждого устройства,
подключённого к интернету. Поэтому для организации многоуровневых сетевых
иерархий были выделены следующие диапазоны адресов:
- с
192.168.0.0
по192.168.255.255
- с
172.16.0.0
по172.31.255.255
- с
10.0.0.0
по10.255.255.255
Для этих адресов инвариантность относительно узла отправления не гарантируется, поэтому эти адреса могут быть использованы системными администраторами по своему усмотрению. Также есть ещё некоторое количество зарезервированных адресов, используемых для служебных целей.
Особенности IPv6
В процессе написания
Протоколы передачи
В процессе написания