Транспортный уровень решает три задачи. Целостность и надежность и работа с потоками данных.

Давайте представим, какой объем задач надо решать на этом уровне.

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

Какой объем задач хотелось бы решать.

Целостность

Первый пункт -- хорошо бы убедиться что то, что мы отправли это то, что мы приняли -- Целостность.

Обратите внимание, что у нас данные фрашгментированы. Мы нарезаем пользовательске данные на куски и ими обмениваемся. Сами куски отлично доезжают, но, данное которое мы передавали больше одного куска. Важно, чтоб ы мы вели учет кусков, отслеживали ситуацию когда этих кусков больше чем нужно или меньше чем нужно. И мы должны проверить что отправленные пакеты пришли в правильном порядке. Точнее, нам неважно как они пришли, лишь бы мы их могли переупорядочить в правильном порядке. Нумерация и учет дело транспортного протокола.

Сам объект может быть бесконечного размера (интернет радио) поэтому в произвольном порядке куски посылать нельзя.

Накладывается ограничение -- пакеты нумеруются и прийти они должны в правильном порядке. Если 4-ый пришел до 3-го, то 4-ый мы не принимаем.

Заботиться об этой последовательности имеет смысл только если данные разблись на несколько пакетов.

Фактически порядок пакетов и их умножение, пропадание и так далее надо контролировать только если их больше одного.

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

Управление процессом передачи

Было бы недурно проверить, идет ли передача. Существует ли получатель. Как ни смешно, это отдельный момент сетевых протоколов, который есть далеко не во всех протоколах. В терминах тцп это называется установление соединения.

Еще было бы неплохо принимать от абонента подтверждение о доставке, а также об ошибке, а также, например о том, что пакет зажевали посередине.

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

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

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

Еще один пункт -- управление пропускной способностью и параметрами потока.

Помните пример, когда с одноой стороны хороший интернет, а с другой плохой. Вливает фильм со скоростью мегабит, а с с другой стороны адсл с 160 килобит.

Регулировка параметров канала

На основании наблюдений делаем неправильный вывод, что ситуаций всего две -- когда пакет один, нам ничего не нужно, и когда есть поток, то нам нужно все.

Два представления данных на Транспортном уровне -- поток и датаграмма.

Выглядит довольно очевидным, что либо все есть, либо нет. Наконец, последняя группа задач, которую надо решать --

Идентификация потоков данных (или датаграмм)

Мы уже решали этот вопрос, как в том анекдоте, когда бизнесмен торговал секундными стрелками и повидлом по смешной цене, потому что они в одном вагоне ехали и перемешались. У нас недостаточно информации на сетевом уровне чтобы различить несколько потоков данных, у которых отправитель и получатель совпадают. зашли на вебсервер, там хтмл и картинки, и то и другое вы скачиваете с одного ип адреса надругой п адрес, как сделать чтобы это были разные потоки данных?

адрес отправителя, адрес получателя и что-то езё, уникально идентифицирующее поток данных.

Недолго думая разработчики тцп/ип придумали такую штуку как порт. Порт отправителя и порт получателя. Слово возникло по аналогии с хардвар терминологии --- последовательный порт, параллельный порт и так далее. Как когда вы пишите программу на ассемблере у вас есть ин и аут и специальный адрес, куда ин и куда аут. Так и здесь -- две дыры, помимо того, что они расположены на каких-то ип-адресах, эти дырки адресуются портами п1 и п2. Такая четверка уникально идентифицирует поток.

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

Самое простое -- за каждым протоколом прикладным закрепить номер порта, и по этому порту будет слушать соответствующее приложение, если оно на этой маршрутизациишине запущено. Если не запущено, то транспортный протокол скажет, что никто на этом порту не слушает. Есть файл /etc/services в котором прописаны цифровые значения портов и наименования назначений.

Порт, по которому осуществляется соединение по протоколу прикладного уровня заранее зарегистрирован.

Вы можете повесить хттп на 25 порт, но непонятно чего вы этим добьетесь.

Отклоняться от этих рекомендаций не рекомендуется. Но, налицо некоторая проблема.

Если мы зашли н вебсервер, то у нас 3 числа из 4 фиксированы. Значит, для каждого сеанса передачи данных ос должна выбрать порт отправителя, так чтобы поток данных стал уникальным. Под это зарезервированы порты от 32768 от 65535.

Как следствие получается что процесс этот строго ассиметричен. Всегда есть клиент, который инициирует соединение и сервер, который его принимает. Те, кто писал практикум на втором курсе про это помнят.

Немного про TCP

Как происходит установление соединения?

У нас есть клиент, есть сервер. Клиент это тот, кто инициирует соединения. Данные при этом могут передавться на сервер, сервер может пользоваться сервисами клиента, итп. То есть, это не вопрос кто большая машина, а кто маленькая.

Обращаю ваше внимание что тцп соединение двунаправленное, устанавливаются сразу два потока данных. Их содержимое друг от друга независимо.

Сразу договримся, что поток данных в одну сторону будет иметь номер один, а в другую номер два.

C - SYN1 -> S
C <- ACK1 + SYN3 - S
C - ACK2 + DATA1 -> S

Пакетами ак-дата они и продолжают обмениваться пока кому-то это не надоедает и он не решает закрыть соединение.

c - ACK2 + FIN1 -> S
C <- ACK1+FIN2 - S
C - ACK2 -> S

Что из этого видно? Если этот оверхед становится большим, надо переходить на UDP.

В этой последовательности есть одна дырка, из-за которой злоумышленник может заставить сервер выделить очень много памяти. Если послать серверу бесконечно много SYN, то на каждый раз сервер заведет буфер под тцп соединение. Это называется SYN flood атака. Борятся с этим обычно межсетевыми экранами.

SeqN генерируется слуайно в первый раз, но затем к нему прибавляется размер переданных данных. Если абонент получил пакет 5, а в нем данных меньше, чем SeqN - Seq(N-1), то пакет 4 он не получил.

В материалах есть неплохая демонструшка на флеше, одна про обработку ошибок, другая про увеличение размера окна.

У этого процесса есть одно тонкое место. Оно связано с ситуацией качества среды. Что, если у нас годный канал и ошибки встречаются редко? Тогда полная синхронизация нам мешает. Еще больше мы начинаем страдать от ситуации, когда наблюдаемые канал хороший, а перемешивание пакетов сильное -- провайдер разбрасывает пакеты по разным каналам. И мы не сможем послать новый пакет пока не получим старый.

В ситуации, когда мы можем параллельно послать несколько пакетов и они дойдут в неправильном порядке, хочется синхронизировать не после каждого пакета, а окнами по несколько пакетов.

При старте у нас размер окна один пакет. Если размер подошел, то он увеличивается в два раза. И так далее, пока не произойдёт ошибки. При ошибке размер схлопывается в минимальный. Получатель так же анонсирует совй максимальный размер окна, больше которого мы его увеличить не пытаемся.

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

UDP

Первое свойство -- весь сеанс обмена данных это одна датаграмма. Именно в этом случае использовать удп выгодно. еще его выгодно использовать когда у вас очень хорший канал связи, то есть операция по обработке ошибок на прикладном уровне возникает крайне редко, а объемы данных настолько велики, что ни одно тцп соединение по человечески с таким соединением не справится.Типичный пример -- файловые системы, например NFS.

Еще одно важное свойство -- отсутвтие траффика в обратную сторону. Предположим вы передаете данных миллиону абонентов. Если это тцп вы получаете миллион потоков с потверждениями. Это слегка нагружает вашу сеть. Если вам эти подтверждения не очень интересны, то UDP это ваш выбор.

Третье свойство udp -- его можно использовать для мультикаст вещания.

Примеры использования udp в реаллайфе:

  1. NFS. Там, на самом деле не так просто. Это stateless протокол. На уровне приложения никогда не отслежваются состояния потока. Просто идут запросы.
  2. DNS.
  3. SNMP, NTP
  4. traceroute
  5. RNTP, протоколы вещания видео в сетях.

NAT

Из каких соображений мы сделаем подстановку внутреннего адреса? Подменяется не только ip адрес, но и порт. И мы можем запомнить, что тцп соединения с нашего порта 40000 идет с такого-то хоста, а 40001 с другого.

Вопрос на разминку. Если это DNS запрос, он может пройти чере трансляцию сетевых адресов. Как вообще устроен днс запрос -- отсылаем датаграмму серверу. Как поймем, что сервер ответил именно нам? У днс запроса есть на прикладном уровне уникальный идентификатор.

FTP

Очень остроумный протокол, который хорошо работал, когда интернета было мало и он был безопасен.

Работает он так. У вас есть 21 порт, управляющий. Клиент присоединяется к серверу и спрашивает что есть. Сервер рассказывает. Клиент говорит "хочу файл, пожалуйста, передай его мне на такой-то порт". После этого сервер инициирует соединение клиенту на порт порт.

Как этому пройти через NAT? Проковыривать дырочки, отслеживая на сервере получения команд о передаче файла и его пробрасывать. Тем паче, что соединение с любой внутренней машиной на проивзольный порт обычно не практикуется.

После некоторого раздумия придумали passive FTP. В нем подключение происходит только от клиента к серверу. Сервер говорит клиенту, на какой из его портов клиент должен подключитсья чтобы взять файл.

По этой причине протокол фтп стремительно устаревает. Кроме того у него есть главна проблема -- клиент и сервер передают пару ип-порт. А если они за натом, то все это нужно по ходу модифицировать, и упражнений там существенно больше чем толку.

Прочее

DCCP -- можно использовать как разделение udp трафика на разные потоки.

Или же типичный пример про хтмл и картинки. В случае тцп устанавливаете много тцп соединений, но тогда возможен син флуд. Это правда можно избежать сделав авторизацю четырехуровневый, включив генерацию ключика.

Как контролируется забитие интернета траффиком? Сбрасыванием окна. Никому не кажется странным, что с забитием боремся увелиением количества трафика?

ecn -- early connection notification. Если сервер видит, что скоро заткнется, он заранее начинает рассылать предупреждения, что мол схлопывайте ваши окна прямо сейчас, или уменьшайте их размер.

rspp -- я собираюсь передавать данные, мне нужно не меньше мегабита, есть? Работает только в ипв6.

LecturesCMC/LinuxNetwork2013/Conspects/06 (последним исправлял пользователь Allena 2013-11-16 14:01:49)