title: 성공과 실패를 결정하는 1%의 네트워크 원리 - 2. Data of TCP/IP to Electronic Signal
date: 2022-10-25
tags:
- Network
Introduction
네트워크에 대한 이해도를 높이기 위하여 네트워크 전반에 대한 지식을 얻고자한다.
처음부터 끝까지 깊게 배우기보다는 전체적인 흐름을 파악하고 필요한 부분을 깊게 배우고 싶었으며, 이 서적이 해당 목적에 가장 잘 어울린다고 판단하였다.
이번 Chapter는 2장 TCP/IP to Electronic Signal
이다.
Purpose
Protocol Stack과 LAN Adapter의 동작과 송수신시 신호 변환까지의 동작을 확인한다.
Configure Socket
Configuration of Protocol Stack
일반적으로 최상위 Layer인 Application은 하위 Layer에 작업을 의뢰하며, 하위 Layer는 해당 작업을 처리하는 방식으로 최하단에는 LAN Adapter가 존재한다.
이 Layer의 구분은 명확하지 않거나 관계가 역전되는 경우도 존재한다.
Application이 Message 송수신을 Protocol Stack에 요청한다. 이 때 Socket Library는 Application과 같은 Layer에 있는 것으로 간주한다.
목적에 맞게 TCP, 혹은 UDP Protocol을 이용하여 송수신한다. 안정적인 통신의 목적의 경우 TCP, DNS Server에 대한 조회와 같은 짧거나 빠른 데이터 송수신의 경우 UDP를 주로 사용한다.
적절한 Protocol 선정 후 IP Protocol을 이용하며, 이 때는 ICMP (Internet Control Message Protocol)와 ARP (Address Resolution Protocol)를 다루는 부분이 포함되어 있다.
ICMP는 Packet 운반시 발생하는 오류나 제어용 Message를 알려주며, ARP는 IP Address에 대응하는 Ethernet의 MAC Address를 조사할 때 사용된다. 두 Protocol에 대한 자세한 설명은 뒤에 다시 나온다.
아래에는 LAN Driver가 LAN Adapter H/W를 제어하며, 그 아래에 존재하는 LAN Adapter가 실제 송수신 작업을 실행한다.
Control Information
이전 장에서 Socket이 네트워크를 연결하는 파이프라고 보았는데, Socket은 엄밀히 말하자면 제어 정보가 포함되어 있으며, Protocol Stack이 이를 참조한다.
Protocol Stack에는 통신 동작을 제어하는 정보를 기록하는 Memory 영역이 존재한다. IP Address, Port number, 통신 동작의 상태 등과 같은 정보가 있다.
Socket은 개념에 가까운 실체가 없는 것이며, 이 제어 정보 혹은 이를 기록하는 Memory 영역이 Socket의 실체라고 볼 수 있다.
Protocol Stack은 이 정보들을 참조하여 동작한다. 송신할 때 상대방의 정보, Timeout을 판단하기 위한 시간 등과 같은 정보가 하나의 예시이다.
Window의 경우 netstat -ano
명령을 통해 Socket의 내용을 확인할 수 있다.
Protocol의 종류, Local IP Address, 연결된 상대방의 IP Address, 통신 State, PID가 나타난다.
Local IP Address의 0.0.0.0은 특정한 IP Address와 연결되지 않은 것을 뜻한다.
상대방의 IP Address의 0.0.0.0도 아직 연결이 되지 않은 것이며, UDP의 경우 상대방과 연결이 되지 않기에 *:*
처럼 나타난다.
통신 State의 경우 LISTENING
은 상대방의 연결을 기다리는 State, ESTABLISHED
는 연결이 되었다는 것을 나타낸다.TIME_WAIT
와 CLOSE_WAIT
와 같은 State도 확인하였는데, 이는 TCP Connection을 끊을 때 진행하는 4-way Handshake의 일부 상태이다.
Process with Socket
이전 장에서 DNS Server를 통해 IP Address를 알아내고 Socket을 이용하여 통신하는 과정을 알아보았다.
DNS Server를 통해 IP Address를 알아내는 과정은 UDP를 이용하며, 이후 Socket을 이용하는 과정은 TCP가 사용된다고 보는 것이 일반적이다.
Socket 생성시 Protocol Stack은 Socket 한 개 분량의 Memory를 확보한 후 Socket의 초기 정보를 기록한다.
이러한 작업을 거쳐 Socket이 생성되며, 이후 Descriptor를 알려주어 Socket을 특정할 수 있게 된다.
Socket에 대한 정보가 Protocol Stack에 저장되어 있기에 Descriptor를 Application에 넘겨주고, 이를 통해 Socket의 정보를 확인하여 처리를 할 수 있는 것이다.
Access to Server
Connection
Ethernet이나 통신 회선은 항상 연결이 유지되지만, Application에서의 연결은 필요할 때 진행한다.
그렇기에 Socket에 대한 Descriptor와 더불어 IP Address와 Port가 필요하다.
Server의 입장에서는 이미 Socket은 생성하였으나 상대방(Client)가 정해지지 않은 상황이다.
우선 Client의 IP Address와 Application에서 사용하는 Port를 Server에 넘겨주고, 연결을 하게 될 Server의 IP Address와 Port를 받는 등 제어 정보를 서로 주고 받는다.
데이터를 송수신할 때 이를 임시로 저장할 공간을 할당하며, 이를 Buffer Memory라 부른다.
Buffer Memory까지 확보가 되면 연결이 된 것이다.
TCP Header
위와 같이 제어 정보를 기록하는 TCP Header가 존재한다.
최소 20Bytes에서 Options Field의 최대 길이인 40Bytes를 포함한 60Bytes까지 가변적인 길이를 가진다.
이 TCP Header를 Segment라 부르며, 연속된 Segment가 송수신된다.
- Source & Destination Port - 송수신하는 Program(Process)의 Port
- Sequence Number - Segment의 시작 위치를 알려준다. 이것이 있어야 연속된 Segment를 구분할 수 있다.
- Acknowledgement Number - 다음에 받아야 하는 위치를 알려준다. Handshake 과정에서는 상대방이 보낸 Sequence Number + 1로 설정하나, 데이터 송수신시에는 상대방이 보낸 Sequence Number + 받은 데이터의 Bytes로 설정한다.
- Data Offset - Options Field가 가변적이므로 TCP Header 이후에 시작되는 Data의 위치를 알려준다. 4Bytes 단위로, 값이 6이라면 현재 Header의 처음 + 24Byte 직전까지 TCP Header라는 의미이다.
- Reserved - 미래를 위해 예약된 Field이나 현재는 사용하지 않는다. 기존에는 6Bits였으나, Control Bits가 늘어나 3Bits로 줄었다.
- Control Bits(Flags) - 각 Bit가 Segment의 속성을 나타낸다. 기존에는 URG부터 FIN까지 6Bits였으나, 3Bits의 추가로 9Bits가 되었다.
- 추가된 3개의 정보는 Network의 ECN (Explicit Congestion Notification)을 위한 정보이다. Timeout을 개선하고자 도입되었다.
- CWR, ECE, ECT, CE 4개의 정보가 있으며 전자 2개는 TCP Header, 후자 2개는 IP Header에 존재한다.
- URG (Urgent) - 긴급한 데이터를 의미하며, 높은 Priority를 가지고 처리가 된다. 요즘에는 잘 사용하지 않는다고 한다.
- ACK (Acknowledgement) - 데이터가 올바르게 도착하였다는 것을 의미한다.
- PSH (Push) - Telnet과 같이 상호작용이 중요한 Protocol에서는 빠른 응답이 중요하다. 현재 Segment의 데이터를 Application에 빠르게 전달한다는 의미이다. 0이라면 무시하고 Segment를 계속 받으며, 1이라면 이후에 Segment가 존재하지 않는다는 것을 의미하기도 한다.
- RST (Reset) - 연결의 재설정을 의미한다. 양측 모두에서 연결을 끊는다.
- SYN (Synchronization) - TCP 연결시 3-way Handshake를 실시하며, Sequence Number의 동기화를 위해 사용하는 Segment를 의미한다.
- FIN (Finish) - 상대방과의 연결을 종료한다는 의미이다. 첫 FIN 이후 4-way Handshake를 통해 연결이 종료된다.
- NS (Nonce Sum) - ECN-Nonce Concealment Protection. CWR Field 혹은 ECE Field의 장애 혹은 의도적인 Concealment로부터 보호하기 위하여 ECN에 추가된 Optional Field이다.
- CWR (Congestion Window Reduced) - ECE Flag를 감지하면 Congestion이라는 것이며, Window Size를 줄인 후 CWR Flag를 설정하여 보낸다.
- ECE (ECN-Echo) - Router의 RED (Random Early Detection)알고리즘으로 인해 지연을 감지했다는 패킷을 수신받을 때 Congestion Control을 위해 사용한다. Window Size를 줄이거나 전송 속도를 줄인다. CWR Flag가 설정된 Packet을 받기 전까지 계속하여 ECE Flag를 설정하여 보낸다.
- SYN = 1 -> TCP 상대가 ECN이 가능함을 의미
- SYN = 0 -> IP Header에 CE Flag를 설정한 Packet이 수신되었음을 의미
- Window Size - 수신 확인 없이 한 번에 전송할 수 있는 데이터의 크기이다. 과거에는 최대 약 64KB이었으나, 대용량 전송이 보편화된 현재에는
WSCALE
Field를 추가적으로 사용하여 Shift를 통해 Window Size의 크기를 증가시킨다. - Checksum - 데이터를 16bits씩 나누어 더하며, Overflow가 발생하는 bit는 최하위 bit로 다시 보내어 계산한 후, 마지막으로 1의 보수를 취한다. 수신측에서는 동일한 방법으로 계산한 후, 1의 보수를 취하지 않고 Checksum과 더해 모든 bit가 1이라면 데이터가 정상적으로 수신되었음을 알 수 있다.
- Urgent Pointer - Control Bit의 URG Flag가 설정되었을 경우, 현재 Field가 가리키는 위치를 우선적으로 처리한다.
- Option - 0 ~ 40Bytes의 크기를 가진다. Window Size를 늘리는 WSCALE, 데이터의 올바른 전송을 위한 Selective Repeat 기법에 관련된 SACK 등이 존재한다. 매우 많은 옵션이 존재하기에 자세히 다루지는 않는다. Data Offset이 0이 아니라면 4Bytes 단위로 전달해야 하기에 부족한 Bytes만큼 0으로 채운다. (Padding)
ECN에 관련된 내용은 간단히 Congestion Control을 위한 내용이며, 상세한 동작의 경우 일관되고 명확한 자료를 찾기가 어려웠으며, 정확하지 않은 내용이 포함되었을 수 있다.
IP Header, Ethernet Header 등도 존재하기에 어떠한 Header인지 명시해주어야 한다.
Packet이 전달될 때는 앞에 Ethernet 혹은 IP Header - TCP Header - Data 순서로 전달이 된다.
Header는 이와 같이 규격화되었으나, Protocol Stack은 그렇지 않기에 만드는 사람에 따라 다른 정보를 처리할 수 있다.
이러한 제어 정보는 Socket의 Memory에도 기록이 되며, 이는 상대방에서 확인할 수 없다.
Process with Connection
Socket Library의 connect 함수가 호출되면 Server와 TCP 3-way Handshake를 통해 연결한다.
SYN을 1로 설정하며, 무작위 숫자를 Sequnce Number로 설정하여 보낸다.
Server는 이를 확인하여, 올바른 연결 요청이라면 Client에 SYN과 ACK를 1로 설정, Acknowledgement Number를 받은 Sequence Number + 1로, Sequence Number를 무작위 숫자로 설정하여 보낸다.
Client는 Server의 정보와 접속 완료를 나타내는 제어 정보를 기록한다. 마지막으로 다시 Server에 ACK를 1로 설정, Acknowledgement Number를 받은 Sequence Number + 1로 설정하여 보내주어 연결이 되는 것이다.
연결이 유지되는 것을 이전 장에서 파이프라고 하였으며, 이는 Connection 혹은 Session이라 부른다. close 함수를 호출하기 전까지 Connection이 유지된다.
Exchange Data
write 함수 호출을 통해 Message를 송신한다.
Fragment of Packet
Protocol Stack은 보내려는 데이터의 Binary 표현의 길이만 알며, 데이터의 내용은 알지 못한다.
보내려는 데이터를 송신 Buffer Memory에 저장하여 Application에서 다음 데이터를 주는 것을 기다린다.
데이터를 한 번에 보낼 수도 있으며, 잘라서 보낼 수도 있으며 이는 Application에서 관장한다.
받는 즉시 데이터를 보내는 것은 과한 전송이 일어날 수 있기에, 우선 Buffer Memory에 저장하여 기다리는 것이다.
기다리는 한계는 OS의 종류와 버전에 따라 다르나, 일반적으로는 데이터의 길이와 송신 타이밍을 기준으로 판단한다.
우선 MTU (Maximum Transmission Unit)는 한 Packet에서 송신할 수 있는 IP Header + TCP Header + Data 의 최대 크기를 의미한다.
Ethernet에서는 보통 1500Bytes이며, Header의 길이를 뺀 MSS (Maximum Segment Size)가 Data의 최대 크기이다.
Buffer Memory에 저장된 데이터가 MSS와 비슷해지거나 이를 초과하면 Packet을 전송한다.
데이터가 저장되는 속도가 느리다면 송신이 지연되기에, Protocol Stack 내부의 타이머가 일정 시간을 지나면 Packet을 전송한다.
전자에 집중하면 데이터 크기 측면에서의 효율은 좋아지나 지연이 발생할 수 있으며, 후자에 집중하면 데이터 크기 측면에서의 효율은 낮으나 지연이 줄어들 수 있다.
이에 대한 규정이 없기에 정확한 기준은 Protocol Stack을 만드는 사람에 달려있으며, 이 때문에 OS의 종류 혹은 버전에 따라 다르다는 것이다.
메신저와 같은 실시간 통신이 중요한 Application에서는 바로 전송을 원할것이며, 이 때문에 Application에는 Buffer Memory에 저장하지 않고 바로 전송하는 Option이 존재한다.
HTTP Method를 이용하여 긴 게시글을 보낼 경우, MSS를 바로 초과해버릴 수 있다.
이러한 경우 HTTP Header 또한 Data 영역으로 간주한 후, MSS에 맞게 데이터를 분할하여 전송한다.
Check Packet Arrival with ACK
TCP를 담당하는 부분에서 긴 데이터를 분할할 때, 각 조각이 첫 통신부터 몇 번째 Byte에 위치하는지 기록한다. 이것이 Sequence Number이다.
데이터의 크기도 전달해야 하지만, 여기서는 데이터를 받을 때 전체 Packet의 길이에서 Header의 길이를 빼 데이터의 크기를 구한다.
이러한 정보들을 통해 Message를 수신할 때 다음에 들어올 데이터의 Sequence Number를 알 수 있으며, 중간에 빠져있다면 데이터가 누락되었음을 알 수 있다.
누락되지 않음을 확인한다면 NBytes까지 수신했을 때, Acknowledgement Number를 N+1로 설정하여 Message를 보냄으로써 데이터를 무사히 받았음을 알려준다. 이것이 Acknowledgement이다.
Sequence Number가 1부터 시작할 경우, 이를 예측한 악의적인 공격이 들어올 수 있기에 무작위 값으로 시작한다.
지금까지는 한 방향의 통신의 경우이지만, 양방향 통신이 이루어질 때는 반대 방향으로 동일한 동작이 중간중간 껴있는 형태이다.
또한 송신한 데이터에 대한 ACK가 오지 않는다면 이를 받을 때까지 데이터를 다시 보낸다.
이 덕분에 TCP는 오류를 검출하고 이를 회복하여 다시 데이터를 보내며, 다른 곳에서 오류 회복을 신경쓰지 않는다.
LAN Adapter, Buffer, Router 모두 이를 신경쓰지 않고 TCP에 맡긴다.
다만 Server가 아예 작동을 안 하거나 케이블 단선 등의 문제가 발생할 수 있기에, TCP는 Packet 재전송을 몇 번 진행하여도 응답이 없으면 회복이 되지 않는다고 판단하고 Application에 이를 알려준다.
Timeout
Connection을 생성하거나 상대방의 응답을 기다리는 시간에 제한이 없다면 평생 기다리는 상황이 생길 수 있다.
이러한 문제를 해결하기 위해 Timeout이 도입되었다.
- Connection Timeout - Connection 생성까지 소요되는 시간의 임계치
- Read Timeout - Connection 생성 이후, 데이터를 전송하고 이에 대한 응답을 받기까지 걸리는 시간의 임계치.
- Network가 혼잡하여 지연이 될 수도 있는데, 올바르게 전송이 되지 않았다고 판단하여 재전송하면 혼잡이 더 가중된다.
- 설정한 시간만큼 기다린 후, 응답이 없다면 Packet을 재전송한다. 너무 짧으면 과한 재전송이 이루어질 수 있으며, 너무 길면 전송이 지연되어 속도가 저하된다.
- Socket Timeout - 각 데이터를 보낼 때 생기는 Gap의 임계치. 이 값이 너무 짧으면 많은 Packet이 전송되며, 너무 길면 전송이 지연된다.
이러한 Timeout 설정에는 많은 요소를 생각해야한다. Read Timeout의 경우 Message 처리, 서버의 거리에 따른 전송 시간, 혼잡하여 지연되는 시간 등을 고려해야 한다.
인트라넷의 경우 수 ms만에 응답이 오기도 하지만, 인터넷의 경우 수백 ms를 넘는 경우도 많다.
또한 TCP는 Timeout 시간을 동적으로 변경한다. 응답 시간이 길어지면 Timeout을 늘리기도 하며, 응답이 빠르면 0.5초 정도로 짧게 줄이기도 한다.
Window Size
Network를 이용하여 데이터 송수신시에 겨우 KB단위의 데이터만 주고받는것이 아닌 MB, GB 단위의 데이터까지 주고받게 된다.
이렇게 데이터의 용량이 커지는 상황에서 한가하게 송신한 데이터의 응답을 기다린다면 적은 데이터의 교환만 가능할 것이다.
이렇게 하나의 데이터를 보내고 이에 대한 응답을 기다리는 방식을 Ping Pong이라고 한다.
Ping Pong의 경우 위와 같은 한계가 존재하며, 이를 해결하기 위해 윈도우 제어 방식이 도입되었다.
송신한 데이터의 응답을 기다리는 대신, 데이터를 계속하여 송신한다. 응답을 기다리는 시간을 낭비하지 않고 빠른 통신이 가능하다.
다만, 수신받는 상대방의 처리 능력 < 전송 속도 일 경우, 상대방의 수신 Buffer가 가득 차 데이터가 제대로 전송이 되지 않고 지연될 수 있다.
상대방에게 자신의 수신 Buffer의 크기를 알려주면 이를 해결할 수 있다.
데이터를 송신할 때 상대방 수신 Buffer에서 받을 수 있는 데이터의 크기를 계산하며, 꽉 차거나 보낼 수 없다면 상대방이 데이터를 임의의 크기만큼 처리했다는 응답을 보내기까지 기다린다.
수신받는 상대방은 데이터 도착과 동시에 처리를 시작하며, 처리가 끝나 수신 Buffer에서 데이터를 추출하면 그 크기를 TCP Header의 Window Size Field에 기록하여 응답으로 보내준다.
수신 가능한 데이터의 최대 크기, 즉 수신 Buffer의 크기를 Window Size라고 부른다.
이러한 방식의 통신은 양방향으로 일어나기에 지연 시간을 줄이고 빠르게 통신을 할 수 있는 것이다.
Combination of ACK and Window
송신의 경우 응답을 기다리지 않고 빠르게 송신할 수 있게 되었다.
하지만 모든 송신에 대한 응답을 해주면 많은 Packet이 응답이 될 것이며, 이는 Network 통신 속도의 저하로 이어진다.
이로 인하여 수신 응답은 매번 일어나지 않는다.
데이터를 정상적으로 수신하였다는 ACK 응답, 그리고 수신 Buffer에 여유가 생겼다는 윈도우 통지 두 가지를 보내주어야 한다.
데이터를 수신하면 바로 ACK 응답을 하지 않고 잠시 기다린다.
이 사이에 데이터가 새로 들어오면 ACK 응답을 최근 값으로 갱신해주며, 수신 Buffer에 여유가 생기면 이러한 내용도 대기중인 Packet에 갱신해준다.
이러한 작업 덕분에 보내야 하는 많은 Packet이 하나의 Packet으로 줄어들어 Network를 효율적으로 사용할 수 있다.
HTTP Response
HTTP Request Method는 Response가 동반된다.
HTTP Request Message를 전송하면 Protocol Stack은 Response Message가 모두 들어올 때까지 수신 Buffer 처리를 중단하였다가, 모든 Response Message가 들어오면 이를 처리하여 Application에 보내준다.
Eliminate the Socket with Disconnection
Cut the Connection when Received All Data
Application에서 보내야하는 데이터를 모두 송신하였다면 Connection을 끊는 과정에 들어간다.
Web Browser라면 HTTP Request Message를 보낼 것이며, Server가 HTTP Reponse Message를 보낸 후 Connnection을 끊으려고 할 수 있다.
상황에 따라 먼저 Connection을 끊는 주체가 다를 수 있기에 Protocol Stack은 먼저 Connection을 끊어도 좋게 만들어져 있다.
Socket Library의 close 함수를 호출하며, 상대방에게 FIN Flag를 1로 설정한 후 Packet을 보낸다.
상대방은 이를 받고 ACK 응답을 하며, 다시 FIN Flag를 1로 설정한 후 Packet을 보낸다.
마지막으로 ACK 응답을 해주고, Socket을 바로 없애지 않고 몇 분 정도 기다린 후 Socket을 없앤다.
Wait to Eliminate the Socket
첫 FIN Packet 송신 직후 Socket을 없앨 경우, 다른 Application이 우연하게도 같은 Port를 이용하여 Socket을 생성할 수 있다.
생성과 동시에 상대방의 FIN Packet이 도착하여 Connection이 종료될 수 있으며, 문제는 없더라도 불필요한 동작이다.
그렇기에 Socket을 없애기까지 몇 분 정도 기다린 후, Socket을 없애는 것이다.
Packet & Exchange Data at Ethernet
지금까지는 TCP Header와 관련한 동작을 살펴보았다. 이제 IP & Ethernet Header에 관련된 동작을 살펴본다.
Packet
Packet 전송 과정에서 송신처에서 수신처를 향해 Packet을 보내면 수신처는 송신처를 향해 응답 Packet을 보낸다.
송신처와 수신처는 바뀔 수 있기에 이를 명확하게 구분하지 않는 것이 편리할 수 있다. 이 두 가지를 묶어 End Node라고 부른다.
TCP는 Header와 데이터를 이용하여 TCP Packet을 만들며, IP 담당 부분에 이후의 동작을 맡긴다.
IP 담당 부분은 IP Address를 포함한 IP Header를 앞에 추가하고, DataLink Layer의 무언가는 MAC Address를 포함한 Ethernet Header를 그 앞에 추가한다.
목적지 방향에 있는 가까운 Router의 MAC Address를 Ethernet Header의 Destination으로 설정한 후, Ethernet의 원리에 따라 같은 Subnet에 있는 Hub에 도착한다.
Hub를 경유하며 목적으로 하는 Router로 이동한 후, Router는 IP Address를 통해 다음 Router를 탐색한 후 Ethernet Header를 새로 만들어 기존의 Ethernet Header는 버린다.
이러한 방식으로 Hub와 Router를 거치며 최종 목적지까지 이동하는 것이 TCP/IP Network에서의 Packet이 전송되는 과정이다.
IP와 Ethernet의 역할이 분담되었으나, Ethernet을 대체할 수 있는 요소는 다양하다. Ethernet을 바꾼다면 Ethernet Header가 바뀌는 통신 기술의 요소에 적합한 Header로 대체된다.
Network Layer & Packet
본 서적에서는 IP 담당 부분이 IP Header와 Ethernet Header 모두 추가한다고 하지만, OSI 7 Layer에서는 이 부분이 나뉘어있다. IP와 관련된 부분은 Kernal이라 볼 수 있으며, MAC과 관련된 부분은 H/W라고 볼 수 있다. 주로 사용하는 TCP/IP 4 Layer 또한 비슷한 구조로 나뉘어있다.
MAC Address는 일반적으로 LAN Card에서 다루며, 본 서적에서는 편의상 두 부분을 합쳐서 말하는 것이라 예상한다.
데이터 송신시 Ethernet Header까지 추가된 Packet을 Network용 H/W에 넘겨주며, 이 장치는 형태에 따라 명칭이 모두 다르다. 서적에서는 이를 간단하게 LAN Adapter로 칭한다.
LAN Adapter에 건네주는 Packet은 0와 1의 bits가 이어진 형태이어야 하며, LAN Adapter가 이것을 빛이나 전기의 신호로 바꾸어 통신한다.
데이터 수신은 이를 역으로 거치면 된다. LAN Adapter는 Analog 신호를 Digital의 형태로 변환하여 상위 Layer에 전달한다.
Ethernet Header를 추출하고 남은 부분을 올리고, IP Header를 추출하고 남은 TCP Header를 TCP 담당 부분에 건네준다.
IP 담당 부분은 TCP Header와 데이터를 한 덩어리의 Binary 데이터로 간주하기에 내용물을 알지 못한다. 이것은 Packet의 누락, 순서 변경 등을 신경쓰지 않는다는 의미이기도 한다.
Ethernet Header를 담당하는 무언가도 IP Header를 포함하여 이것을 Binary 데이터로 간주할 것이라 예측한다.
IP Header
TCP Header의 앞에는 IP Header가 들어간다.
TCP Header와 동일하게 최소 20Bytes에서 Options Field의 최대 길이인 40Bytes를 포함한 60Bytes까지 가변적인 길이를 가진다.
- Version - IP Protocol의 버전이다. 현재는 IPv4가 주류이며, 이 경우 Version 값은 4이다.
- IHL (Internet Header Length) - IP Header의 크기이다. Option에 따라 가변적인 길이를 가지기에 이를 명시한다. 값이 N이라면 (N << 2)Bytes의 크기라는 의미이다.
- DSCP (Differentiated Services Code Point) - Network Traffic을 분류하고 QoS (Quality of Service)를 제공하기 위한 Field이다. VoIP, SLB 등에 사용된다.
- ECN - TCP Header에서 추가된 Field과 같이 Congestion Control을 위해 사용한다.
- TCP Header의 ( ECT << 1 | CE ) 값이며, 둘 중 하나라도 1이 되면 ECT (ECN-Capable Transport)를 나타낸다.
- Router는 이를 동일하게 취급하며, 발견되면 모두 1로 세팅하여 CE (Congestion Experienced) Flag를 완성하여 Congetsion을 알린다.
- TCP Connection을 생성할 때 양측에서 SYN Flag와 함께 ECE를 설정하였다면 ECN이 지원된다.
- Total Length - IP Header를 포함한 전체 Packet의 길이를 알려준다.
- Identification - Packet을 식별하는 번호이다. Packet이 분할될 경우 동일한 값을 가진다.
- Flags - 상위 1Bit는 사용되지 않고 2Bits만 사용한다. 2번째 Bit는 Packet이 분할되었는지에 대한 정보로 0이면 분할되었다는 의미이다. 3번째 Bit는 분할된 Packet이 더 있는지에 대한 정보로 0이면 마지막 Packet이라는 의미이다.
- Fragment Offset - Packet이 분할되었을 때, 몇 번째 Byte부터의 데이터인지 알려준다. 값이 N이라면 (N << 3) Bytes부터의 데이터라는 의미이다.
- TTL (Time To Live) - Network에서 loop로 인하여 Packet이 영원히 처리되지 않고 이동하는 상황을 방지하기 위한 값이다.
- 일반적으로 경유할 수 있는 Router의 수를 의미하며, Router를 지날 때마다 1씩 값이 감소한다. 0이 되면 Packet을 폐기하고 송신측에 ICMP Time Exceeded Message를 보낸다.
- 일반적으로 OS에 따라 값이 달라지며(Window 128, Linux 64, etc ...) 보통 30번이면 목적지에 도달할 수 있다.
- Protocol - 상위 Layer에서 사용한 Protocol을 기록한다. TCP - 0x06, UDP - 0x11 , ICMP - 0x01
- Header Checksum - Packet이 올바르게 전송되었는지 확인하기 위한 Field이다. IP Header도 확인 대상이며, Router 방문시마다 TTL 값이 변경되므로 Checksum도 다시 계산한다. TCP Header와 동일하게 16bits씩 끊어서 계산한 후 1의 보수를 취한다.
- Source & Destination IP Address - 송수신하는 장치의 IP Address이다.
- Options - TCP Header처럼 Option을 사용할 수 있다. 일반적으로 잘 사용하지 않으며, IP Header의 길이가 4Bytes 단위이기에 부족한 Bytes가 존재한다면 0으로 채워준다. (Padding)
TCP Connection을 맺을 때 Application에서 알려준 IP Address를 이용하여 목적지를 정하며, 잘못된 IP Address인지 확인하지 않는다. 모든 책임은 Application에 있다.
IP Address는 컴퓨터당 하나라고 생각할 수 있으나, 사실 LAN Adapter에 할당되는 것이기에 하나라고 단정지을 수 없다.
LAN Adapter가 여러개라면 IP Address도 여러개이며, 어떠한 LAN Adapter를 이용할지 결정해야한다.
Packet을 받을 Router가 결정되면 어떠한 LAN Adapter를 사용할지 결정되며, 이것은 IP Address를 결정하는 것과 같다.
Routing Table을 이용하여 Router가 결정되며, 서적에는 가볍게 설명이 되어 있으나 3장에서 깊게 다루기에 자세한 내용은 적지 않는다.
Ethernet Header
Ethernet은 TCP/IP와 다른 구조로 되어 있기에 현재까지 만든 정보로는 Packet을 전달할 수 없다. 그렇기에 이 앞에 Ethernet Header를 만들어야한다.
위 사진은 Ethernet Frame이다. Header 부분은 MAC Destination ~ Ethertype 부분이다.
Ethernet Header는 2 Layer인 DataLink Layer에서 처리되며, Preamble, SFD (Start Frame Delimiter)는 하위 레이어인 Physical Layer에서 처리되기에 구분이 되는 것이다.
또한 위 사진이 표준이지만, SFD를 없애고 Preamble을 8Bits로 사용하는 Ethernet II(DIX II) Frame이 가장 많이 사용된다.
- MAC Destination & Source - 송수신처의 MAC Address이다. IP Address보다 더 긴 48Bits = 6Bytes를 사용한다.
- Tag - VLAN (Virtual LAN) 정보에 대한 Field이다. 802.1Q에서 VLAN을 지원하면서 추가되었다. 선택적으로 사용되며, 사용하지 않는다면 Header 크기는 14Bytes, 사용한다면 18Bytes가 된다.
- Ethertype - 값이 1500 이하라면 Payload의 크기를 알려주며, 1536 이상의 값은 Network Protocol Type을 특정한다.
MAC Address는 LAN Adapter에 할당되어 이 안의 ROM에 기록되며, 정확히는 NIC (Network Interface Card)에 들어있다.
NIC가 여러개라면 MAC Address도 여러개이며, 자주 변경되지는 않으나 변경이 가능하다.
Ethernet Header의 MAC Destination에는 수신하는 장치의 MAC Address를 기록하게 되는데, 아직까지는 상대방의 MAC Address는 알아내지 못한 상황이다.
Get MAC Address with ARP
ARP (Address Resolution Protocol)를 이용하여 수신하는 Router의 MAC Address를 알아낸다.
Routing Table에는 같은 Subnet의 장치들이 있으며, Broadcast를 이용하여 수신하는 IP Address를 가지고 있는지 물어본다.
동일한 IP Address를 가지는 장치만 이에 응답하며, 이 때 MAC Address를 알려주는 것이다.
같은 Subnet에 존재하지 않다면 수신받을 장치가 없는 것이기에 ARP의 응답은 오지 않으며, Packet 전송이 실패한다.
Packet을 보낼 때마다 해당 동작을 실행하면 ARP의 Packet이 늘어나기에 한 번 조사한 결과를 ARP Cache에 저장하여 이를 활용한다.
ARP Cache에 있는지 먼저 조사한 후, 없을 때 위 동작을 실시한다.
또한 IP Address를 다시 설정할 수 있기에 Cache의 정보가 영원히 유효하다고 보장할 수 없다. 그렇기에 Cache의 정보는 유효 시간이 존재하며, OS마다 다르지만 보통 몇 분 후에 삭제한다.
다만 IP Address를 재설정한 직후에는 Cache가 남아있으며, 이 경우 ARP Cache의 내용을 확인하여 수동으로 삭제한다.
지금까지는 MAC Header를 설정하는 부분이 IP Header를 설정하는 부분과 다른 것처럼 작성하였으나, IP Address를 이용하여 MAC Address를 가져오기에 서적에서는 IP Header를 담당하는 부분이 MAC Header까지 담당한 후 LAN Adapter로 넘겨준다고 나와있다.
이 부분은 더 깊게 찾아보아야 명확한 정보를 확인할 수 있을 것이다.
IP Address 대신 다른 정보를 사용하더라도, 해당 정보가 이와 같은 동작을 진행하여 LAN Adapter에 보내줌으로써 LAN Adapter가 여러 정보에 호환된다.
Basic of Ethernet
LAN Adapter가 통신하기 위해서는 Ethernet에 대한 이해가 필요하다.
Ethernet은 같은 Subnet에서의 여러 장치가 상대적으로 적은 비용을 사용하여 통신하기 위해 고안된 기술이다.
초기 Ethernet은 모든 장치에 연결된 Trunk Cable이 존재하며, 중간에 각 장치가 Transceiver Cable로 연결된 구조이다.
완성한 Packet을 전송하면 각 장치가 Packet을 확인하여 이를 수신하거나 폐기한다.
실제로 여러 기기가 동시에 송신하면 충돌이 발생할 것이며, 이에 대한 처리는 복잡하다. 다만 이후 설명하는 Switching Hub의 도입으로 이 문제가 해결되었다.
이 구조가 각 장치가 하나의 Repeater Hub에 Twisted Pair Cable을 이용하여 연결이 된 구조로 바뀐다.
Repeater Hub에 송신하며, Repeater Hub는 모든 장치에 이를 다시 중개해준다.
다만 이 방식은 불필요한 송신이 반복되며, 신호가 약해지면 증폭을 해주는데 송신 과정에서 발생한 잡음도 증폭된다.
이러한 단점들을 개선하기 위하여 Repeater Hub가 Switching Hub로 구조가 변경되었다.
Switching Hub에 송신하는 것은 동일하나, Switching Hub는 이를 읽어 목적으로 하는 장치에만 신호를 전달한다.
이전까지는 신호를 읽은 후 그 신호를 그대로 보내거나 증폭하였는데, Switching Hub는 신호를 Packet으로 읽는 과정이 추가된다.
이 덕분에 목적으로 하는 장치에만 신호가 전달되기에 부하가 낮아지고, Packet을 읽고 다시 신호로 변환하기에 잡음이 제거되어 전달된다.
Ethernet은 이러한 원리를 이용하여 같은 Subnet에서 장치간의 송수신을 원활하게 해주며, 무선 LAN에서는 Ethertype을 다른 무언가로 대체하여 사용한다.
Change Digital Data to Signal
Packet은 0과 1의 Digital Data이다. 케이블을 이용하여 이를 그대로 전송할 수는 없다.
이 데이터를 빛이나 전기 신호로 변환하여 전송해야하며, 변환된 정보를 수신하여 0과 1의 데이터로 변환해야 한다.
이 동작은 LAN Adapter가 담당한다. 다만 LAN Adapter를 사용하기 위해서는 LAN Driver S/W가 필요하다.
이것은 LAN Adapter에만 한정된 내용이 아닌, 모든 H/W에 공통되는 내용이다.
LAN Adapter는 제조 업체나 기종에 따라 구조가 달라진다. 제품별 Driver가 존재하는 것도 이와 같은 이유이다.
송수신시 작업의 내부 구조를 표현하자면 Application - Protocol Stack - LAN Driver - Expansion Bus Slots - Buffer Memory - MAC - PHY(MAU) - Connector - LAN Cable
이다.
Buffer Memory ~ Connector까지가 LAN Adapter에 해당한다.
- Buffer Memory - 송수신하는 Packet을 임시로 저장한다.
- MAC - 충돌 검출, 재송신 등 Ethernet의 송수신 동작을 제어. 옆에 ROM이 존재하며, 이 부분에 MAC Address를 기록한다.
- PHY(MAU) - Physical Layer Device와 Medium Attachment Unit이다. 송신과 수신을 각각 담당하는 회로를 합친 것이라고 한다.
- Connector - LAN Cable 접속을 담당한다. 여기서 LAN Cable로 나가며, PHY(MAU)에서 Connector로 이어지는 부분은 송신과 수신을 담당하는 Cable이 각각 다르다.
위 구조는 이해를 돕기 위한 개념적인 구조이다. LAN Adapter는 OS를 시작할 때 LAN Driver가 초기화 작업을 해주어야 사용할 수 있다. H/W 공통되는 초기화 작업 + MAC Address 설정이 이루어진다. ROM에는 전 세계의 장치와 중복되지 않도록 일원화해서 관리하는 MAC Address를 기록한다. 이 외에도 명령이나 설정 파일을 이용하여 MAC Address를 받아 설정하는 경우도 있다. 이러한 특수한 작업을 통해 설정할 경우, ROM의 MAC Address는 무시하게 된다.
3 Additional Control Data
TCP/IP 관련 Packet이 LAN Adapter로 내려오면 Buffer Memory에 복사한 후 Packet의 앞에 Preamble과 SFD (Start Frame Delimiter), 뒤에 FCS(Frame Check Sequence)를 붙인다.
- Preamble - 송수신 동기화를 위해
10101010
을 7Bytes에 걸쳐 기록한다. - SFD -
10101011
을 기록하여 Packet의 시작을 나타낸다. - FCS - 4Bytes로 오류 검출을 위해 사용한다. CRC (Cyclic Redundancy Check) 방식을 사용한다.
전기 신호로 변환하는 과정은 꽤 복잡하다. 이해하지 못한 내용도 존재하나, 개발에 필요한 지식만 간추려서 정리한다.
데이터와 클록 신호를 이용하여 하나의 신호를 만든다. 데이터만 이용하면 비트의 구분을 알 수 없으며, 클록을 같이 보내면 신호에 왜곡이 생겨 잘못 해석할 수 있다. 그렇기에 두 신호를 조합하여 하나의 신호로 만든다.
수신할 때는 이를 이용하여 클록 신호를 추출하고, 이를 이용하여 데이터를 추출한다.
1과 0의 신호를 쉽게 구분하기 위하여 앞에 Preamble로 1과 0을 교차하여 사용한 것이다.
송신 과정에서 신호에 왜곡이 생겨 0과 1을 잘못 인식할 수 있으며, 이러한 것을 확인하기 위하여 FCS를 이용하여 오류를 검출한다.
Send Packet with Duplex
자세한 내용은 이전과 동일하게 복잡하다. 개발에 필요한 부분만 정리해보겠다.
Hub 사용시 Half Duplex와 Full Duplex 방식이 존재한다.
Half Duplex는 한 시점에 한 방향으로만 신호가 전달될 수 있다. 신호가 정지하였거나 흐르지 않으면 PHY(MAU) 회로를 이용하여 신호를 변환하여 송신한다.
송신 도중 신호가 들어오면 충돌이 발생하며, 이 경우 송신을 중지시키고 Jamming Signal을 보내 충돌이 발생함을 알린 후 다시 송신한다.
Full Duplex는 양방향으로 동시에 흐를 수 있으며, 충돌이 일어나지 않아 번거로운 일이 발생하지 않는다. 이는 3장에서 자세히 알아본다.
Receive Packet
신호를 수신하면 LAN Adapter의 내부에서 생략한 동작들을 통해 0과 1의 Digital Data로 변환한 후, CRC 방식을 이용하여 FCS와 비교하여 오류가 있는지 확인한다.
FCS에 문제가 없다면 MAC Address를 확인한 후, 올바른 Packet이라면 Buffer Memory에 저장하고 Interrupt를 통해 Packet 수신을 알린다.
특수한 경우로 수신자를 검사하지 않고 모든 Packet을 수신하는 Promiscuous Mode가 존재한다고 한다.
Interrupt 발생은 LAN Adapter가 Expansion Bus Slots에 Interrupt용 신호를 보내고, 이것이 CPU에 연결이 되며, OS 내부의 Interrupt 처리 Program으로 전환한다.
Interrupt 번호가 존재하는데, 이는 Plug and Play가 도입된 이후 자동으로 처리가 되기에 신경쓰지 않아도 된다.
이후 Buffer Memory의 Packet을 추출하여 Ethertype을 이용하여 Protocol을 확인한 후 해당 Protocol Stack에 넘겨준다.
과거에는 TCP/IP가 아닌 여러 Protocol을 사용하였기에 이러한 동작이 존재한다.
Give Packet from IP to TCP
TCP/IP Protocol의 경우, IP Header를 확인한다.
Destination IP Address가 본인과 다르면 ICMP (Internet Control Message Protocol)을 이용하여 상대방에게 오류를 알려준다.
이 때 사용하는 Message는 Destination Unreachable
이지만 이 외에도 많은 ICMP Message가 존재한다.
올바른 Destination IP Address라면 하나의 Packet이 분할되었는지 확인한다. 이는 3장에 더 자세히 설명한다.
위와 같은 방식으로 IP Header의 Flags 값을 통해 분할되었는지 확인하며, 분할의 경우 내부 Memory에 임시로 저장하여 Packet이 모이기를 기다린다.
이렇게 Packet을 원래대로 되돌리는 동작을 Reassembling이라고 한다.
모든 작업이 완료되면 TCP에 넘겨주며, TCP는 Header를 확인하여 해당하는 Socket을 찾는다.
Socket에 기록된 통신의 상태에 따라 적절한 동작을 실행한다.
Exchange Data with UDP
지금까지는 TCP의 동작이나, UDP를 사용하는 경우도 존재한다.
Short Data
TCP는 데이터의 안정적인 송수신을 위해 사용하였다.
하나의 Packet에 수용할 정도로 짧은 데이터를 취급하면 Packet이 유실되어도 재전송이 빠르며, Connection 설정 및 해제에 송수신이 필요가 없다.
Control Data
제어용 정보 교환은 한 개의 Packet이면 충분한 경우가 많기에 UDP를 사용한다.
Connection 작업이 필요가 없으며, 오류가 발생하면 다시 정보를 요청하면 된다.
UDP Header의 경우 Source & Destination Port, Data Length, Checksum 이며 각 2Bytes로 간단하다.
Sound and Video
소리나 영상의 경우 빠른 데이터 전송이 이루어져야 하며, 오류 발생으로 데이터 유실이 되더라도 시간이 흘렀기에 타이밍이 맞지 않아 재전송을 해도 무의미하다.
또한 이러한 데이터는 일부 유실이 되더라도 이용에 큰 문제가 없기에 UDP를 사용하는 것이 효유렂ㄱ이다.
Conclusion
Protocol Stack과 LAN Adapter의 동작과 송수신시 신호 변환까지의 동작을 확인하였다.
후반에는 물리, 회로와 같은 지식까지 동원된 내용이었기에 이해가 어려운 부분이 있었다.
당장은 이러한 지식이 필요가 없을 것 같으나, 추후 필요해지면 LAN Adapter부터의 동작을 다시 확인해야 할 것이다.
'Network' 카테고리의 다른 글
HTTP The Definitive Guide - 04. Connection Management (0) | 2022.11.07 |
---|---|
HTTP The Definitive Guide - 03. HTTP Messages (0) | 2022.11.04 |
성공과 실패를 결정하는 1%의 네트워크 원리 - 1. Web Browser (0) | 2022.10.20 |
HTTP The Definitive Guide - 02. URLs and Resources (0) | 2022.10.14 |
HTTP The Definitive Guide - 01. Overview of HTTP (0) | 2022.10.13 |