3-Way Handshake & 4-Way Handshake

Hyeon-Uk·2023년 4월 11일
0
post-thumbnail

❓ TCP의 특징

3-Way Handshake를 보기전에 TCP의 특징에 대해서 알아보자

TCP의 특징

  • 데이터의 순서를 보장
  • 신뢰성 있는 데이터를 전송
  • 데이터 흐름 제어 및 혼잡 제어
  • 연결형 서비스로 연결이 성공해야 통신이 가능

연결이 성공해야 통신이 가능

  • Client와 Server가 논리적 으로 연결된 상태를 말하는것.
  • 이런 논리적인 연결을 하기 위해서 3-Way Handshake 과정을 이용하는것.
  • 3-Way Handshake 과정을 통해 논리적으로 연결이 되었다면, 클라이언트와 서버가 데이터를 주고받을 준비가 되어있다는것을 의미함.

🤝 3-Way Handshake

tcp에서 클라이언트와 서버가 서로 연결을 확인하는 과정을 의미함.

  1. 클라이언트에서 임의의 포트를 open한뒤, 서버에 SYN 사인을 보내고, 클라이언트는 SYN/ACK 응답을 기다리는 SYN_SENT 상태가 됨.

  2. 클라이언트의 요청을 받은 서버는 SYN _RECEIVED 상태가 되고, 클라이언트에 SYN/ACK 응답을 보냄.

  3. SYN/ACK 응답을 받은 클라이언트는 서버의 응답을 확인했다는 의미로 ACK패킷을 보냄.

그럼, 직접 언박싱을 해보자!

실제 3-way Handshake 과정.

먼저 패킷을 요약하면 다음과 같다.

NOSourceDestinationProtocolInfo
1내IP상대IPTCP[SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
2상대IP내IPTCP[SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1440 SACK_PERM=1 WS=512
3내IP상대IPTCP[ACK] Seq=1 Ack=1 Win=263424 Len=0

🎁 1번 패킷

1번패킷(클라이언트에서 서버로 SYN 사인을 보내는 패킷)에 대한 내용이다.

아래는 텍스트로 복사한 내용이다.

Transmission Control Protocol, Src Port: 58028, Dst Port: 443, Seq: 0, Len: 0
    Source Port: 58028
    Destination Port: 443
    [Stream index: 36]
    [Conversation completeness: Complete, WITH_DATA (31)]
    [TCP Segment Len: 0]
    Sequence Number: 0    (relative sequence number)
    Sequence Number (raw): 3107905017
    [Next Sequence Number: 1    (relative sequence number)]
    Acknowledgment Number: 0
    Acknowledgment number (raw): 0
    1000 .... = Header Length: 32 bytes (8)
    Flags: 0x002 (SYN)
    Window: 64240
    [Calculated window size: 64240]
    Checksum: 0xd48c [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0
    Options: (12 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), SACK permitted
    [Timestamps]

주로 봐야할 변수명들에 대한 설명이다.

  • Source Port = 클라이언트의 Port
  • Destination Port = 서버의 Port
  • Sequence Number (raw) = 난수, 해당 프로세스의 고유 seq값

🎁 2번 패킷

2번 패킷(서버에서 응답을 확인하는 SYN,ACK 사인을 보내는 패킷)에 대한 내용이다.

Transmission Control Protocol, Src Port: 443, Dst Port: 58028, Seq: 0, Ack: 1, Len: 0
    Source Port: 443
    Destination Port: 58028
    [Stream index: 36]
    [Conversation completeness: Complete, WITH_DATA (31)]
    [TCP Segment Len: 0]
    Sequence Number: 0    (relative sequence number)
    Sequence Number (raw): 3506320147
    [Next Sequence Number: 1    (relative sequence number)]
    Acknowledgment Number: 1    (relative ack number)
    Acknowledgment number (raw): 3107905018
    1000 .... = Header Length: 32 bytes (8)
    Flags: 0x012 (SYN, ACK)
    Window: 65535
    [Calculated window size: 65535]
    Checksum: 0x1afa [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0
    Options: (12 bytes), Maximum segment size, No-Operation (NOP), No-Operation (NOP), SACK permitted, No-Operation (NOP), Window scale
    [Timestamps]
    [SEQ/ACK analysis]
        [This is an ACK to the segment in frame: 2318]
        [The RTT to ACK the segment was: 0.003307000 seconds]
        [iRTT: 0.003392000 seconds]

달라진것을 보면

  • Source Port, Destination Port : 당연히 서버에서 요청한 클라이언트에게 응답을 줘야하기 때문에 바뀜

  • Sequence Number (raw) : 이것도 서버 프로세스에서 생성된 고유한 난수값이기 때문에 1번패킷과는 다르다.

  • Acknowledgment Number (raw) : SYN 요청을 보낸 클라이언트의 SequenceNumber(3107905017) 에 +1이 된 값으로 보내주는것을 확인 가능

🎁 3번 패킷

3번 패킷(클라이언트에서 SYN,ACK 사인을 받고 ACK 사인을 보내는 패킷) 에 대한 내용이다.

Transmission Control Protocol, Src Port: 443, Dst Port: 58028, Seq: 0, Ack: 1, Len: 0
    Source Port: 443
    Destination Port: 58028
    [Stream index: 36]
    [Conversation completeness: Complete, WITH_DATA (31)]
    [TCP Segment Len: 0]
    Sequence Number: 0    (relative sequence number)
    Sequence Number (raw): 3506320147
    [Next Sequence Number: 1    (relative sequence number)]
    Acknowledgment Number: 1    (relative ack number)
    Acknowledgment number (raw): 3107905018
    1000 .... = Header Length: 32 bytes (8)
    Flags: 0x012 (SYN, ACK)
    Window: 65535
    [Calculated window size: 65535]
    Checksum: 0x1afa [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0
    Options: (12 bytes), Maximum segment size, No-Operation (NOP), No-Operation (NOP), SACK permitted, No-Operation (NOP), Window scale
    [Timestamps]
    [SEQ/ACK analysis]
        [This is an ACK to the segment in frame: 2318]
        [The RTT to ACK the segment was: 0.003307000 seconds]
        [iRTT: 0.003392000 seconds]
  • 당연히 클라이언트→서버로 전송하는것이기 때문에 SourcePort와 DestinationPort가 다시 바뀜
  • 처음 SYN 요청을 보낼때의 SequenceNumber(3107905017) 보다 1이 증가함.
  • Acknowledge Number (raw) 값은 2번패킷과 같이 서버의 SequenceNumber(3506320147) 에 1을 더한 값인 3506320148가 된다.

👋 4-way Handshake

3-way Handshake 과정이 클라이언트와 서버가 통신을 위해 연결하는 과정이라고하면, 4-way Handshake과정은 통신을 종료하는 과정을 말한다.

  1. 먼저 클라이언트가 서버에게 종료의 의미로 FIN 사인을 보냄.

  2. 서버는 클라이언트가 종료를 하겠다는 FIN 사인을 받고, 종료준비를 하기위해 먼저 클라이언트에게 일단 알겠다는 ACK사인을 보냄.

  3. 서버에서 아직 전송을 못다한 데이터들이 있으면 클라이언트로 남은 데이터를 모두 보냄

  4. 더이상 보낼 데이터가 없다면 서버에서 클라이언트로 FIN사인을 보냄

  5. 클라이언트에서 서버에서 모든 데이터를 다 보냈고, 종료했다는 FIN사인을 받고 확인의 ACK사인을 보냄.

실제 4-WAY Handshake 과정

정리하면 다음 표와 같다.

NOSourceDestinationProtocolInfo
1내IP상대IPTCP[FIN, ACK] Seq=618 Ack=579 Win=65392 Len=0
2상대IP내IPTCP[ACK] Seq=579 Ack=619 Win=64240 Len=0
3상대IP내IPTCP[FIN, ACK] Seq=579 Ack=619 Win=64240 Len=0
4내IP상대IPTCP[ACK] Seq=619 Ack=580 Win=65392 Len=0

🎁 1번패킷(클라이언트에서 종료하겠다는 FIN,ACK패킷)에 대한 내용

Transmission Control Protocol, Src Port: 64923, Dst Port: 47611, Seq: 618, Ack: 579, Len: 0
    Source Port: 64923
    Destination Port: 47611
    [Stream index: 17]
    [Conversation completeness: Complete, WITH_DATA (31)]
    [TCP Segment Len: 0]
    Sequence Number: 618    (relative sequence number)
    Sequence Number (raw): 42802010
    [Next Sequence Number: 619    (relative sequence number)]
    Acknowledgment Number: 579    (relative ack number)
    Acknowledgment number (raw): 1833648668
    0101 .... = Header Length: 20 bytes (5)
    Flags: 0x011 (FIN, ACK)
    Window: 65392
    [Calculated window size: 65392]
    [Window size scaling factor: -2 (no window scaling used)]
    Checksum: 0xa660 [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0
    [Timestamps]
        [Time since first frame in this TCP stream: 0.019074000 seconds]
        [Time since previous frame in this TCP stream: 0.000128000 seconds]
    [SEQ/ACK analysis]
        [This is an ACK to the segment in frame: 1960]
        [The RTT to ACK the segment was: 0.000128000 seconds]
        [iRTT: 0.003214000 seconds]

🎁 2번패킷(서버에서 일단 OK하는 ACK패킷)

Transmission Control Protocol, Src Port: 47611, Dst Port: 64923, Seq: 579, Ack: 619, Len: 0
    Source Port: 47611
    Destination Port: 64923
    [Stream index: 17]
    [Conversation completeness: Complete, WITH_DATA (31)]
    [TCP Segment Len: 0]
    Sequence Number: 579    (relative sequence number)
    Sequence Number (raw): 1833648668
    [Next Sequence Number: 579    (relative sequence number)]
    Acknowledgment Number: 619    (relative ack number)
    Acknowledgment number (raw): 42802011
    0101 .... = Header Length: 20 bytes (5)
    Flags: 0x010 (ACK)
    Window: 64240
    [Calculated window size: 64240]
    [Window size scaling factor: -2 (no window scaling used)]
    Checksum: 0x89b6 [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0
    [Timestamps]
        [Time since first frame in this TCP stream: 0.022203000 seconds]
        [Time since previous frame in this TCP stream: 0.003129000 seconds]
    [SEQ/ACK analysis]
        [This is an ACK to the segment in frame: 1961]
        [The RTT to ACK the segment was: 0.003129000 seconds]
        [iRTT: 0.003214000 seconds]
  • 클라이언트의 SeqNumber+1 한 값을 AckNumber로 보내준 것을 확인할 수 있다.

🎁 3번 패킷(서버에서 종료하겠다는 FIN,ACK 패킷)

Transmission Control Protocol, Src Port: 47611, Dst Port: 64923, Seq: 579, Ack: 619, Len: 0
    Source Port: 47611
    Destination Port: 64923
    [Stream index: 17]
    [Conversation completeness: Complete, WITH_DATA (31)]
    [TCP Segment Len: 0]
    Sequence Number: 579    (relative sequence number)
    Sequence Number (raw): 1833648668
    [Next Sequence Number: 580    (relative sequence number)]
    Acknowledgment Number: 619    (relative ack number)
    Acknowledgment number (raw): 42802011
    0101 .... = Header Length: 20 bytes (5)
    Flags: 0x011 (FIN, ACK)
    Window: 64240
    [Calculated window size: 64240]
    [Window size scaling factor: -2 (no window scaling used)]
    Checksum: 0x89b5 [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0
    [Timestamps]
        [Time since first frame in this TCP stream: 0.022245000 seconds]
        [Time since previous frame in this TCP stream: 0.000042000 seconds]

🎁 4번 패킷(클라이언트에서 서버의 FIN,ACK를 확인했다는 ACK패킷)

Transmission Control Protocol, Src Port: 64923, Dst Port: 47611, Seq: 619, Ack: 580, Len: 0
    Source Port: 64923
    Destination Port: 47611
    [Stream index: 17]
    [Conversation completeness: Complete, WITH_DATA (31)]
    [TCP Segment Len: 0]
    Sequence Number: 619    (relative sequence number)
    Sequence Number (raw): 42802011
    [Next Sequence Number: 619    (relative sequence number)]
    Acknowledgment Number: 580    (relative ack number)
    Acknowledgment number (raw): 1833648669
    0101 .... = Header Length: 20 bytes (5)
    Flags: 0x010 (ACK)
    Window: 65392
    [Calculated window size: 65392]
    [Window size scaling factor: -2 (no window scaling used)]
    Checksum: 0xa660 [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0
    [Timestamps]
        [Time since first frame in this TCP stream: 0.022279000 seconds]
        [Time since previous frame in this TCP stream: 0.000034000 seconds]
    [SEQ/ACK analysis]
        [This is an ACK to the segment in frame: 1963]
        [The RTT to ACK the segment was: 0.000034000 seconds]
        [iRTT: 0.003214000 seconds]
  • 3번패킷에서 보낸 SequenceNumber+1을 한 값을 AckNumber로 보내주는것을 볼 수 있다.
profile
Hi🖐

0개의 댓글