2025-Курс БКС-ВМК-весна-Лекция-6.pdf$hello

jimmmm1 10 views 116 slides Sep 08, 2025
Slide 1
Slide 1 of 116
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46
Slide 47
47
Slide 48
48
Slide 49
49
Slide 50
50
Slide 51
51
Slide 52
52
Slide 53
53
Slide 54
54
Slide 55
55
Slide 56
56
Slide 57
57
Slide 58
58
Slide 59
59
Slide 60
60
Slide 61
61
Slide 62
62
Slide 63
63
Slide 64
64
Slide 65
65
Slide 66
66
Slide 67
67
Slide 68
68
Slide 69
69
Slide 70
70
Slide 71
71
Slide 72
72
Slide 73
73
Slide 74
74
Slide 75
75
Slide 76
76
Slide 77
77
Slide 78
78
Slide 79
79
Slide 80
80
Slide 81
81
Slide 82
82
Slide 83
83
Slide 84
84
Slide 85
85
Slide 86
86
Slide 87
87
Slide 88
88
Slide 89
89
Slide 90
90
Slide 91
91
Slide 92
92
Slide 93
93
Slide 94
94
Slide 95
95
Slide 96
96
Slide 97
97
Slide 98
98
Slide 99
99
Slide 100
100
Slide 101
101
Slide 102
102
Slide 103
103
Slide 104
104
Slide 105
105
Slide 106
106
Slide 107
107
Slide 108
108
Slide 109
109
Slide 110
110
Slide 111
111
Slide 112
112
Slide 113
113
Slide 114
114
Slide 115
115
Slide 116
116

About This Presentation

Hacking


Slide Content

Безопасность компьютерных систем
Денис Гамаюнов
[email protected]
Лекция 21:Компьютерные сети и безопасность. Системный уровень.

Интернет в прошлом

Автономные системы

Internet в 1990 году, Hal Burch and Bill Cheswick's Internet Mapping Project.

Маршрутизаторы

Интернет как сеть равноправных
систем
•IP –основной сетевой протокол обмена между
условно «стационарными» устройствами
•Многочисленные прикладные протоколы поверхTCP и
UDP
•Трафик «разнообразен»

Современная экосистема интернета
Веб –«новый десктоп»Развитие веб-технологий

Количество -> качество
•Более18 млрд мобильных устройств в 2025 г.•В ~15 раз больше, чем стационарных ПК и ноутбуков
8
Доступ к
большинству
сервисов –
через
мобильные
устройства
Взрывной рост разнообразия
Облачные приложения
Мобильные устройства
Интернет

Интернет вещей

Интернет вещей

… и огромная куча спутников

Основные задачи при разработке
сетевых приложений
•Оптимизация производительности:
•Latency(задержка)
•Скорость передачи данных (бит/сек) [max]
•Время передачи= latency + length / transfer rate
•Пропускная способность
•Использование нескольких каналов параллельно можно
позволить получить пропускную способность> скорости
передачи данных
•Перегрузки могут сделать получить пропускную способность
< скорости передачи данных
•Часто скорость чтения/записи по сети < локального диска

Основные задачи при разработке
сетевых приложений
•Масштабируемость
•Надежность
•Данные редко портятся в канале
•Высокоуровневые механизмы исправления ошибок
•Ошибки чаще возникают в форме задержек, когда одна из сторон не
успевает обрабатывать поток
•Безопасность
•сетевое разграничение доступа
•конфиденциальность и целостность данных
•атаки на приложения
•Мобильность!
•QoS–вопросы обеспечения режима реального времени

Модельный пример приложения
•Модельный пример №1 –веб-приложение. Цепочка
технологий, которые обеспечивают функционирование современного веба. От протоколов
HTTP (HTTPS) вниз через DNS и TCP к канальной сети.

Основные принципы
•Пакетная передача данных
•Сообщение –логическая единица
•Пакет –единица передачи данных
•Потоковая передача данных
•Аудио/видео
•В зависимости от используемого кодека, требуется от сотен Кб/сек
до сотен Мб/сек
•Время проигрывания –время, в которое должен быть отображен
заданный кадр
•IPv4 не даёт никаких гарантий по QoS
•Resource Reservation Protocol (RSVP), Real-time Transport Protocol
(RTP)

Основные принципы(2)
•Схема коммутации (передача между двумя конечными узлами)
•Вещание: ethernet, wireless
•Коммутация каналов: традиционная телефонная связь
•Коммутация пакетов (основная в cовременномИнтернете):
•store-and-forward
•Различные маршруты пакетов между двумя узлами
•“store-and-forward”требует буфера размером в целый пакет
•Коммутация ячеек (frame relay, ATM)
•Пакеты малого размера (фиксированного)
•Смотрим только в первые биты
•Не требуется буферизация ячейки целиком

Основные принципы(3)
•Уровневая организация
Уровеньn
Уровень2
Уровень1
Отправка сообщенияПолучение сообщения
Среда передачи
данныхОтправительПолучатель

Основные принципы(3)
•Инкапсуляция
Presentation header
Application-layer message
Session header
Transport header
Network header

Модель TCP/IP
•5уровней
Транспортный
Сетевой
Прикладной
Канальный
Физический
Отправка сообщенияПолучение сообщения
Среда передачи
данныхОтправительПолучатель

Передача по каналу
•Сборка пакетов
•Заголовок + данные
•maximum transfer unit (MTU): 1500 дляEthernet
•до 64K дляIP (8K типичный размер т.к. распространен для
дискового хранения)
•порт: адрес получателя (приложение или служебный
протокол)
•адресация: транспортный адрес = сетевой адрес + порт

Маршрутизация
•Построение маршрутов между узлами
•LAN?
•Алгоритм маршрутизации
•Выбрать, в какой канал отправить пакет
•Для коммутации пакетов –независимо для каждого пакета
•Для коммутации каналов –при первичном установлении
канала
•Обновить состояние подключенных каналов
•Таблица маршрутизации
•Запись про каждый известный маршрут
•Поля: в какой канал и какая цена

Маршрутизация (2)
•Пример маршрута
УзлыКаналыилиЛВС
A
DE
B
C
12
5
43
6
Маршрутизаторы

Таблицы маршрутизации
Маршруты от D Маршруты от E
A
B
C
D
E
3
3
6
local
6
1
2
2
0
1
A
B
C
D
E
4
4
5
6
local
2
1
1
1
0
Маршруты от AМаршруты от BМаршруты от C
КудаКаналСтоимость
A
B
C
D
E
local
1
1
3
1
0
1
2
1
2
A
B
C
D
E
1
local
2
1
4
1
0
1
2
1
A
B
C
D
E
2
2
local
5
5
2
1
0
2
1
КудаКаналСтоимостьКудаКаналСтоимость
КудаКаналСтоимостьКудаКаналСтоимость

Пример таблицы маршрутизации

Тунеллирование
Сетевой туннель:
•Передача через другой «чужой» протокол
•Гостевой протокол “прячется”в данных
A BIPv6 IPv6
IPv6 инкапсулирован в пакеты IPv4
Устройства «упаковки»
Сеть IPv4

Основные протоколы
IP (Internet Protocol)
•Протоколсетевого уровня
•IP адресация
TCP (Transmission Control Protocol)
•Транспортный уровень
•Ориентированный на соединения
UDP (User Datagram Protocol)
•Транспортный уровень
•Без соединений

Инкапсуляция уровней TCP/IP
Application message
TCP header
IP header
Ethernet header
Ethernet frame
port
TCP
IP

Уровни с точки зрения
программиста
IP
Application Application
TCP UDP

IP адресация
•IPv4 (классовая)
7 24
Class A:0Network ID Host ID
14 16
Class B:10 Network ID Host ID
21 8
Class C:110 Network ID Host ID
28
Class D (multicast):1110 Multicast address
27
Class E (reserved):1111 unused0

Десятичное представление
•163.118.131.9 октет1октет2октет 3
Class A:1 to 127
0 to 2550 to 2551 to 254
Class B:128 to 191
Class C:192 to 223
224 to 239 Class D (multicast):
Network ID
Network ID
Network ID
Host ID
Host ID
Host ID
Multicast address
0 to 2550 to 2551 to 254
0 to 2550 to 2550 to 255
0 to 2550 to 2550 to 255
0 to 2550 to 2551 to 254240 to 255 Class E (reserved):
1.0.0.0 to 127.255.255.255
128.0.0.0 to 191.255.255.255
192.0.0.0 to 223.255.255.255
224.0.0.0 to 239.255.255.255
240.0.0.0 to 255.255.255.255
Диапазон адресов

Бесклассовая маршрутизация
•Classless interdomainrouting (CIDR)
•Нехватка сетей классов B и C
•Битовая маска переменной длины для адресации сети
•138.73.59.32/22 [подсеть: 22; хост: остальные 10]

Бесклассовая маршрутизация
dataIP address of destinationIP address of source
header
up to 64 kilobytes

Network Address Translation(NAT)
•Использование одного “общего”IP адреса для выхода домашних устройств в Интернет•Маршрутизаторы с NAT•Маршрутизатор обладает “глобальным”IP адресом, полученным от провайдера•У каждой машины есть “локальный”IP адрес, полученный черезDHCP•Машины-> маршрутизатор•Маршрутизатор сохраняет локальный IP адрес и номер порта у себя в таблице•Таблица индексируется номером порта•Маршрутизатор-> интернет•Указывает IP адрес маршрутизатора и виртуальный номер порта в исходящем пакете•интернет-> маршрутизатор•Отвечает на IP адрес маршрутизатора и виртуальный номер порта•Маршрутизатор -> машина•Находит запись в таблице по виртуальному номеру порта•Отправляет на локальный IP•Но что будет, если мы захотим локальную машину сделать сервером?

NAT
83.215.152.95
Ethernet switch
Modem / firewall / router (NAT enabled)
printer
DSL or Cable
connection to ISP
192.168.1.xx subnet
PC 1
WiFi base station/
access point 192.168.1.10
192.168.1.5
192.168.1.2
192.168.1.1
192.168.1.104
PC 2
192.168.1.101
Laptop
192.168.1.105
Game box
192.168.1.106
Media hub
TV monitor
Bluetooth
adapter
Bluetooth
printer
Camera

Основные инструменты
Диагностика:
•ifconfig
•lsof
•netstat
•ping
•traceroute
•nc
Настройка
•ifconfig
•route
•sysctl
•ethtool
Анализ
•tcpdump
•wireshark
•burp suite

Модельный пример сетевого
приложения
•Веб-приложение!
$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

Посмотрим на него внимательнее
•$ stracepython –m SimpleHTTPServer

socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
getsockname(3, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr("0.0.0.0")}, [16]) = 0
getsockname(3, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr("0.0.0.0")}, [16]) = 0
socket(PF_LOCAL, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 4

Посмотрим на него внимательнее(2)

open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=475, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0x7f043b2ed000
read(4, "# /etc/nsswitch.conf\n#\n# Example"..., 4096) = 475
munmap(0x7f043b2ed000, 4096) = 0
open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=92, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0x7f043b2ed000
open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 4

Посмотрим на него внимательнее(3)

open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=188, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f043b2ed000
read(4, "127.0.0.1\tlocalhost\n127.0.1.1\twa"..., 4096) = 188
listen(3, 5) = 0
getsockname(3, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr("0.0.0.0")}, [16]) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 19), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f043b2ed000
write(1, "Serving HTTP on 0.0.0.0 port 800"..., 38Serving HTTP on 0.0.0.0 port 8000 ...
) = 38
select(4, [3], [], [], {0, 500000}) = 0 (Timeout)

Интересно…
•Зачем приложение читает /etc/hosts?
•А nsswitch.conf?
•И что такое resolv.confи зачем он нужен?

Domain Name System
•DNS–это распределенная база данных,
поддерживающая иерархическую систему
имен для идентификации узлов в Интернете
•Почтовый индекс vsIPадрес в сети
•Структура региональной системы имен

Доменные имена
•Глобальная иерархия имён

Доменные имена -2
•seclab.cs.msu.su
•SECLAB.CS.MSU.SU
•Seclab.Cs.Msu.Su
•…
seclab.cs.msu.su.

Формат базы DNS
$ORIGIN .
$TTL 3600 ; 1 hour
cs.msu.suIN SOA ns.cs.msu.su. root.cs.msu.su. (
2010052274 ; serial
10800 ; refresh(3 hours)
1800 ; retry(30 minutes)
3600000 ; expire(5 weeks6 days16 hours)
3600 ; minimum(1 hour)
)
NS ns.cs.msu.su.
NS ns.radio-msu.net.
NS ns1.radio-msu.net.
NS ns2.radio-msu.net.
A158.250.10.250
MX 10 mailhost.cs.msu.su.
MX 15 imap.cmc.msu.ru.
TXT “BMK Zone"
$ORIGIN cs.msu.su.
academyCNAME educert.cmc.msu.ru.
adlerCNAME farm
alA212.192.248.21
MX 10 imap
$ORIGIN al.cs.msu.su.
wwwCNAME al.cs.msu.su.
Каждый домен описывают в виде множества ресурсов :
Domain_nameTime_to_liveClass Type Value

Резолвер
•Встроен в операционную систему
•UNIX/Linux:
•/etc/nsswitch.conf
~> grepdns/etc/nsswitch.conf
hosts: files dns
•/etc/resolv.conf
~> cat/etc/resolv.conf
searchseclab
nameserver10.0.0.53

Утилиты
•dig
$ dig mx bushwhackers.ru
; <<>> DiG9.9.5-3ubuntu0.1-Ubuntu <<>> mx bushwhackers.ru
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<-opcode: QUERY, status: NOERROR, id: 57269
;; flags: qrrdra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;bushwhackers.ru. IN MX
;; ANSWER SECTION:
bushwhackers.ru. 3600 IN MX 0 mail.seclab.cs.msu.ru.
;; Query time: 704 msec
;; SERVER: 10.0.0.53#53(10.0.0.53)
;; WHEN: Tue Apr 18 00:24:09 MSK 2017
;; MSG SIZE rcvd: 68•host
$ host -t mx bushwhackers.ru
bushwhackers.rumail is handled by 0 mail.seclab.cs.msu.ru.

Интерфейсы приложения к TCP/IP
•В самом протоколе TCP отсутствует определение
стандартного API
•Для работы с TCP/IP существуют разные наборы API
•Сокеты
•TLI, XTI
•Winsock
•MacTCP
47

Функции API
•Определение локального и удаленного концов
транспортного канала
•Инициация соединения
•Ожидание входящего соединения
•Отправка и прием данных
•Надежное завершение соединения
•Обработка ошибок
48

Berkeley Sockets
•Достаточно общие:
•Поддерживают различные семейства протоколов
•Не зависят от способа представления адреса
•Используют привычный (на момент создания)
интерфейс работы с I/O
49

Сокет
•Сокет –абстракция оконечной точки транспортного
канала
•Сокеты работают с типовыми сервисами ввода-вывода
в UNIX точно так же, как файлы, пайпы, очереди и т.п.
50

Таблица файловых дескрипторов
51
Таблица дескрипторов
0
1
2
3
4
Структура данных файла 0
Структура данных файла1
Структура данных файла2

Структура данных
дескриптора сокета
52
Таблица дескрипторов
0
1
2
3
4
Family: PF_INET
Service: SOCK_STREAM
Local IP: 111.22.3.4
Remote IP: 123.45.6.78
Local Port: 2249
Remote Port: 3726

Создание сокета
int socket(int family, int type,
int proto);
•family задает используемое семейство протоколов
•PF_INET for TCP/IP
•type задает тип сервиса
•SOCK_STREAM, SOCK_DGRAM
•protocol определяет используемый протокол
•обычно0, значение по-умолчанию

socket()
•Системный вызовsocket() возвращает дескриптор
сокета –небольшое целое число или -1 в случае ошибки
•socket()аллоцируетнеобходимые ресурсы для
обслуживания соединения
•Но он не работает с адресацией концов соединения
54

Задание адресов
•APIсокетов достаточно общее
•Должен быть также достаточно общий способ задания адресов концов соединения
•Для TCP/IP необходимо задать IP адрес и номер порта
для каждого из двух концов соединения
•Другие семейства протоколов могут использовать
другие схемы адресации
55

Типы данных POSIX
•int8_tsigned 8 bit int
•uint8_tunsigned 8 bit int
•int16_tsigned 16 bit int
•uint16_tunsigned 16 bit int
•int32_tsigned 32 bit int
•uint32_tunsigned 32 bit int
•sa_family_taddress family
•socklen_tlength of struct
•in_addr_tIPv4 address
•in_port_tIP port number
56

struct sockaddr_in (IPv4)
structsockaddr_in{
uint8_tsin_len;
sa_family_tsin_family;
in_port_tsin_port;
structin_addrsin_addr;
char sin_zero[8];
};
structin_addr{
in_addr_ts_addr;
};
57
Размер структуры (16)
AF_INET
16 битный номер порта
32 бита адреса
IPv4
«Добить» структуру до 16
байтов

struct sockaddr_in (IPv6)
structsockaddr_in6 {
uint8_tsin6_len;
sa_family_tsin6_family;
in_port_tsin6_port;
uint32_tsin6_flowinfo;
structin6_addrsin6_addr;
uint32_t sin6_scope_id;
};
structin6_addr {
uint8_ts6_addr[16];
}; 58
Размер структуры (28)
AF_INET6
Номер порта
128 бита адреса
IPv6
Область
действия адреса
Метка потока

sockaddr
59
sa_lensa_family
sa_data
lengthAF_INETport
addr
нули
sockaddrsockaddr_insockaddr_in6
lengthAF_INET6port
Flow-label
Scope ID
addr
28 байтов
Переменной
длины
16 байтов

Порядок следования байтов
•Все байты, которые хранятся в sockaddr_in, должны
быть в «сетевом» порядке
•sin_portномер портаTCP/IP
•sin_addrIP адрес
60

Функции работы с endianness
•‘h’: «хостовой» порядок следования байтов(little
endian)
•‘n’: «сетевой» порядок следования байтов (big endian)
•‘s’: short (16bit)
•‘l’: long (32bit)
•uint16_t htons(uint16_t);
•uint16_t ntohs(uint_16_t);
•uint32_t htonl(uint32_t);
•uint32_t ntohl(uint32_t);
61

Назначение адреса сокету
•Системный вызовbind() нужен для того, чтобы
назначить адрес уже существующему сокету
intbind( intsockfd,
conststructsockaddr*myaddr,
intaddrlen);
•bind возвратит0 при успехе и -1 в случае ошибки
62

bind()
•вызовbind() присваеваетадрес, заданный в структуре
sockaddr, дескриптору сокета
•Можно передатьbind() структуруsockaddr_in:
bind( mysock,
(structsockaddr*) &myaddr,
sizeof(myaddr) );
63

Пример для bind()
intmysock,err;
structsockaddr_inmyaddr;
mysock= socket(PF_INET,SOCK_STREAM,0);
myaddr.sin_family= AF_INET;
myaddr.sin_port= htons( portnum);
myaddr.sin_addr= htonl( ipaddress);
err=bind(mysock, (sockaddr*) &myaddr,
sizeof(myaddr));
64

Пример для bind()-python
import socket
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = 'localhost'
port = 8007
s.bind((host), (port))
65

Варианты использования bind()
•Вызовbind()может использоваться в нескольких
вариантах:
•Сервер можно привязать к зарезервированному адресу
приложения
•Номер порта, «well known»
•Клиент может привязаться к некоторому фиксированному
порту
или
•Клиент может попросить API привязать его конец к любому
свободному порту
66

Мне вообще всё равно какой порт
•Для клиентских приложений обычно нет никакой
разницы между номерами портов
•При вызове bind() можно попросить дать любой
свободный адрес:
•myaddr.port= htons(0);
67

А какой у меня IPадрес?
•Как узнать, какой адрес нужно передать как параметр
bind() ?
•Вообще, нет никакой разумной стратегии в общем
случае, какой IP адрес передатьbind()
•Что если у машины есть несколько IP адресов?
•Можно задать IP адрес как: INADDR_ANY, это способ
попросить ОС «сделать всё красиво»
68

Прочие сокетныесистемные
вызовы
•Общие
•read()
•write()
•close()
69
•Для работы с соединениями (TCP)
–connect()
–listen()
–accept()
•Без соединения(UDP)
–send()
–recv()

Сокеты TCP
CPE 401/601 Lecture 3 : TCP Socket
Programming70

Диаграмма состояний
TCP

СозданиеTCP сокета
int socket(int family, int type, int
proto);
•family: AF_INET, AF_INET6, AF_LOCAL, …
•type: SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW
•protocol: IPPROTO_TCP, IPPROTO_UDP, IPPROTO_SCTP
int sock;
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock<0) { /* ERROR */ }
72

Связывание с 80 портом
intbind(intsockfd, conststructsockaddr*myaddr,
socklen_taddrlen);
intmysock;
structsockaddr_inmyaddr;
mysock= socket(PF_INET,SOCK_STREAM,0);
myaddr.sin_family= AF_INET;
myaddr.sin_port= htons( 80 );
myaddr.sin_addr= htonl( INADDR_ANY );
bind(mysock, (sockaddr*) &myaddr, sizeof(myaddr));
73

«Пассивный» TCP
•Пассивный режим
•Адрес уже задан
•Говорим ядру, что надо принимать входящие запросы
на соединение с нашим портом
•Обработка «троекратного рукопожатия»
•Говорим ядру, чтобы организовало очередь входящих
соединений
74

listen()
intlisten(intsockfd, intbacklog);
•sockfdэто TCP сокет
•Уже связан с каким-то адресом
•backlogмаксимальное число буферизованных
входящих соединений
•Завершенные и незавершенные «рукопожатия»
•Когда приложение готово обработать новое соединение
•Спрашиваем у ОС следующее соединение из очереди
75

accept()
intaccept( intsockfd,
structsockaddr* cliaddr,
socklen_t*addrlen);
•sockfdэто дескриптор сокетаTCP, открытого в «пассивном»
режиме
•Создан с помощьюsocket(), bind()иlisten()
•cliaddrуказатель на аллоцированнуюструктуру
•addrlenаргумент значение-результат
•Должен содержать размерcliaddr
•В него будет записано число использованыхбайтов в cliaddr76

Что вернет accept()
•accept() возвращает новый дескриптор сокета
•Небольшое целое число или -1 при ошибке
•После того как accept() вернул дескриптор,можно
выполнять ввод-выводI/O с использованием
системных вызовов read()иwrite()
•read()иwrite()на сокетах работают не совсем
так, как с файлами
77

ЗавершениеTCP соединения
intclose(intsockfd);
•Любая из сторон соединения может позвать системный
вызовclose()
•Что если в этот момент передаются данные?
•Если дальний конец закрыл соединение и буферизованных
данных нет, то
•Чтение из сокета вернёт 0 в качестве EOF
78CPE 401/601 Lecture 3 : TCP
Socket Programming

Клиентский код
•TCP клиент может вызвать connect():
•Он установит адрес клиентского конца соединения
•Попытается установить соединение с серверной стороной
•Троекратное рукопожатие
•Нет необходимости вызывать bind,ОС позаботится
о выставлении адресов
•Номер порта и IP адрес
79

connect()
intconnect( intsockfd,
conststructsockaddr*server,
socklen_taddrlen);
•sockfdранее созданный TCP сокет
•serverадрес сервера
•connect() вернет0 еслиOK, -1 в случае ошибки
•Нет ответа на SYN запрос(3 попытки)
•Пришел RST
•Пришел ICMP destination unreachable (3 попытки)
80

Чтение из сокета
intread(intfd, char *buf, intmax);
•По-умолчанию read()заблокируется до получения данных
•Чтение из TCP сокета может вернуть меньше, чем максимальное
число байтов
•Отдаст, что есть
•Возможно даже чтение по 1 байту
81

Запись в сокет
intwrite(intfd, char *buf, int
num);
•writeможет не смочь записать все байты в
неблокирующий сокет
•readn(), writen()иreadline()
82

UDP сокеты

Создание UDP сокета
intsocket(intfamily, inttype,
intproto);
intsock;
sock = socket(PF_INET, SOCK_DGRAM,
0);
if (sock<0) { /* ERROR */ }
84CPE 401/601 Lecture 3: UDP
Socket Programming

Связывание с известным адресом
•Обычно только сервер
intmysock;
structsockaddr_inmyaddr;
mysock=socket(PF_INET,SOCK_DGRAM,0);
myaddr.sin_family= AF_INET;
myaddr.sin_port= htons(1234);
myaddr.sin_addr= htonl(INADDR_ANY);
bind(mysock, &myaddr,
sizeof(myaddr));
85

ОтправкаUDP дейтаграм
ssize_tsendto( intsockfd, void *buff,
size_tnbytes, intflags,
conststructsockaddr* to,
socklen_taddrlen);
•sockfd-сокет
•buffадрес буфера данных(длиной nbytes)
•toадрес назначения•Возвращаемое значение –число переданных байт,
•или-1 при ошибке
86

sendto()
•Возвращаемое значение sendto()показывает,
сколько данных примет ОС для отправки в
дейтаграмме
•А не сколько уехало по назначению
•Нет никакой индикации, что получатель принял
данные
•Можно отправить 0 байтов данных
87

Получение UDP дейтаграмм
ssize_trecvfrom( intsockfd, void *buff,
size_tnbytes, intflags,
structsockaddr* from,
socklen_t*fromaddrlen);
•sockfd-сокет
•buffадрес буфера данных (nbytes)
•fromадрес структурыsockaddr
•Возвращаемое значение –число данных, принятых и записанных в буфер, или-1
при ошибке

recvfrom()
•еслиbuffнедостаточно большой, всё что превышает
буфер, будет потеряно
•можно получить 0 байт данных
•структураsockaddrвоfromсодержит адрес
отправителя
89

Типовой клиентский код для UDP
•СоздаемUDP сокет
•Создаем структуруsockaddrс адресом сервера
•Зовем sendto(), отправляя запрос на сервер
•Вызов bind()не нужен
•Возможно зовем recvfrom()
•Если мы ждем ответа
90

Типичный серверный код для UDP
•Создаем UDP сокет и связываем его с известным портом
•Зовемrecvfrom() для получения запроса от клиентов
•Обрабатываем запрос и отвечаем обратно с помощьюsendto()
91

Типовое взаимодействие по UDP
92

Sendfile() –к быстрым
HTTP серверам

Проблема диспетчеризации большого
числа одновременных соединений
•В 1990-е годы основным HTTP-сервером в экосистеме UNIX-
подобных операционных систем был Apache1.
•Архитектура типичная для TCP-сервера того времени: для каждого
нового соединения мастер-процесс порождал потомка и потомок
работал с этим соединением, в частности, посылал файлыс
помощью цикла, подобного этому:
char buf[BUFSIZE]; size_trem, len; rem = nbytes;
for (rem = nbytes; rem > 0; rem −= len) {
len= min(BUFSIZE, rem); read(fd, buf, len); write(sd, buf, len);
}

Появление sendfile()
•Буфер отсылаемых данных совершенно не модифицируется
между read(2) и write(2)
•Копирование данных из ядерного адресного пространства в
адресное пространство процесса только для того, чтобы затем
скопировать их обратно -напрасная трата вычислительных
ресурсов
•Ответ –новый системный вызов, который внутри ядра осуществит
передачу немодифицированныхданных из файлав сокет

Появление sendfile()
intsendfile(intfd, ints, off_toffset, size_tnbytes, .. );
•1997 год: HP-UX 11.00
•1998 год: FreeBSD 3.0 и Linux 2.2

Появление sendfile()
•Перваяреализация-маппингюзерлендциклавядро:
•read(filefd) → VOP_READ(vnode)
•write(netfd) → sosend(socket)
•blksize→ PAGE_SIZE

Масштабируемость HTTP серверов
•Начало 2000-х -рост количества одновременных TCP-соединений,
обслуживаемых отдельным HTTP-сервером
•Выяснилось, что, во-первых, порождать новый процесс на каждое
соединение чрезвычайнонеэффективно, а во-вторых,
классические интерфейсыPOSIX совершенно непригодны для
работы с тысячами дескрипторов
•Этот феномен получил имя “C10K problem” или “проблема 10 тысяч
соединений”

Новые интерфейсы работы с
дескрипторами в ОС
•kqueue(FreeBSD)
•epoll(Linux)
•Алгоритм работы современного HTTP-сервера:
•Получить очередной дескриптор из kevent(2)
•Выполнить write(2)/read(2)/sendfile(2) с ним
•Перейтик 1
•Узкое место: время работы системного вызова

Новые веб-серверы
•nginxимеет фиксированное количество рабочих
процессов, также называемых workerprocesses
•эти процессы делят между собой поровну TCP-
соединения
•число worker-овкак правило того же порядка, что и
число физических процессоров в сервере
•каждыйworkerпредставляет собойконечный автомат,
работающий с соединениями поочерёдно

Типовые вызовы HTTP сервера
при работе
•Открытие/закрытие файлов: open(2), close(2).
•Открытие/закрытие сокетов: accept(2), close(2), shutdown(2).
•Дисковый ввод: read(2).
•Чтение из сокета/запись в сокет: read(2), write(2).
•Дисковый ввод и запись в сокет: sendfile(2).

Медленный I/O
•Системный вызов read(2) над файловымдескриптором разворачивается приблизительно в
следующий стек ядерных функций:
sys_read() -> vn_read() -> VOP_READ() -> ffs_read() -> GEOM -> драйвер•Ядро находит vnode, соответствующий данному дескриптору, и вызывает VFS метод
VOP_READ(), который транслируется в специфичный для файловой системы метод read, в
данном случае это FFS. •Код файловой системы находит или выделяет страницы памяти, отражающие данный регион
читаемого файла. •Если страницы невалидны, то их необходимо заполнить. Посылается запрос на чтение в
уровень GEOM, реализующий абстракцию над блочными устройствами, который в свою
очередь передаётего в драйвер. •По окончании чтения, код файловой системы осуществляет копирование данных из теперь
уже валидных страниц в буфер в памяти приложения.

Медленный I/O
•Системный вызов write(2) над дескриптором, отображающим TCP-соединение,
разворачивается приблизительно в следующий стек в ядре:
sys_write() -> sosend() -> tcp_usr_send() -> tcp_output() -> ip_output() -> ether_output() ->
коддрайвера
•Находится сокет, соответствующий данному дескриптору, и вызывается sosend().
•Здесь происходит копирование данных из буфера приложения в цепочку
специальных структур сетевого стека, называемых mbuf-ы.
•Каждыйmbufпредставляет собой описание буфера и прикреплённый к нему mbuf
cluster, где собственно хранятся данные. Цепочка mbufsотсылается в
протокольный метод sendданного сокета, в данном случае TCP. Далее цепочка
mbuf-овследует по всем уровням сетевого стека до драйвера.

Режим неблокирующего I/O
•fcntl(O_NONBLOCK)
•eслисокетныедескрипторы переведены в этот режим, они будут немедленно возвращать код ошибки EAGAIN
вместо того, чтобы блокироваться
•cистемныевызовы могут блокироваться и на дисковом
вводе/выводе
•флаг O_NONBLOCK не меняет поведения файловых
дескрипторов!!!

Попытки решения проблемы
блокирования на I/O
•Отдельные контексты: процессы-потомки, треды
•Apache
•nginx2
•POSIX Asynchronous I/O
•aio_read(2), aio_write(2)
•sendfile(2) с запретом чтения с диска
•новый флаг SF_NODISKIO запрещал системному вызову
блокироваться на чтении с диска

Проблема №2 –контроль над
виртуальной памятью
•VOP_READ() оставляет страницы в VM кэше
•VOP_READ() [для UFS] осуществляет readahead
•И запретить ему это делать не так просто!
•VOP_READ() → VOP_GETPAGES()
•Плюсы:
•sendfile() уже работает постранично
код для vnodeи shmemстановится общим
контроль над VM оказывается элементарнойзадачей

VOP_GETPAGES_ASYNC() (old)
intVOP_GETPAGES(structvnode*vp, vm_page_t*ma, intcount, int
reqpage);
•Инициализироватьbuf(9)
•buf->b_iodone= bdone;
•bstrategy(buf);
•bwait(buf); /* засыпаетдоокончанияI/O */
•return;

VOP_GETPAGES_ASYNC() (old)
intVOP_GETPAGES_ASYNC(structvnode*vp, vm_page_t*ma, intcount, int
reqpage, vop_getpages_iodone_t*iodone, void *arg);
•Инициализироватьbuf(9)
buf->b_iodone= vnode_pager_async_iodone;
bstrategy(buf);
return;
•vnode_pager_async_iodoneвызываетiodone() .

Наивныйнеблокирующийся
sendfile(2)
•В kern_sendfile():
•nios++;
•VOP_GETPAGES_ASYNC(sendfile_iodone);
•В sendfile_iodone():
•nios--;
•if (nios) return;
•sosend();

Проблема наивной реализации
•sendfile(filefd, sockfd, ..);
•write(sockfd, ..);

Буфер сокета

Буфер сокета с «неготовыми»
данными

Неблокирующийсяsendfile()
•В kern_sendfile():
•nios++;
•VOP_GETPAGES_ASYNC(sendfile_iodone);
•sosend(NOT_READY);
•В sendfile_iodone():
•nios--;
•if (nios) return;
•soready();

Трафик

Старый sendfile() в Ne?lix

Новый sendfile() в Ne?lix
Tags