heo-jae-won@home:~$

Network fourth week

TCP 프로토콜

  • 연결성과 신뢰성 있는 데이터 전송 프로토콜이다.
  • UDP와 달리 연결을 맺고 끊는 과정이 존재한다.
    • 연결을 맺는 과정은 3 way handshake라고 부른다.
    • 연결을 끊는 과정은 4 way handshake라고 부른다.
  • 3 way handshake의 과정은 아래와 같다.
    • client가 server에게 syn(x) 패킷을 보낸다.
      • syn패킷에 시퀀스 번호를 포함해 보낸다.
      • SYN 플래그 비트를 1로 설정한 세그먼트를 전송한다.
      • 이 때 client는 SYN_SENT이며, server는 listen 상태다.
    • server는 syn(x)을 받고 client에게 syn(y)/ack(x+1) 패킷을 보낸다.
      • client의 Sequence Number에 1을 더해 ack 패킷에 넣어 보낸다.
      • YN과 ACK 플래그 비트를 1로 설정한 새그먼트를 보낸다.
      • 이 때 client는 CLOSED이며, server는 SYN_RCV 상태다.
    • client는 server에게서 ACK(x+1)와 SYN(y) 패킷을 받고, ack 패킷(y+1)을 보낸다.
      • 이 때 client는 ESTABLISED이며, server는 ESTABLISHED가 된다.
  • 3 단계를 거치면서 클라이언트와 서버 모두 데이터를 전송하고 받을 준비가 되었다는 것을 보장한다.
  • 이러한 3way handshake connection 과정을 통해 안전한 데이터 전송이 이루어 지게 된다.

  • 4 way handshake의 과정은 아래와 같다.
    • client가 server에게 FIN패킷을 보낸다.
      • 이 때 FIN 패킷에는 ack(x)이 포함되어 있다.
      • 일단 client에서는 server에서 오는 데이터를 기다려야 한다.
      • server가 보낸 잔여 데이터에 응답하지 않으면 서버가 커넥션을 닫지 못한기 때문이다.
      • 이 때 client는 FIN_WAIT상태다.
    • server는 FIN을 받고, 확인했다는 ACK를 client에게 보낸다.
      • server는 ack을(x + 1)로 지정하고, ACK 플래그 비트를 1로 설정한 세그먼트를 전송한다.
      • server는 남은 데이터가 있다면 마저 전송을 마친 후에 close를 호출한다.
      • 이 때 server는 ClOSE_WAIT 상태다.
    • server는 연결이 종료에 합의 한다는 의미로 FIN 패킷을 client에게 보낸다.
      • server는 FIN 패킷을 보낸 뒤 client가 ack을 보내줄 때까지 기다린다.
      • 이 떄 server는 LAST_ACK 상태다.
    • client는 FIN을 받고, 확인했다는 ACK를 server에게 보낸다.
      • 아직 server로부터 받지 못한 데이터가 있을 수 있으므로 TIME_WAIT을 통해 기다린다
      • 이 때 client의 상태는 FIN_WAIT 에서 TIME-WAIT 으로 변경된다.
    • server는 ACK를 받은 이후 소켓을 닫는다 (Closed)
    • TIME_WAIT 시간이 끝나면 클라이언트도 닫는다 (Closed)
  • ClOSE_WAIT/TIME_WAIT 상태를 일정 시간 유지하는 이유는 뭘까?
    • 아직 서버/클라에서 받지 못한 데이터가 연결이 해제되어 유실되는 경우를 대비해 잉여 패킷을 기다리는 것이다.
    • 이렇게 서로 완전히 닫지 않고 약간 대기하는 것을 half close라고 한다.
      • half close가 되면 송신은 가능하지만, 수신은 불가능하거나 그 반대 상황이 된다.

  • TCP는 신뢰성 있는 프로토콜이라 불리는 이유가 있다.
  • flow control과 congestion control을 통해 데이터의 신뢰성을 보장하기 때문이다.
  • 먼저 flow control을 알아보자.
    • 송신과 수신 측 데이터 처리 속도의 차이를 해결한다.
    • receiver가 packet을 지나치게 많이 받지 않도록 조절하는 것이다.
    • receiver가 sender에게 현재 자신의 상태를 feedback 한다.
      • stop and wait: 매번 전송한 패킷에 대해 확인 응답을 받아야만 그 다음 패킷을 전송하는 방법
      • Sliding Window: 수신측에서 설정한 윈도우 크기만큼 송신측에서 확인응답없이 세그먼트를 전송하는 방법
      • 여기서 window란 단위 시간 내에 보내는 패킷의 수를 의미한다.

  • TCP는 원래 flow control 기능만 존재했다.
  • 그런데 네트워크가 활발해지면서 혼잡을 통제하기 어려워졌다.
  • 그에 따라 congestion control도 차후에 등장하게 되었다.
  • 혼잡을 피하기 위해 송신 측에서 보내는 데이터의 전송속도를 강제로 줄이는 방식이다.
    • AIMD
      • 패킷을 보내 문제없이 도착하면 window 크기를 1씩 증가시켜가며 전송
      • 패킷 전송에 실패하거나 일정 시간을 넘으면 패킷의 보내는 속도를 절반으로 줄인다.
      • 네트워크가 혼잡해지고 나서야 대역폭을 줄이는 방식이다.
    • slow start
      • 패킷을 보내 문제없이 도착하면 각 ACK 패킷마다 window size를 1씩 늘려준다
      • AIMD가 선형적으로 전송속도가 증가했던 것과 달리 지수 함수 꼴로 증가한다.
      • 대신에 혼잡 현상이 발생하면 window size를 1로 떨어뜨리게 된다.
    • fast recovery
      • 혼잡한 상태가 되면 window size를 1로 줄이지 않고 반으로 줄이고 선형증가시킨다.
      • 혼잡 상황을 한번 겪고 나서부터는 순수한 AIMD 방식으로 동작
    • fast retransmit
      • 중복된 순번의 패킷을 3개 받으면 재전송을 하게 된다.
      • 재전송은 곧 혼잡을 의미하므로 window size를 줄이게 된다.

UDP 프로토콜

  • TCP와 달리 연결을 맺는 과정 없이 데이터를 통신하는 프로토콜이다.
    • 비연결, 비신뢰의 프로토콜이다.
    • flow control, congestion control, pakce retransmit, handshake도 없다.
    • 위의 신뢰성을 보장하는 기법이 모두 없어 그만큼 속도가 빠르지만, 패킷 손실도 그만큼 높다.
    • 주로 패킷손실을 감내할 수 있는 영상 스트리밍, 인터넷전화, DNS 등에 쓰인다.
    • UDP에서도 데이터의 무결성을 위한 checksum은 존재한다.
      • 전송된 데이터의 값이 변경되었는지(무결성)를 검사하는 값으로, 수신된 데이터에 오류가 없는지 여부를 확인한다.
      • IP Header 와 UDP header에 있는 일부 정보들을 가져와 IPv4 Pseudo Header 를 만든 후에 계산해 줘야 한다.
      • checksum 값은 선택이며, 0으로 보내면 수신자 측에서 별도로 검증하지 않는다.

전송후대기 프로토콜

  • RDT는 reliable data transfer로 신뢰성 있는 데이터의 전송을 위한 프로토콜이다.
  • RDT 1.0은 완벽하게 신뢰할 수 있는 채널이라 별도의 조치가 없다. 이론적으로 존재한다.
  • RDT 2.0은 비트 오류를 가정한다.
    • ACK, NAK으로 재전송 여부를 결정하는 ARQ 프로토콜이다.
    • 기본적으론 stop and wait 방식이다.
  • RDT 2.1은 여기서 sequence number가 붙였다.
    • 중복이면 같은 seq number가 오고, 새로운 거면 +1된 seq number가 온다.
  • RDT 2.2는 NAK 대신 ACK만 사용한다.
    • 패킷의 정상 수신 여부를 ACK만으로 판별할 수 있게 되었다.
  • RDT 3.0은 비트 오류 및 패킷 손실을 가정한다.
    • 패킷이 손실되었을 때 행위는 RDT 2.2와 동일하다.
      • checksum, seq number, ACK, 재전송 등..
    • 다른 것은 패킷 손실을 검출하는 방법이 추가됐다는 점이다.
      • Timer를 이용한다. 정해진 시간안에 답변이 n번 오지 않으면 손실이라고 보는 식이다.
  • RDT 3.0까지는 모두 stop and wait 방식이라 느리다.
  • 그래서 ACK을 기다리지 않고 한꺼번에 packet을 보내는 방법이 등장했다.
  • 그게 바로 파이프라이닝 프로토콜이다. 훨씬 더 빠르다.

파이프라인 프로토콜

  • 기존의 RDT 3.0으로는 stop and wait 방식이라 고속으로 네트워크를 활용할 수가 없다.
  • RTT(Round Trip Time, 하나의 패킷이 전송되고 ACK가 돌아올 때까지의 시간)동안 다른 packet을 보낼 수 없기 때문이다.
  • 그래서 한번에 많이 보내는 프로토콜인 파이프라인 프로토콜이 개발되었다.
    • Go-Back-N
      • 만약 윈도우 크기가 3이면 ACK가 돌아올 때까지 3개까지의 메시지를 동시에 보낼 수 있는 것이다.
      • ack11은 11번 packet에만 한정된 ack이 아니라 11번 패킷까지 모두 잘받았다는 의미다.
      • 대신 어느 패킷까지 전송되었는지 알 수 없다. 누적이기 때문이다.
      • 그런 이유로 유실되어 timeout이 발생할 시 재전송할 패킷이 불분명하다. 따라서 모두 재전송해주게 된다.
      • 재전송하기 위해서 보냈던 packet은 모두 송신자가 버퍼에 담고 있어야 한다. 수신자는 버퍼가 불필요하다.
      • go-back-n의 문제는 정상 전송된 패킷이 버려지고 재전송된다는 점이다.
    • Selective repeat
      • go-back-n의 문제를 개선했다. 패킷이 유실되어 재전송할 때 선별적으로 패킷을 재전송한다.
      • go-back-n과 달리 패킷을 받을 때마다 각각 ACK를 전송시켜준다.
      • ACK 7을 받게 되면 여태까지의 패킷을 모두 받았다는 게 아니라, 7번 패킷만 받았다는 의미가 된다.
      • 패킷이 순서대로 정렬되어야 하므로 순서의 패킷을 임시로 저장해 줄 필요가 있다. 여기서는 송신자와 수신자 모두 버퍼를 사용한다.
      • 2번 패킷을 받지 못하고 3, 4번 패킷을 받았을 때 3,4번 패킷을 수신자 버퍼에 저장해주게 된다.
      • 2번 패킷을 다시 보내면 송신자는 2번 패킷과 더불어 버퍼의 내용(3, 4, 5번 패킷)도 함께 저장해준다.
      • 0, 1, 2, 3, 4, 5번 패킷이 순서대로 정렬되게 된다.
      • 시퀀스 번호를 전달하기 위해서는 세그먼트 헤더에 정보를 넣어야 하는데, 더 큰 수를 지원하려면 더 많은 비트가 필요해져서 헤더 또한 길이가 길어지게 된다.
      • 대략 window size가 N이라면 시퀀스 번호는 N*2 정도가 필요하다.
    • TCP는 두개의 방식이 섞였다.
      • buffer의 경우 sender와 receiver 양측 모두에 존재한다.
      • ack은 cumulative ACK 방식을 사용한다
      • Timer는 각 packet마다 별도로 만들지 않고 os별 공용 timer 설정을 사용한다.
      • Timeout이 되거나 3-duplicated ACK를 받았을 때 fast retransmission이 일어난다.

출처

  • https://velog.io/@nnnyeong/Network-TCP-3-way-4-way-Handshake - tcp 3/4 way handshake
  • https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=sdug12051205&logNo=221053748674 - tcp half close
  • https://gyoogle.dev/blog/computer-science/network/%ED%9D%90%EB%A6%84%EC%A0%9C%EC%96%B4%20&%20%ED%98%BC%EC%9E%A1%EC%A0%9C%EC%96%B4.html - tcp 흐름제어/혼잡제어
  • https://www.cloudflare.com/ko-kr/learning/ddos/glossary/user-datagram-protocol-udp/#:~:text=%EC%82%AC%EC%9A%A9%EC%9E%90%20%EB%8D%B0%EC%9D%B4%ED%84%B0%EA%B7%B8%EB%9E%A8%20%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C - udp
  • https://limjunho.github.io/2021/06/05/UDP-cksum.html - udp checksum
  • https://dev-nicitis.tistory.com/28 - 파이프라인 프로토콜
  • https://dev-nicitis.tistory.com/29 - timeout 설정
  • https://huammmm1.tistory.com/168 - tcp의 파이프라인 프로토콜