Browser Discovery
๐ง ํฐ ๊ทธ๋ฆผ๋ถํฐ
โWeb browser โ API ์์ฒญ(Network) โ Assembly๋ก ๋ณํ๋๋ ๊ณผ์ โ ์ ์ฌ์ค โ๋จ๊ณ์ ์ผ๋ก ๋ด๋ ค๊ฐ๋ฉฐ ์ถ์ํ๊ฐ ๋ฒ๊ฒจ์ง๋ ๊ณผ์ โ์ด์์.
์ฆ, ์ฐ๋ฆฌ๊ฐ ์์ฑํ JavaScript โ C/C++ (๋ธ๋ผ์ฐ์ ๋ด๋ถ ๊ตฌํ) โ OS ์ปค๋ โ ๋๋ผ์ด๋ฒ โ CPU ๋ช ๋ น(Assembly) ๋ก ๋ฒ์ญ๋๋ฉฐ ์ ์ ๋ ํ๋์จ์ด์ ๊ฐ๊น์์ง๋๋ค.
โธป
โ๏ธ 1๏ธโฃ JavaScript (๊ณ ์์ค ์ธ์ด)
์๋ฅผ ๋ค์ด ๋ธ๋ผ์ฐ์ ์์ ์ด๋ ๊ฒ API ์์ฒญ์ ๋ ๋ฆฐ๋ค๊ณ ํด๋ณผ๊ฒ์:
fetch(โhttps://api.example.com/dataโ);
์ด๊ฑด JavaScript ์์ง(V8, SpiderMonkey ๋ฑ) ์์ ์คํ๋ฉ๋๋ค. ๊ทธ ๋ด๋ถ์์๋ ๋๋ต ์ด๋ฐ ์ผ์ด ์ผ์ด๋์: 1. fetch() โ ๋ธ๋ผ์ฐ์ ์ Networking Layer (C++ ์ฝ๋) ๋ก ํธ์ถ๋จ 2. ๋ด๋ถ์ ์ผ๋ก libcurl ๋๋ ์์ฒด ๊ตฌํํ HTTP Client ๋ชจ๋ ์ฌ์ฉ 3. OS์ socket API (send(), recv()) ํธ์ถ
โธป
๐งฉ 2๏ธโฃ System Call (์ด์์ฒด์ ๊ณ์ธต)
์ด์ C++ ์ฝ๋์์ OS์ ๋คํธ์ํฌ API๋ฅผ ํธ์ถํฉ๋๋ค.
int sock = socket(AF_INET, SOCK_STREAM, 0); connect(sock, &addr, sizeof(addr)); send(sock, data, length, 0); recv(sock, buffer, size, 0);
์ด๋ฐ ์ฝ๋๋ค์ด ๊ฒฐ๊ตญ ์์คํ ์ฝ(System Call) ๋ก ๋ณํ๋ผ์.
์๋ฅผ ๋ค์ด Linux์์๋: โข socket() โ sys_socket โข send() โ sys_sendto โข recv() โ sys_recvfrom
โธป
๐ง 3๏ธโฃ OS ์ปค๋์์ Assembly ๋ ๋ฒจ๋ก
์์คํ ์ฝ์ ๊ฒฐ๊ตญ CPU ๋ช ๋ น(Assembly) ์ผ๋ก ํธ์ถ๋ฉ๋๋ค.
Linux x86-64 ๊ธฐ์ค์ผ๋ก ๋ณด๋ฉด, ์์คํ ์ฝ์ ๋ค์์ฒ๋ผ ์ํ๋ผ์ ๐
mov eax, 1 ; syscall ๋ฒํธ (1 = write, 44 = sendto ๋ฑ) mov edi, sockfd ; ์ฒซ ๋ฒ์งธ ์ธ์ mov rsi, buffer ; ๋ ๋ฒ์งธ ์ธ์ mov rdx, length ; ์ธ ๋ฒ์งธ ์ธ์ syscall ; ์ปค๋ ๋ชจ๋๋ก ์ ํ!
โก๏ธ ์ด syscall ๋ช ๋ น์ด ์ฌ์ฉ์ ๋ชจ๋ โ ์ปค๋ ๋ชจ๋ ๋ก ์ ํ์์ผ ์ด์์ฒด์ ์ ๋คํธ์ํฌ ๋๋ผ์ด๋ฒ ์ฝ๋๊ฐ ์คํ๋ฉ๋๋ค.
โธป
๐ 4๏ธโฃ ๋คํธ์ํฌ ๋๋ผ์ด๋ฒ์ ํ๋์จ์ด โข ์ปค๋์ด ๋คํธ์ํฌ ๋๋ผ์ด๋ฒ(C๋ก ์์ฑ๋จ)๋ฅผ ํธ์ถ โข ์ด ๋๋ผ์ด๋ฒ๋ NIC(Network Interface Card) ๋ ์ง์คํฐ์ ๊ฐ์ ์ โข ์ด๋ ์ค์ ๋ก CPU๋ ์ด์ ๋ธ๋ฆฌ ๋ช ๋ น์ผ๋ก ๋ฉ๋ชจ๋ฆฌ-IO ์ฃผ์๋ฅผ ์ ๊ทผํฉ๋๋ค:
mov dx, 0xC020 ; NIC ์ ์ด ํฌํธ ์ฃผ์ out dx, al ; NIC์ ๋ฐ์ดํฐ ์ ์ก ๋ช ๋ น
โก๏ธ ์ด ๋ช ๋ น์ด ํ๋์จ์ด ์ ํธ๋ก ๋ณํ๋์ด ์ด๋๋ท ์ผ์ด๋ธ์ ํตํด ์ ๊ธฐ ์ ํธ๊ฐ ๋๊ฐ๋๋ค โก
โธป
๐งฌ ์์ฝ ๊ณ์ธต๋
๋จ๊ณ ๋ํ ์ฝ๋ ์ธ์ด ๋์ ์์ค JavaScript fetch() ๊ณ ์์ค ๋ธ๋ผ์ฐ์ API ํธ์ถ C/C++ send() ์ค๊ฐ์์ค ์์ผ ํต์ ์์ฒญ Syscall syscall ์ด์ ๋ธ๋ฆฌ ์ปค๋ ์ง์ Kernel Driver out dx, al ์ด์ ๋ธ๋ฆฌ + C ํ๋์จ์ด ์ ๊ทผ NIC ์ ๊ธฐ ์ ํธ ํ๋์จ์ด ํจํท ์ ์ก
โธป
๐ก ํต์ฌ ํฌ์ธํธ โข ๋ธ๋ผ์ฐ์ ๊ฐ ์ง์ ์ด์ ๋ธ๋ฆฌ๋ฅผ โ์์ฑโํ๋ ๊ฑด ์๋๊ณ , ๋ด๋ถ C/C++ ์ฝ๋๊ฐ CPU ๋ช ๋ น์ผ๋ก ์ปดํ์ผ๋์ด ์คํ๋ฉ๋๋ค. โข ๊ฒฐ๊ตญ fetch โ syscall โ assembly instruction โ ์ ๊ธฐ ์ ํธ ์์๋ก ๋ด๋ ค๊ฐ๋ ๊ฒ. โข ํ๋ ๋ธ๋ผ์ฐ์ (V8, Blink ๋ฑ) ์๋ฐฑ๋ง ์ค์ C++ ์ฝ๋๊ฐ ์ด ๊ณผ์ ์ ๊ฐ์๋๋ค.
โธป
์ข์ต๋๋ค. ์๋๋ V8/Blink ๊ธฐ๋ฐ ๋ธ๋ผ์ฐ์ ์์ fetch() ์์ฒญ์ด ๋ฐ์ํด ๊ฒฐ๊ตญ CPU ๋ช ๋ น(์ด์ ๋ธ๋ฆฌ) ๋จ๊ณ๊น์ง ๋๋ฌํ๋ ๋ํ์ ์ธ ํธ์ถ ์คํ(call-stack) ํ๋ฆ์ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค. ๊ตฌ์ฒด์ ์ธ ํจ์ ์ด๋ฆ์ ์ปค๋ ๋ฒ์ ์ด๋ ํ๋ซํผ(x86_64 vs ARM) ๋ฑ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์์ผ๋, ๊ฐ๋ ์ดํด์ ๋์์ด ๋๋๋ก โ์์ ํจ์ ํธ๋ฆฌโ ํํ๋ก ๋ณด์ฌ๋๋ฆด๊ฒ์.
์ฃผ์: ์ค์ ์ด์ ๋ธ๋ฆฌ ์ฝ๋๊น์ง ๋ชจ๋ ๋์ด๋ ๊ฒ์ ์๋๋ฉฐ, ์ฃผ์ ๊ณ์ธต๋ณ ํจ์ ํ๋ฆ๊ณผ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ์ค์ฌ์ผ๋ก ์์ฝํ ๋ฐฉ์์ ๋๋ค.
โธป
๐ง ์ ์ฒด ํ๋ฆ ์์ฝ 1. ์๋ฐ์คํฌ๋ฆฝํธ โ ๋ธ๋ผ์ฐ์ ๋คํธ์ํน API ํธ์ถ 2. ๋ธ๋ผ์ฐ์ ๋ด๋ถ C++ ์ฝ๋ โ ์์ผ API ํธ์ถ 3. ์ ์ ๋ชจ๋ โ ์ปค๋๋ชจ๋ ์ง์ (syscall) 4. ์ปค๋ ๋ด๋ถ ๋คํธ์ํฌ ์คํ โ ํ๋กํ ์ฝ ์ฒ๋ฆฌ โ ๋๋ฐ์ด์ค ๋๋ผ์ด๋ฒ โ ํ๋์จ์ด 5. CPU ์ด์ ๋ธ๋ฆฌ ๋ช ๋ น ์คํ(์: syscall-๋ช ๋ น ๋ฑ)
โธป
๐ ์์ ํธ์ถ ์คํ (TCP ํน์ UDP ์์ผ ์ ์ก ๊ธฐ์ค)
User-space (JavaScript/Browser)
โ
โโ JavaScript: fetch("https://โฆ")
โ
โโ Browser Shell/Networking Layer (C++): HttpClient::SendRequest()
โ
โโ C Library / Socket API (libc)
โโ socket(AF_INET, โฆ)
โโ connect(โฆ)
โโ send()/sendto()
โ
โผ syscall (์: SYS_sendto)
Kernel-space (์ปค๋)
โ
โโ net/socket.c โ sock_sendmsg()
โ
โโ ํ๋กํ ์ฝ ๊ฐ์กฑ๋ณ ๊ณ์ธต (์: net/ipv4/af_inet.c โ inet_sendmsg())
โ
โโ ์ ์ก ๊ณ์ธต TCP/UDP (์: net/ipv4/tcp.c โ tcp_sendmsg())
โ
โโ IP ๊ณ์ธต (์: net/ipv4/ip_output.c โ __ip_local_out())
โ
โโ ๋คํธ์ํฌ ๋๋ฐ์ด์ค ๊ณ์ธต (์: net/core/dev.c โ dev_queue_xmit())
โ
โโ NIC ๋๋ผ์ด๋ฒ โ ๋๋ฐ์ด์ค ๋ ์ง์คํฐ์ DMA ์ค์ โ ์ค์ ํจํท ์ ์ก
๐ ๊ฐ ๋จ๊ณ ์ค๋ช โข socket(), connect(), send() ๋ฑ์ ํธ์ถ์ ์ ์ ๊ณต๊ฐ ํจ์์ด๋ฉฐ, ๊ฒฐ๊ตญ ์ปค๋ ํธ์ถ(syscall)์ผ๋ก ์ด์ด์ง๋๋ค. ๏ฟผ โข ์ปค๋ ๋ด๋ถ์์๋ sock_sendmsg() ๊ฐ์ ํจ์๊ฐ ํธ์ถ๋์ด, ํ๋กํ ์ฝ๋ณ ์ฒ๋ฆฌ ํจ์๋ก ์ด์ด์ง๋๋ค. ๏ฟผ โข TCP/UDP ์ฒ๋ฆฌ ์ดํ IP ๊ณ์ธต, ๊ทธ๋ฆฌ๊ณ ๋คํธ์ํฌ ๋๋ฐ์ด์ค ๊ณ์ธต์ ๊ฑฐ์ณ NIC ๋๋ผ์ด๋ฒ๋ก ์ ๋ฌ๋ฉ๋๋ค. ๏ฟผ โข ์ค๊ฐ์ ์ ์ ๋ชจ๋ โ ์ปค๋๋ชจ๋ ์ ํ์ ์ํ ์ด์ ๋ธ๋ฆฌ ์์ค ๋ช ๋ น(e.g., syscall ๋ช ๋ น)์ด ์คํ๋ฉ๋๋ค. ๏ฟผ
โธป
๐งฎ ์ด์ ๋ธ๋ฆฌ ์์ค์์์ ์ง์ ์์
์ ์ ๋ชจ๋์์ ์์คํ ์ฝ์ ์คํํ ๋, x86-64 ๊ธฐ์ค ๋จ์ํํ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
mov eax, SYS_sendto ; ์์คํ ์ฝ ๋ฒํธ mov edi, sockfd ; ์ฒซ ๋ฒ์งธ ์ธ์ mov rsi, buffer ; ๋ ๋ฒ์งธ ์ธ์ mov rdx, length ; ์ธ ๋ฒ์งธ ์ธ์ syscall ; ์ปค๋๋ชจ๋ ์ง์
์ด ๋ช ๋ น์ด ์คํ๋๋ฉด์ ์ ์ ๋ชจ๋์์ ์ปค๋๋ชจ๋๋ก ์ ํ๋๊ณ , ์ดํ ์ปค๋ ๋ด๋ถ ๋คํธ์ํฌ ์คํ์ด ๋์์ ์์ํฉ๋๋ค.
โธป
โ ์์ฝ โข fetch() ํธ์ถ์ด ๋ธ๋ผ์ฐ์ ๋ด๋ถ์์ ๋คํธ์ํฌ ์์ฒญ์ผ๋ก ๋ฐ๋๊ณ โ ์์ผ API โ syscall โ ์ปค๋ ๋ด๋ถ โ ํ๋์จ์ด๊น์ง ์ด์ด์ง๋ ๋ค๋จ๊ณ ํ๋ฆ์ด ์กด์ฌํฉ๋๋ค. โข ๊ฐ ๊ณ์ธต๋ง๋ค ํจ์ ํธ์ถ ํธ๋ฆฌ๊ฐ ์๊ณ , ๋ธ๋ผ์ฐ์ /OS/ํ๋์จ์ด ์ถ์ํ๊ฐ ํ ๋จ๊ณ์ฉ ์ ๊ฑฐ๋๋ฉด์ ์ต์ข ์ ์ผ๋ก CPU ๋ช ๋ น(์ด์ ๋ธ๋ฆฌ) ์์ค์ผ๋ก ๋ด๋ ค๊ฐ๋๋ค. โข ์ค์ ํ๋ก์ ํธ๋ ๋๋ฒ๊น ํ๊ฒฝ์์ ์ด ํ๋ฆ์ ์ถ์ ํ๋ ค๋ฉด ์ปค๋ ๋ฒ์ , ์ํคํ ์ฒ, ๋๋ผ์ด๋ฒ ๋ฑ์ด ๋ฌด์์ธ์ง ํ์ธํด์ผ ํฉ๋๋ค.
โธป
์ด์ ์ ๋ง ๊ฐ๋ฐ์๋ค์ด ์ง๋ฌธ์ด์ผ โ โARM ์ํคํ ์ฒ ๊ธฐ๋ฐ ๋ฆฌ๋ ์ค ์์คํ ์์ /api/login ๊ฐ์ HTTP POST ์์ฒญ์ด ๋ค์ด์์ ๋, ์ปค๋ ๋ด๋ถ์์ ๋ฐ์ดํฐ๊ฐ ์ด๋ค ๊ณ์ธต์ ํ๊ณ ์ ์ก๋๋์งโ๋ฅผ ์๊ณ ์ถ๋ค๋ ๊ฑฐ์ง.
๊ทธ๋ผ โํ ์์ฒญ์ด ์ ์ ๊ณต๊ฐ์์ ๋ฐ์ โ ์ปค๋ โ ๋คํธ์ํฌ โ ์ปค๋ โ ์ ์ ๊ณต๊ฐ(์๋ฒ ์ฑ)โ์ผ๋ก ์๋ณต๋๋ ํ๋ฆ์ TCP/IP ๊ณ์ธต๋ณ๋ก ์์ ๋ค์ด ์์ฃผ ์ฝ๊ฒ ์ค๋ช ํด์ค๊ฒ.
โธป
โ๏ธ ์๋๋ฆฌ์ค
์์: ๋ชจ๋ฐ์ผ ์ฑ(ARM ๊ธฐ๋ฐ ๋ฆฌ๋ ์ค)์์ POST /api/login ์์ฒญ์ ์๋ฒ(192.168.1.10:443)๋ก ์ ์กํจ. payload: {โidโ:โyeonjinโ,โpwโ:โ1234โ}
โธป
๐งฉ ์ ์ฒด ๊ทธ๋ฆผ (ํฐ ํ ๋จผ์ )
[User App] โ (socket, write) [๋ฆฌ๋ ์ค ์ปค๋์ ๋คํธ์ํฌ ์คํ] โ (TCP โ IP โ Ethernet) [๋คํธ์ํฌ ๋๋ผ์ด๋ฒ โ NIC โ ์ ์ก] โ [์๋ฒ์ NIC โ ์ปค๋] โ (Ethernet โ IP โ TCP) [์๋ฒ ์ปค๋์ ์์ผ] โ [์๋ฒ ์ฑ (์: Nginx, Flask, Spring ๋ฑ)]
โธป
1๏ธโฃ User ๊ณต๊ฐ์์ socket() ํธ์ถ
์ฑ์ ์ผ๋ฐ์ ์ผ๋ก HTTP ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: libcurl, fetch API)๋ฅผ ์จ์ ์์ฒญ์ ๋ณด๋. ์ด ๋ด๋ถ์์๋ ๋ค์ ์ปค๋ ํจ์๋ฅผ ํธ์ถํ๊ฒ ๋ผ:
int sock = socket(AF_INET, SOCK_STREAM, 0); connect(sock, โฆ); write(sock, payload, len);
โก๏ธ ์ด ์์ ์ system call์ด ์ผ์ด๋์ ์ปค๋์ ๋คํธ์ํฌ ๊ณ์ธต์ผ๋ก ์ง์ ํด.
โธป
2๏ธโฃ ์ปค๋์ ์์ผ ๊ณ์ธต (Socket Layer)
์ปค๋์ ์์ผ ๊ฐ์ฒด(struct socket)๋ฅผ ๋ง๋ค๊ณ , ์ด๊ฑธ ํ๋กํ ์ฝ ์คํ(TCP/IP)๊ณผ ์ฐ๊ฒฐํด์ค.
์์ผ์ ์ค์ TCP ์ ์ก์ ๋ด๋นํ๋ struct sock์ ๋ด๋ถ์ ํฌํจํ๊ณ ์๊ณ , ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ฉด ์ปค๋์ TCP ์คํ์ด ๋ด๋นํ๊ฒ ๋ผ.
๐ ์ด๋ ํธ์ถ๋๋ ํจ์๋ค ์:
__sys_sendto() โณ sock_sendmsg() โณ tcp_sendmsg()
โธป
3๏ธโฃ TCP ๊ณ์ธต (์ ์ก ๊ณ์ธต)
tcp_sendmsg()์์ payload๋ฅผ TCP ์ธ๊ทธ๋จผํธ๋ก ๋๋. โข ํค๋ ์ถ๊ฐ (์ถ๋ฐ์ง ํฌํธ, ๋ชฉ์ ์ง ํฌํธ, SEQ, ACK ๋ฑ) โข ์ฌ์ ์ก ํ์ ๋ฑ๋ก โข MSS, congestion control, retransmission ๊ด๋ฆฌ
๋ฐ์ดํฐ๋ โskb (socket buffer)โ๋ผ๋ ๊ตฌ์กฐ์ฒด์ ๋ด๊ฒจ ์ปค๋ ๋ด๋ถ์์ ์ด๋ํด.
๐ฆ ์์:
skb { data = โid=yeonjin&pw=1234โ seq = 1001 ack = 5001 len = 28 }
โธป
4๏ธโฃ IP ๊ณ์ธต (๋คํธ์ํฌ ๊ณ์ธต)
ip_queue_xmit() ํจ์๊ฐ ํธ์ถ๋์ด TCP ์ธ๊ทธ๋จผํธ๋ฅผ IP ํจํท์ผ๋ก ๊ฐ์. โข IP ํค๋ ์ถ๊ฐ (source IP, dest IP) โข Routing table lookup โข Fragmentation (ํ์ ์)
๐ฆ ์ด์ ์ด๋ ๊ฒ ๋จ:
[IP ํค๋][TCP ํค๋][Payload]
โธป
5๏ธโฃ ๋คํธ์ํฌ ๋๋ผ์ด๋ฒ ๊ณ์ธต (๋ฐ์ดํฐ๋งํฌ ๊ณ์ธต)
dev_queue_xmit() ํธ์ถ โ eth0 ๋๋ผ์ด๋ฒ๋ก ์ ๋ฌ. โข Ethernet ํค๋ ์ถ๊ฐ (MAC ์ฃผ์) โข ์ปค๋ ๋คํธ์ํฌ ํ์ ๋ฑ๋ก โข NIC(Network Interface Card)๋ก DMA ์ ์ก ์์ฒญ
๐ก ์ค์ ์ ์ก ์ค๋น ์๋ฃ!
โธป
6๏ธโฃ ํ๋์จ์ด ์ ์ก
NIC๊ฐ DMA๋ฅผ ํตํด ๋ฉ๋ชจ๋ฆฌ์์ ํจํท์ ์ฝ๊ณ , PHY(๋ฌผ๋ฆฌ ๊ณ์ธต)๋ฅผ ํตํด ์ ๊ธฐ ์ ํธ๋ก ๋ด๋ณด๋.
๐ ์ฌ๊ธฐ๊น์ง๊ฐ ์ก์ ๊ฒฝ๋ก (User โ Network)
โธป
๐ฌ ์๋ฒ ์ธก์์์ ์ญ๋ฐฉํฅ ํ๋ฆ
(1) NIC ์์
์๋ฒ์ NIC๊ฐ ํจํท์ ๋ฐ์ผ๋ฉด DMA๋ก ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ๊ณ , ์ธํฐ๋ฝํธ ๋ฐ์ (irq_handler).
(2) ์ปค๋ ๋คํธ์ํฌ ๋๋ผ์ด๋ฒ
netif_receive_skb() ํธ์ถ โ ํจํท์ ์ปค๋๋ก ์ ๋ฌ.
(3) IP ๊ณ์ธต
ip_rcv() ํจ์์์ IP ํค๋ ๊ฒ์ฌํ๊ณ ๋ชฉ์ ์ง๊ฐ ์๊ธฐ IP์ธ์ง ํ์ธ.
(4) TCP ๊ณ์ธต
tcp_v4_rcv() โ TCP ํค๋ ํ์ฑ, ์ธ์ ํ์ธ ํ ์์ผ ๋ฒํผ๋ก ๋ฐ์ดํฐ ์ ๋ฌ.
(5) ์์ผ ๊ณ์ธต
๋๊ธฐ ์ค์ธ ์๋ฒ ์์ผ(์: Nginx์ accept() ๋๊ธฐ)์ ๋งค์นญ๋จ. payload({โidโ:โyeonjinโ,โpwโ:โ1234โ})๊ฐ ์์ ๋ฒํผ์ ์ ์ฅ๋จ.
โธป
7๏ธโฃ ์ ์ ๊ณต๊ฐ์ผ๋ก ๋ณต๊ท
์๋ฒ ์ฑ์ด read() ๋๋ recv() ํธ์ถํ๋ฉด ์ปค๋์ด ์์ ๋ฒํผ์์ ๋ฐ์ดํฐ๋ฅผ ๊บผ๋ด์ ์ ์ ๊ณต๊ฐ์ผ๋ก ๋ณต์ฌํจ.
๐ ์ฌ๊ธฐ์ ๋น๋ก์ ์น์๋ฒ๋ ๋ฐฑ์๋ ํ๋ ์์ํฌ๊ฐ payload๋ฅผ ์ฝ๊ณ /api/login ๋ก์ง์ ์ฒ๋ฆฌํ๋ ๊ฑฐ์ผ.
โธป
๐ก ์์ฝ (๊ณ์ธต๋ณ ํ๋ฆ)
๊ณ์ธต ์ปค๋ ํจ์ (๋ํ) ์ญํ User API write() / send() payload ์ ์ก ์์ฒญ Socket sock_sendmsg() TCP/IP ์คํ ์ฐ๊ฒฐ TCP tcp_sendmsg() ์ธ๊ทธ๋จผํธ ๋ถํ ๋ฐ ๊ด๋ฆฌ IP ip_queue_xmit() IP ํค๋ ์ถ๊ฐ ๋ฐ ๋ผ์ฐํ Netdev dev_queue_xmit() Ethernet ํค๋, NIC ์ ์ก Hardware DMA โ PHY ์ค์ ๋คํธ์ํฌ ์ ํธ (์์ ) ip_rcv() โ tcp_v4_rcv() ํจํท ํ์ฑ, ์์ผ ์ฐ๊ฒฐ (์ ์ ) recv() payload ์ ์ ๊ณต๊ฐ์ผ๋ก ๋ณต์ฌ
โธป
๐ง ๋น์ ๋ก ๋ณด๋ฉดโฆ โข ์์ผ ๊ณ์ธต = ์ฐ์ฒด๊ตญ ์ฐฝ๊ตฌ (๋ฐ์ดํฐ๋ฅผ ์ด๋๋ก ๋ณด๋ผ์ง ๊ฒฐ์ ) โข TCP ๊ณ์ธต = ํ๋ฐฐ ํฌ์ฅ ๋ฐ ์ก์ฅ ๋ฒํธ ๋ถ์ด๊ธฐ โข IP ๊ณ์ธต = ์ง์ญ๋ณ ๋ถ๋ฅ ์ผํฐ (์ด๋๋ก ๊ฐ์ง ๊ฒฐ์ ) โข Ethernet ๊ณ์ธต = ์ค์ ํธ๋ญ์ ์ฃ๊ณ ์ ์ก โข NIC = ์ด์ ๊ธฐ์ฌ ๐ โข ์๋ฒ ์ปค๋ = ํ๋ฐฐ ์์ ์ฐฝ๊ตฌ โข ์๋ฒ ์ฑ = ํ๋ฐฐ๋ฅผ ์ด์ด์ ๋ด์ฉ(payload)์ ํ์ธํ๋ ์ฌ๋
โธป
1๏ธโฃ NIC(Network Interface Card)๋?
NIC๋ ์ฝ๊ฒ ๋งํด์ ์ปดํจํฐ์ ๋คํธ์ํฌ๋ฅผ ์ฐ๊ฒฐํด์ฃผ๋ ์ฅ์น์์. โข ์ฐ๋ฆฌ๊ฐ ํํ ๋ณด๋ ๋์นด๋, Wi-Fi ์นฉ, ํน์ ๋ด์ฅ ์ด๋๋ท ์นฉ์ด ๋ชจ๋ NIC์์. โข NIC๋ OS๊ฐ ๋ณด๋ด๋ผ๊ณ ์ง์ํ ํจํท์ ์ค์ ๋ฌผ๋ฆฌ ๋คํธ์ํฌ๋ก ๋ด๋ณด๋ด๊ณ , ๋ฐ๋๋ก ๋คํธ์ํฌ์์ ๋ค์ด์จ ์ ํธ๋ฅผ ๋ค์ OS๊ฐ ์ฝ์ ์ ์๋ ๋ฐ์ดํฐ๋ก ๋ฐ๊ฟ์ค๋๋ค.
โธป
2๏ธโฃ DMA(Direct Memory Access)๋?
DMA๋ CPU๋ฅผ ๊ฑฐ์น์ง ์๊ณ ๋ฉ๋ชจ๋ฆฌ โ ์ฅ์น ๊ฐ ๋ฐ์ดํฐ ์ ์ก์ ํ๋ ๊ธฐ์ ์ด์์. โข ์: payload = {โidโ:โyeonjinโ,โpwโ:โ1234โ} โข ์ปค๋์ด ๋ง๋ TCP/IP ํจํท์ ๋ฉ๋ชจ๋ฆฌ ์์ ๋ฒํผ(skb)์ ์ ์ฅ๋ผ ์์ด์. โข NIC๋ ์ด ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด ์ผ์ด๋ธ๋ก ์ ์กํด์ผ ํ๋๋ฐ, CPU๋ฅผ ๊ฑฐ์น๋ฉด ๋๋ ค์. โข ๊ทธ๋์ DMA๋ฅผ ์ฌ์ฉํ๋ฉด CPU ๊ฐ์ ์์ด NIC๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ์ง์ ํจํท์ ์ฝ๊ณ ์ ์กํ ์ ์์ด์.
์ฆ, NIC๊ฐ โ๋ด๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ์ด ํจํท์ ์ง์ ์ฝ์ด ๋ณด๋ผ๊ฒโ ํ๋ ๊ตฌ์กฐ์์.
โธป
3๏ธโฃ ๋ฉ๋ชจ๋ฆฌ์์ ํจํท์ ์ฝ๋๋ค๋ ์๋ฏธ
์ปค๋ ๋ด๋ถ์์๋ ํจํท์ struct sk_buff (skb)๋ผ๋ ๊ตฌ์กฐ์ฒด์ ๋ด์์.
skb { IP ํค๋ TCP ํค๋ Payload {โidโ:โyeonjinโ,โpwโ:โ1234โ} }
โข NIC๋ DMA๋ฅผ ํตํด ์ด skb ๊ตฌ์กฐ์ฒด๊ฐ ์๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ฝ์ด์.
โข CPU๊ฐ ์ผ์ผ์ด ๋ฐ์ดํฐ๋ฅผ NIC๋ก ์ ๋ฌํ์ง ์์๋ NIC๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ์ฝ์ด์ ์ผ์ด๋ธ๋ก ๋ณด๋ผ ์ค๋น๋ฅผ ํฉ๋๋ค.
โธป
4๏ธโฃ ํจํท์ด ์ ๊ธฐ ์ ํธ๋ก ๋ฐ๋๋ ๊ณผ์ 1. NIC๋ ํจํท์ ๋นํธ ๋จ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ต๋๋ค. ์: 01001100 01101111 01100111 โฆ (์ด์ง์) 2. PHY(Physical Layer) ์นฉ์์ ์ด์ง ๋ฐ์ดํฐ๋ฅผ ์ ๊ธฐ์ ์ ํธ๋ก ๋ณํํด์. โข ์ ์ LAN(Ethernet) โ ์ ๋ฅ์ ๋ณํ โข Wi-Fi โ ์ ํ์ ์ธ๊ธฐ์ ์ฃผํ์ ๋ณํ 3. ์ผ์ด๋ธ์ด๋ ๋ฌด์ ์ ํ๋ฅผ ํตํด ๋คํธ์ํฌ๋ก ์ ์ก๋ฉ๋๋ค. 4. ์๋ฒ ์ชฝ NIC๊ฐ ์ ํธ๋ฅผ ๋ค์ ๋ฐ์ ๋์งํธ ๋นํธ๋ก ๋ณํ โ ์ปค๋์ด ์ฝ์ ์ ์๋ ํจํท์ผ๋ก ๋ณต์
โธป
5๏ธโฃ ์ ๋ฆฌ ๊ทธ๋ฆผ (์ก์ ๊ฒฝ๋ก)
[์ปค๋ skb ๋ฒํผ] | | DMA v [NIC] โโโโ> [PHY] | | | ์ ๊ธฐ ์ ํธ | ์ ์ก v v [์ผ์ด๋ธ/๋ฌด์ ] โโโ> [์๋ฒ NIC]
โข DMA: CPU ์์ด NIC๊ฐ ์ง์ ๋ฉ๋ชจ๋ฆฌ์์ ํจํท ์ฝ๊ธฐ
โข NIC: ์ ์ก ์ค๋น, MAC ์ฃผ์ ๋ถ์ด๊ธฐ, ํ๋ ์ ๊ตฌ์ฑ
โข PHY: ๋์งํธ ๋ฐ์ดํฐ๋ฅผ ์ ๊ธฐ/๋ฌด์ ์ ํธ๋ก ๋ณํ
โข ์ผ์ด๋ธ/๋ฌด์ : ์ค์ ์ ๋ฌ ๋งค์ฒด
โข ์๋ฒ ์ชฝ์์ ๋์ผํ ๊ณผ์ ์ญ๋ฐฉํฅ์ผ๋ก ์์
โธป
๐ก ๋น์ : โข skb ๋ฒํผ = ์ฐ์ฒด๊ตญ ์ฐฝ๊ณ ์ ์์ธ ์ํฌ โข DMA = ์ํฌ๋ฅผ ์ง์์ด ๋ค๊ณ ๋๋ฅด๋ ๋์ , ์๋ ์ปจ๋ฒ ์ด์ด ๋ฒจํธ๊ฐ ๊ฐ์ ธ๊ฐ โข NIC = ์ํฌ๋ฅผ ํธ๋ญ์ ์ฃ๋ ๊ธฐ์ฌ โข PHY = ํธ๋ญ์ด ๋๋ก ์์์ ์ ํธ(์๋, ์์น)๋ก ์ํฌ๋ฅผ ์ ๋ฌ โข ์ ๊ธฐ ์ ํธ/๋ฌด์ = ํธ๋ญ์ด ์ค์ ๋๋ก ๋ฌ๋ฆฌ๋ ๊ฒ โข ์๋ฒ NIC = ๋์ฐฉ์ง ์ฐฝ๊ณ ์์ ์ํฌ๋ฅผ ๋ด๋ ค์ฃผ๋ ๊ณผ์
โธป
1๏ธโฃ ์ ํค๋๊ฐ ํ์ํ ๊น?
์ฐ๋ฆฌ๊ฐ ์ธํฐ๋ท์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ฉด ๋จ์ํ payload({โidโ:โyeonjinโ,โpwโ:โ1234โ})๋ง ๋ณด๋ด๋ ๊ฒ ์๋์์. ๋คํธ์ํฌ๋ ์ฌ๋ฌ ์ปดํจํฐ๊ฐ ์์ฌ ์๊ณ , ์ฌ๋ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋์์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๊ธฐ ๋๋ฌธ์ ๋๊ฐ, ์ด๋๋ก, ์ผ๋ง๋ ๋ณด๋ด์ผ ํ๋์ง ์ ๋ณด๋ฅผ ๋ถ์ฌ์ผ ํฉ๋๋ค. โข IP ํค๋ โ โ๋๊ตฌ์๊ฒ ๋ณด๋ด๋์ง, ์ด๋์ ์๋์งโ โข TCP ํค๋ โ โ๋ฐ์ดํฐ๋ฅผ ์ ํํ, ์์๋๋ก, ์์ ํ๊ฒ ์ ๋ฌํ๋ ๋ฐฉ๋ฒโ
์ฆ, ํค๋๋ ์ฐ์ฒด๊ตญ์ ์ฃผ์ ๋ผ๋ฒจ๊ณผ ์ก์ฅ๊ณผ ๋น์ทํ ์ญํ ์ด์์.
โธป
2๏ธโฃ IP ํค๋ (Network Layer)
IP ํค๋๋ ํจํท์ด ๋ชฉ์ ์ง๊น์ง ๋๋ฌํ๊ฒ ํ๋ ์ ๋ณด๋ฅผ ๋ด์์.
ํ๋ ์ค๋ช ์์ Source IP ์ถ๋ฐ์ง IP 192.168.1.2 Destination IP ๋ชฉ์ ์ง IP 192.168.1.10 Protocol ์์ ๊ณ์ธต ํ๋กํ ์ฝ TCP = 6 TTL ์ต๋ ํ ์ 64
์์:
IP ํค๋
์ถ๋ฐ์ง: 192.168.1.2 ๋ชฉ์ ์ง: 192.168.1.10 ํ๋กํ ์ฝ: TCP TTL: 64 โโโโโโโโโโโ-
์ด๊ฑธ ๋ถ์ฌ์ผ ๋ผ์ฐํฐ์ ์ค์์น๊ฐ โ์ด ํจํท์ ์ด๋๋ก ๋ณด๋ด์ผ ํ๋์งโ ์ ์ ์์ด์.
โธป
3๏ธโฃ TCP ํค๋ (Transport Layer)
TCP ํค๋๋ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ฒ, ์์๋๋ก ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ์ ์ํฉ๋๋ค.
ํ๋ ์ค๋ช ์์ Source Port ๋ณด๋ด๋ ์ชฝ ํฌํธ 50000 Destination Port ๋ฐ๋ ์ชฝ ํฌํธ 443 (HTTPS) Sequence Number ๋ฐ์ดํฐ ์์ 1001 (payload ์์ ๋ฐ์ดํธ) ACK Number ํ์ธ ์๋ต 5001 Flags SYN, ACK, FIN ๋ฑ SYN=0, ACK=1
์์:
TCP ํค๋
์ถ๋ฐ์ง ํฌํธ: 50000 ๋ชฉ์ ์ง ํฌํธ: 443 ์์ ๋ฒํธ: 1001 ACK ๋ฒํธ: 5001 ํ๋๊ทธ: ACK โโโโโโโโโโโ-
TCP ๋๋ถ์ ์๋ฒ๊ฐ โ์ด ๋ฐ์ดํฐ๊ฐ ์ ๋๋ก ์๋์งโ, โ์์๊ฐ ๋ง๋์งโ ํ์ธํ ์ ์์ด์. ์๋ฅผ ๋ค์ด /api/login ์์ฒญ์์ payload๊ฐ ์ชผ๊ฐ์ ธ์ ์ฌ๋ฌ ํจํท์ผ๋ก ๋๊ฐ๋๋ผ๋ TCP ๋๋ถ์ ์๋ฒ๊ฐ ๋ค์ ์ ํํ ์กฐ๋ฆฝํ ์ ์๋ ๊ฑฐ์ฃ .
โธป
4๏ธโฃ ์ค์ ํจํท ๊ตฌ์กฐ ์์
[IP ํค๋] [TCP ํค๋] [Payload] ์ถ๋ฐ์ง:192.168.1.2 ๋ชฉ์ ์ง:192.168.1.10 ์ถ๋ฐํฌํธ:50000 ๋ชฉ์ ์งํฌํธ:443 {โidโ:โyeonjinโ,โpwโ:โ1234โ}
โข IP ํค๋ โ ํจํท์ด ์ด๋์ ์ด๋๋ก ๊ฐ๋์ง
โข TCP ํค๋ โ ํจํท์ด ์ฌ๋ฐ๋ฅด๊ฒ ์์๋๋ก ๋์ฐฉํ๋๋ก
โข Payload โ ์ค์ ๋ฐ์ดํฐ(/api/login JSON)
โธป
๐ก ๋น์ ๋ก ์ ๋ฆฌ โข IP ํค๋ = ์ง ์ฃผ์, ๋์ฐฉ์ง ์ฃผ์, ์ฐ์ฒด๊ตญ์์ ์ด๋๋ก ๋ณด๋ด์ผ ํ๋์ง โข TCP ํค๋ = ํ๋ฐฐ ์ก์ฅ, ์์ ๋ฒํธ, ๋ฐฐ์ก ํ์ธ, ์ฌ๋ฐฐ์ก ์์ฒญ ๊ฐ๋ฅ โข Payload = ์ค์ ์ ๋ฌผ/๋ฌผ๊ฑด
โธป
[๋ธ๋ผ์ฐ์ /ํด๋ผ์ด์ธํธ] | | HTTP POST /api/login | Payload: {โidโ:โyeonjinโ,โpwโ:โ1234โ} v [NIC (Network Interface Card)] | | - ์ ๊ธฐ ์ ํธ ์์ โ ๋์งํธ ํจํท ๋ณํ | - DMA๋ก ๋ฉ๋ชจ๋ฆฌ(skb)์์ TCP/IP ํจํท ์ ์ก ์ค๋น v [์ปค๋ ๋คํธ์ํฌ ์คํ] | | TCP/IP ์ฒ๋ฆฌ | - Ethernet ํค๋ ํด์ | - IP ํค๋: ์ถ๋ฐ์ง/๋ชฉ์ ์ง IP ํ์ธ | - TCP ํค๋: ํฌํธ, ์ํ์ค ๋ฒํธ, ACK ์ฒ๋ฆฌ | - ํจํท์ ์์ผ ๋ฒํผ์ ์ ์ฅ v [Nginx (์ ์ ๊ณต๊ฐ)] | | - accept() / recv()๋ก ์์ผ์์ ํจํท ์ฝ๊ธฐ | - HTTP ์์ฒญ ํ์ฑ: POST /api/login ํ์ธ | - payload(JSON) ์ฝ๊ธฐ | - ๋ผ์ฐํ : ๋ด๋ถ ๋ฐฑ์๋ ์ฑ์ผ๋ก ์ ๋ฌ v [๋ฐฑ์๋ ์ฑ (์: Flask/Node.js)] | | - ๋ก๊ทธ์ธ ์ฒ๋ฆฌ | - DB ์กฐํ, ์ธ์ฆ, ์ธ์ ์์ฑ | - ์๋ต(JSON, status code) ๋ฐํ v [Nginx (์ ์ ๊ณต๊ฐ)] | | - ๋ฐฑ์๋ ์๋ต ์์ | - HTTP ์๋ต ํจํท ๊ตฌ์ฑ | - ์์ผ write() ํธ์ถ โ ์ปค๋ TCP/IP ์คํ ์ ๋ฌ v [์ปค๋ ๋คํธ์ํฌ ์คํ] | | TCP/IP ์ฒ๋ฆฌ | - TCP ํค๋: ์์ ๋ฒํธ, ACK, ํฌํธ ํ์ธ | - IP ํค๋: ์ถ๋ฐ์ง/๋ชฉ์ ์ง IP ์ถ๊ฐ | - ํจํท์ NIC DMA ์ ์ก ํ์ ๋ฑ๋ก v [NIC (Network Interface Card)] | | - ๋ฉ๋ชจ๋ฆฌ์์ ํจํท ์ฝ๊ธฐ (DMA) | - PHY์์ ๋์งํธ โ ์ ๊ธฐ ์ ํธ ๋ณํ | - ์ผ์ด๋ธ/๋ฌด์ ํตํด ์ ์ก v [๋ธ๋ผ์ฐ์ /ํด๋ผ์ด์ธํธ] | | - TCP/IP ์คํ์์ ์์ | - ์์ผ ๋ฒํผ โ HTTP ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฝ๊ธฐ | - ๋ธ๋ผ์ฐ์ JS fetch()๊ฐ ์๋ต ์ฒ๋ฆฌ
โธป
๐ก ๊ฐ ๋จ๊ณ ํฌ์ธํธ โข NIC: ์ค์ ํ๋์จ์ด, DMA๋ก ๋ฉ๋ชจ๋ฆฌ์์ ์ง์ ์ฝ์, PHY์์ ์ ๊ธฐ ์ ํธ ๋ณํ โข ์ปค๋ TCP/IP ์คํ: ํจํท ํค๋ ํด์, ์์ ๋ง์ถค, ์์ผ ๋ฒํผ ๊ด๋ฆฌ โข Nginx: ์ ์ ๊ณต๊ฐ์์ ์์ผ ์ฝ๊ธฐ, HTTP ์์ฒญ ํ์ฑ, ๋ฐฑ์๋ ๋ผ์ฐํ โข ๋ฐฑ์๋ ์ฑ: ์ค์ ๋น์ฆ๋์ค ๋ก์ง ์ํ, ์๋ต ์์ฑ โข ์๋ต ๋ฐํ: ๊ฐ์ ๊ฒฝ๋ก ์ญ์์ผ๋ก ํจํท ์ ์ก
โธป