TCP 3&4 handshake

HunkiKim·2022년 9월 5일
0
post-custom-banner

TCP 3&4 handshake

TCP 상태

  • CLOSED : 연결이 존재하지 않을떄
  • LISTEN : 서버에서 SYN이 오는 것을 기다리는 상태.
  • SYN-SENT : SYN을 보내고 ACK을 기다리는 상태(클라이언트)
  • SYN-RCVD : SYN을 받고 SYN+ACK을 보낸 상태(서버)
  • ESTABLISHED : ACk을 받게 되면 서버 클라이언트 각각 이상태로 들어섬
  • FIN-WAIT-1 : FIN을 클라이언트 쪽에서 보냈을 때 ACK을 기다리는 상태
  • FIN-WAIT-2 : 첫번째 FIN에 대한 ACK을 받고 다음 FIN이 날라올 때까지 기다리는 상태
  • CLOSE-WAIT : 첫번쨰 FIN을 받고 ACK을 보낸 뒤 데이터들을 보내고 ACK을 받는 상태
  • LAST-ACK : 전송이 완료되고 서버쪽에서는 FIN을 보내고 ACK을 기다리는 상태
  • TIME-WAIT : FIN이 오고 ACK을 보내준 뒤 일정 시간동안 기다림

TCP 3-way Handshake?

TCP는 장치들 사이에 논리적인 접속을 성립하기 위해 이 방식을 사용한다. 즉 연결을 위해 사용하는 것이다.

TCP 3 Way Handshake는 TCP/IP 프로토콜을 이용해서 통신을 하는 응용프로그램이 데이터 전송 전에 서로간의 컴퓨터와 세션을 맺는 과정이다 .

먼저 클라이언트에서 서버와 연결하는것을 원한다고 클라이언트 TCP에게 알린다. 그러면 클라이언트 안의 TCP는 다음과 같은 방법으로 TCP를 이용해 서버와 TCP 연결 설정을 시작한다.

  1. 먼저 클라이언트 측 TCP는 서버 TCP에게 특별한 TCP 세그먼트를 송신한다. 특별한 세그먼트는 애플리케이션 데이터를 포함하지 않는다. 그러나 헤더에 SYN 비트라고 불리는 하나의 플래그 비트를 가진다. 그래서 특별한 세그먼트를 SYN 세그먼트라고 부른다. 그리고 최초의 TCP SYN 세그먼트의 순서번호 필드에 이 번호를 넣는다. 이 세그먼트는 IP 데이터그램 안에서 캡슐화되고 서버로 송신된다.
  1. TCP SYN 세그먼트를 포함한 IP 데이터그램이 서버 호스트에 도착했을때, 서버는 데이터그램으로부터 TCP SYN를 뽑아낸다. 그리고 연결에 TCP 버퍼와 변수들을 할당한다. 또한 클라이언트 TCP로 연결 승인 세그먼트를 송신한다.또한, 이 연결 승인 세그먼트도 애플리케이션 계층 데이터를 포함하지 않는다. 그러나 세그먼트 헤더에 중요한 정보 3가지를 포함한다. 첫째, SYN 비트는 1로 설정된다. 둘째, TCP 세그먼트 헤더의 확인응답 필드는 client_isn+1로 설정된다. 마지막으로, 서버는 자신의 최초의 순서번호(server_isn)를 선택하고, TCP 세그먼트 헤더의 순서번호 필드에 이 값을 넣는다.

정리하자면 연결 승인 세그먼트는 사실상, "나는 당신의 최초 순서번호 client_isn을 가지고 연결을 시작하기 위해 당신의 SYN 패킷을 수신했다. 나는 이 연결을 동의한다. 내 자신의 최초의 순서번호는 server_sin이다"라고 하는것과 같다. 연결 승인 세그먼트는 때때로 SYNACK 세그먼트로 불린다.

  1. SYNACK 세그먼트를 수신하면, 클라이언트는 연결에 버퍼와 변수들을 할당한다. 그 다음 클라이언트는 서버로 또 다른 세그먼트를 송신한다. 이 마지막 세그먼트가 서버의 연결 승인 세그먼트를 확인한다.(클라이언트는 TCP 세그먼트 헤더의 확인응답 필드 안에 server_isn+1 값을 넣는 것으로 그 일을 한다.) 연결이 설정되었기 떄문에 SYN 비트는 0으로 설정된다. 세 방향 핸드셰잌의 세 번쨰 단계는 클라이언트에서 서버로 세그먼트 페이로드에 데이터가 운반 될 수 있다.

간단하게 정리하자면
1. 서버로 SYN(a) 패킷을 보낸다. / 상태 : CLOSED -> SYN_SENT
2. 서버는 SYN(a) 패킷에 대한 요청 수락 응답으로 ACK(a+1) 패킷과 클라이언트 포트를 열어달라는 SYN(b) 패킷을 보낸다. / 상태 : LISTEN -> SYN_RCVD
3. 클라이언트는 ACK(a+1)패킷과 SYN(b) 패킷을 받고 이에 대한 응답으로 ACK(b+1) 패킷을 보내며 연결이 성립된다./ 상태 : ESTABLISHED
4. 서버는 클라이언트의 ACK(b+1)를 받은 후 상태가 ESTABLISHED로 된다.

이렇게 연결이 성립되면 서로에게 데이터를 포함하는 세그먼트를 보낼 수 있다. 이 각각의 다음에 세그먼트들에 SYN 비트는 0으로 설정된다. 이는 암벽 등산가와 아래에 안전밧줄을 다루는 사람은 세 방향 핸드셰잌을다루는데 이와 비슷하다.

두 방향 핸드셰잌으로 안되는 이유는 서버와 클라이언트는 서로를 볼 수 없으므로, 신호를 통해서 확인해야 한다. 또한 중간에 메시지가 중간에 loss되는 경우, 2 handshake로는 확인할 수 없다. 즉 확인응답절차가 필요하기 때문에 두 방향 핸드셰잌으로는 신뢰적인 전달을 할 수없다.

TCP 4-way handshake?

연결을 했으면 종료도 해야한다. TCP 연결에 참여하는 2개의 프로세스 중 하나는 연결을 끝낼 수 있다. 연결이 끝날때, 호스트의 자원(버퍼, 변수)은 회수된다. 만약 클라이언트가 연결 종료를 결정한다고 가정하자. 클라이언트 애플리케이션 프로세스는 종료 명령을 내리고, 클라이언트 TCP가 서버 프로세스에게 특별한 TCP 세그먼트를 보내도록 한다. 특별한 세그먼트는 1로 설정된 FIN 비트라 불리는 플래그 비트를 세그먼트 헤더에 포함하고 있다. 서버가 이 세그먼트를 수신하면, 서버는 클라이언트에게 확인 세그먼트를 보낸다. 그다음에 FIN 비트가 1로 설정된 자신의 종료 세그먼트를 송신한다.마지막으로 클라이언트는 서버의 종료 세그먼트에 확인 응답을 핟나. 이 시점에서 두 호스트의 모든 자원들은 할당이 해제된다.

정리하자면
1. 클라이언트는 서버에 접속을 요청하는 FIN 플래그를 보낸다. / 상태 : ESTB -> FIN_WAIT 1
2. 서버는 FIN을 받고, 확인했다는 ACK를 클라이언트에게 보낸다. / 상태 : ESTB -> CLOSE_WAIT
1. CLOSE_WAIT는 나의 close를 wait하는 상태
2. 처리해야 할 자신의 통신이 끝날때까지 기다림
3. 이때, 클라는 서버가 close하기만 기다리며 ack를 받으면 FIN_WAIT1 -> FIN_WAIT2로 상태가 바뀐다.
3. 서버는 자신의 데이터를 다 보낸 후 연결을 종료하겠다는 FIN 플래그를 보낸다. / 상태 : CLOSE_WAIT -> LAST_ACK
1. LAST-ACK : 전송이 완료되고 서버쪽에서는 FIN을 보내고 ACK을 기다리는 상태
4. 클라이언트에서 서버의 FIN을 받고, 확인했다는 ACK를 서버로 보낸다.
1. 이때 클라는, 아직 서버로 혹시 못받은 데이터가 있을까봐 TIME_WAIT 상태로 대기(FIN을 보내고 일정시간 대기)
2. 서버는 ACK를 받으면 바로 종료 (LAST_ACK->CLOSED)(소켓을 닫음)
3. 이후 TIME_WAIT 시간이 끝나면 클라이언트도 종료한다. (TIME_WAIT -> CLOSED) 대체로 30초,1분, 또는 2분이다. 대기 시간이 끝나면 연결은 정식으로 종료되고, 클라이언트 측의 모든 자원은 해제된다. 이 TIME_WAIT는 포트 재사용 방지 및 남은 데이터를 받을 수 있게 해준다.

세방향 핸드셰잌과 달리 종료가 4단계인 이유는 클라이언트가 데이터 전송을 마쳐도 Server는 보낼 데이터가 남아있을 수 있기 때문에 일단 FIN에 대한 ACK만 보내고, 데이터를 모두 전송한 후에 자신도 FIN메세지를 보내기 때문이다. 즉 3방향은 SYN를 받으면 바로 SYN/ACK를 보내면 되지만 종료시엔 자원을 정리해야 하기 때문에 바로 보낼수 없다.

초기 Sequence Number를 난수로 설정하는 이유

연결 맺을 때 사용하는 포트는 유한 범위 내에서 사용하고 시간이 지나면 재사용 될 수 있다. 따라서 두 통신 호스트가 과거에 사용되었던 포트 번호 쌍을 사용하는 가능성이 존재한다. Sequence Number가 순차적인 숫자로 전송되면 서버는 이전의 Connection으로부터 전송되는 패킷으로 인식할 수 있다. 따라서 이런 문제를 해결하기 위해 난수로 쓴다. seq가 예측 가능하면 보안문제가 생길 수 있다.

post-custom-banner

0개의 댓글