Що саме відбувається, коли користувач набирає в адресному рядку google.com? Частина 1

Переклад першої частини матеріалу з github, докладно пояснює роботу інтернету: що саме відбувається, коли користувач набирає в адресному рядку google.com?

Кнопка «enter» повертається у вихідне положення

Для початку відліку виберемо момент, коли кнопка «enter» втоплена. У цей момент замикається контур, який відповідає за цю кнопку. Невеликий струм проходить по логічним контурах клавіатури. Вони сканують стан всіх перемикачів, гасять паразитні електричні імпульси, і перетворюють натискання код клавіші 13. Контролер кодує код для передачі в комп'ютер. Тепер це майже завжди робиться через USB або Bluetooth, а раніше в процесі брали участь PS/2 або ADB.

Якщо це USB

USB в клавіатурі запитано з напругою 5В по першому штырьку контролера хоста USB на комп'ютері. Код клавіші зберігається в пам'яті клавіатури в регістрі «endpoint». Кожні 10 мілісекунд контролер USB запрошує дані з цього регістра. Так він отримує збережені коди. Код передається в USB SIE (Serial Interface Engine) і перетворюється в один або кілька пакетів низькорівневого USB-протоколу. Пакети відправляються допомогою диференціального електричного сигналу по штырькам D+ і D — з максимальною швидкістю в 1.5 Мб/с, оскільки HID (Human Interface Device) вважається низькошвидкісних пристроєм.

Потім послідовний сигнал декодується в контролері і інтерпретується драйвер HID клавіатури. Значення коду передається в шар абстракції заліза операційної системи.

Якщо це віртуальна клавіатура (сенсорний екран)

Коли користувач поміщає палець на ємнісному дисплеї, між ним і пальцем проходить невеликий струм. Це замикає контур в електростатичному полі провідного шару і створює падіння напруги в цій точці екрану. Контролер екрана піднімає переривання, повідомляючи координати натискання.

Мобільна ОС передає повідомлення в поточний додаток з приводу кліка на одному з GUI-елементів (в даному випадку це клавіші віртуальної клавіатури). Клавіатура піднімає переривання для надсилання повідомлення про натискання клавіш в ОС.

Виникнення переривання (не на USB-клавіатури)

Клавіатура відправляє запит переривання (IRQ), який контролер переривань зіставляє з вектором переривань. CPU використовує таблицю описів переривань IDT, щоб зіставити вектора з функціями-обробниками переривань, які надає ядро. По приходу переривання CPU запускає потрібний обробник. Так ми потрапляємо в ядро.

(Windows) В додаток надсилається повідомлення WM_KEYDOWN

HID передає подія натискання в драйвер KBDHID.sys, який перетворює його в сканкод. У нашому випадку він дорівнює VK_RETURN (0x0D). Цей драйвер спілкується з драйвером KBDCLASS.sys. Останній відповідає за обробку введення клавіатури безпечним способом. Він викликає Win32K.sys (можливо, після передачі повідомлення через різні фільтри клавіатури). Це відбувається в режимі ядра.

Win32K.sys дізнається, яке вікно активно, через API GetForegroundWindow(). Це API надає хендлер для рядка введення браузера. Потім система обробки повідомлень Windows викликає SendMessage(hWnd, WM_KEYDOWN, VK_RETURN, lParam). lParam — бітова маска, що містить додаткову інформацію про натискання — повторення, сканкод, натиснуті додаткові клавіші і ін

SendMessage API додає повідомлення в чергу для заданого хендлер вікна (hWnd). Пізніше для обробки черги викликається функція обробки повідомлень WindowProc.

Активне вікно hWnd — вікно редагування, і в цьому випадку у WindowProc є обробник повідомлень для WM_KEYDOWN. Оскільки був переданий код VK_RETURN, він знає, що користувач натиснув Enter.

(OS X) В додаток передається KeyDown NSEvent

Сигнал переривання викликає подія в драйвері I/O Kit. Він перетворює сигнал в код клавіші і передає його в процес WindowServer. Той створює подія для активних додатків через їх порт Mach. Події поміщаються в черзі цих додатків. Прочитуються вони звідти тредами, які мають відповідний рівень доступу за допомогою функції mach_ipc_dispatch. Найчастіше це робиться через головний цикл NSApplication за допомогою NSEvent / NSEventType Натискання.

(GNU/Linux) Сервер Xorg відстежує коди

При використанні графічного сервера X для отримання коду буде задіяний драйвер evdev. За наявними правилами код клавіші буде перетворений в сканкод. Після цього символ передається в менеджер вікон (DWM, metacity, i3, і т. д.), який у свою чергу передає символ вікна, що знаходиться в фокусі. Графічний API вікна отримує символ і виводить відповідний символ в тому вікні, в якому знаходиться фокус.

Розбір URL

Тепер у браузера є наступна інформація з URL (Uniform Resource Locator):

Протокол «http» — використовуємо 'Hyper Text Transfer Protocol'
Ресурс "/" — запросити головну сторінку


Це URL або пошуковий запит?

Якщо не задано протокол і рядок не є допустимим доменним ім'ям, браузер передає цей текст пошуковій системі за умовчанням.

Перевірка списку HSTS

Браузер перевіряє список HSTS (HTTP Strict Transport Security). Це список сайтів, до яких потрібно звертатися тільки по HTTPS. Якщо сайт в списку, то браузер посилає запит через HTTPS. Інакше — через HTTP.

Перетворимо символи в імені сервера, які не відносяться до таблиці ASCII.

Браузер перевіряє, чи є символи не з діапазонів a-z, A-Z, 0-9, -,.
Оскільки у нас google.com таких символів не буде. Інакше до імені сервера буде застосовано кодування по системі Punycode.

Запит DNS

Браузер перевіряє, чи є домен в Кеші. Якщо ні, викликається бібліотечна функція gethostbyname (залежно від ОС). Вона перевіряє, чи можна дізнатися адресу сервера по імені на підставі інформації з локального файлу hosts. Якщо це не допомагає, відбувається запит до DNS-серверу, який вказаний в налаштуваннях мережі. Це або локальний роутер, або DNS-сервер провайдера. Якщо DNS-сервер в тій же підмережі, бібліотека працює по протоколу ARP з сервером. Інакше запит відправляється на IP-адресу стандартного шлюзу.

Протокол ARP (Address Resolution Protocol)

Для відправки широкомовного запиту ARP, мережевого стека потрібно дізнатися IP-адресу одержувача і MAC-адреса інтерфейсу, який буде для цього використаний.

Спочатку перевіряється кеш ARP на предмет наявності IP одержувача. Якщо він є в кеші, повертається результат «IP одержувача = MAC».

Якщо її немає в кеші, то таблиця роутінга проглядається на предмет наявності ip-адреси в який-небудь з локальних підмереж. Якщо він там є, використовується інтерфейс, присвоєний цій підмережі. Якщо ні, бібліотека використовує інтерфейс підмережі основного шлюзу. Потім шукається MAC-адресу обраного інтерфейсу і відправляється Layer 2 ARP запит:

Sender MAC: interface:mac:address:here
Sender IP: interface.ip.goes.here
Target MAC: FF:FF:FF:FF:FF:FF (Broadcast)
Target IP: target.ip.goes.here


Якщо комп'ютер підключений до роутера безпосередньо, роутер дає відповідь ARP Reply. Якщо підключення йде через хаб, той передає запит по всіх портах. Якщо там буде роутер, він дасть відповідь. Якщо підключення через світч, той визначить за своєю таблиці CAM/MAC, у якого порту є потрібний MAC-адресу. Якщо не знайде, то поширить запит по всіх портах. А якщо знайде, то відправить запит з того порту, де є потрібний MAC.

Відповідь ARP Reply:

Sender MAC: target:mac:address:here
Sender IP: target.ip.goes.here
Target MAC: interface:mac:address:here
Target IP: interface.ip.goes.here


Тепер у бібліотеки є ip-адресу або DNS-сервера, або основного шлюзу. Можна продовжити процес розпізнавання домену. Відкривається 53 порт і відправляється на сервер UDP-запит (у разі великих запитів використовується TCP). Якщо інформації у DNS-сервера не виявляється, то запитується рекурсивний пошук, який проходить за списком DNS-серверів, поки не доходить до SOA і не знаходиться потрібний відповідь.

Відкриття сокета

Коли браузер отримує ip-адресу сервера, він разом з портом (для HTTP порт за замовчуванням — 80, для HTTPS — 443) використовує їх як параметри виклику функції socket і запитує потік TCP socket stream — AF_INET і SOCK_STREAM.

Спочатку цей запит передається транспортний шар, де створюється сегмент TCP. Порт призначення додається в заголовок, а порт джерела вибирається динамічно зі списку портів ядра (в Linux це ip_local_port_range).

Сегмент відправляється в мережевий шар, де йому додають ip-заголовок, у якому міститься ip-адресу сервера ip-адресу нашого комп'ютера. Потім пакет потрапляє в Link Layer. До нього додається заголовок кадру, в якому міститься MAC-адресу комп'ютера і шлюзу (локального роутера). Якщо ядра невідомий MAC-адресу шлюзу, для його з'ясування відправляється ARP-броадкаст. І тепер наш пакет готовий до відправлення через Ethernet, WiFi або мобільний зв'язок.

У більшості випадків пакет з комп'ютера проходить по локальній мережі, потім потрапляє в модем (модулятор/демодулятор), де перетворюється з цифрового в аналоговий сигнал. Такий сигнал можна передавати по телефону, кабелю або бездротовому з'єднанню. Модем приймаючої сторони перетворює його назад в цифрову форму, звідки він надходить на наступний вузол мережі, де адреси відправника та одержувача піддаються подальшого розбору.

Іноді пакет відправляється відразу через Ethernet або оптику, тоді він залишається цифровим і доходить до наступного вузла мережі. Зрештою сигнал доходить до роутера локальної підмережі. Звідти він йде через прикордонні роутери AS, інші AS, і доходить до сервера. Кожен роутер по шляху отримує ip-адресу призначення і передає пакет наступного хопу. При цьому TTL в пакеті зменшується на одиницю. Пакет відкидається, якщо воно досягає нуля, або якщо у поточного роутера закінчилося місце в черзі. Відправка і отримання пакетів відбуваються багаторазово в рамках з'єднання TCP.

Спочатку клієнт вибирає початковий номер послідовності (ISN) і надсилає пакет на сервер, встановивши біт SYN так, щоб було ясно, що це ISN.

Якщо сервер отримує SYN і знаходиться в сприятливому розташуванні духу, тоді він вибирає свій ISN, встановлює SYN для індикації того, що в пакеті міститься ISN, копіює в поле ACK клієнтський ISN+1 і додає прапор ACK, щоб підтвердити отримання першого пакету.

Клієнт підтверджує з'єднання, відправляючи пакет, де збільшується свій ISN, збільшується ISN відправника та встановлено полі ACK.

Дані передаються так: коли одна сторона надсилає N байт, вона збільшує SEQ на це число. Коли інша сторона підтверджує отримання пакета (або їх ланцюжка), вона відправляє пакет ACK, де значення ACK дорівнює останньої отриманої від іншої сторони послідовності.

Для закриття з'єднання закриває сторона надсилає пакет FIN, інша сторона підтверджує отримання пакета і відправляє свій FIN, а перша підтверджує його отримання.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.