05AM

TCP 3-way handshake와 4-way handshake: 연결 설정과 해제 과정 본문

1 week 1 conquer/CS

TCP 3-way handshake와 4-way handshake: 연결 설정과 해제 과정

_05AM 2023. 10. 22. 22:55

☀️ 전송 계층 (Transport Layer)

양 끝단의 사용자들이 신뢰성있는 데이터를 주고 받을 수 있도록 해주어, 상위 계층들이 데이터 전달의 유효성이나 효율성을 생각하지 않도록 해주는 역할

  • 상위 계층과 하위 계층 간의 인터페이스 역할
  • 프로세스 간의 논리적인 통신을 제공한다.
    • 데이터 링크 계층 : 물리적인 연결
    • 네트워크 계층 : 호스트 간 논리적인 통신, 데이터의 전달 경로를 설정
  • 💡 참고
  • 전송 계층의 대표적인 프로토콜은 TCP와 UDP이다.
  • 전송 계층의 패킷을 세그먼트라고 부르는데, UDP 프로토콜에서는 이를 종종 데이터그램이라고 하기도 한다.

[출처] [네트워크] TCP/UDP와 3 -Way Handshake & 4 -Way Handshake (velog.io)

☀️ TCP (Transmission Control Protocol)

인터넷 상에서 데이터를 메시지의 형태로 보내기 위해 IP와 함께 사용하는 프로토콜

  • TCP는 어플리케이션에게 신뢰성있고 연결지향적인 서비스를 제공한다. 일반적으로 TCP와 IP는 함께 사용되며 IP는 배달을, TCP는 패킷의 추적 및 관리를 맡는다.
  • TCP는 연결형 서비스로, 신뢰할 수 있는 전송을 보장을 위해 handshaking을 사용하고, 데이터의 흐름제어와 혼잡제어를 수행한다. 이 때문에 속도가 느리다.

특징

  • 높은 신뢰성 보장
  • 3-way handshake 과정을 통해 연결을 설정하고, 4-way handshake를 통해 해제
  • 흐름 제어 및 혼잡 제어
  • UDP보다 속도가 느림
  • 전이중(full-duplex), 점대점(point to point) 방식

TCP 세그먼트 형식

[출처] 컴퓨터 네트워크 - TCP segment structure (tistory.com)

  1. source port #
  2. 데이터를 전송하는 애플리케이션의 포트 번호
  3. dest port #
  4. 데이터를 수신하는 측의 포트 번호
  5. sequence number예시) 500,000 바이트 데이터를 1,000 바이트 크기로 나누면, 첫 번째 세그먼트 번호는 0, 두 번째는 1,000이다.
  6. TCP는 데이터 스트림을 세그먼트로 나누어 전송한다. 이 필드는 해당 세그먼트의 첫 바이트가 전체 데이터 스트림에서 몇 번째 바이트인지를 나타낸다. 연결 시작시에는 랜덤 값으로 초기화된다.
  7. acknowledgment number예시) 1,000 바이트 세그먼트를 받으면 1000이 ACK로 보내짐.
  8. 수신자가 다음에 받기를 원하는 데이터의 sequence number를 나타낸다. 동시에 이미 성공적으로 수신된 데이터까지의 번호도 알려준다.
  9. flags(U, A, P, R, S, F)
    • A(ACK) : acknowledgment 필드가 유효한지 나타내는 플래그. 연결 초기화 후 모든 패킷에 설정되어야 한다.
    • R(RST) : 잘못된 연결 또는 오류 상황에서 TCP 연결을 재설정하라는 플래그
    • S(SYN) : TCP 연결 설정 요청을 나타내는 플래그
    • F(FIN) : TCP 연결을 종료하라는 요청을 나타내는 플래그
  10. Receive window
  11. 수신 버퍼에 사용 가능한 공간을 바이트 단위로 나타낸다. 송신자는 이 값보다 많은 데이터를 전송해서는 안 되며, 이는 흐름 제어 메커니즘의 일부이다.
  12. checksum
  13. 헤더와 데이터를 더해 계산한 값으로, 전송 중인 데이터와 헤더에 대한 에러 검사 값을 나타낸다. 수신 측은 이 값을 통해 패킷의 무결성을 검사한다.

☀️ 용어 정리

포트(Port) 상태 정보

  • CLOSED : 닫힌 상태
  • LISTEN : 열린 상태로 연결 요청 대기 중
  • SYN_RCV : SYNC 요청을 받고 상대방의 응답을 기다리는 중
  • ESTABLISHED : 연결 상태

플래그(Flag) 정보

  • TCP Header에는 CONTROL BIT(플래그 비트, 6 Bit)가 존재하며, 각각의 Bit는 URG / ACK / PSH / RST / SYN / FIN의 의미를 가진다.
  • 즉, 해당 위치의 Bit가 1이면 해당 패킷이 어떠한 내용을 담고 있는 패킷인지를 나타낸다.
  • SYN (Synchronize Sequence Numbers) [000010] : 연결 요청
    • TCP 연결 설정 시에 두 장치 간의 시퀀스 번호를 동기화하기 위해 사용되는 플래그
  • ACK (Acknowledgement) [010000] : 응답 확인
    • 데이터의 안정성을 확보하기 위해 수신자가 송신자에게 해당 패킷을 제대로 받았음을 알려주는 플래그
    • ACK 플래그가 설정된 패킷에는 Acknowledgment Number 필드가 포함되어 있어, 이 번호를 통해 어떤 패킷까지 제대로 수신되었는지를 알린다.
  • FIN (Finish) [000001] : 연결 종료
    • TCP 연결의 종료를 나타내는 플래그로, 더 이상 전송할 데이터가 없음을 의미
    • TCP 연결은 양방향이므로 양쪽 모두 연결을 종료하려는 의사를 나타내야 한다. 따라서 한 쪽에서 연결을 종료하고자 할 때 FIN 플래그가 설정된 패킷을 상대방에게 보내게 된다. 상대방은 이를 받아 연결 종료의 시작을 알게 되고, 연결을 종료하기 위한 자체 절차를 시작한다.

☀️ TCP의 연결 요청 : TCP 3-way handshake

TCP 프로토콜을 사용하여 클라이언트와 서버 간에 신뢰성있는 연결을 설정하는 과정

  • 양쪽 모두 데이터를 전송할 준비가 되었다는 것을 보장하고, 실제로 데이터 전달이 시작하기 전에 한 쪽이 다른 쪽이 준비되었다는 것을 알 수 있도록 한다.
  • 즉, TCP/IP 프로토콜을 이용해서 통신을 하는 응용 프로그램이 데이터를 전송하기 전에 먼저 정확한 전송을 보장하기 위해 상대방 컴퓨터와 사전에 세션을 수립하는 과정을 의미한다.

기본 매커니즘

PAR (Positive Acknowledgement with Re-transmission) 을 통해 신뢰적인 통신을 제공한다.

  • PAR을 사용하는 기기는 ACK을 받을 때까지 데이터 유닛을 재전송한다.
  • 수신자가 오류 검출에 사용되는 전송 계층의 검사합(check sum)을 활용하여 세그먼트(데이터 유닛)의 손상을 확인하면, 해당 세그먼트를 없앤다. 그러면 송신자는 Positive ACK가 오지 않은 데이터 유닛을 다시 보내야 한다.
  • ⇒ 이 과정에서 클라이언트와 서버 사이에서 3개의 세그먼트가 교환되는 것을 확인할 수 있다. 이것이 바로 3-way handshake의 기본 매커니즘이다.

[출처] TCP 3 way handshake 내용 정리 (tistory.com)

작동 방식

연결 설정을 위해서 서버와 클라이언트는 3개의 패킷(세그먼트)을 교환한다.

  1. SYN (클라이언트 → 서버)
    • 패킷 내용
    • Seq=x, SYN
    • PORT 상태
      • Client : CLOSED``SYN_SENT 로 변함
      • Server : LISTEN
  2. 연결을 시작할 때, 클라이언트는 SYN 플래그가 설정된 패킷을 서버에게 보냄으로써 연결의 시작을 요청한다. 이때 클라이언트는 자신의 초기 시퀀스 번호(x)를 랜덤하게 선택하여 이 패킷에 포함한다.
  3. SYN-ACK (서버 → 클라이언트)
    • SYN - 랜덤하게 설정한 서버의 초기 시퀀스 번호(y)가 포함된다.
    • ACK - ACK Number 필드를 클라이언트의 초기 시퀀스 번호에 1을 더한 값으로 설정하여 패킷에 포함시킨다. 이것으로 서버는 클라이언트의 SYN 패킷을 제대로 받았음을 클라이언트에게 알린다.
    • 패킷 내용
    • Seq=y, Ack=x+1, SYN, ACK
    • PORT 상태
      • Client : CLOSED
      • Server : SYN_RCV
    💡 클라이언트의 시퀀스 번호에 1을 더하는 이유?
  4. TCP는 바이트 스트림을 전송하는 프로토콜이므로, 각 바이트에는 고유한 시퀀스 번호가 있다. SYN 플래그가 설정된 패킷을 보낼 때, 해당 패킷은 시퀀스 공간에서 1바이트를 차지하게 된다. 따라서, 서버는 다음 예상되는 바이트의 시퀀스 번호를 응답하는 ACK 번호로 설정하기 위해 클라이언트의 초기 시퀀스 번호에 1을 더하게 된다.
  5. 클라이언트가 보낸 SYN 패킷을 받은 서버는 SYN 및 ACK 플래그가 설정된 패킷으로 응답한다.
  6. ACK (클라이언트 → 서버)
    • 이 패킷의 시퀀스 번호는 클라이언트 초기 시퀀스 번호 + 1이다.
    • ACK 번호로 서버의 초기 시퀀스 번호에 1을 더한 값을 설정한다. 이는 서버의 SYN 패킷을 받았음을 의미한다.
    • 전송할 데이터가 있으면 이 단계에서 데이터를 전송할 수 있다.
    • 패킷 내용
    • Ack=y+1, ACK
    • PORT 상태
      • Client : ESTABLISED
      • Server : SYN_RCV ⇒ ACK ⇒ ESTABLISED
  7. SYN-ACK 패킷을 받은 클라이언트는 서버에 대한 연결 요청을 확인하고 수락한다는 의미로 ACK 패킷을 보낸다.

☀️ TCP의 연결 종료

Temination의 종류

TCP는 대부분의 connection-oriented 프로토콜과 같은 두 가지 연결 종료 방식이 있다.

  1. Graceful Termination = 4-way Handshake (정상 종료)
  2. 정상 연결 해제에서는 양쪽이 커넥션이 서로 모두 커넥션을 닫을 때까지 연결되어 있다.
  3. Abrupt Termination (비정상 종료)
    • 갑자기 한 TCP 엔티티가 연결을 강제로 닫는 경우
    • 한 사용자가 두 데이터 전송 방향을 모두 닫는 경우

☀️ 작동방식 (Abrupt)

비정상 종료는 연결을 갑자기 끊어버리는 방식으로, RST 플래그가 설정된 패킷으로 이루어 진다. RST(TCP reset) 세그먼트가 전송되면 갑작스러운 연결 해제가 수행되는데, RST 세그먼트는 다음과 같은 경우에 전송된다.

  1. 유효하지 않은 시퀀스 번호ex) 아직 정상적으로 연결되지 않은 TCP 상태에서, 연결 설정을 위한 SYN 플래그 없이 다른 데이터나 정보를 담은 패킷이 도착한 경우
  2. : 잘못된 시퀀스 번호를 가진 패킷이 수신되면, 해당 연결은 유효하지 않다고 판단되어 RST 패킷을 보낼 수 있다.
  3. 리소스 부족
  4. : 시스템에서 사용 가능한 리소스가 부족한 경우, 이미 설정된 연결이나 새로운 연결 요청을 처리할 수 없을 때 RST 패킷을 보낼 수 있다.
  5. 보안 문제
  6. : 방화벽, IDS (침입 탐지 시스템), IPS (침입 방지 시스템) 등의 보안 장치나 소프트웨어가 악의적인 활동이나 정책 위반을 감지하면, 해당 연결을 강제로 종료하기 위해 RST 패킷을 보낼 수 있다.
  7. 프로토콜 오류ex) 커넥션에서 일부 TCP 구현은 잘못된 헤더가 있는 세그먼트가 수신된 경우, RST 세그먼트를 보내 해당 커넥션을 닫아 공격을 방지한다.
  8. : TCP 통신 중 프로토콜 규약에 따르지 않는 행위나 오류가 발생하면 연결을 강제로 종료시킬 수 있다.
  9. 소프트웨어/하드웨어 오류
  10. : 시스템 또는 응용 프로그램에서의 오류나 문제로 인해 연결이 비정상적으로 종료될 수 있다.

☀️ 작동방식 (Graceful) = TCP 4-way handshake

TCP 프로토콜을 사용하여 클라이언트와 서버 간에 연결을 해제하는 과정

서버와 클라이언트는 모두 서로 연결 요청을 먼저 할 수 있기 때문에, 먼저 요청한 요청자를 클라이언트로, 연결 요청을 받은 수신자를 서버로 생각한다.

[출처] TCP 4 way handshake 내용 정리 (tistory.com)

  1. FIN (클라이언트 → 서버)
    • PORT 상태
      • Client : FIN_WAIT1
  2. 클라이언트(연결을 종료하고 싶은 측)가 서버에게 연결을 종료하고자 함을 알리기 위해 FIN 플래그가 설정된 패킷을 보낸다. 이때 FIN 패킷에는 실직적으로 ACK도 포함되어 있다.
  3. ACK (서버 → 클라이언트)
    • PORT 상태
      • Server : CLOSE_WAIT
      • Client : FIN_WAIT2
  4. 서버는 클라이언트의 FIN 패킷을 받았음을 확인하기 위해 ACK Number 필드를 시퀀스 넘버 + 1, ACK 플래그가 설정된 패킷을 클라이언트에게 되돌려 보낸다.
  5. FIN (서버 → 클라이언트)
    • PORT 상태
      • Client : TIME_WAIT
      • Server : LAST_ACK
  6. 서버가 모든 데이터를 클라이언트에게 전송한 후, 서버도 연결을 종료하길 원하므로 자신의 FIN 패킷을 클라이언트에게 보낸다.
  7. ACK (클라이언트 → 서버)
    • TIME_WAIT 상태
      • 지연된 패킷 처리: 네트워크 상의 지연이나 다른 요인으로 인해 이전에 보낸 패킷들이 늦게 도착할 수 있습니다. TIME_WAIT 상태는 이런 패킷들이 도착하고 처리될 시간을 제공합니다.
      • 연결 재설정을 위한 안전 장치: TIME_WAIT 상태는 빠르게 연속해서 같은 포트로의 연결 재시도를 방지합니다. 이는 지연된 패킷이 새 연결에 혼란을 줄 수 있는 상황을 방지합니다.
    • 클라이언트가 서버에게 **ACK**를 보낸 후, 클라이언트는 TIME_WAIT 상태로 전환됩니다. 연결이 종료된 후에도 일정 시간 동안 소켓을 열어 둔다. 이 사아태에서는 실제로 데이터를 전송하지 않지만, 이전 연결에서 발생할 수 있는 지연된 패킷들을 받아들일 준비가 되어있다. TIME_WAIT 상태는 주로 두 가지 목적을 가집니다:
    • TIME_WAIT 상태의 지속 시간
    • 대부분의 TCP 구현에서 **TIME_WAIT**의 지속 시간은 2 * Maximum Segment Life (MSL)입니다. MSL은 TCP 세그먼트가 네트워크 상에 존재할 수 있는 최대 시간을 나타냅니다. 따라서 TIME_WAIT 상태는 보통 4분 정도 지속됩니다(구현마다 조금씩 다를 수 있습니다).
    • CLOSED 상태
    • TIME_WAIT 상태가 지정된 시간 동안 지속된 후, 클라이언트는 연결을 완전히 종료하고 CLOSED 상태가 됩니다. 만약 TIME_WAIT 상태에서 예상치 못한 문제나 오류가 발생하여 정상적인 종료가 지연되거나 불가능할 경우, 지정된 시간이 초과되면 클라이언트는 자동으로 CLOSED 상태로 전환됩니다.
    • PORT 상태
      • Client : → CLOSED
      • Server : → CLOSED
  8. 클라이언트는 서버의 FIN 패킷을 받았음을 확인하기 위해 ACK 플래그가 설정된 패킷을 서버에게 보낸다.

Half-Close 기법

TCP 연결의 특징 중 하나는 양방향 통신이 가능하다는 것이다. 한 쪽이 데이터 전송을 중지하더라도 다른 쪽은 계속 데이터를 보낼 수 있다. half-close 기법은 이러한 양방향 통신의 특징을 활용한 것이다.

아래 그림에서 처음 보내는 종료 요청인 FIN 패킷에 실질적으로 ACK가 포함되어 있는 것을 알 수 있는데, 이는 Half-Close 기법 을 사용하기 때문이다. 즉, 연결을 종료하려고 할 때 완전히 종료하지 않고 반만 종료한다.

Half-Close 기법을 사용하면 종료 요청자가 처음 보내는 FIN 패킷에 ACK Number를 함께 담아서 보내게 되는데, 이때 승인 번호의 의미는 "일단 연결은 종료할건데 귀는 열어둘게. 이 승인 번호까지 처리했으니까 더 보낼 거 있으면 보내" 이다.

이후 수신자가 남은 데이터를 모두 보내고 나면 다시 요청자에게 FIN 패킷을 보냄으로써 모든 데이터가 처리되었다는 신호를 보낸다. 그럼 요청자는 그때 나머지 반을 닫으면서 좀 더 안전하게 연결을 종료할 수 있게 된다.

  1. 클라이언트는 더 이상 보낼 데이터가 없다고 판단하면 FIN 플래그가 설정된 패킷을 서버에게 보내 연결의 한 방향을 종료한다. 이는 "전송 종료"라고도 한다.
  2. 서버는 클라이언트의 FIN 패킷을 받고, **ACK**로 응답한다. 이 시점에서 클라이언트는 서버로부터 데이터를 계속 수신할 수 있지만, 클라이언트로부터의 데이터 전송은 종료된다. 이 상태가 half-close 상태이다.
  3. 서버가 모든 데이터를 클라이언트에게 전송하고 나면, 서버 역시 FIN 패킷을 클라이언트에게 보내 연결의 반대 방향도 종료를 요청한다.
  4. 클라이언트는 **ACK**로 응답하여 서버의 FIN 패킷을 확인하고, 이로써 양방향 모두 연결이 종료된다.

참고

  • Chat GPT

OSI 7계층 - 전송 계층

[네트워크] TCP/UDP와 3 -Way Handshake & 4 -Way Handshake

컴퓨터 네트워크 - TCP segment structure

Comments